Add groups to minecart entities (for containers), fix cart node watch handling, relocate hopper_push_to_mc in mcl_hopper/init.lua, implement hopper-to-minecart push using enter/leave hooks for both straight and bent hoppers
This commit is contained in:
parent
6646c6e84f
commit
1dd8f0efef
|
@ -61,8 +61,9 @@ local function handle_cart_enter_exit(self, pos, next_dir, event)
|
||||||
local node_def = minetest.registered_nodes[node.name]
|
local node_def = minetest.registered_nodes[node.name]
|
||||||
|
|
||||||
-- node-specific hook
|
-- node-specific hook
|
||||||
local hook = node_def["_mcl_minecarts_"..event..check[4]]
|
local hook_name = "_mcl_minecarts_"..event..check[4]
|
||||||
if hook then hook(check_pos, self, next_dir) end
|
local hook = node_def[hook_name]
|
||||||
|
if hook then hook(check_pos, self, next_dir, pos) end
|
||||||
|
|
||||||
-- global minecart hook
|
-- global minecart hook
|
||||||
hook = mcl_minecarts[event..check[4]]
|
hook = mcl_minecarts[event..check[4]]
|
||||||
|
@ -89,7 +90,7 @@ local function handle_cart_node_watches(self, dtime)
|
||||||
local node_def = minetest.registered_nodes[node.name]
|
local node_def = minetest.registered_nodes[node.name]
|
||||||
local hook = node_def._mcl_minecarts_node_on_step
|
local hook = node_def._mcl_minecarts_node_on_step
|
||||||
if hook and hook(node_pos, self, dtime) then
|
if hook and hook(node_pos, self, dtime) then
|
||||||
new_watches[#new_watches] = node_pos
|
new_watches[#new_watches+1] = node_pos
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ end
|
||||||
local function direction_away_from_players(self, staticdata)
|
local function direction_away_from_players(self, staticdata)
|
||||||
local objs = minetest.get_objects_inside_radius(self.object:get_pos(), 1.1)
|
local objs = minetest.get_objects_inside_radius(self.object:get_pos(), 1.1)
|
||||||
for n=1,#objs do
|
for n=1,#objs do
|
||||||
obj = objs[n]
|
local obj = objs[n]
|
||||||
local player_name = obj:get_player_name()
|
local player_name = obj:get_player_name()
|
||||||
if player_name and player_name ~= "" and not ( self._driver and self._driver == player_name ) then
|
if player_name and player_name ~= "" and not ( self._driver and self._driver == player_name ) then
|
||||||
local diff = obj:get_pos() - self.object:get_pos()
|
local diff = obj:get_pos() - self.object:get_pos()
|
||||||
|
@ -314,7 +315,7 @@ local function do_movement_step(self, dtime)
|
||||||
handle_cart_enter(self, pos, next_dir)
|
handle_cart_enter(self, pos, next_dir)
|
||||||
|
|
||||||
-- Handle end of track
|
-- Handle end of track
|
||||||
if next_dir == staticdata.dir * -1 and ( hopper_pulled or next_dir.y == 0 ) then
|
if next_dir == staticdata.dir * -1 and next_dir.y == 0 then
|
||||||
if DEBUG then print("Stopping cart at end of track at "..tostring(pos)) end
|
if DEBUG then print("Stopping cart at end of track at "..tostring(pos)) end
|
||||||
staticdata.velocity = 0
|
staticdata.velocity = 0
|
||||||
end
|
end
|
||||||
|
@ -593,6 +594,13 @@ end
|
||||||
|
|
||||||
local function register_entity(entity_id, def)
|
local function register_entity(entity_id, def)
|
||||||
assert( def.drop, "drop is required parameter" )
|
assert( def.drop, "drop is required parameter" )
|
||||||
|
|
||||||
|
-- Entity groups
|
||||||
|
local groups = { minecart = 1 }
|
||||||
|
for k,v in pairs(def.groups or {}) do
|
||||||
|
groups[k] = v
|
||||||
|
end
|
||||||
|
|
||||||
local cart = {
|
local cart = {
|
||||||
initial_properties = {
|
initial_properties = {
|
||||||
physical = true,
|
physical = true,
|
||||||
|
@ -603,8 +611,11 @@ local function register_entity(entity_id, def)
|
||||||
textures = def.textures,
|
textures = def.textures,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
groups = groups,
|
||||||
|
|
||||||
on_rightclick = def.on_rightclick,
|
on_rightclick = def.on_rightclick,
|
||||||
on_activate_by_rail = def.on_activate_by_rail,
|
on_activate_by_rail = def.on_activate_by_rail,
|
||||||
|
|
||||||
_mcl_minecarts_on_enter = def._mcl_minecarts_on_enter,
|
_mcl_minecarts_on_enter = def._mcl_minecarts_on_enter,
|
||||||
_mcl_minecarts_on_place = def._mcl_minecarts_on_place,
|
_mcl_minecarts_on_place = def._mcl_minecarts_on_place,
|
||||||
_mcl_minecarts_on_step = def._mcl_minecarts_on_step,
|
_mcl_minecarts_on_step = def._mcl_minecarts_on_step,
|
||||||
|
@ -665,7 +676,7 @@ local function register_entity(entity_id, def)
|
||||||
staticdata.connected_at = rounded_pos
|
staticdata.connected_at = rounded_pos
|
||||||
pos = rounded_pos
|
pos = rounded_pos
|
||||||
else
|
else
|
||||||
print("TODO: handle detached cart behavior")
|
mineclone.log("warning","TODO: handle detached cart behavior")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -757,14 +768,19 @@ local function register_entity(entity_id, def)
|
||||||
|
|
||||||
function cart:add_node_watch(pos)
|
function cart:add_node_watch(pos)
|
||||||
local staticdata = self._staticdata
|
local staticdata = self._staticdata
|
||||||
local watches = staticdata.watches
|
local watches = staticdata.node_watches or {}
|
||||||
|
|
||||||
for _,watch in ipairs(watches) do
|
for _,watch in ipairs(watches) do
|
||||||
if watch == pos then return end
|
if watch == pos then return end
|
||||||
end
|
end
|
||||||
|
|
||||||
watches[#watches+1] = pos
|
watches[#watches+1] = pos
|
||||||
|
staticdata.node_watches = watches
|
||||||
end
|
end
|
||||||
function cart:remove_node_watch(pos)
|
function cart:remove_node_watch(pos)
|
||||||
|
local staticdata = self._staticdata
|
||||||
|
local watches = staticdata.node_watches or {}
|
||||||
|
|
||||||
local new_watches = {}
|
local new_watches = {}
|
||||||
for _,node_pos in ipairs(watches) do
|
for _,node_pos in ipairs(watches) do
|
||||||
if node_pos ~= post then
|
if node_pos ~= post then
|
||||||
|
@ -792,8 +808,6 @@ local function register_entity(entity_id, def)
|
||||||
end
|
end
|
||||||
|
|
||||||
local pos, rou_pos, node = self.object:get_pos()
|
local pos, rou_pos, node = self.object:get_pos()
|
||||||
--local update = {}
|
|
||||||
--local acceleration = 0
|
|
||||||
|
|
||||||
-- Controls
|
-- Controls
|
||||||
local ctrl, player = nil, nil
|
local ctrl, player = nil, nil
|
||||||
|
@ -820,7 +834,7 @@ local function register_entity(entity_id, def)
|
||||||
|
|
||||||
do_movement(self, dtime)
|
do_movement(self, dtime)
|
||||||
|
|
||||||
-- TODO: move this into do_movement_step
|
-- TODO: move this into mcl_core:cactus _mcl_minecarts_on_enter_side
|
||||||
-- Drop minecart if it collides with a cactus node
|
-- Drop minecart if it collides with a cactus node
|
||||||
local r = 0.6
|
local r = 0.6
|
||||||
for _, node_pos in pairs({{r, 0}, {0, r}, {-r, 0}, {0, -r}}) do
|
for _, node_pos in pairs({{r, 0}, {0, r}, {-r, 0}, {0, -r}}) do
|
||||||
|
@ -1156,6 +1170,7 @@ register_minecart({
|
||||||
},
|
},
|
||||||
icon = "mcl_minecarts_minecart_chest.png",
|
icon = "mcl_minecarts_minecart_chest.png",
|
||||||
drop = {"mcl_minecarts:minecart", "mcl_chests:chest"},
|
drop = {"mcl_minecarts:minecart", "mcl_chests:chest"},
|
||||||
|
groups = { container = 1 },
|
||||||
on_rightclick = nil,
|
on_rightclick = nil,
|
||||||
on_activate_by_rail = nil,
|
on_activate_by_rail = nil,
|
||||||
creative = true
|
creative = true
|
||||||
|
@ -1269,6 +1284,7 @@ register_minecart({
|
||||||
},
|
},
|
||||||
icon = "mcl_minecarts_minecart_hopper.png",
|
icon = "mcl_minecarts_minecart_hopper.png",
|
||||||
drop = {"mcl_minecarts:minecart", "mcl_hoppers:hopper"},
|
drop = {"mcl_minecarts:minecart", "mcl_hoppers:hopper"},
|
||||||
|
groups = { container = 1 },
|
||||||
on_rightclick = nil,
|
on_rightclick = nil,
|
||||||
on_activate_by_rail = nil,
|
on_activate_by_rail = nil,
|
||||||
_mcl_minecarts_on_enter = function(self,pos)
|
_mcl_minecarts_on_enter = function(self,pos)
|
||||||
|
|
|
@ -96,6 +96,48 @@ local function bent_hopper_act(pos, node, active_object_count, active_object_cou
|
||||||
mcl_util.hopper_pull(pos, src_pos)
|
mcl_util.hopper_pull(pos, src_pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function hopper_push_to_mc(mc_ent, dest_pos, inv_size)
|
||||||
|
local dest_inv = mcl_entity_invs.load_inv(mc_ent, inv_size)
|
||||||
|
if not dest_inv then
|
||||||
|
mcl_log("No inv")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta = minetest.get_meta(dest_pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
if not inv then
|
||||||
|
mcl_log("No dest inv")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
mcl_log("inv. size: " .. mc_ent._inv_size)
|
||||||
|
for i = 1, mc_ent._inv_size, 1 do
|
||||||
|
local stack = inv:get_stack("main", i)
|
||||||
|
|
||||||
|
mcl_log("i: " .. tostring(i))
|
||||||
|
mcl_log("Name: [" .. tostring(stack:get_name()) .. "]")
|
||||||
|
mcl_log("Count: " .. tostring(stack:get_count()))
|
||||||
|
mcl_log("stack max: " .. tostring(stack:get_stack_max()))
|
||||||
|
|
||||||
|
if not stack:get_name() or stack:get_name() ~= "" then
|
||||||
|
if dest_inv:room_for_item("main", stack:peek_item()) then
|
||||||
|
mcl_log("Room so unload")
|
||||||
|
dest_inv:add_item("main", stack:take_item())
|
||||||
|
inv:set_stack("main", i, stack)
|
||||||
|
|
||||||
|
-- Take one item and stop until next time
|
||||||
|
return
|
||||||
|
else
|
||||||
|
mcl_log("no Room")
|
||||||
|
end
|
||||||
|
|
||||||
|
else
|
||||||
|
mcl_log("nothing there")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Downwards hopper (base definition)
|
-- Downwards hopper (base definition)
|
||||||
|
|
||||||
---@type node_definition
|
---@type node_definition
|
||||||
|
@ -201,6 +243,29 @@ local def_hopper = {
|
||||||
minetest.log("action", player:get_player_name() ..
|
minetest.log("action", player:get_player_name() ..
|
||||||
" takes stuff from mcl_hoppers at " .. minetest.pos_to_string(pos))
|
" takes stuff from mcl_hoppers at " .. minetest.pos_to_string(pos))
|
||||||
end,
|
end,
|
||||||
|
_mcl_minecarts_on_enter_above = function(pos, cart, next_dir)
|
||||||
|
-- Only push to containers
|
||||||
|
if cart.groups and (cart.groups.container or 0) ~= 0 then
|
||||||
|
cart:add_node_watch(pos)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
_mcl_minecarts_on_leave_above = function(pos, cart, next_dir)
|
||||||
|
cart:remove_node_watch(pos)
|
||||||
|
end,
|
||||||
|
_mcl_minecarts_node_on_step = function(pos, cart, dtime)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
|
||||||
|
local timer = meta:get_int("minecart_hopper_timer")
|
||||||
|
if timer < dtime then
|
||||||
|
hopper_push_to_mc(cart, pos, 5)
|
||||||
|
timer = timer + 1
|
||||||
|
else
|
||||||
|
timer = timer - dtime
|
||||||
|
end
|
||||||
|
meta:set_int("minecart_hopper_timer", timer)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end,
|
||||||
sounds = mcl_sounds.node_sound_metal_defaults(),
|
sounds = mcl_sounds.node_sound_metal_defaults(),
|
||||||
|
|
||||||
_mcl_blast_resistance = 4.8,
|
_mcl_blast_resistance = 4.8,
|
||||||
|
@ -406,6 +471,44 @@ local def_hopper_side = {
|
||||||
on_rotate = on_rotate,
|
on_rotate = on_rotate,
|
||||||
sounds = mcl_sounds.node_sound_metal_defaults(),
|
sounds = mcl_sounds.node_sound_metal_defaults(),
|
||||||
|
|
||||||
|
_mcl_minecarts_on_enter_side = function(pos, cart, next_dir, rail_pos)
|
||||||
|
-- Only try to push to minecarts when the spout position is pointed at the rail
|
||||||
|
local face = minetest.get_node(pos).param2
|
||||||
|
local dst_pos = {}
|
||||||
|
if face == 0 then
|
||||||
|
dst_pos = vector.offset(pos, -1, 0, 0)
|
||||||
|
elseif face == 1 then
|
||||||
|
dst_pos = vector.offset(pos, 0, 0, 1)
|
||||||
|
elseif face == 2 then
|
||||||
|
dst_pos = vector.offset(pos, 1, 0, 0)
|
||||||
|
elseif face == 3 then
|
||||||
|
dst_pos = vector.offset(pos, 0, 0, -1)
|
||||||
|
end
|
||||||
|
if dst_pos ~= rail_pos then return end
|
||||||
|
|
||||||
|
-- Only push to containers
|
||||||
|
if cart.groups and (cart.groups.container or 0) ~= 0 then
|
||||||
|
cart:add_node_watch(pos)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
_mcl_minecarts_on_leave_side = function(pos, cart, next_dir)
|
||||||
|
cart:remove_node_watch(pos)
|
||||||
|
end,
|
||||||
|
_mcl_minecarts_node_on_step = function(pos, cart, dtime)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
|
||||||
|
local timer = meta:get_int("minecart_hopper_timer")
|
||||||
|
if timer < dtime then
|
||||||
|
hopper_push_to_mc(cart, pos, 5)
|
||||||
|
timer = timer + 1
|
||||||
|
else
|
||||||
|
timer = timer - dtime
|
||||||
|
end
|
||||||
|
meta:set_int("minecart_hopper_timer", timer)
|
||||||
|
|
||||||
|
return true
|
||||||
|
end,
|
||||||
|
|
||||||
_mcl_blast_resistance = 4.8,
|
_mcl_blast_resistance = 4.8,
|
||||||
_mcl_hardness = 3,
|
_mcl_hardness = 3,
|
||||||
}
|
}
|
||||||
|
@ -480,47 +583,6 @@ local function hopper_pull_from_mc(mc_ent, dest_pos, inv_size)
|
||||||
end
|
end
|
||||||
mcl_hoppers.pull_from_minecart = hopper_pull_from_mc
|
mcl_hoppers.pull_from_minecart = hopper_pull_from_mc
|
||||||
|
|
||||||
local function hopper_push_to_mc(mc_ent, dest_pos, inv_size)
|
|
||||||
local dest_inv = mcl_entity_invs.load_inv(mc_ent, inv_size)
|
|
||||||
if not dest_inv then
|
|
||||||
mcl_log("No inv")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local meta = minetest.get_meta(dest_pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
if not inv then
|
|
||||||
mcl_log("No dest inv")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
mcl_log("inv. size: " .. mc_ent._inv_size)
|
|
||||||
for i = 1, mc_ent._inv_size, 1 do
|
|
||||||
local stack = inv:get_stack("main", i)
|
|
||||||
|
|
||||||
mcl_log("i: " .. tostring(i))
|
|
||||||
mcl_log("Name: [" .. tostring(stack:get_name()) .. "]")
|
|
||||||
mcl_log("Count: " .. tostring(stack:get_count()))
|
|
||||||
mcl_log("stack max: " .. tostring(stack:get_stack_max()))
|
|
||||||
|
|
||||||
if not stack:get_name() or stack:get_name() ~= "" then
|
|
||||||
if dest_inv:room_for_item("main", stack:peek_item()) then
|
|
||||||
mcl_log("Room so unload")
|
|
||||||
dest_inv:add_item("main", stack:take_item())
|
|
||||||
inv:set_stack("main", i, stack)
|
|
||||||
|
|
||||||
-- Take one item and stop until next time
|
|
||||||
return
|
|
||||||
else
|
|
||||||
mcl_log("no Room")
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
mcl_log("nothing there")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[ BEGIN OF ABM DEFINITONS ]]
|
--[[ BEGIN OF ABM DEFINITONS ]]
|
||||||
|
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
|
|
Loading…
Reference in New Issue