mirror of
https://git.minetest.land/VoxeLibre/VoxeLibre.git
synced 2024-11-28 05:21:05 +01:00
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
ec2d08524e
commit
f9e8f60a1c
2 changed files with 129 additions and 51 deletions
|
@ -61,8 +61,9 @@ local function handle_cart_enter_exit(self, pos, next_dir, event)
|
|||
local node_def = minetest.registered_nodes[node.name]
|
||||
|
||||
-- node-specific hook
|
||||
local hook = node_def["_mcl_minecarts_"..event..check[4]]
|
||||
if hook then hook(check_pos, self, next_dir) end
|
||||
local hook_name = "_mcl_minecarts_"..event..check[4]
|
||||
local hook = node_def[hook_name]
|
||||
if hook then hook(check_pos, self, next_dir, pos) end
|
||||
|
||||
-- global minecart hook
|
||||
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 hook = node_def._mcl_minecarts_node_on_step
|
||||
if hook and hook(node_pos, self, dtime) then
|
||||
new_watches[#new_watches] = node_pos
|
||||
new_watches[#new_watches+1] = node_pos
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -141,7 +142,7 @@ end
|
|||
local function direction_away_from_players(self, staticdata)
|
||||
local objs = minetest.get_objects_inside_radius(self.object:get_pos(), 1.1)
|
||||
for n=1,#objs do
|
||||
obj = objs[n]
|
||||
local obj = objs[n]
|
||||
local player_name = obj:get_player_name()
|
||||
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()
|
||||
|
@ -314,7 +315,7 @@ local function do_movement_step(self, dtime)
|
|||
handle_cart_enter(self, pos, next_dir)
|
||||
|
||||
-- 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
|
||||
staticdata.velocity = 0
|
||||
end
|
||||
|
@ -593,6 +594,13 @@ end
|
|||
|
||||
local function register_entity(entity_id, def)
|
||||
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 = {
|
||||
initial_properties = {
|
||||
physical = true,
|
||||
|
@ -603,8 +611,11 @@ local function register_entity(entity_id, def)
|
|||
textures = def.textures,
|
||||
},
|
||||
|
||||
groups = groups,
|
||||
|
||||
on_rightclick = def.on_rightclick,
|
||||
on_activate_by_rail = def.on_activate_by_rail,
|
||||
|
||||
_mcl_minecarts_on_enter = def._mcl_minecarts_on_enter,
|
||||
_mcl_minecarts_on_place = def._mcl_minecarts_on_place,
|
||||
_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
|
||||
pos = rounded_pos
|
||||
else
|
||||
print("TODO: handle detached cart behavior")
|
||||
mineclone.log("warning","TODO: handle detached cart behavior")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -757,14 +768,19 @@ local function register_entity(entity_id, def)
|
|||
|
||||
function cart:add_node_watch(pos)
|
||||
local staticdata = self._staticdata
|
||||
local watches = staticdata.watches
|
||||
local watches = staticdata.node_watches or {}
|
||||
|
||||
for _,watch in ipairs(watches) do
|
||||
if watch == pos then return end
|
||||
end
|
||||
|
||||
watches[#watches+1] = pos
|
||||
staticdata.node_watches = watches
|
||||
end
|
||||
function cart:remove_node_watch(pos)
|
||||
local staticdata = self._staticdata
|
||||
local watches = staticdata.node_watches or {}
|
||||
|
||||
local new_watches = {}
|
||||
for _,node_pos in ipairs(watches) do
|
||||
if node_pos ~= post then
|
||||
|
@ -792,8 +808,6 @@ local function register_entity(entity_id, def)
|
|||
end
|
||||
|
||||
local pos, rou_pos, node = self.object:get_pos()
|
||||
--local update = {}
|
||||
--local acceleration = 0
|
||||
|
||||
-- Controls
|
||||
local ctrl, player = nil, nil
|
||||
|
@ -820,7 +834,7 @@ local function register_entity(entity_id, def)
|
|||
|
||||
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
|
||||
local r = 0.6
|
||||
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",
|
||||
drop = {"mcl_minecarts:minecart", "mcl_chests:chest"},
|
||||
groups = { container = 1 },
|
||||
on_rightclick = nil,
|
||||
on_activate_by_rail = nil,
|
||||
creative = true
|
||||
|
@ -1269,6 +1284,7 @@ register_minecart({
|
|||
},
|
||||
icon = "mcl_minecarts_minecart_hopper.png",
|
||||
drop = {"mcl_minecarts:minecart", "mcl_hoppers:hopper"},
|
||||
groups = { container = 1 },
|
||||
on_rightclick = nil,
|
||||
on_activate_by_rail = nil,
|
||||
_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)
|
||||
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)
|
||||
|
||||
---@type node_definition
|
||||
|
@ -201,6 +243,29 @@ local def_hopper = {
|
|||
minetest.log("action", player:get_player_name() ..
|
||||
" takes stuff from mcl_hoppers at " .. minetest.pos_to_string(pos))
|
||||
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(),
|
||||
|
||||
_mcl_blast_resistance = 4.8,
|
||||
|
@ -406,6 +471,44 @@ local def_hopper_side = {
|
|||
on_rotate = on_rotate,
|
||||
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_hardness = 3,
|
||||
}
|
||||
|
@ -480,47 +583,6 @@ local function hopper_pull_from_mc(mc_ent, dest_pos, inv_size)
|
|||
end
|
||||
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 ]]
|
||||
|
||||
minetest.register_abm({
|
||||
|
|
Loading…
Reference in a new issue