From c1a7001c312dc3aa023490a4e22ced4ba06b23c6 Mon Sep 17 00:00:00 2001 From: teknomunk Date: Wed, 3 Apr 2024 21:33:48 +0000 Subject: [PATCH] Add immortal item entity support, add legacy rail conversion that uses immortal item drops for corners/tees/crosses that are no longer possible --- mods/ENTITIES/mcl_item_entity/init.lua | 4 +- mods/ENTITIES/mcl_minecarts/functions.lua | 49 +++++++++++++++-------- mods/ENTITIES/mcl_minecarts/rails.lua | 49 ++++++++++++++++++++++- 3 files changed, 83 insertions(+), 19 deletions(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 2cb506450..a06e4020b 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -832,6 +832,7 @@ minetest.register_entity(":__builtin:item", { _insta_collect = self._insta_collect, _flowing = self._flowing, _removed = self._removed, + _immortal = self._immortal, }) -- sfan5 guessed that the biggest serializable item -- entity would have a size of 65530 bytes. This has @@ -884,6 +885,7 @@ minetest.register_entity(":__builtin:item", { self._insta_collect = data._insta_collect self._flowing = data._flowing self._removed = data._removed + self._immortal = data._immortal end else self.itemstring = staticdata @@ -976,7 +978,7 @@ minetest.register_entity(":__builtin:item", { if self._collector_timer then self._collector_timer = self._collector_timer + dtime 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.object:remove() return diff --git a/mods/ENTITIES/mcl_minecarts/functions.lua b/mods/ENTITIES/mcl_minecarts/functions.lua index 63f3df191..5c498ab5d 100644 --- a/mods/ENTITIES/mcl_minecarts/functions.lua +++ b/mods/ENTITIES/mcl_minecarts/functions.lua @@ -108,6 +108,7 @@ local HORIZONTAL_STANDARD_RULES = { [W] = { "", 1, mask = W, score = 1, 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 = { [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 }, } - table_merge(HORIZONTAL_CURVES_RULES, HORIZONTAL_STANDARD_RULES) +mod.HORIZONTAL_CURVES_RULES = HORIZONTAL_CURVES_RULES + local HORIZONTAL_RULES_BY_RAIL_GROUP = { [1] = HORIZONTAL_STANDARD_RULES, [2] = HORIZONTAL_CURVES_RULES, @@ -165,7 +167,31 @@ local function make_sloped_if_straight(pos, dir) 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 nodedef = minetest.registered_nodes[node.name] if not nodedef._mcl_minecarts then @@ -181,22 +207,11 @@ local function update_rail_connections(pos, update_neighbors) if not rules then return end -- 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 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 ) end @@ -212,8 +227,8 @@ local function update_rail_connections(pos, update_neighbors) end end end - if rule then + if rule then -- Apply the mapping local new_name = nodedef._mcl_minecarts.base_name..rule[1] if new_name ~= node.name or node.param2 ~= rule[2] then diff --git a/mods/ENTITIES/mcl_minecarts/rails.lua b/mods/ENTITIES/mcl_minecarts/rails.lua index ba02717cd..0924f9502 100644 --- a/mods/ENTITIES/mcl_minecarts/rails.lua +++ b/mods/ENTITIES/mcl_minecarts/rails.lua @@ -87,7 +87,7 @@ local BASE_DEF = { _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."), after_place_node = function(pos, placer, itemstack, pointed_thing) - update_rail_connections(pos, true) + update_rail_connections(pos) end, drawtype = "nodebox", 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") 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