Add immortal item entity support, add legacy rail conversion that uses immortal item drops for corners/tees/crosses that are no longer possible

This commit is contained in:
teknomunk 2024-04-03 21:33:48 +00:00
parent b6d8bf7093
commit 54eb88c2c3
3 changed files with 83 additions and 19 deletions

View File

@ -840,6 +840,7 @@ minetest.register_entity(":__builtin:item", {
_insta_collect = self._insta_collect, _insta_collect = self._insta_collect,
_flowing = self._flowing, _flowing = self._flowing,
_removed = self._removed, _removed = self._removed,
_immortal = self._immortal,
}) })
-- sfan5 guessed that the biggest serializable item -- sfan5 guessed that the biggest serializable item
-- entity would have a size of 65530 bytes. This has -- entity would have a size of 65530 bytes. This has
@ -892,6 +893,7 @@ minetest.register_entity(":__builtin:item", {
self._insta_collect = data._insta_collect self._insta_collect = data._insta_collect
self._flowing = data._flowing self._flowing = data._flowing
self._removed = data._removed self._removed = data._removed
self._immortal = data._immortal
end end
else else
self.itemstring = staticdata self.itemstring = staticdata
@ -985,7 +987,7 @@ minetest.register_entity(":__builtin:item", {
if self._collector_timer then if self._collector_timer then
self._collector_timer = self._collector_timer + dtime self._collector_timer = self._collector_timer + dtime
end end
if time_to_live > 0 and self.age > time_to_live then if time_to_live > 0 and ( self.age > time_to_live and not self._immortal ) then
self._removed = true self._removed = true
self.object:remove() self.object:remove()
return return

View File

@ -108,6 +108,7 @@ local HORIZONTAL_STANDARD_RULES = {
[W] = { "", 1, mask = W, score = 1, can_slope = true }, [W] = { "", 1, mask = W, score = 1, can_slope = true },
[E+W] = { "", 1, mask = E+W, score = 2, can_slope = true }, [E+W] = { "", 1, mask = E+W, score = 2, can_slope = true },
} }
mod.HORIZONTAL_STANDARD_RULES = HORIZONTAL_STANDARD_RULES
local HORIZONTAL_CURVES_RULES = { local HORIZONTAL_CURVES_RULES = {
[N+E] = { "_corner", 3, name = "ne corner", mask = N+E, score = 3 }, [N+E] = { "_corner", 3, name = "ne corner", mask = N+E, score = 3 },
@ -122,8 +123,9 @@ local HORIZONTAL_CURVES_RULES = {
[N+S+E+W] = { "_cross", 0, mask = N+S+E+W, score = 5 }, [N+S+E+W] = { "_cross", 0, mask = N+S+E+W, score = 5 },
} }
table_merge(HORIZONTAL_CURVES_RULES, HORIZONTAL_STANDARD_RULES) table_merge(HORIZONTAL_CURVES_RULES, HORIZONTAL_STANDARD_RULES)
mod.HORIZONTAL_CURVES_RULES = HORIZONTAL_CURVES_RULES
local HORIZONTAL_RULES_BY_RAIL_GROUP = { local HORIZONTAL_RULES_BY_RAIL_GROUP = {
[1] = HORIZONTAL_STANDARD_RULES, [1] = HORIZONTAL_STANDARD_RULES,
[2] = HORIZONTAL_CURVES_RULES, [2] = HORIZONTAL_CURVES_RULES,
@ -165,7 +167,31 @@ local function make_sloped_if_straight(pos, dir)
end end
end end
local function update_rail_connections(pos, update_neighbors) local function get_rail_connections(pos, opt)
local legacy = opt and opt.legacy
local ignore_neighbor_connections = opt and opt.ignore_neighbor_connections
local connections = 0
for i,dir in ipairs(CONNECTIONS) do
local neighbor = vector.add(pos, dir)
local node = minetest.get_node(neighbor)
local nodedef = minetest.registered_nodes[node.name]
-- Only allow connections to the open ends of rails, as decribed by get_next_dir
if get_path(nodedef, "groups", "rail") and ( legacy or get_path(nodedef, "_mcl_minecarts", "get_next_dir" ) ) then
local rev_dir = vector.direction(dir,vector.new(0,0,0))
if ignore_neighbor_connections or mcl_minecarts:is_connection(neighbor, rev_dir) then
connections = connections + bit.lshift(1,i - 1)
end
end
end
return connections
end
mod.get_rail_connections = get_rail_connections
local function update_rail_connections(pos, opt)
local ignore_neighbor_connections = opt and opt.ignore_neighbor_connections
local node = minetest.get_node(pos) local node = minetest.get_node(pos)
local nodedef = minetest.registered_nodes[node.name] local nodedef = minetest.registered_nodes[node.name]
if not nodedef._mcl_minecarts then if not nodedef._mcl_minecarts then
@ -181,22 +207,11 @@ local function update_rail_connections(pos, update_neighbors)
if not rules then return end if not rules then return end
-- Horizontal rules, Check for rails on each neighbor -- Horizontal rules, Check for rails on each neighbor
local connections = 0 local connections = get_rail_connections(pos, opt)
-- Check for rasing rails to slopes
for i,dir in ipairs(CONNECTIONS) do for i,dir in ipairs(CONNECTIONS) do
local neighbor = vector.add(pos, dir) local neighbor = vector.add(pos, dir)
local node = minetest.get_node(neighbor)
local nodedef = minetest.registered_nodes[node.name]
-- Only allow connections to the open ends of rails, as decribed by get_next_dir
if get_path(nodedef, "groups", "rail") and get_path(nodedef, "_mcl_minecarts", "get_next_dir" ) then
local rev_dir = vector.direction(dir,vector.new(0,0,0))
--local next_dir = nodedef._mcl_minecarts.get_next_dir(neighbor, rev_dir, node)
if mcl_minecarts:is_connection(neighbor, rev_dir) then
connections = connections + bit.lshift(1,i - 1)
end
end
-- Check for rasing rails to slopes
make_sloped_if_straight( vector.offset(neighbor, 0, -1, 0), dir ) make_sloped_if_straight( vector.offset(neighbor, 0, -1, 0), dir )
end end
@ -212,8 +227,8 @@ local function update_rail_connections(pos, update_neighbors)
end end
end end
end end
if rule then
if rule then
-- Apply the mapping -- Apply the mapping
local new_name = nodedef._mcl_minecarts.base_name..rule[1] local new_name = nodedef._mcl_minecarts.base_name..rule[1]
if new_name ~= node.name or node.param2 ~= rule[2] then if new_name ~= node.name or node.param2 ~= rule[2] then

View File

@ -87,7 +87,7 @@ local BASE_DEF = {
_doc_items_usagehelp = railuse, _doc_items_usagehelp = railuse,
_doc_items_longdesc = S("Rails can be used to build transport tracks for minecarts. Normal rails slightly slow down minecarts due to friction."), _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) after_place_node = function(pos, placer, itemstack, pointed_thing)
update_rail_connections(pos, true) update_rail_connections(pos)
end, end,
drawtype = "nodebox", drawtype = "nodebox",
groups = RAIL_DEFAULT_GROUPS, groups = RAIL_DEFAULT_GROUPS,
@ -595,3 +595,50 @@ if minetest.get_modpath("doc") then
doc.add_entry_alias("nodes", "mcl_minecarts:golden_rail", "nodes", "mcl_minecarts:golden_rail_on") doc.add_entry_alias("nodes", "mcl_minecarts:golden_rail", "nodes", "mcl_minecarts:golden_rail_on")
end end
if 0==0 then
local CURVY_RAILS_MAP = {
["mcl_minecarts:rail"] = "mcl_minecarts:rail_v2",
}
minetest.register_lbm({
name = "mcl_minecarts:update_legacy_curvy_rails",
nodenames = {"mcl_minecarts:rail"},
action = function(pos, node)
node.name = CURVY_RAILS_MAP[node.name]
if node.name then
minetest.swap_node(pos, node)
mod.update_rail_connections(pos, { legacy = true, ignore_neighbor_connections = true })
end
end
})
local STRAIGHT_RAILS_MAP ={
["mcl_minecarts:golden_rail"] = "mcl_minecarts:golden_rail_v2",
["mcl_minecarts:golden_rail_on"] = "mcl_minecarts:golden_rail_v2_on",
["mcl_minecarts:activator_rail"] = "mcl_minecarts_activator_rail_v2",
["mcl_minecarts:activator_rail_on"] = "mcl_minecarts:activator_rail_v2_on",
["mcl_minecarts:detector_rail"] = "mcl_minecarts:detector_rail_v2",
["mcl_minecarts:detector_rail_on"] = "mcl_minecarts:detector_rail_v2_on",
}
minetest.register_lbm({
name = "mcl_minecarts:update_legacy_straight_rails",
nodenames = {"mcl_minecarts:golden_rail"},
action = function(pos, node)
node.name = STRAIGHT_RAILS_MAP[node.name]
if node.name then
local connections = mod.get_rail_connections(pos, { legacy = true, ignore_neighbor_connections = true })
if not mod.HORIZONTAL_STANDARD_RULES[connections] then
-- Drop an immortal object at this location
local item_entity = minetest.add_item(pos, ItemStack(node.name))
if item_entity then
item_entity:get_luaentity()._immortal = true
end
-- This is a configuration that doesn't exist in the new rail
-- Replace with a standard rail
node.name = "mcl_minecarts:rail_v2"
end
minetest.swap_node(pos, node)
mod.update_rail_connections(pos, { legacy = true, ignore_neighbor_connections = true })
end
end
})
end