From ce457eb3510bd48096b52201c30baaaaf3dc2180 Mon Sep 17 00:00:00 2001 From: ancientmarinerdev Date: Sat, 12 Nov 2022 17:47:20 +0000 Subject: [PATCH] Who doesn't love hopper minecarts? --- mods/ENTITIES/mcl_entity_invs/init.lua | 94 +++++++++++---- mods/ENTITIES/mcl_item_entity/README.txt | 8 +- mods/ENTITIES/mcl_item_entity/init.lua | 144 +++++++++++++++++++++++ mods/ENTITIES/mcl_minecarts/init.lua | 7 +- 4 files changed, 223 insertions(+), 30 deletions(-) diff --git a/mods/ENTITIES/mcl_entity_invs/init.lua b/mods/ENTITIES/mcl_entity_invs/init.lua index cc2badec0..259259d21 100644 --- a/mods/ENTITIES/mcl_entity_invs/init.lua +++ b/mods/ENTITIES/mcl_entity_invs/init.lua @@ -2,6 +2,15 @@ mcl_entity_invs = {} local open_invs = {} +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default",false) +local LOG_MODULE = "[Entity Invs]" +local function mcl_log (message) + if LOGGING_ON and message then + minetest.log(LOG_MODULE .. " " .. message) + end +end + + local function check_distance(inv,player,count) for _,o in pairs(minetest.get_objects_inside_radius(player:get_pos(),5)) do local l = o:get_luaentity() @@ -22,20 +31,25 @@ local inv_callbacks = { end, } -local function load_inv(ent,size) +function mcl_entity_invs.load_inv(ent,size) + mcl_log("load_inv") if not ent._inv_id then return end + mcl_log("load_inv 2") local inv = minetest.get_inventory({type="detached", name=ent._inv_id}) if not inv then + mcl_log("load_inv 3") inv = minetest.create_detached_inventory(ent._inv_id, inv_callbacks) inv:set_size("main", size) if ent._items then inv:set_list("main",ent._items) end + else + mcl_log("load_inv 4") end return inv end -local function save_inv(ent) +function mcl_entity_invs.save_inv(ent) if ent._inv then ent._items = {} for i,it in ipairs(ent._inv:get_list("main")) do @@ -46,32 +60,60 @@ local function save_inv(ent) end end +local function load_default_formspec (ent, text) + text = text or "" + + local invent_size = ent._inv_size + local div_by_two = invent_size % 2 == 0 + local div_by_three = invent_size % 3 == 0 + + --mcl_log("Div by 3: ".. tostring(div_by_three)) + --mcl_log("Div by 2: ".. tostring(div_by_two)) + --mcl_log("invent_size: ".. tostring(invent_size)) + local rows = 3 + if invent_size > 18 or (div_by_three == true and invent_size > 8) then + --mcl_log("Div by 3") + rows = 3 + elseif (div_by_two == true and invent_size > 3) or invent_size > 9 then + --mcl_log("Div by 2") + rows = 2 + else + --mcl_log("Not div by 2 or 3") + rows = 1 + end + + --local rows = 3 + local cols = (math.ceil(ent._inv_size/rows)) + local spacing = (9 - cols) / 2 + + local formspec = "size[9,8.75]" + .. "label[0,0;" .. minetest.formspec_escape( + minetest.colorize("#313131", ent._inv_title .. " ".. text)) .. "]" + .. "list[detached:"..ent._inv_id..";main;"..spacing..",0.5;"..cols..","..rows..";]" + .. mcl_formspec.get_itemslot_bg(spacing,0.5,cols,rows) + .. "label[0,4.0;" .. minetest.formspec_escape( + minetest.colorize("#313131", "Inventory")) .. "]" + .. "list[current_player;main;0,4.5;9,3;9]" + .. mcl_formspec.get_itemslot_bg(0,4.5,9,3) + .. "list[current_player;main;0,7.74;9,1;]" + .. mcl_formspec.get_itemslot_bg(0,7.74,9,1) + .. "listring[detached:"..ent._inv_id..";main]" + .. "listring[current_player;main]" + return formspec +end + + function mcl_entity_invs.show_inv_form(ent,player,text) if not ent._inv_id then return end if not open_invs[ent] then open_invs[ent] = 0 end - text = text or "" - ent._inv = load_inv(ent,ent._inv_size) + ent._inv = mcl_entity_invs.load_inv(ent,ent._inv_size) open_invs[ent] = open_invs[ent] + 1 + local playername = player:get_player_name() - local rows = 3 - local cols = (math.ceil(ent._inv_size/rows)) - local spacing = (9 - cols) / 2 - local formspec = "size[9,8.75]" - .. "label[0,0;" .. minetest.formspec_escape( - minetest.colorize("#313131", ent._inv_title .. " ".. text)) .. "]" - .. "list[detached:"..ent._inv_id..";main;"..spacing..",0.5;"..cols..","..rows..";]" - .. mcl_formspec.get_itemslot_bg(spacing,0.5,cols,rows) - .. "label[0,4.0;" .. minetest.formspec_escape( - minetest.colorize("#313131", "Inventory")) .. "]" - .. "list[current_player;main;0,4.5;9,3;9]" - .. mcl_formspec.get_itemslot_bg(0,4.5,9,3) - .. "list[current_player;main;0,7.74;9,1;]" - .. mcl_formspec.get_itemslot_bg(0,7.74,9,1) - .. "listring[detached:"..ent._inv_id..";main]" - .. "listring[current_player;main]" - minetest.show_formspec(playername,ent._inv_id,formspec) + + minetest.show_formspec(playername, ent._inv_id, load_default_formspec (ent, text)) end local function drop_inv(ent) @@ -85,9 +127,9 @@ local function drop_inv(ent) end local function on_remove(self,killer,oldf) - save_inv(self) - drop_inv(self) - if oldf then return oldf(self,killer) end + mcl_entity_invs.save_inv(self) + drop_inv(self) + if oldf then return oldf(self,killer) end end minetest.register_on_player_receive_fields(function(player, formname, fields) @@ -95,7 +137,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if formname == k._inv_id then open_invs[k] = open_invs[k] - 1 if open_invs[k] < 1 then - save_inv(k) + mcl_entity_invs.save_inv(k) open_invs[k] = nil end end @@ -151,7 +193,7 @@ function mcl_entity_invs.register_inv(entity_name,show_name,size,no_on_righclick local old_ode = minetest.registered_entities[entity_name].on_deactivate minetest.registered_entities[entity_name].on_deactivate = function(self,removal) - save_inv(self) + mcl_entity_invs.save_inv(self) if removal then on_remove(self) end diff --git a/mods/ENTITIES/mcl_item_entity/README.txt b/mods/ENTITIES/mcl_item_entity/README.txt index 41e9e6e57..d39ec0ba9 100644 --- a/mods/ENTITIES/mcl_item_entity/README.txt +++ b/mods/ENTITIES/mcl_item_entity/README.txt @@ -25,4 +25,10 @@ http://minetest.net/ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - 0. You just DO WHAT THE FUCK YOU WANT TO. + 0. You just DO WHAT THE FUCK YOU WANT TO. + +--------- + +Alterations and contributions are released under GNU GPLv3 after 11/11/2022 and for contributors: + +AncientMariner/ancientmarinerdev \ No newline at end of file diff --git a/mods/ENTITIES/mcl_item_entity/init.lua b/mods/ENTITIES/mcl_item_entity/init.lua index 5d91a6aad..429ffdac2 100644 --- a/mods/ENTITIES/mcl_item_entity/init.lua +++ b/mods/ENTITIES/mcl_item_entity/init.lua @@ -6,6 +6,17 @@ local pool = {} local tick = false + +local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default",false) +local LOG_MODULE = "[Item entities]" +local function mcl_log (message) + if LOGGING_ON and message then + minetest.log(LOG_MODULE .. " " .. message) + end +end + + + minetest.register_on_joinplayer(function(player) local name name = player:get_player_name() @@ -375,6 +386,133 @@ local function cxcz(o, cw, one, zero) return o end +local function hopper_take_item (self, pos) + --mcl_log("self.itemstring: ".. self.itemstring) + + --local current_itemstack = nil + --if self.itemstring then + -- mcl_log("there is an itemstring") + -- current_itemstack = ItemStack(self.itemstring) + --else + -- mcl_log("no item string") + --end + + --mcl_log("self.itemstring: ".. minetest.pos_to_string(pos)) + --minetest.get_node(pos).name + + 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 + + -- Do we still need this def stuff + local node_def = minetest.registered_nodes[ent.name] + if node_def then + mcl_log("stack max: ".. tostring(node_def.get_stack_max())) + end + + mcl_log("ent.name: ".. tostring(ent.name)) + mcl_log("ent pos: ".. tostring(ent.object:get_pos())) + mcl_log("Inv id: " .. ent._inv_id) + + 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 pat of a floating item stack + for i = 1, ent._inv_size,1 do + local stack1 = inv:get_stack("main", i) + + mcl_log("i: " .. tostring(i)) + mcl_log("Items remaining: " .. items_remaining) + mcl_log("Name: " .. tostring(stack1:get_name())) + + if current_itemstack:get_name() == stack1:get_name() then + mcl_log("We have a match. Name: " .. tostring(stack1:get_name())) + + local room_for = stack1:get_stack_max() - stack1: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 + -- Set full stack + stack1:set_count(stack1:get_stack_max()) + inv:set_stack("main", i, stack1) + taken_items = true + else + local new_stack_size = stack1:get_count() + items_remaining + mcl_log("We have more than enough space. Now holds: " .. new_stack_size) + + stack1:set_count(new_stack_size) + inv:set_stack("main", i, stack1) + items_remaining = 0 + + -- Delete as no longer needed + self.object:get_luaentity().itemstring = "" + self.object:remove() + taken_items = true + break + end + + mcl_log("Count: " .. tostring(stack1:get_count())) + mcl_log("stack max: " .. tostring(stack1:get_stack_max())) + --mcl_log("Is it empty: " .. stack1: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 = { hp_max = 1, @@ -648,6 +786,12 @@ 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_or_nil(p) local in_unloaded = (node == nil) diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index 992442b7a..d736a1372 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -770,8 +770,9 @@ register_minecart( }, "mcl_minecarts_minecart_hopper.png", {"mcl_minecarts:minecart", "mcl_hoppers:hopper"}, - nil, nil, false + nil, nil, true ) +mcl_entity_invs.register_inv("mcl_minecarts:hopper_minecart", "Hopper Minecart", 5, false, true) -- Minecart with TNT register_minecart( @@ -841,14 +842,14 @@ minetest.register_craft({ -- TODO: Re-enable crafting of special minecarts when they have been implemented ---[[minetest.register_craft({ +minetest.register_craft({ output = "mcl_minecarts:hopper_minecart", recipe = { {"mcl_hoppers:hopper"}, {"mcl_minecarts:minecart"}, }, }) ---]] + minetest.register_craft({ output = "mcl_minecarts:chest_minecart",