91 lines
2.9 KiB
Lua
91 lines
2.9 KiB
Lua
|
|
local TIMER_INTERVAL = 0.8
|
|
local TIMER_INTERVAL_LONG = 2.0
|
|
local DEF_RADIUS = 3
|
|
local INV_MAIN = "main"
|
|
local ITEM_TAKE_PER_CYCLE_LIMIT = 10
|
|
local NUM_PARTICLES_PER_COLLECT = 3
|
|
|
|
local function random_offset()
|
|
return vector.new((math.random() - 0.5)/4, (math.random() - 0.5)/4, (math.random() - 0.5)/4)
|
|
end
|
|
|
|
local function add_particle_effect_for_item_taken(itemPos, vaccuumPos)
|
|
for _ = 1, NUM_PARTICLES_PER_COLLECT do
|
|
local startPos = vector.add(itemPos, random_offset())
|
|
local endPos = vector.add(vaccuumPos, vector.new(0, -0.45, 0))
|
|
local vel = vector.multiply(vector.normalize(vector.subtract(endPos, startPos)), 2)
|
|
minetest.add_particle({
|
|
pos = startPos,
|
|
velocity = vel,
|
|
expirationtime = 2,
|
|
size = 1,
|
|
collisiondetection = true,
|
|
collision_removal = true,
|
|
object_collision = false,
|
|
texture = "logistica_vaccuum_particle.png",
|
|
})
|
|
end
|
|
end
|
|
|
|
-- returns how many were inserted
|
|
local function collect_items_into(pos, distance)
|
|
local inserted = 0
|
|
|
|
local nodeName = minetest.get_node(pos).name
|
|
if not logistica.GROUPS.vaccuum_suppliers.is(nodeName) then return inserted end
|
|
local nodeDef = minetest.registered_nodes[nodeName]
|
|
if not nodeDef or not nodeDef.logistica or not nodeDef.on_metadata_inventory_put then
|
|
return inserted
|
|
end
|
|
|
|
distance = distance + 0.5
|
|
local minPos = vector.subtract(pos, distance)
|
|
local maxPos = vector.add(pos, distance)
|
|
local inv = minetest.get_meta(pos):get_inventory()
|
|
for _, obj in pairs(minetest.get_objects_in_area(minPos, maxPos)) do
|
|
local entity = obj:get_luaentity()
|
|
if entity
|
|
and entity.name == "__builtin:item"
|
|
and entity.itemstring ~= ""
|
|
and not entity._removed then
|
|
local itemStack = ItemStack(entity.itemstring)
|
|
if inv:room_for_item(INV_MAIN, itemStack) then
|
|
add_particle_effect_for_item_taken(obj:get_pos(), pos)
|
|
inv:add_item(INV_MAIN, itemStack)
|
|
-- this look unsafe, but we only target our supplier nodes
|
|
entity.itemstring = ""
|
|
inserted = inserted + 1
|
|
obj:remove()
|
|
if ITEM_TAKE_PER_CYCLE_LIMIT > 0
|
|
and inserted >= ITEM_TAKE_PER_CYCLE_LIMIT then
|
|
nodeDef.on_metadata_inventory_put(pos, nil, nil, nil, nil)
|
|
return inserted
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if inserted > 0 then
|
|
nodeDef.on_metadata_inventory_put(pos, nil, nil, nil, nil)
|
|
end
|
|
return inserted
|
|
end
|
|
|
|
-- global functions
|
|
|
|
function logistica.vaccuum_chest_on_timer(pos, elapsed)
|
|
if not logistica.is_machine_on(pos) then return false end
|
|
local inserted = collect_items_into(pos, DEF_RADIUS)
|
|
if inserted then
|
|
logistica.start_node_timer(pos, TIMER_INTERVAL)
|
|
else
|
|
logistica.start_node_timer(pos, TIMER_INTERVAL_LONG)
|
|
end
|
|
return false
|
|
end
|
|
|
|
function logistica.vaccuum_chest_on_power(pos, power)
|
|
logistica.set_node_tooltip_from_state(pos, nil, power)
|
|
logistica.start_node_timer(pos, TIMER_INTERVAL)
|
|
end
|