2016-05-29 11:27:30 -07:00
--advtrains by orwell96, see readme.txt
2016-08-26 09:13:16 -07:00
--dev-time settings:
--EDIT HERE
--If the old non-model rails on straight tracks should be replaced by the new...
--false: no
--true: yes
2016-12-03 14:53:12 -08:00
advtrains.register_replacement_lbms = false
2016-08-26 09:13:16 -07:00
2016-05-29 11:27:30 -07:00
--[[TracksDefinition
nodename_prefix
texture_prefix
description
2016-07-04 04:08:25 -07:00
common = { }
2016-05-29 11:27:30 -07:00
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 = { }
2016-08-22 13:41:09 -07:00
--definition preparation
2017-12-18 12:44:36 -08:00
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
2016-08-22 13:41:09 -07:00
2017-08-20 05:32:38 -07:00
advtrains.ap = { }
advtrains.ap . t_30deg_flat = {
2016-08-22 13:41:09 -07:00
regstep = 1 ,
variant = {
2017-12-18 12:44:36 -08:00
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 = " swlcr " ,
switchmc = " on " ,
switchst = " st " ,
} ,
swlcr = {
conns = conns3 ( 0 , 7 , 8 ) ,
desc = " left switch (curve) " ,
trackworker = " swrcr " ,
switchalt = " swlst " ,
switchmc = " off " ,
switchst = " cr " ,
} ,
swrst = {
conns = conns3 ( 0 , 8 , 9 ) ,
desc = " right switch (straight) " ,
trackworker = " st " ,
switchalt = " swrcr " ,
switchmc = " on " ,
switchst = " st " ,
} ,
swrcr = {
conns = conns3 ( 0 , 9 , 8 ) ,
desc = " right switch (curve) " ,
trackworker = " st " ,
switchalt = " swrst " ,
switchmc = " off " ,
switchst = " cr " ,
} ,
2017-02-01 15:02:11 -08:00
} ,
2016-11-10 13:58:27 -08:00
regtp = true ,
2016-08-22 13:41:09 -07:00
tpdefault = " st " ,
trackworker = {
[ " swrcr " ] = " st " ,
[ " swrst " ] = " st " ,
[ " cr " ] = " swlst " ,
[ " swlcr " ] = " swrcr " ,
[ " swlst " ] = " swrst " ,
} ,
2017-03-09 02:09:01 -08:00
rotation = { " " , " _30 " , " _45 " , " _60 " } ,
}
2017-08-20 05:32:38 -07:00
advtrains.ap . t_30deg_slope = {
2017-03-09 02:09:01 -08:00
regstep = 1 ,
variant = {
2017-12-18 12:44:36 -08:00
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 } ,
2017-03-09 02:09:01 -08:00
} ,
2016-12-13 10:28:10 -08:00
regsp = true ,
slopeplacer = {
[ 2 ] = { " vst1 " , " vst2 " } ,
[ 3 ] = { " vst31 " , " vst32 " , " vst33 " } ,
max = 3 , --highest entry
} ,
slopeplacer_45 = {
[ 2 ] = { " vst1_45 " , " vst2_45 " } ,
max = 2 ,
} ,
2016-08-22 13:41:09 -07:00
rotation = { " " , " _30 " , " _45 " , " _60 " } ,
2017-03-09 02:09:01 -08:00
trackworker = { } ,
2016-12-13 10:28:10 -08:00
increativeinv = { } ,
2016-08-22 13:41:09 -07:00
}
2017-08-20 05:32:38 -07:00
advtrains.ap . t_30deg_straightonly = {
2016-11-10 12:08:39 -08:00
regstep = 1 ,
variant = {
2017-12-18 12:44:36 -08:00
st = {
conns = conns ( 0 , 8 ) ,
desc = " straight " ,
tpdouble = true ,
tpsingle = true ,
trackworker = " st " ,
} ,
2016-11-10 12:08:39 -08:00
} ,
2016-11-10 13:58:27 -08:00
regtp = true ,
tpdefault = " st " ,
rotation = { " " , " _30 " , " _45 " , " _60 " } ,
}
2017-08-20 05:32:38 -07:00
advtrains.ap . t_30deg_straightonly_noplacer = {
2016-11-10 13:58:27 -08:00
regstep = 1 ,
variant = {
2017-12-18 12:44:36 -08:00
st = {
conns = conns ( 0 , 8 ) ,
desc = " straight " ,
tpdouble = true ,
tpsingle = true ,
trackworker = " st " ,
} ,
2016-11-10 12:08:39 -08:00
} ,
tpdefault = " st " ,
rotation = { " " , " _30 " , " _45 " , " _60 " } ,
}
2017-08-20 05:32:38 -07:00
advtrains.ap . t_45deg = {
2016-08-22 13:41:09 -07:00
regstep = 2 ,
variant = {
2017-12-18 12:44:36 -08:00
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 = " swlcr " ,
switchmc = " on " ,
switchst = " st " ,
} ,
swlcr = {
conns = conns3 ( 0 , 6 , 8 ) ,
desc = " left switch (curve) " ,
trackworker = " swrcr " ,
switchalt = " swlst " ,
switchmc = " off " ,
switchst = " cr " ,
} ,
swrst = {
conns = conns3 ( 0 , 8 , 10 ) ,
desc = " right switch (straight) " ,
trackworker = " st " ,
switchalt = " swrcr " ,
switchmc = " on " ,
switchst = " st " ,
} ,
swrcr = {
conns = conns3 ( 0 , 10 , 8 ) ,
desc = " right switch (curve) " ,
trackworker = " st " ,
switchalt = " swrst " ,
switchmc = " off " ,
switchst = " cr " ,
} ,
2017-02-01 15:02:11 -08:00
} ,
2016-11-10 13:58:27 -08:00
regtp = true ,
2016-08-22 13:41:09 -07:00
tpdefault = " st " ,
trackworker = {
[ " swrcr " ] = " st " ,
[ " swrst " ] = " st " ,
[ " cr " ] = " swlst " ,
[ " swlcr " ] = " swrcr " ,
[ " swlst " ] = " swrst " ,
} ,
2017-12-18 12:44:36 -08:00
rotation = { " " , " _30 " , " _45 " , " _60 " } ,
2016-08-22 13:41:09 -07:00
}
2017-08-20 05:32:38 -07:00
advtrains.trackpresets = advtrains.ap
2016-08-22 13:41:09 -07:00
--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
2017-12-18 12:44:36 -08:00
}
[ 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
] ]
2016-08-22 13:41:09 -07:00
function advtrains . register_tracks ( tracktype , def , preset )
advtrains.trackplacer . register_tracktype ( def.nodename_prefix , preset.tpdefault )
2016-11-10 13:58:27 -08:00
if preset.regtp then
advtrains.trackplacer . register_track_placer ( def.nodename_prefix , def.texture_prefix , def.description )
end
2016-12-13 10:28:10 -08:00
if preset.regsp then
advtrains.slope . register_placer ( def , preset )
end
2017-12-18 12:44:36 -08:00
for suffix , var in pairs ( preset.variant ) do
2016-08-22 13:41:09 -07:00
for rotid , rotation in ipairs ( preset.rotation ) do
if not def.formats [ suffix ] or def.formats [ suffix ] [ rotid ] then
2017-12-18 12:44:36 -08:00
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 / 2 , - 1 / 2 , 1 / 2 , - 1 / 2 + 1 / 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 = 1 ,
2018-03-14 12:57:07 -07:00
advtrains_track = 1 ,
2017-12-18 12:44:36 -08:00
[ " advtrains_track_ " .. tracktype ] = 1 ,
save_in_at_nodedb = 1 ,
dig_immediate = 2 ,
not_in_creative_inventory = 1 ,
not_blocking_trains = 1 ,
} ,
can_dig = function ( pos )
return not advtrains.get_train_at_pos ( pos )
end ,
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 )
if var.switchalt and var.switchst then
local switchfunc = function ( pos , node , newstate )
if newstate ~= var.switchst then
advtrains.ndb . swap_node ( pos , { name = def.nodename_prefix .. " _ " .. var.switchalt .. rotation , param2 = node.param2 } )
advtrains.invalidate_all_paths ( pos )
end
end
ndef.on_rightclick = function ( pos , node , player )
2018-03-14 12:57:07 -07:00
if advtrains.check_turnout_signal_protection ( pos , player : get_player_name ( ) ) then
2017-12-18 12:44:36 -08:00
switchfunc ( pos , node )
2018-02-21 10:58:45 -08:00
advtrains.log ( " Switch " , player : get_player_name ( ) , pos )
2017-12-18 12:44:36 -08:00
end
end
if var.switchmc then
ndef.mesecons = { effector = {
[ " action_ " .. var.switchmc ] = switchfunc ,
rules = advtrains.meseconrules
} }
end
ndef.luaautomation = {
getstate = var.switchst ,
setstate = switchfunc ,
}
2016-08-22 13:41:09 -07:00
end
2017-12-18 12:44:36 -08:00
2016-11-10 13:58:27 -08:00
local adef = { }
if def.get_additional_definiton then
adef = def.get_additional_definiton ( def , preset , suffix , rotation )
end
2017-12-18 12:44:36 -08:00
ndef = advtrains.merge_tables ( ndef , adef )
2016-11-10 13:58:27 -08:00
2017-12-18 12:44:36 -08:00
minetest.register_node ( " : " .. def.nodename_prefix .. " _ " .. suffix .. rotation , ndef )
2016-08-22 13:41:09 -07:00
--trackplacer
2016-11-10 13:58:27 -08:00
if preset.regtp then
2017-12-18 12:44:36 -08:00
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 )
2016-11-10 13:58:27 -08:00
end
2017-12-18 12:44:36 -08:00
if var.tpsingle then
advtrains.trackplacer . add_single_conn ( def.nodename_prefix , suffix , rotation , tpconns )
2016-11-10 13:58:27 -08:00
end
2016-08-22 13:41:09 -07:00
end
2017-12-18 12:44:36 -08:00
advtrains.trackplacer . add_worked ( def.nodename_prefix , suffix , rotation , var.trackworker )
2016-08-22 13:41:09 -07:00
end
2016-08-21 07:30:36 -07:00
end
end
2016-12-22 09:55:10 -08:00
advtrains.all_tracktypes [ tracktype ] = true
2016-08-21 07:30:36 -07:00
end
2016-12-22 09:55:10 -08:00
function advtrains . is_track_and_drives_on ( nodename , drives_on_p )
2017-11-22 14:13:42 -08:00
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
2016-05-29 11:27:30 -07:00
if not minetest.registered_nodes [ nodename ] then
return false
end
local nodedef = minetest.registered_nodes [ nodename ]
2017-11-22 14:13:42 -08:00
for k , v in pairs ( drives_on ) do
2016-12-22 09:55:10 -08:00
if nodedef.groups [ " advtrains_track_ " .. k ] then
2016-05-29 11:27:30 -07:00
return true
end
end
return false
end
function advtrains . get_track_connections ( name , param2 )
local nodedef = minetest.registered_nodes [ name ]
2017-12-18 12:44:36 -08:00
if not nodedef then atprint ( " get_track_connections couldn't find nodedef for nodename " .. ( name or " nil " ) ) return nil end
2016-05-29 11:27:30 -07:00
local noderot = param2
if not param2 then noderot = 0 end
2017-01-08 12:10:02 -08:00
if noderot > 3 then atprint ( " get_track_connections: rail has invaild param2 of " .. noderot ) noderot = 0 end
2016-05-29 11:27:30 -07:00
2017-01-04 12:23:15 -08:00
local tracktype
for k , _ in pairs ( nodedef.groups ) do
local tt = string.match ( k , " ^advtrains_track_(.+)$ " )
if tt then
tracktype = tt
end
end
2017-12-18 12:44:36 -08:00
return advtrains.rotate_conn_by ( nodedef.at_conns , noderot * AT_CMAX / 4 ) , ( nodedef.at_rail_y or 0 ) , tracktype
2016-05-29 11:27:30 -07:00
end
2016-11-10 11:24:47 -08:00
--detector code
--holds a table with nodes on which trains are on.
advtrains.detector = { }
advtrains.detector . on_node = { }
2017-10-25 02:49:34 -07:00
--Returns true when position is occupied by a train other than train_id, false when occupied by the same train as train_id and nil in case there's no train at all
function advtrains . detector . occupied ( pos , train_id )
local ppos = advtrains.round_vector_floor_y ( pos )
local pts = minetest.pos_to_string ( ppos )
local s = advtrains.detector . on_node [ pts ]
if not s then return nil end
if s == train_id then return false end
--in case s is a table, it's always occupied by another train
return true
end
-- If given a train id as second argument, this is considered as 'not there'.
-- Returns the train id of (one of, nondeterministic) the trains at this position
function advtrains . detector . get ( pos , train_id )
2017-01-27 14:43:01 -08:00
local ppos = advtrains.round_vector_floor_y ( pos )
2017-02-03 11:40:30 -08:00
local pts = minetest.pos_to_string ( ppos )
2017-10-25 02:49:34 -07:00
local s = advtrains.detector . on_node [ pts ]
if not s then return nil end
if type ( s ) == " table " then
for _ , t in ipairs ( s ) do
if t ~= train_id then return t end
end
return nil
end
return s
end
function advtrains . detector . enter_node ( pos , train_id )
advtrains.detector . stay_node ( pos , train_id )
local ppos = advtrains.round_vector_floor_y ( pos )
2017-01-27 14:43:01 -08:00
advtrains.detector . call_enter_callback ( ppos , train_id )
2016-11-10 11:24:47 -08:00
end
function advtrains . detector . leave_node ( pos , train_id )
2017-01-27 14:43:01 -08:00
local ppos = advtrains.round_vector_floor_y ( pos )
2017-10-25 02:49:34 -07:00
local pts = minetest.pos_to_string ( ppos )
local s = advtrains.detector . on_node [ pts ]
if type ( s ) == " table " then
local i
for j , t in ipairs ( s ) do
if t == train_id then i = j end
end
if not i then return end
s = table.remove ( s , i )
if # s == 0 then
s = nil
elseif # s == 1 then
s = s [ 1 ]
end
advtrains.detector . on_node [ pts ] = s
else
advtrains.detector . on_node [ pts ] = nil
end
2017-01-27 14:43:01 -08:00
advtrains.detector . call_leave_callback ( ppos , train_id )
2016-11-10 11:24:47 -08:00
end
2017-01-27 14:43:01 -08:00
function advtrains . detector . stay_node ( pos , train_id )
local ppos = advtrains.round_vector_floor_y ( pos )
2017-02-03 11:40:30 -08:00
local pts = minetest.pos_to_string ( ppos )
2017-10-25 02:49:34 -07:00
local s = advtrains.detector . on_node [ pts ]
if not s then
advtrains.detector . on_node [ pts ] = train_id
elseif type ( s ) == " string " then
advtrains.detector . on_node [ pts ] = { s , train_id }
elseif type ( s ) == " table " then
advtrains.detector . on_node [ pts ] = table.insert ( s , train_id )
end
2016-11-10 11:24:47 -08:00
end
2017-01-27 14:43:01 -08:00
2016-11-10 11:24:47 -08:00
function advtrains . detector . call_enter_callback ( pos , train_id )
2017-01-16 11:07:04 -08:00
--atprint("instructed to call enter calback")
2016-11-10 11:24:47 -08:00
2017-02-03 11:40:30 -08:00
local node = advtrains.ndb . get_node ( pos ) --this spares the check if node is nil, it has a name in any case
2016-11-10 11:24:47 -08:00
local mregnode = minetest.registered_nodes [ node.name ]
if mregnode and mregnode.advtrains and mregnode.advtrains . on_train_enter then
mregnode.advtrains . on_train_enter ( pos , train_id )
2017-01-04 03:02:00 -08:00
end
2016-11-10 11:24:47 -08:00
end
function advtrains . detector . call_leave_callback ( pos , train_id )
2017-01-16 11:07:04 -08:00
--atprint("instructed to call leave calback")
2016-11-10 11:24:47 -08:00
2017-02-03 11:40:30 -08:00
local node = advtrains.ndb . get_node ( pos ) --this spares the check if node is nil, it has a name in any case
2016-11-10 11:24:47 -08:00
local mregnode = minetest.registered_nodes [ node.name ]
if mregnode and mregnode.advtrains and mregnode.advtrains . on_train_leave then
mregnode.advtrains . on_train_leave ( pos , train_id )
end
end
2016-12-13 10:28:10 -08:00
-- slope placer. Defined in register_tracks.
--crafted with rail and gravel
local sl = { }
function sl . register_placer ( def , preset )
2017-08-20 05:32:38 -07:00
minetest.register_craftitem ( " : " .. def.nodename_prefix .. " _slopeplacer " , {
2017-01-23 12:29:59 -08:00
description = attrans ( " @1 Slope " , def.description ) ,
2016-12-13 10:28:10 -08:00
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
2017-01-23 12:29:59 -08:00
minetest.chat_send_player ( player : get_player_name ( ) , attrans ( " Can't place: not pointing at node " ) )
2016-12-13 10:28:10 -08:00
return istack
end
local pos = pt.above
if not pos then
2017-01-23 12:29:59 -08:00
minetest.chat_send_player ( player : get_player_name ( ) , attrans ( " Can't place: not pointing at node " ) )
2016-12-13 10:28:10 -08:00
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
2017-01-23 12:29:59 -08:00
minetest.chat_send_player ( player : get_player_name ( ) , attrans ( " Can't place: space occupied! " ) )
2016-12-13 10:28:10 -08:00
return istack
end
2017-03-30 12:21:03 -07:00
if advtrains.is_protected ( pos , player : get_player_name ( ) ) then
minetest.record_protection_violation ( pos , player : get_player_name ( ) )
2016-12-13 10:28:10 -08:00
return istack
end
--determine player orientation (only horizontal component)
--get_look_horizontal may not be available
2016-12-13 10:49:28 -08:00
local yaw = player.get_look_horizontal and player : get_look_horizontal ( ) or ( player : get_look_yaw ( ) - math.pi / 2 )
2016-12-13 10:28:10 -08:00
--rounding unit vectors is a nice way for selecting 1 of 8 directions since sin(30°) is 0.5.
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?
2017-03-30 12:21:03 -07:00
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
2016-12-13 10:28:10 -08:00
--do slopes of this distance exist?
if lookup [ step ] then
2017-06-07 03:53:52 -07:00
if minetest.settings : get_bool ( " creative_mode " ) or istack : get_count ( ) >= step then
2016-12-13 10:28:10 -08:00
--start placing
local placenodes = lookup [ step ]
while step > 0 do
minetest.set_node ( pos , { name = def.nodename_prefix .. " _ " .. placenodes [ step ] , param2 = param2 } )
2017-06-07 03:53:52 -07:00
if not minetest.settings : get_bool ( " creative_mode " ) then
2016-12-13 10:40:20 -08:00
istack : take_item ( )
end
2016-12-13 10:28:10 -08:00
step = step - 1
pos = vector.subtract ( pos , dirvec )
end
else
2017-01-23 12:29:59 -08:00
minetest.chat_send_player ( player : get_player_name ( ) , attrans ( " Can't place: Not enough slope items left (@1 required) " , step ) )
2016-12-13 10:28:10 -08:00
end
else
2017-01-23 12:29:59 -08:00
minetest.chat_send_player ( player : get_player_name ( ) , attrans ( " Can't place: There's no slope of length @1 " , step ) )
2016-12-13 10:28:10 -08:00
end
return istack
end
step = step + 1
pos = vector.add ( pos , dirvec )
end
2017-01-23 12:29:59 -08:00
minetest.chat_send_player ( player : get_player_name ( ) , attrans ( " Can't place: no supporting node at upper end. " ) )
2016-12-13 10:28:10 -08:00
return itemstack
end
end
advtrains.slope = sl
2016-08-22 13:41:09 -07:00
--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
} ] ]
2016-05-29 11:27:30 -07:00