From 59f4a62fd643005489402fddf155cb57ba809bc0 Mon Sep 17 00:00:00 2001 From: ancientmarinerdev Date: Tue, 28 Mar 2023 01:51:51 +0100 Subject: [PATCH] Move hopper minecarts off item entity. Do not run every on_step. Use more accurate object search location. Cut down object search distance. --- mods/ENTITIES/mcl_item_entity/init.lua | 120 +------------------ mods/ENTITIES/mcl_minecarts/init.lua | 153 ++++++++++++++++++++++--- 2 files changed, 141 insertions(+), 132 deletions(-) diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 48a2f34cb..8ee718f59 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -7,12 +7,7 @@ local pool = {} local tick = false -local LOGGING_ON = minetest.settings:get_bool("mcl_logging_item_entities", false) -local function mcl_log(message) - if LOGGING_ON then - mcl_util.mcl_log(message, "[Item Entities]", true) - end -end + minetest.register_on_joinplayer(function(player) pool[player:get_player_name()] = 0 @@ -408,115 +403,7 @@ local function cxcz(o, cw, one, zero) return o end -local function hopper_take_item(self, pos) - --mcl_log("self.itemstring: ".. self.itemstring) - --mcl_log("self.itemstring: ".. minetest.pos_to_string(pos)) - local objs = minetest.get_objects_inside_radius(pos, 2) - - if objs and self.itemstring then - --mcl_log("there is an itemstring. Number of objs: ".. #objs) - - for k, v in pairs(objs) do - local ent = v:get_luaentity() - - -- Don't forget actual hoppers - if ent and ent.name == "mcl_minecarts:hopper_minecart" then - local taken_items = false - - mcl_log("ent.name: " .. tostring(ent.name)) - mcl_log("ent pos: " .. tostring(ent.object:get_pos())) - - local inv = mcl_entity_invs.load_inv(ent, 5) - - if not inv then - mcl_log("No inv") - return false - end - - local current_itemstack = ItemStack(self.itemstring) - - mcl_log("inv. size: " .. ent._inv_size) - if inv:room_for_item("main", current_itemstack) then - mcl_log("Room") - inv:add_item("main", current_itemstack) - self.object:get_luaentity().itemstring = "" - self.object:remove() - taken_items = true - else - mcl_log("no Room") - end - - if not taken_items then - local items_remaining = current_itemstack:get_count() - - -- This will take part of a floating item stack if no slot can hold the full amount - for i = 1, ent._inv_size, 1 do - local stack = inv:get_stack("main", i) - - mcl_log("i: " .. tostring(i)) - mcl_log("Items remaining: " .. items_remaining) - mcl_log("Name: " .. tostring(stack:get_name())) - - if current_itemstack:get_name() == stack:get_name() then - mcl_log("We have a match. Name: " .. tostring(stack:get_name())) - - local room_for = stack:get_stack_max() - stack:get_count() - mcl_log("Room for: " .. tostring(room_for)) - - if room_for == 0 then - -- Do nothing - mcl_log("No room") - elseif room_for < items_remaining then - mcl_log("We have more items remaining than space") - - items_remaining = items_remaining - room_for - stack:set_count(stack:get_stack_max()) - inv:set_stack("main", i, stack) - taken_items = true - else - local new_stack_size = stack:get_count() + items_remaining - stack:set_count(new_stack_size) - mcl_log("We have more than enough space. Now holds: " .. new_stack_size) - - inv:set_stack("main", i, stack) - items_remaining = 0 - - self.object:get_luaentity().itemstring = "" - self.object:remove() - - taken_items = true - break - end - - mcl_log("Count: " .. tostring(stack:get_count())) - mcl_log("stack max: " .. tostring(stack:get_stack_max())) - --mcl_log("Is it empty: " .. stack:to_string()) - end - - if i == ent._inv_size and taken_items then - mcl_log("We are on last item and still have items left. Set final stack size: " .. items_remaining) - current_itemstack:set_count(items_remaining) - --mcl_log("Itemstack2: " .. current_itemstack:to_string()) - self.itemstring = current_itemstack:to_string() - end - end - end - - --Add in, and delete - if taken_items then - mcl_log("Saving") - mcl_entity_invs.save_inv(ent) - return taken_items - else - mcl_log("No need to save") - end - end - end - end - - return false -end minetest.register_entity(":__builtin:item", { initial_properties = { @@ -793,11 +680,6 @@ minetest.register_entity(":__builtin:item", { end local p = self.object:get_pos() - -- If hopper has taken item, it has gone, and no operations should be conducted on this item - if hopper_take_item(self, p) then - return - end - local node = minetest.get_node(p) local in_unloaded = node.name == "ignore" diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index aa9ef7edc..92136c37f 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -11,6 +11,14 @@ mcl_minecarts.check_float_time = 15 dofile(mcl_minecarts.modpath.."/functions.lua") dofile(mcl_minecarts.modpath.."/rails.lua") +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_minecarts", false) +local function mcl_log(message) + if LOGGING_ON then + mcl_util.mcl_log(message, "[Minecarts]", true) + end +end + + local function detach_driver(self) if not self._driver then return @@ -51,6 +59,134 @@ end local activate_normal_minecart = detach_driver +local function hopper_take_item(self, dtime) + local pos = self.object:get_pos() + if not pos then return end + + if not self or self.name ~= "mcl_minecarts:hopper_minecart" then return end + + if mcl_util.check_dtime_timer(self, dtime, "hoppermc_take", 0.15) then + --minetest.log("The check timer was triggered: " .. dump(pos) .. ", name:" .. self.name) + else + --minetest.log("The check timer was not triggered") + return + end + + --mcl_log("self.itemstring: ".. self.itemstring) + + local above_pos = vector.offset(pos, 0, 0.9, 0) + --mcl_log("self.itemstring: ".. minetest.pos_to_string(above_pos)) + local objs = minetest.get_objects_inside_radius(above_pos, 1.25) + + if objs then + + mcl_log("there is an itemstring. Number of objs: ".. #objs) + + for k, v in pairs(objs) do + local ent = v:get_luaentity() + + if ent._removed or not ent.itemstring or ent.itemstring == "" then + --minetest.log("Ignore this item") + break + end + + -- Don't forget actual hoppers + + local taken_items = false + + mcl_log("ent.name: " .. tostring(ent.name)) + mcl_log("ent pos: " .. tostring(ent.object:get_pos())) + + local inv = mcl_entity_invs.load_inv(self, 5) + + if not inv then + mcl_log("No inv") + return false + end + + local current_itemstack = ItemStack(ent.itemstring) + + mcl_log("inv. size: " .. self._inv_size) + if inv:room_for_item("main", current_itemstack) then + mcl_log("Room") + inv:add_item("main", current_itemstack) + ent.object:get_luaentity().itemstring = "" + ent.object:remove() + taken_items = true + else + mcl_log("no Room") + end + + if not taken_items then + local items_remaining = current_itemstack:get_count() + + -- This will take part of a floating item stack if no slot can hold the full amount + for i = 1, self._inv_size, 1 do + local stack = inv:get_stack("main", i) + + mcl_log("i: " .. tostring(i)) + mcl_log("Items remaining: " .. items_remaining) + mcl_log("Name: " .. tostring(stack:get_name())) + + if current_itemstack:get_name() == stack:get_name() then + mcl_log("We have a match. Name: " .. tostring(stack:get_name())) + + local room_for = stack:get_stack_max() - stack:get_count() + mcl_log("Room for: " .. tostring(room_for)) + + if room_for == 0 then + -- Do nothing + mcl_log("No room") + elseif room_for < items_remaining then + mcl_log("We have more items remaining than space") + + items_remaining = items_remaining - room_for + stack:set_count(stack:get_stack_max()) + inv:set_stack("main", i, stack) + taken_items = true + else + local new_stack_size = stack:get_count() + items_remaining + stack:set_count(new_stack_size) + mcl_log("We have more than enough space. Now holds: " .. new_stack_size) + + inv:set_stack("main", i, stack) + items_remaining = 0 + + ent.object:get_luaentity().itemstring = "" + ent.object:remove() + + taken_items = true + break + end + + mcl_log("Count: " .. tostring(stack:get_count())) + mcl_log("stack max: " .. tostring(stack:get_stack_max())) + --mcl_log("Is it empty: " .. stack:to_string()) + end + + if i == self._inv_size and taken_items then + mcl_log("We are on last item and still have items left. Set final stack size: " .. items_remaining) + current_itemstack:set_count(items_remaining) + --mcl_log("Itemstack2: " .. current_itemstack:to_string()) + ent.itemstring = current_itemstack:to_string() + end + end + end + + --Add in, and delete + if taken_items then + mcl_log("Saving") + mcl_entity_invs.save_inv(ent) + return taken_items + else + mcl_log("No need to save") + end + end + end + + return false +end + -- Table for item-to-entity mapping. Keys: itemstring, Values: Corresponding entity ID local entity_mapping = {} @@ -182,6 +318,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o local passenger_attach_position = vector.new(0, -1.75, 0) function cart:on_step(dtime) + hopper_take_item(self, dtime) + local ctrl, player = nil, nil if self._driver then player = minetest.get_player_by_name(self._driver) @@ -266,19 +404,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o return end - -- Drop items and remove cart entity - local pname = "" - if player then - pname = player:get_player_name() - end - if not minetest.is_creative_enabled(pname) then - for d=1, #drop do - minetest.add_item(self.object:get_pos(), drop[d]) - end - end - - self.object:remove() - return + -- Do not drop minecart. It goes off the rails too frequently, and anyone using them for farms won't + -- notice and lose their iron and not bother. Not cool until fixed. end self._last_float_check = 0 end