Who doesn't love hopper minecarts?

This commit is contained in:
ancientmarinerdev 2022-11-12 17:47:20 +00:00 committed by cora
parent c21527d207
commit ce457eb351
4 changed files with 223 additions and 30 deletions

@ -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

@ -26,3 +26,9 @@ http://minetest.net/
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
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

@ -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)

@ -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",