elepower/elepower_farming/machines/harvester.lua

220 lines
5.9 KiB
Lua

-- How many seconds there are between runs
local HARVESTER_TICK = 10
-- How many plants we can collect in one run
local HARVESTER_SWEEP = 9
-- How much sludge is generated as a by-product
local SLUDGE_PRODUCED = 10
local function can_dig(pos, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
return inv:is_empty("dst")
end
local fdir_areas = {
{ -- NEG Z (0)
{x = -4, z = -8, y = 0},
{x = 4, z = 0, y = 0},
},
{ -- NEG X (1)
{x = -8, z = -4, y = 0},
{x = 0, z = 4, y = 0},
},
{ -- POS Z (2)
{x = -4, z = 0, y = 0},
{x = 4, z = 8, y = 0},
},
{ -- POS X (3)
{x = 0, z = -4, y = 0},
{x = 8, z = 4, y = 0},
},
nil, nil
}
local function harvest(pos, harvested, fdir)
local front = ele.helpers.face_front(pos, fdir)
local ranges = fdir_areas[fdir + 1]
if not ranges then return nil end
local range_st = vector.add(front, ranges[1])
local range_end = vector.add(front, ranges[2])
local shots = HARVESTER_SWEEP
for x = range_st.x, range_end.x do
for z = range_st.z, range_end.z do
if shots == 0 then break end
local check_pos = {x = x, y = range_st.y, z = z}
local check_node = minetest.get_node_or_nil(check_pos)
if check_node and ele.helpers.get_item_group(check_node.name, "plant") then
local nodedef = minetest.registered_nodes[check_node.name]
if (not nodedef['next_plant'] or not minetest.registered_nodes[nodedef.next_plant])
and not ele.helpers.get_item_group(check_node.name, "growing") then
-- Can harvest
local drop = minetest.get_node_drops(check_node.name)
if drop then
for _,item in ipairs(drop) do
harvested[#harvested + 1] = item
end
minetest.remove_node(check_pos)
shots = shots - 1
end
end
elseif check_node and ele.helpers.get_item_group(check_node.name, "tree") then
local success = elefarm.tc.capitate_tree(vector.subtract(check_pos, {x=0,y=1,z=0}))
if success then
shots = 0
for _,i in pairs(success) do
harvested[#harvested + 1] = i
end
end
end
end
end
return harvested
end
local function get_formspec(timer, power, sludge, state)
return "size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
ele.formspec.state_switcher(7, 2.5, state)..
ele.formspec.power_meter(power)..
ele.formspec.fluid_bar(7, 0, sludge)..
ele.formspec.create_bar(1, 0, 100 - timer, "#00ff11", true)..
"list[context;dst;1.5,0;5,3;]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
"listring[context;dst]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25)
end
local function on_timer(pos, elapsed)
local refresh = false
local meta = minetest.get_meta(pos)
local node = minetest.get_node(pos)
local inv = meta:get_inventory()
local capacity = ele.helpers.get_node_property(meta, pos, "capacity")
local usage = ele.helpers.get_node_property(meta, pos, "usage")
local storage = ele.helpers.get_node_property(meta, pos, "storage")
local work = meta:get_int("src_time")
local sludge = fluid_lib.get_buffer_data(pos, "sludge")
local state = meta:get_int("state")
local is_enabled = ele.helpers.state_enabled(meta, pos, state)
local active = "Idle"
local pow_buffer = {capacity = capacity, storage = storage, usage = 0}
if pow_buffer.storage > usage and sludge.amount + SLUDGE_PRODUCED < sludge.capacity and is_enabled then
if work == HARVESTER_TICK then
local harvested = {}
harvest(pos, harvested, node.param2)
work = 0
if #harvested > 0 then
pow_buffer.storage = pow_buffer.storage - usage
sludge.amount = sludge.amount + SLUDGE_PRODUCED
for _,itm in ipairs(harvested) do
local stack = ItemStack(itm)
if inv:room_for_item("dst", stack) then
inv:add_item("dst", stack)
end
end
end
else
work = work + 1
end
active = "Active"
refresh = true
pow_buffer.usage = usage
ele.helpers.swap_node(pos, "elepower_farming:harvester_active")
else
if not is_enabled then
active = "Off"
end
ele.helpers.swap_node(pos, "elepower_farming:harvester")
end
local work_percent = math.floor((work / HARVESTER_TICK)*100)
meta:set_string("formspec", get_formspec(work_percent, pow_buffer, sludge, state))
meta:set_string("infotext", ("Harvester %s\n%s"):format(active,
ele.capacity_text(capacity, storage)))
meta:set_int("storage", pow_buffer.storage)
meta:set_int("src_time", work)
meta:set_string("sludge_fluid", "elepower_farming:sludge_source")
meta:set_int("sludge_fluid_storage", sludge.amount)
return refresh
end
ele.register_machine("elepower_farming:harvester", {
description = "Automatic Harvester",
ele_capacity = 12000,
ele_inrush = 288,
ele_usage = 128,
tiles = {
"elefarming_machine_base.png", "elefarming_machine_base.png", "elefarming_machine_side.png",
"elefarming_machine_side.png", "elefarming_machine_side.png", "elefarming_machine_harvester.png",
},
groups = {
oddly_breakable_by_hand = 1,
ele_machine = 1,
ele_user = 1,
cracky = 1,
tubedevice = 1,
fluid_container = 1,
},
fluid_buffers = {
sludge = {
capacity = 8000,
drainable = true,
}
},
on_construct = function (pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("layout", 9)
inv:set_size("dst", 15)
meta:set_int("src_time", 0)
local capacity = ele.helpers.get_node_property(meta, pos, "capacity")
meta:set_string("formspec", get_formspec(0, {capacity = capacity, storage = 0, usage = 0}))
local node = minetest.get_node(pos)
end,
ele_active_node = true,
ele_active_nodedef = {
tiles = {
"elefarming_machine_base.png", "elefarming_machine_base.png", "elefarming_machine_side.png",
"elefarming_machine_side.png", "elefarming_machine_side.png", {
name = "elefarming_machine_harvester_animated.png",
animation = {
aspect_w = 16,
aspect_h = 16,
type = "vertical_frames",
length = 0.25,
},
},
}
},
can_dig = can_dig,
on_timer = on_timer,
})