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)

This commit is contained in:
teknomunk 2024-03-31 11:13:50 +00:00
parent 19e2dc58eb
commit 4589206985
3 changed files with 86 additions and 53 deletions

View file

@ -1133,7 +1133,7 @@ end
local function table_merge(base, overlay) local function table_merge(base, overlay)
for k,v in pairs(overlay) do 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) table_merge(base[k], v)
else else
base[k] = v base[k] = v

View file

@ -149,7 +149,7 @@ local function update_rail_connections(pos, update_neighbors)
local node = minetest.get_node(neighbor) local node = minetest.get_node(neighbor)
local nodedef = minetest.registered_nodes[node.name] 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 if (nodedef.groups or {}).rail and nodedef._mcl_minecarts and nodedef._mcl_minecarts.get_next_dir then
local diff = vector.direction(neighbor, pos) local diff = vector.direction(neighbor, pos)
local next_dir = nodedef._mcl_minecarts.get_next_dir(neighbor, diff, node) local next_dir = nodedef._mcl_minecarts.get_next_dir(neighbor, diff, node)

View file

@ -77,12 +77,20 @@ local function register_rail(itemstring, tiles, def_extras, creative)
table_merge(ndef, def_extras) table_merge(ndef, def_extras)
minetest.register_node(itemstring, ndef) minetest.register_node(itemstring, ndef)
end 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 = { local BASE_DEF = {
description = S("New Rail"), -- Temporary name to make debugging easier
_tt_help = S("Track for minecarts"),
_doc_items_usagehelp = railuse, _doc_items_usagehelp = railuse,
groups = { _doc_items_longdesc = S("Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction."),
rail = 1, after_place_node = function(pos, placer, itemstack, pointed_thing)
}, update_rail_connections(pos, true)
end,
drawtype = "nodebox", drawtype = "nodebox",
groups = RAIL_DEFAULT_GROUPS,
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
@ -93,7 +101,6 @@ local BASE_DEF = {
paramtype2 = "facedir", paramtype2 = "facedir",
} }
table_merge(BASE_DEF, RAIL_DEFAULTS) -- Merge together old rail values 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) local SLOPED_RAIL_DEF = table.copy(BASE_DEF)
table_merge(SLOPED_RAIL_DEF,{ table_merge(SLOPED_RAIL_DEF,{
@ -115,22 +122,18 @@ table_merge(SLOPED_RAIL_DEF,{
} }
}) })
local function register_rail_v2(itemstring, def) local function register_rail_v2(itemstring, ndef)
assert(def.tiles) assert(ndef.tiles)
-- Extract out the craft recipe -- Extract out the craft recipe
local craft = def.craft local craft = ndef.craft
def.craft = nil ndef.craft = nil
-- Merge together the definition with the base definition
local ndef = table.copy(def)
table_merge(ndef, BASE_DEF)
-- Add sensible defaults -- Add sensible defaults
if not ndef.inventory_image then ndef.inventory_image = ndef.tiles[1] end 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 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 -- Make registrations
minetest.register_node(itemstring, ndef) minetest.register_node(itemstring, ndef)
@ -139,6 +142,7 @@ end
mod.register_rail = register_rail_v2 mod.register_rail = register_rail_v2
local function rail_dir_straight(pos, dir, node) local function rail_dir_straight(pos, dir, node)
local function inside(pos,dir,node)
if node.param2 == 0 or node.param2 == 2 then if node.param2 == 0 or node.param2 == 2 then
if vector.equals(dir, north) then if vector.equals(dir, north) then
return north return north
@ -153,6 +157,21 @@ local function rail_dir_straight(pos, dir, node)
end end
end 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
return raw_dir
end
end
local function rail_dir_curve(pos, dir, node) local function rail_dir_curve(pos, dir, node)
if node.param2 == 0 then if node.param2 == 0 then
-- South and East -- South and East
@ -181,50 +200,61 @@ local function rail_dir_curve(pos, dir, node)
end end
end end
local function rail_dir_tee(pos, dir, node)
-- TODO: implement
return north
end
local function rail_dir_cross(pos, dir, node) local function rail_dir_cross(pos, dir, node)
-- Always continue in the same direction. No direction changes allowed -- Always continue in the same direction. No direction changes allowed
return dir return dir
end 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) local function register_straight_rail(base_name, tiles, def)
def = def or {} def = def or {}
local base_def = table.copy(BASE_DEF) local base_def = table.copy(BASE_DEF)
table_merge(base_def,{ table_merge(base_def,{
tiles = { tiles[1] },
_mcl_minecarts = { base_name = base_name }, _mcl_minecarts = { base_name = base_name },
drop = 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) table_merge(base_def, def)
-- Register the base node -- Register the base node
mod.register_rail(base_name, table_merge(table.copy(base_def),{ mod.register_rail(base_name, base_def)
tiles = { tiles[1] }, 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 = { _mcl_minecarts = {
get_next_dir = rail_dir_straight get_next_dir = rail_dir_cross,
} },
tiles = { tiles[1] },
})) }))
BASE_DEF.craft = nil
end end
mod.register_straight_rail = register_straight_rail mod.register_straight_rail = register_straight_rail
local function register_curves_rail(base_name, tiles, def) local function register_curves_rail(base_name, tiles, def)
def = def or {} def = def or {}
local base_def = table.copy(BASE_DEF) local base_def = table.copy(BASE_DEF)
table_merge(base_def,{ table_merge(base_def,{
_mcl_minecarts = { base_name = base_name }, _mcl_minecarts = { base_name = base_name },
groups = {
rail = mod.RAIL_GROUPS.CURVES
},
drop = base_name, drop = base_name,
}) })
table_merge(base_def, def) table_merge(base_def, def)
@ -236,7 +266,14 @@ local function register_curves_rail(base_name, tiles, def)
get_next_dir = rail_dir_straight 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 -- Corner variants
mod.register_rail(base_name.."_corner", table_merge(table.copy(base_def),{ 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 = { _mcl_minecarts = {
get_next_dir = rail_dir_curve, get_next_dir = rail_dir_curve,
}, },
groups = {
not_in_creative_inventory = 1,
},
})) }))
-- Tee variants -- 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),{ mod.register_rail(base_name.."_tee_on", table_merge(table.copy(base_def),{
tiles = { tiles[4] }, tiles = { tiles[4] },
groups = { _mcl_minecarts = {
not_in_creative_inventory = 1, get_next_dir = rail_dir_tee,
}, },
mesecons = { mesecons = {
effector = { 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),{ mod.register_rail_sloped(base_name.."_sloped", table_merge(table.copy(base_def),{
description = S("Sloped Rail"), -- Temporary name to make debugging easier description = S("Sloped Rail"), -- Temporary name to make debugging easier
_mcl_minecarts = { _mcl_minecarts = {
@ -291,9 +327,6 @@ local function register_curves_rail(base_name, tiles, def)
-- Cross variant -- Cross variant
mod.register_rail(base_name.."_cross", table_merge(table.copy(base_def),{ mod.register_rail(base_name.."_cross", table_merge(table.copy(base_def),{
tiles = { tiles[5] }, tiles = { tiles[5] },
groups = {
not_in_creative_inventory = 1,
},
})) }))
end end
mod.register_curves_rail = register_curves_rail mod.register_curves_rail = register_curves_rail