From 793210f7c216302d4970ebe52c2975c542f8f193 Mon Sep 17 00:00:00 2001 From: Blockhead Date: Tue, 16 Nov 2021 21:33:51 +1100 Subject: Make selection boxes of track nodes larger This reduces the difficulty of having to point at the centre of the correct track node, and hopefully does not prevent placing tracks in more than a couple of cases. Three-way turnouts on an angle may be an exception but they may be worth it. User feedback is needed. --- advtrains_train_track/init.lua | 426 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 424 insertions(+), 2 deletions(-) (limited to 'advtrains_train_track/init.lua') diff --git a/advtrains_train_track/init.lua b/advtrains_train_track/init.lua index 87720e2..5065155 100755 --- a/advtrains_train_track/init.lua +++ b/advtrains_train_track/init.lua @@ -1,6 +1,182 @@ -- 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", @@ -10,6 +186,14 @@ advtrains.register_tracks("default", { 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({ @@ -21,6 +205,59 @@ minetest.register_craft({ }, }) +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", @@ -30,6 +267,7 @@ advtrains.register_tracks("default", { 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', @@ -48,6 +286,7 @@ advtrains.register_tracks("default", { 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', @@ -59,6 +298,35 @@ minetest.register_craft({ }) -- 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", @@ -67,7 +335,10 @@ advtrains.register_tracks("default", { models_suffix=".obj", shared_texture="advtrains_dtrack_shared.png", description=attrans("Perpendicular Diamond Crossing Track"), - formats = {} + formats = {}, + get_additional_definiton = function(def, preset, suffix, rotation) + return perp_boxen[rotation] or {} + end }, advtrains.ap.t_perpcrossing) minetest.register_craft({ @@ -79,6 +350,73 @@ minetest.register_craft({ } }) +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. @@ -89,7 +427,10 @@ advtrains.register_tracks("default", { models_suffix=".obj", shared_texture="advtrains_dtrack_shared.png", description=attrans("90+Angle Diamond Crossing Track"), - formats = {} + 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', @@ -99,6 +440,7 @@ minetest.register_craft({ {'', '', 'advtrains:dtrack_placer'} } }) + -- Deprecate any rails using the old name scheme minetest.register_lbm({ label = "Upgrade legacy 4590 rails", @@ -119,6 +461,83 @@ minetest.register_lbm({ -- 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 @@ -131,6 +550,9 @@ advtrains.register_tracks("default", { 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', -- cgit v1.2.3 From 21ed1d23b5a71c962a47b5bc1f67a2833cd8f5ca Mon Sep 17 00:00:00 2001 From: Maverick2797 Date: Tue, 30 May 2023 17:07:26 +0800 Subject: Turn loading tracks into loading ramps when within the loaded area - Partially addresses Hemiptera #165 / Notabug #6 - Will recalculate wagon textures when the inventory is modified - Only acts as a loading ramp when in a loaded area. - Retains previous flood loading of entire train when area unloaded --- advtrains_train_track/init.lua | 133 +++++++++++++++++++++++++-------- advtrains_train_track/settingtypes.txt | 4 + 2 files changed, 104 insertions(+), 33 deletions(-) mode change 100755 => 100644 advtrains_train_track/init.lua create mode 100644 advtrains_train_track/settingtypes.txt (limited to 'advtrains_train_track/init.lua') diff --git a/advtrains_train_track/init.lua b/advtrains_train_track/init.lua old mode 100755 new mode 100644 index 5065155..32e1235 --- a/advtrains_train_track/init.lua +++ b/advtrains_train_track/init.lua @@ -678,8 +678,45 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end end) +local function load_wagon(wagon_id, node_inv, node_fc, unload) + local inv_modified = false + local w_inv=minetest.get_inventory({type="detached", name="advtrains_wgn_"..wagon_id}) + if w_inv and w_inv:get_list("box") then + + local wagon_data = advtrains.wagons[wagon_id] + 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(node_inv:get_list("main")) do + if w_inv:get_list("box") and w_inv:room_for_item("box", item) then + w_inv:add_item("box", item) + node_inv:remove_item("main", item) + if item.name ~= "" then inv_modified = true end + end + end + else + for _, item in ipairs(w_inv:get_list("box")) do + if node_inv:get_list("main") and node_inv:room_for_item("main", item) then + w_inv:remove_item("box", item) + node_inv:add_item("main", item) + if item.name ~= "" then inv_modified = true end + end + end + end + end + end + return inv_modified +end -local function train_load(pos, train_id, unload) +local function load_entire_train(pos, train_id, unload) -- flood load when not in an active area + if advtrains.is_node_loaded(pos) then -- leave the loading to the nodetimer if area is loaded + return + end 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 @@ -692,43 +729,60 @@ local function train_load(pos, train_id, unload) --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 + local node_inv = minetest.get_inventory({type="node", pos={x=pos.x, y=pos.y-1, z=pos.z}}) + if node_inv and train.velocity <= 2 then + for _, wagon_id in ipairs(train.trainparts) do + load_wagon(wagon_id, node_inv, node_fc, unload) + end + end +end + +local function load_wagon_on_timer(pos, unload) -- loading ramp when in an active area + if not advtrains.is_node_loaded(pos) then -- leave the loading for the flood load function. we're out of area + return true -- reset the nodetimer until the node is loaded again + end + local tid, tidx = advtrains.get_train_at_pos(pos) + if not tid or tid == "" then + return true + end -- no train to load. + + local train = advtrains.trains[tid] + 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 true + end + local node_fc = minetest.get_meta(pos):get_string("fc") or "" + if node_fc == "#" then + --track section is disabled + return true + end + local node_inv = minetest.get_inventory({type="node", pos={x=pos.x, y=pos.y-1, z=pos.z}}) + if node_inv and train.velocity <= 2 then + local _, wagon_id, wagon_data = advtrains.get_wagon_at_index(tid, tidx) + if wagon_id then + local inv_modified = load_wagon(wagon_id, node_inv, node_fc, unload) + if inv_modified then + if advtrains.wagon_prototypes[advtrains.get_wagon_prototype(wagon_data)].set_textures then + local wagon_object = advtrains.wagon_objects[wagon_id] + if wagon_object and wagon_data then + local ent = wagon_object:get_luaentity() + if ent and ent.set_textures then + ent:set_textures(wagon_data) end end end end end end + return true end - +local nodetimer_interval = minetest.settings:get("advtrains_loading_track_timer") or 1 +local function start_nodetimer(pos) + local timer = minetest.get_node_timer(pos) + timer:start(nodetimer_interval) +end advtrains.register_tracks("default", { nodename_prefix="advtrains:dtrack_unload", @@ -747,9 +801,16 @@ advtrains.register_tracks("default", { on_rightclick = function(pos, node, player) show_fc_formspec(pos, player) end, + after_place_node = function(pos) + advtrains.ndb.update(pos) + start_nodetimer(pos) + end, + on_timer = function(pos) + return load_wagon_on_timer(pos, true) + end, advtrains = { on_train_enter = function(pos, train_id) - train_load(pos, train_id, true) + load_entire_train(pos, train_id, true) end, }, } @@ -772,9 +833,16 @@ advtrains.register_tracks("default", { on_rightclick = function(pos, node, player) show_fc_formspec(pos, player) end, + after_place_node = function(pos) + advtrains.ndb.update(pos) + start_nodetimer(pos) + end, + on_timer = function(pos) + return load_wagon_on_timer(pos, false) + end, advtrains = { on_train_enter = function(pos, train_id) - train_load(pos, train_id, false) + load_entire_train(pos, train_id, false) end, }, } @@ -788,7 +856,6 @@ if minetest.get_modpath("basic_materials") then elseif minetest.get_modpath("technic") then loader_core = "technic:control_logic_unit" end ---print("Loader Core: "..loader_core) minetest.register_craft({ type="shapeless", diff --git a/advtrains_train_track/settingtypes.txt b/advtrains_train_track/settingtypes.txt new file mode 100644 index 0000000..0af0081 --- /dev/null +++ b/advtrains_train_track/settingtypes.txt @@ -0,0 +1,4 @@ +# Set the nodetimer delay for the loading tracks. +# A longer delay may cause wagons to be missed if the pass over too fast. +# A shorter delay may cause lag as wagons are checked multiple times as they pass over. +advtrains_loading_track_timer (Loading Track Timer) int 1 \ No newline at end of file -- cgit v1.2.3 From 922e654b7bef51c7ddaf510ec70880d48181dd35 Mon Sep 17 00:00:00 2001 From: orwell Date: Mon, 25 Nov 2024 22:31:26 +0100 Subject: Make Buffers become implicitly their own TCBs and signals when interlocking is enabled --- advtrains/signals.lua | 8 +- advtrains/trackplacer.lua | 16 ++-- advtrains/tracks.lua | 1 + advtrains_interlocking/database.lua | 41 +++++++++- advtrains_interlocking/mod.conf | 2 +- advtrains_interlocking/route_prog.lua | 7 +- advtrains_interlocking/signal_api.lua | 23 ++++-- advtrains_interlocking/tcb_ts_ui.lua | 146 ++++++++++++++++++++++++++++++++-- advtrains_train_track/init.lua | 29 +++++++ advtrains_train_track/mod.conf | 2 +- 10 files changed, 242 insertions(+), 33 deletions(-) (limited to 'advtrains_train_track/init.lua') diff --git a/advtrains/signals.lua b/advtrains/signals.lua index 4dec7f5..8bdd877 100644 --- a/advtrains/signals.lua +++ b/advtrains/signals.lua @@ -3,15 +3,15 @@ local mrules_wallsignal = advtrains.meseconrules -local function can_dig_func(pos) +local function can_dig_func(pos, player) if advtrains.interlocking then - return advtrains.interlocking.signal.can_dig(pos) + return advtrains.interlocking.signal.can_dig(pos, player) end return true end -local function after_dig_func(pos) +local function after_dig_func(pos, oldnode, oldmetadata, digger) if advtrains.interlocking then - return advtrains.interlocking.signal.after_dig(pos) + return advtrains.interlocking.signal.after_dig(pos, oldnode, oldmetadata, digger) end return true end diff --git a/advtrains/trackplacer.lua b/advtrains/trackplacer.lua index 6a2c7a8..1543209 100644 --- a/advtrains/trackplacer.lua +++ b/advtrains/trackplacer.lua @@ -152,12 +152,14 @@ local function check_or_bend_rail(origin, dir, pname, commit) end end -local function track_place_node(pos, node, ndef) +local function track_place_node(pos, node, ndef, pname) --atdebug("track_place_node: ",pos, node) 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) + -- resolve player again + local player = pname and core.get_player_by_name(pname) or nil + ndef.after_place_node(pos, player) -- note: itemstack and pointed_thing are NOT available here anymore (crap!) end end @@ -191,16 +193,16 @@ function tp.place_track(pos, tpg, pname, yaw) 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. + -- order of conn1/conn2: prefer conn1 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 + if advtrains.yawToDirection(yaw, conn1, conn2) == conn1 then -- does there exist a suitable double-connection rail? --atdebug("Try double conn: ",conn1, conn2) 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 + track_place_node(pos, node, pname) -- calls after_place_node implicitly return true end end @@ -220,13 +222,13 @@ function tp.place_track(pos, tpg, pname, yaw) 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 + track_place_node(pos, node, nil, pname) -- calls after_place_node implicitly return true end end -- 4. if nothing worked, set the default local node = g.default - track_place_node(pos, node) -- calls after_place_node implicitly + track_place_node(pos, node, nil, pname) -- calls after_place_node implicitly return true end diff --git a/advtrains/tracks.lua b/advtrains/tracks.lua index 661da8a..fa7b702 100644 --- a/advtrains/tracks.lua +++ b/advtrains/tracks.lua @@ -253,6 +253,7 @@ 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" +-- Impl Note: possibly duplicate code in "self contained TCB" - see interlocking/tcb_ts_ui.lua! 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.") diff --git a/advtrains_interlocking/database.lua b/advtrains_interlocking/database.lua index e77d073..75247de 100644 --- a/advtrains_interlocking/database.lua +++ b/advtrains_interlocking/database.lua @@ -802,10 +802,18 @@ function ildb.create_tcb_at(pos) end -- Remove TCB at the position and update/repair the now joined section -function ildb.remove_tcb_at(pos) +-- skip_tsrepair: should be set to true when the rail node at the TCB position is already gone. +-- Assumes the track sections are now separated and does not attempt the repair process. +function ildb.remove_tcb_at(pos, pname, skip_tsrepair) --atdebug("remove_tcb_at",pos) local pts = advtrains.encode_pos(pos) local old_tcb = track_circuit_breaks[pts] + -- unassign signals if defined + for connid=1,2 do + if old_tcb[connid].signal then + ildb.set_sigd_for_signal(old_tcb[connid].signal, nil) + end + end track_circuit_breaks[pts] = nil -- purge the track sections adjacent if old_tcb[1].ts_id then @@ -823,7 +831,9 @@ function ildb.remove_tcb_at(pos) end advtrains.interlocking.remove_tcb_marker(pos) -- If needed, merge the track sections here - ildb.check_and_repair_ts_at_pos(pos, nil) + if not skip_tsrepair then + ildb.check_and_repair_ts_at_pos(pos, pname) + end return true end @@ -973,11 +983,34 @@ function ildb.get_sigd_for_signal(pos) end return nil end -function ildb.set_sigd_for_signal(pos, sigd) +function ildb.set_sigd_for_signal(pos, sigd) -- do not use! local pts = advtrains.roundfloorpts(pos) signal_assignments[pts] = sigd end +-- Assign the signal at pos to the given TCB side. +function ildb.assign_signal_to_tcbs(pos, sigd) + local tcbs = ildb.get_tcbs(sigd) + assert(tcbs, "assign_signal_to_tcbs invalid sigd!") + tcbs.signal = pos + if not tcbs.routes then + tcbs.routes = {} + end + ildb.set_sigd_for_signal(pos, sigd) +end + +-- unassign the signal from the given sigd (looks in tcbs.signal for the signalpos) +function ildb.unassign_signal_for_tcbs(sigd) + local tcbs = advtrains.interlocking.db.get_tcbs(sigd) + if not tcbs then return end + local pos = tcbs.signal + if not pos then return end + ildb.set_sigd_for_signal(pos, nil) + tcbs.signal = nil + tcbs.route_aspect = nil + tcbs.route_remote = nil +end + -- checks if there's any influence point set to this position -- if purge is true, checks whether the associated signal still exists -- and deletes the ip if not. @@ -987,7 +1020,7 @@ function ildb.is_ip_at(pos, purge) if purge then -- is there still a signal assigned to it? for connid, sigpos in pairs(influence_points[pts]) do - local asp = advtrains.interlocking.signal_get_aspect(sigpos) + local asp = advtrains.interlocking.signal.get_aspect(sigpos) if not asp then atlog("Clearing orphaned signal influence point", pts, "/", connid) ildb.clear_ip_signal(pts, connid) diff --git a/advtrains_interlocking/mod.conf b/advtrains_interlocking/mod.conf index 3b2d029..9191dd9 100644 --- a/advtrains_interlocking/mod.conf +++ b/advtrains_interlocking/mod.conf @@ -4,4 +4,4 @@ description=Interlocking system for Advanced Trains author=orwell96 depends=advtrains -optional_depends=advtrains_train_track +#optional_depends=advtrains_train_track diff --git a/advtrains_interlocking/route_prog.lua b/advtrains_interlocking/route_prog.lua index 2f0f8ee..3bdf6d6 100644 --- a/advtrains_interlocking/route_prog.lua +++ b/advtrains_interlocking/route_prog.lua @@ -535,9 +535,12 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing) -- show formspec show_routing_form(pname, tcbpos) - advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, pname) - + return + elseif advtrains.interlocking.database.get_tcb(pos) then + -- the punched node itself is a TCB + show_routing_form(pname, pos) + advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, pname) return end if advtrains.is_passive(pos) then diff --git a/advtrains_interlocking/signal_api.lua b/advtrains_interlocking/signal_api.lua index 9b0479f..8347b1c 100644 --- a/advtrains_interlocking/signal_api.lua +++ b/advtrains_interlocking/signal_api.lua @@ -400,7 +400,8 @@ end -- 0: not a signal at all -- 1: signal has get_aspect_info() but the aspect is not variable (e.g. a sign) -- 2: signal has apply_aspect() but does not have main aspects (e.g. a pure distant signal) --- 3: Full capabilities, signal has main aspects and can be used as main/shunt signal (can be start/endpoint of a route) +-- 3: signal has main signal role but can only ever display a halt aspect, such as a bumper (can be endpoint, but not startpoint, of a route) +-- 4: Full capabilities, signal has main aspects and can be used as main/shunt signal (can be start/endpoint of a route) function signal.get_signal_cap_level(pos) local node = advtrains.ndb.get_node_or_nil(pos) local ndef = node and minetest.registered_nodes[node.name] @@ -408,6 +409,10 @@ function signal.get_signal_cap_level(pos) if ndefat and ndefat.get_aspect_info then if ndefat.apply_aspect then if ndefat.main_aspects then + -- if the table contains anything, 4, otherwise 3 + for _,_ in pairs(ndefat.main_aspects) do + return 4 + end return 3 end return 2 @@ -419,9 +424,17 @@ end ---------------- -function signal.can_dig(pos) +function signal.can_dig(pos, player) local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos) if sigd then + -- check privileges + if not player or not minetest.check_player_privs(player:get_player_name(), "interlocking") then + if not player then -- intermediate debug to uncover hard-to-find bugz + atdebug("advtrains.interlocking.signal.can_dig(",pos,") called with player==nil!") + end + return false + end + -- check if route is set local tcbs = advtrains.interlocking.db.get_tcbs(sigd) if tcbs.routeset then return false @@ -434,11 +447,7 @@ function signal.after_dig(pos, oldnode, oldmetadata, player) -- unassign signal if necessary local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos) if sigd then - local tcbs = advtrains.interlocking.db.get_tcbs(sigd) - advtrains.interlocking.db.set_sigd_for_signal(pos, nil) - tcbs.signal = nil - tcbs.route_aspect = nil - tcbs.route_remote = nil + advtrains.interlocking.db.unassign_signal_for_tcbs(sigd) minetest.chat_send_player(player:get_player_name(), "Signal has been unassigned. Name and routes are kept for reuse.") end -- TODO clear influence point diff --git a/advtrains_interlocking/tcb_ts_ui.lua b/advtrains_interlocking/tcb_ts_ui.lua index 1cdbb29..2b93234 100755 --- a/advtrains_interlocking/tcb_ts_ui.lua +++ b/advtrains_interlocking/tcb_ts_ui.lua @@ -156,7 +156,7 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing) local tcbnpos = players_assign_tcb[pname] if tcbnpos then if vector.distance(pos, tcbnpos)<=20 then - local node_ok, conns, rhe = advtrains.get_rail_info_at(pos, advtrains.all_tracktypes) + local node_ok, conns, rhe = advtrains.get_rail_info_at(pos) if node_ok and #conns == 2 then -- if there is already a tcb here, reassign it if ildb.get_tcb(pos) then @@ -189,11 +189,7 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing) if ndef and ndef.advtrains and ndef.advtrains.apply_aspect then local tcbs = ildb.get_tcbs(sigd) if tcbs then - tcbs.signal = pos - if not tcbs.routes then - tcbs.routes = {} - end - ildb.set_sigd_for_signal(pos, sigd) + ildb.assign_signal_to_tcbs(pos, sigd) minetest.chat_send_player(pname, "Configuring TCB: Successfully assigned signal.") advtrains.interlocking.show_ip_form(pos, pname, true) else @@ -212,6 +208,138 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing) end end) +-- "Self-contained TCB" +-- 2024-11-25: Buffers should become their own TCB (and signal) automatically to permit setting routes to them +-- These are support functions for this kind of node. + +-- Create an after_place_node callback for a self-contained TCB node. The parameters control additional behavior: +-- fail_silently_on_noprivs: (boolean) Does not give an error in case the placer does not have the interlocking privilege +-- auto_create_self_signal: (boolean) Automatically assign this same node as signal to the A side of the newly-created TCB +-- (this is useful for buffers as they serve both as TCB and as an always-halt signal) +function advtrains.interlocking.self_tcb_make_after_place_callback(fail_silently_on_noprivs, auto_create_self_signal) + return function(pos, player, itemstack, pointed_thing) + atdebug("selftcb apn ",pos, player, itemstack, pointed_thing) + local pname = player:get_player_name() + if not minetest.check_player_privs(pname, "interlocking") then + if not fail_silently_on_noprivs then + minetest.chat_send_player(pname, "Insufficient privileges to use this!") + end + return + end + if ildb.get_tcb(pos) then + minetest.chat_send_player(pname, "TCB already existed at this position, now linked to this node") + else + ildb.create_tcb_at(pos, pname) + end + if auto_create_self_signal then + local sigd = { p = pos, s = 1 } + local tcbs = ildb.get_tcbs(sigd) + -- make sure signal doesn't already exist + if tcbs.signal then + minetest.chat_send_player(pname, "Signal on B side already assigned!") + return + end + ildb.assign_signal_to_tcbs(pos, sigd) + -- assign influence point to itself + ildb.set_ip_signal(advtrains.roundfloorpts(pos), 1, pos) + end + end +end + +-- Create an can_dig callback for a self-contained TCB node. The parameters control additional behavior: +-- is_signal: (boolean) Whether this node is also a signal (in addition to being a TCB), e.g. when auto_create_self_signal was set. +-- Causes also the signal API's can_dig to be called +function advtrains.interlocking.self_tcb_make_can_dig_callback(is_signal) + return function(pos, player) + local pname = player and player:get_player_name() or "" + -- need to duplicate logic of the regular "can_dig_or_modify_track()" function in core/tracks.lua + if advtrains.get_train_at_pos(pos) then + minetest.chat_send_player(pname, "Can't remove track, a train is here!") + return false + end + -- end of standard checks + local tcb = ildb.get_tcb(pos) + if not tcb then + -- digging always allowed because the TCB hasn't been created (unless signal callback interjects) + if is_signal then + return advtrains.interlocking.signal.can_dig(pos, player) + else + return true + end + end + -- TCB exists + if not minetest.check_player_privs(pname, "interlocking") then + return false + end + -- fine to remove (unless signal callback interjects) + if is_signal then + return advtrains.interlocking.signal.can_dig(pos, player) + else + return true + end + end +end + +-- Create an after_dig_node callback for a self-contained TCB node. The parameters control additional behavior: +-- is_signal: (boolean) Whether this node is also a signal (in addition to being a TCB), e.g. when auto_create_self_signal was set. +-- Causes also the signal API's after_dig_node to be called +function advtrains.interlocking.self_tcb_make_after_dig_callback(is_signal) + return function(pos, oldnode, oldmetadata, player) + local pname = player:get_player_name() + if is_signal then + -- "dig" the signal first + advtrains.interlocking.signal.after_dig(pos, oldnode, oldmetadata, player) + end + if ildb.get_tcb(pos) then + -- remove the TCB + ildb.remove_tcb_at(pos, pname, true) + end + end +end + +-- Create an on_rightclick callback for a self-contained TCB node. The rightclick callback tries to repeat the TCB assignment +-- if necessary and otherwise shows the TCB formspec. The parameters control additional behavior: +-- fail_silently_on_noprivs: (boolean) Does not give an error in case the placer does not have the interlocking privilege +-- auto_create_self_signal: (boolean) Automatically assign this same node as signal to the B side of the +-- newly-created TCB if that has not already happened during place. +-- Otherwise, opens the signal dialog instead of the TCB dialog on rightclick +function advtrains.interlocking.self_tcb_make_on_rightclick_callback(fail_silently_on_noprivs, auto_create_self_signal) + return function(pos, node, player, itemstack, pointed_thing) + local pname = player:get_player_name() + if not minetest.check_player_privs(pname, "interlocking") then + if not fail_silently_on_noprivs then + minetest.chat_send_player(pname, "Insufficient privileges to use this!") + end + return + end + if ildb.get_tcb(pos) then + -- TCB already here. go on + else + -- otherwise create tcb + ildb.create_tcb_at(pos, pname) + end + if auto_create_self_signal then + local sigd = { p = pos, s = 1 } + local tcbs = ildb.get_tcbs(sigd) + -- make sure signal doesn't already exist + if not tcbs.signal then + -- go ahead and assign signal + ildb.assign_signal_to_tcbs(pos, sigd) + -- assign influence point to itself + ildb.set_ip_signal(advtrains.roundfloorpts(pos), 1, pos) + end + -- in any case open the signalling form nouw + local control = player:get_player_control() + advtrains.interlocking.show_signal_form(pos, node, pname, control.aux1) + return + else + -- not an autosignal. Then show the TCB form + advtrains.interlocking.show_tcb_form(pos, pname) + return + end + end +end + -- TCB Form local function mktcbformspec(pos, side, tcbs, offset, pname) @@ -666,7 +794,7 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte, calle -- no route is active, and no route is so far defined if not tcbs.signal then atwarn("signalling form missing signal?!", pos) return end -- safeguard, nothing else in this function checks tcbs.signal local caps = advtrains.interlocking.signal.get_signal_cap_level(tcbs.signal) - if caps >= 3 then + if caps >= 4 then -- offer user the "block signal mode" form = form.."label[0.5,2.5;No routes are yet defined.]" if hasprivs then @@ -683,6 +811,10 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte, calle .."Sets a route into the section ahead with auto-working set on\n" .."Short block: This signal becomes distant signal for next signal.]" end + elseif caps >= 3 then + -- it's a buffer! + form = form.."label[0.5,2.5;This is an always-halt signal (e.g. a buffer)\n" + .."No routes can be set from here.]" else -- signal caps say it cannot be route start/end form = form.."label[0.5,2.5;This is a Non-Halt signal (e.g. pure distant signal)\n" diff --git a/advtrains_train_track/init.lua b/advtrains_train_track/init.lua index 32e1235..f551ec5 100644 --- a/advtrains_train_track/init.lua +++ b/advtrains_train_track/init.lua @@ -600,6 +600,35 @@ advtrains.register_tracks("default", { --bumpers still use the old texture until the models are redone. description=attrans("Bumper"), formats={}, + get_additional_definiton = function(def, preset, suffix, rotation) + -- 2024-11-25: Bumpers get the additional feature of being both a signal and a self-contained TCB, when interlocking is used. + if advtrains.interlocking then + return { + -- use the special callbacks for self_tcb (see tcb_ts_ui.lua) + can_dig = advtrains.interlocking.self_tcb_make_can_dig_callback(true), + after_dig_node = advtrains.interlocking.self_tcb_make_after_dig_callback(true), + after_place_node = advtrains.interlocking.self_tcb_make_after_place_callback(true, true), + on_rightclick = advtrains.interlocking.self_tcb_make_on_rightclick_callback(false, true), + advtrains = { + main_aspects = { + -- No main aspects, it always shows Stop. + -- But we need to define the table so that signal caplevel is 3 + }, + apply_aspect = function(pos, node, main_aspect, rem_aspect, rem_aspinfo) + -- is a no-op for bumpers, it always shows Stop + end, + get_aspect_info = function(pos, main_aspect) + -- it always shows Stop + return advtrains.interlocking.signal.ASPI_HALT + end, + distant_support = false, -- not a distant + route_role = "end", -- the end is nigh! + } + } + else + return {} -- no additional defs when interlocking is not used + end + end, }, advtrains.ap.t_30deg_straightonly) minetest.register_craft({ output = 'advtrains:dtrack_bumper_placer 2', diff --git a/advtrains_train_track/mod.conf b/advtrains_train_track/mod.conf index 2aece3e..a7fef4d 100644 --- a/advtrains_train_track/mod.conf +++ b/advtrains_train_track/mod.conf @@ -4,4 +4,4 @@ description=Default track set for Advanced Trains author=orwell96 depends=advtrains -optional_depends=mesecons,digtron +optional_depends=mesecons,digtron,advtrains_interlocking -- cgit v1.2.3 From 867eb387c5893b004996d6e68efddd9ca2fca36a Mon Sep 17 00:00:00 2001 From: Maverick2797 Date: Fri, 28 Mar 2025 22:28:11 +0800 Subject: Add craft recipes for LuaATC components --- advtrains_luaautomation/init.lua | 3 +++ advtrains_luaautomation/recipes.lua | 27 +++++++++++++++++++++++++++ advtrains_luaautomation/settingtypes.txt | 2 ++ advtrains_train_track/init.lua | 8 ++++++++ 4 files changed, 40 insertions(+) create mode 100644 advtrains_luaautomation/recipes.lua create mode 100644 advtrains_luaautomation/settingtypes.txt (limited to 'advtrains_train_track/init.lua') diff --git a/advtrains_luaautomation/init.lua b/advtrains_luaautomation/init.lua index b359142..a2f4eb9 100644 --- a/advtrains_luaautomation/init.lua +++ b/advtrains_luaautomation/init.lua @@ -40,6 +40,9 @@ dofile(mp.."/pcnaming.lua") dofile(mp.."/chatcmds.lua") +if minetest.settings:get_bool("advtrains_luaautomation_enable_atlac_recipes",false) == true then + dofile(mp.."/recipes.lua") +end local filename=minetest.get_worldpath().."/advtrains_luaautomation" diff --git a/advtrains_luaautomation/recipes.lua b/advtrains_luaautomation/recipes.lua new file mode 100644 index 0000000..16121a8 --- /dev/null +++ b/advtrains_luaautomation/recipes.lua @@ -0,0 +1,27 @@ +-- depends on default, digilines and mesecons for crafting recipes +minetest.register_craft({ + output = "advtrains_luaautomation:dtrack_placer", + recipe = { + {"","mesecons_luacontroller:luacontroller0000",""}, + {"","advtrains:dtrack_atc_placer",""}, + {"","digilines:wire_std_00000000",""}, + } +}) + +minetest.register_craft({ + output = "advtrains_luaautomation:mesecon_controller0000", + recipe = { + {"","mesecons:wire_00000000_off",""}, + {"mesecons:wire_00000000_off","advtrains_luaautomation:dtrack_placer","mesecons:wire_00000000_off"}, + {"","mesecons:wire_00000000_off",""}, + } +}) + +minetest.register_craft({ + output = "advtrains_luaautomation:oppanel", + recipe = { + {"","mesecons_button:button_off",""}, + {"","advtrains_luaautomation:mesecon_controller0000",""}, + {"","default:stone",""}, + } +}) \ No newline at end of file diff --git a/advtrains_luaautomation/settingtypes.txt b/advtrains_luaautomation/settingtypes.txt new file mode 100644 index 0000000..20ed52e --- /dev/null +++ b/advtrains_luaautomation/settingtypes.txt @@ -0,0 +1,2 @@ +# Enable or disable craft recipes for LuaATC components +advtrains_luaautomation_enable_atlac_recipes (Enable LuaATC component craft recipes) bool true \ No newline at end of file diff --git a/advtrains_train_track/init.lua b/advtrains_train_track/init.lua index f551ec5..35937bc 100644 --- a/advtrains_train_track/init.lua +++ b/advtrains_train_track/init.lua @@ -654,6 +654,14 @@ advtrains.register_tracks("default", { get_additional_definiton = advtrains.atc_function }, advtrains.trackpresets.t_30deg_straightonly) +minetest.register_craft({ + output = "advtrains:dtrack_atc_placer", + recipe = { + {"","mesecons_microcontroller:microcontroller0000",""}, + {"","advtrains:dtrack_placer",""}, + {"","",""} + } +}) -- Tracks for loading and unloading trains -- Copyright (C) 2017 Gabriel Pérez-Cerezo -- cgit v1.2.3