From 00dccd18234a178490a1bc187b73069bbaf84a93 Mon Sep 17 00:00:00 2001 From: teknomunk Date: Sun, 31 Mar 2024 11:13:50 +0000 Subject: [PATCH] Fix mcl_util.table_merge where a standard value overwrites a table, fix base definition usage, implement behavior difference when there is a solid block after a straight piece of track (this will eventually allow minecarts to fly off the end of the track) --- mods/CORE/mcl_util/init.lua | 2 +- mods/ENTITIES/mcl_minecarts/functions.lua | 2 +- mods/ENTITIES/mcl_minecarts/rails.lua | 135 ++++++++++++++-------- 3 files changed, 86 insertions(+), 53 deletions(-) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index bd9c68ac7..4722ad575 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -1161,7 +1161,7 @@ end local function table_merge(base, overlay) for k,v in pairs(overlay) do - if type(base[k]) == "table" then + if type(base[k]) == "table" and type(v) == "table" then table_merge(base[k], v) else base[k] = v diff --git a/mods/ENTITIES/mcl_minecarts/functions.lua b/mods/ENTITIES/mcl_minecarts/functions.lua index 985fadb46..f8adf8b7f 100644 --- a/mods/ENTITIES/mcl_minecarts/functions.lua +++ b/mods/ENTITIES/mcl_minecarts/functions.lua @@ -149,7 +149,7 @@ local function update_rail_connections(pos, update_neighbors) local node = minetest.get_node(neighbor) local nodedef = minetest.registered_nodes[node.name] - -- TODO: modify to only allow connections to the ends of rails (direction rules) + -- Only allow connections to the open ends of rails, as decribed by get_next_dir if (nodedef.groups or {}).rail and nodedef._mcl_minecarts and nodedef._mcl_minecarts.get_next_dir then local diff = vector.direction(neighbor, pos) local next_dir = nodedef._mcl_minecarts.get_next_dir(neighbor, diff, node) diff --git a/mods/ENTITIES/mcl_minecarts/rails.lua b/mods/ENTITIES/mcl_minecarts/rails.lua index e4770f39b..8ecf0c8ec 100644 --- a/mods/ENTITIES/mcl_minecarts/rails.lua +++ b/mods/ENTITIES/mcl_minecarts/rails.lua @@ -77,12 +77,20 @@ local function register_rail(itemstring, tiles, def_extras, creative) table_merge(ndef, def_extras) minetest.register_node(itemstring, ndef) end + +-- Now get the translator after we have finished using S for other things +mod.text = mod.text or {} +mod.text.railuse = railuse local BASE_DEF = { + description = S("New Rail"), -- Temporary name to make debugging easier + _tt_help = S("Track for minecarts"), _doc_items_usagehelp = railuse, - groups = { - rail = 1, - }, + _doc_items_longdesc = S("Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction."), + after_place_node = function(pos, placer, itemstack, pointed_thing) + update_rail_connections(pos, true) + end, drawtype = "nodebox", + groups = RAIL_DEFAULT_GROUPS, node_box = { type = "fixed", fixed = { @@ -93,7 +101,6 @@ local BASE_DEF = { paramtype2 = "facedir", } table_merge(BASE_DEF, RAIL_DEFAULTS) -- Merge together old rail values -table_merge(BASE_DEF.groups, RAIL_DEFAULT_GROUPS) local SLOPED_RAIL_DEF = table.copy(BASE_DEF) table_merge(SLOPED_RAIL_DEF,{ @@ -115,22 +122,18 @@ table_merge(SLOPED_RAIL_DEF,{ } }) -local function register_rail_v2(itemstring, def) - assert(def.tiles) +local function register_rail_v2(itemstring, ndef) + assert(ndef.tiles) -- Extract out the craft recipe - local craft = def.craft - def.craft = nil - - -- Merge together the definition with the base definition - local ndef = table.copy(def) - table_merge(ndef, BASE_DEF) + local craft = ndef.craft + ndef.craft = nil -- Add sensible defaults if not ndef.inventory_image then ndef.inventory_image = ndef.tiles[1] end if not ndef.wield_image then ndef.wield_image = ndef.tiles[1] end - --print("registering rail "..itemstring.." with definition: "..dump(ndef)) + print("registering rail "..itemstring.." with definition: "..dump(ndef)) -- Make registrations minetest.register_node(itemstring, ndef) @@ -139,18 +142,34 @@ end mod.register_rail = register_rail_v2 local function rail_dir_straight(pos, dir, node) - if node.param2 == 0 or node.param2 == 2 then - if vector.equals(dir, north) then - return north + local function inside(pos,dir,node) + if node.param2 == 0 or node.param2 == 2 then + if vector.equals(dir, north) then + return north + else + return south + end else - return south + if vector.equals(dir,east) then + return east + else + return west + end end + end + + local raw_dir = inside(pos, dir, node) + + -- Handle reversing if there is a solid block in the next position + -- Only do this for straight tracks + local next_pos = vector.add(pos, raw_dir) + local next_node = minetest.get_node(next_pos) + local node_def = minetest.registered_nodes[next_node.name] + if node_def and node_def.groups and node_def.groups.solid then + -- Reverse the direction without giving -0 members + return vector.direction(next_pos, pos) else - if vector.equals(dir,east) then - return east - else - return west - end + return raw_dir end end local function rail_dir_curve(pos, dir, node) @@ -181,50 +200,61 @@ local function rail_dir_curve(pos, dir, node) end end +local function rail_dir_tee(pos, dir, node) + -- TODO: implement + return north +end + local function rail_dir_cross(pos, dir, node) -- Always continue in the same direction. No direction changes allowed return dir end --- Now get the translator after we have finished using S for other things -local S = minetest.get_translator(modname) -mod.text = mod.text or {} -mod.text.railuse = railuse -local BASE_DEF = { - description = S("New Rail"), -- Temporary name to make debugging easier - _tt_help = S("Track for minecarts"), - _doc_items_longdesc = S("Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction."), - groups = { - rail = mod.RAIL_GROUPS.CURVES, - }, - after_place_node = function(pos, placer, itemstack, pointed_thing) - update_rail_connections(pos, true) - end, -} local function register_straight_rail(base_name, tiles, def) def = def or {} local base_def = table.copy(BASE_DEF) table_merge(base_def,{ + tiles = { tiles[1] }, _mcl_minecarts = { base_name = base_name }, drop = base_name, + groups = { + rail = mod.RAIL_GROUPS.STRANDARD, + }, + _mcl_minecarts = { + base_name = base_name, + get_next_dir = rail_dir_straight + }, }) table_merge(base_def, def) -- Register the base node - mod.register_rail(base_name, table_merge(table.copy(base_def),{ - tiles = { tiles[1] }, + mod.register_rail(base_name, base_def) + base_def.craft = false + table_merge(base_def,{ + groups = { + not_in_creative_inventory = 1, + }, + }) + + -- Sloped variant + mod.register_rail_sloped(base_name.."_sloped", table_merge(table.copy(base_def),{ + description = S("Sloped Rail"), -- Temporary name to make debugging easier _mcl_minecarts = { - get_next_dir = rail_dir_straight - } + get_next_dir = rail_dir_cross, + }, + tiles = { tiles[1] }, })) - BASE_DEF.craft = nil end mod.register_straight_rail = register_straight_rail + local function register_curves_rail(base_name, tiles, def) def = def or {} local base_def = table.copy(BASE_DEF) table_merge(base_def,{ _mcl_minecarts = { base_name = base_name }, + groups = { + rail = mod.RAIL_GROUPS.CURVES + }, drop = base_name, }) table_merge(base_def, def) @@ -236,7 +266,14 @@ local function register_curves_rail(base_name, tiles, def) get_next_dir = rail_dir_straight } })) - BASE_DEF.craft = nil + + -- Update for other variants + base_def.craft = nil + table_merge(base_def, { + groups = { + not_in_creative_inventory = 1 + } + }) -- Corner variants mod.register_rail(base_name.."_corner", table_merge(table.copy(base_def),{ @@ -244,9 +281,6 @@ local function register_curves_rail(base_name, tiles, def) _mcl_minecarts = { get_next_dir = rail_dir_curve, }, - groups = { - not_in_creative_inventory = 1, - }, })) -- Tee variants @@ -267,8 +301,8 @@ local function register_curves_rail(base_name, tiles, def) })) mod.register_rail(base_name.."_tee_on", table_merge(table.copy(base_def),{ tiles = { tiles[4] }, - groups = { - not_in_creative_inventory = 1, + _mcl_minecarts = { + get_next_dir = rail_dir_tee, }, mesecons = { effector = { @@ -280,6 +314,8 @@ local function register_curves_rail(base_name, tiles, def) } } })) + + -- Sloped variant mod.register_rail_sloped(base_name.."_sloped", table_merge(table.copy(base_def),{ description = S("Sloped Rail"), -- Temporary name to make debugging easier _mcl_minecarts = { @@ -291,9 +327,6 @@ local function register_curves_rail(base_name, tiles, def) -- Cross variant mod.register_rail(base_name.."_cross", table_merge(table.copy(base_def),{ tiles = { tiles[5] }, - groups = { - not_in_creative_inventory = 1, - }, })) end mod.register_curves_rail = register_curves_rail