From e82e5f805fc844a8d2f1f7d952e248dac9df417e Mon Sep 17 00:00:00 2001 From: teknomunk Date: Mon, 11 Mar 2024 07:26:51 +0000 Subject: [PATCH] Implement custom item dropper handlers, implement droppers placing minecarts --- mods/ENTITIES/mcl_minecarts/init.lua | 14 ++++++++ mods/ITEMS/REDSTONE/mcl_droppers/init.lua | 40 +++++++++++++++++++---- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index 1346e502b..6d31a1fa1 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -850,6 +850,19 @@ function mcl_minecarts.place_minecart(itemstack, pointed_thing, placer) return itemstack end +local function dropper_place_minecart(dropitem, pos) + local node = minetest.get_node(pos) + local nodedef = minetest.registered_nodes[node.name] + + -- Don't try to place the minecart if pos isn't a rail + if (nodedef.groups.rail or 0) == 0 then return false end + + mcl_minecarts.place_minecart(dropitem, { + above = pos, + under = vector.offset(pos,0,-1,0) + }) + return true +end local function register_craftitem(itemstring, entity_id, description, tt_help, longdesc, usagehelp, icon, creative) entity_mapping[itemstring] = entity_id @@ -860,6 +873,7 @@ local function register_craftitem(itemstring, entity_id, description, tt_help, l end local def = { stack_max = 1, + _mcl_dropper_on_drop = dropper_place_minecart, on_place = function(itemstack, placer, pointed_thing) if not pointed_thing.type == "node" then return diff --git a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua index e47371bc9..75a9c5390 100644 --- a/mods/ITEMS/REDSTONE/mcl_droppers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_droppers/init.lua @@ -129,9 +129,9 @@ local dropperdef = { -- If they are containers - double down as hopper mcl_util.hopper_push(pos, droppos) end - if dropnodedef.walkable then - return - end + if dropnodedef.walkable then return end + + -- Build a list of items in the dropper local stacks = {} for i = 1, inv:get_size("main") do local stack = inv:get_stack("main", i) @@ -139,12 +139,32 @@ local dropperdef = { table.insert(stacks, { stack = stack, stackpos = i }) end end + + -- Pick an item to drop + local dropitem = nil + local stack = nil + local r = nil if #stacks >= 1 then - local r = math.random(1, #stacks) - local stack = stacks[r].stack - local dropitem = ItemStack(stack) + r = math.random(1, #stacks) + stack = stacks[r].stack + dropitem = ItemStack(stack) dropitem:set_count(1) - local stack_id = stacks[r].stackpos + end + if not dropitem then return end + + -- Flag for if the item was dropped. If true the item will be removed from + -- the inventory after dropping + local item_dropped = false + + -- Check if the drop item has a custom handler + local itemdef = minetest.registered_craftitems[dropitem:get_name()] + if itemdef._mcl_dropper_on_drop then + item_dropped = itemdef._mcl_dropper_on_drop(dropitem, droppos) + end + + -- If a custom handler wasn't successful then drop the item as an entity + if not item_dropped then + -- Drop as entity local pos_variation = 100 droppos = vector.offset(droppos, math.random(-pos_variation, pos_variation) / 1000, @@ -156,6 +176,12 @@ local dropperdef = { local speed = 3 item_entity:set_velocity(vector.multiply(drop_vel, speed)) stack:take_item() + item_dropped = trie + end + + -- Remove dropped items from inventory + if item_dropped then + local stack_id = stacks[r].stackpos inv:set_stack("main", stack_id, stack) end end,