2022-06-13 06:10:36 +02:00
|
|
|
-- for creating the circular saw and similar nodes
|
2022-06-14 01:11:20 +02:00
|
|
|
|
|
|
|
local api = stairsplus.api
|
|
|
|
|
2022-06-21 21:22:26 +02:00
|
|
|
local resolve_aliases = stairsplus.util.resolve_aliases
|
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
local default_stack_max = tonumber(minetest.settings:get("default_stack_max")) or 99
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
local station = {}
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-19 01:23:11 +02:00
|
|
|
function station.get_cost(shaped_node)
|
2022-06-15 01:30:41 +02:00
|
|
|
if shaped_node == "" then
|
|
|
|
return 0
|
|
|
|
end
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
local shape = api.get_shape_of_shaped_node(shaped_node)
|
|
|
|
if shape == "node" then
|
|
|
|
return 8
|
|
|
|
end
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
local shape_def = api.registered_shapes[shape]
|
|
|
|
return shape_def and shape_def.eighths
|
|
|
|
end
|
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
function station.get_current_node(inv)
|
|
|
|
local input_stack = inv:get_stack("stairsplus:input", 1)
|
2022-06-15 01:30:41 +02:00
|
|
|
if not input_stack:is_empty() then
|
2022-06-22 20:51:58 +02:00
|
|
|
return api.get_node_of_shaped_node(input_stack:get_name())
|
2022-06-14 01:11:20 +02:00
|
|
|
end
|
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
local micro_stack = inv:get_stack("stairsplus:micro", 1)
|
2022-06-15 01:30:41 +02:00
|
|
|
if not micro_stack:is_empty() then
|
|
|
|
return api.get_node_of_shaped_node(micro_stack:get_name())
|
|
|
|
end
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
local recycle_stack = inv:get_stack("stairsplus:recycle", 1)
|
2022-06-15 01:30:41 +02:00
|
|
|
if not recycle_stack:is_empty() then
|
|
|
|
return api.get_node_of_shaped_node(recycle_stack:get_name())
|
|
|
|
end
|
2022-06-14 01:11:20 +02:00
|
|
|
end
|
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
function station.can_dig(meta, inv)
|
|
|
|
return inv:is_empty("stairsplus:input") and inv:is_empty("stairsplus:micro")
|
2022-06-19 01:23:11 +02:00
|
|
|
end
|
2022-06-15 01:30:41 +02:00
|
|
|
|
2022-06-20 23:29:13 +02:00
|
|
|
function station.on_receive_fields(meta, inv, formname, fields, sender, build_formspec, update_metadata)
|
2022-06-19 01:23:11 +02:00
|
|
|
local max = tonumber(fields.max_offered)
|
|
|
|
if max and max > 0 then
|
2022-06-20 00:26:05 +02:00
|
|
|
meta:set_int("stairsplus:max_offered", max)
|
2022-06-19 01:23:11 +02:00
|
|
|
-- Update to show the correct number of items:
|
2022-06-20 00:26:05 +02:00
|
|
|
station.update_inventory(meta, inv)
|
2022-06-20 23:29:13 +02:00
|
|
|
if update_metadata then
|
|
|
|
update_metadata(meta, inv)
|
2022-06-20 00:26:05 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
if build_formspec then
|
|
|
|
meta:set_string("formspec", build_formspec(meta, inv))
|
|
|
|
end
|
2022-06-14 01:11:20 +02:00
|
|
|
end
|
2022-06-15 01:30:41 +02:00
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
return not not fields.max_offered
|
|
|
|
end
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-21 21:22:26 +02:00
|
|
|
local function fix_aliases(inv)
|
|
|
|
local input = inv:get_stack("stairsplus:input", 1)
|
|
|
|
input:set_name(resolve_aliases(input:get_name()))
|
|
|
|
inv:set_stack("stairsplus:input", 1, input)
|
|
|
|
|
|
|
|
local micro = inv:get_stack("stairsplus:micro", 1)
|
|
|
|
micro:set_name(resolve_aliases(micro:get_name()))
|
|
|
|
inv:set_stack("stairsplus:micro", 1, micro)
|
|
|
|
|
|
|
|
local recycle = inv:get_stack("stairsplus:recycle", 1)
|
|
|
|
recycle:set_name(resolve_aliases(recycle:get_name()))
|
|
|
|
inv:set_stack("stairsplus:recycle", 1, recycle)
|
|
|
|
|
|
|
|
for i = 1, inv:get_size("stairsplus:output") do
|
|
|
|
local output = inv:get_stack("stairsplus:output", i)
|
|
|
|
output:set_name(resolve_aliases(output:get_name()))
|
|
|
|
inv:set_stack("stairsplus:output", i, output)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
function station.update_inventory(meta, inv, taken_stack)
|
2022-06-21 21:22:26 +02:00
|
|
|
fix_aliases(inv)
|
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
local node = station.get_current_node(inv)
|
2022-06-21 21:22:26 +02:00
|
|
|
local valid_shapes = api.shapes_by_node[node]
|
2022-06-15 01:30:41 +02:00
|
|
|
|
2022-06-21 21:22:26 +02:00
|
|
|
if not (node and valid_shapes) then
|
|
|
|
inv:set_stack("stairsplus:input", 1, ItemStack())
|
|
|
|
inv:set_stack("stairsplus:micro", 1, ItemStack())
|
|
|
|
inv:set_stack("stairsplus:recycle", 1, ItemStack())
|
2022-06-20 00:26:05 +02:00
|
|
|
for i = 1, inv:get_size("stairsplus:output") do
|
|
|
|
inv:set_stack("stairsplus:output", i, ItemStack())
|
2022-06-14 01:11:20 +02:00
|
|
|
end
|
2022-06-15 01:30:41 +02:00
|
|
|
return
|
2022-06-14 01:11:20 +02:00
|
|
|
end
|
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
local input_stack = inv:get_stack("stairsplus:input", 1)
|
|
|
|
local micro_stack = inv:get_stack("stairsplus:micro", 1)
|
|
|
|
local recycle_stack = inv:get_stack("stairsplus:recycle", 1)
|
2022-06-15 01:30:41 +02:00
|
|
|
|
2022-06-22 20:51:58 +02:00
|
|
|
local input_cost = station.get_cost(input_stack:get_name())
|
|
|
|
local micro_cost = station.get_cost(micro_stack:get_name())
|
|
|
|
local recycle_cost = station.get_cost(recycle_stack:get_name())
|
|
|
|
|
|
|
|
local total_value = (
|
|
|
|
(input_stack:get_count() * input_cost) +
|
|
|
|
(micro_stack:get_count() * micro_cost) +
|
|
|
|
(recycle_stack:get_count() * recycle_cost)
|
|
|
|
)
|
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
if taken_stack then
|
2022-06-22 20:51:58 +02:00
|
|
|
total_value = total_value - station.get_cost(taken_stack:get_name()) * taken_stack:get_count()
|
2022-06-15 01:30:41 +02:00
|
|
|
end
|
2022-06-22 20:51:58 +02:00
|
|
|
|
|
|
|
local new_micros = total_value % 8
|
|
|
|
local new_blocks = math.floor(total_value / 8)
|
|
|
|
|
|
|
|
local micronode = api.get_micronode(node)
|
2022-06-15 01:30:41 +02:00
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
inv:set_stack("stairsplus:input", 1, ItemStack({name = node, count = new_blocks}))
|
2022-06-22 20:51:58 +02:00
|
|
|
inv:set_stack("stairsplus:micro", 1, ItemStack({name = micronode, count = new_micros}))
|
2022-06-20 00:26:05 +02:00
|
|
|
inv:set_stack("stairsplus:recycle", 1, ItemStack())
|
2022-06-15 01:30:41 +02:00
|
|
|
|
2022-06-22 20:51:58 +02:00
|
|
|
if total_value == 0 then
|
2022-06-20 00:26:05 +02:00
|
|
|
for i = 1, inv:get_size("stairsplus:output") do
|
|
|
|
inv:set_stack("stairsplus:output", i, "")
|
2022-06-14 01:11:20 +02:00
|
|
|
end
|
2022-06-15 01:30:41 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
local max_offered = meta:get_int("stairsplus:max_offered")
|
|
|
|
local shape_groups = minetest.parse_json(meta:get_string("stairsplus:shape_groups"))
|
2022-06-15 01:30:41 +02:00
|
|
|
|
|
|
|
local i = 1
|
|
|
|
for _, group in ipairs(shape_groups) do
|
|
|
|
for _, shape in ipairs(api.shapes_by_group[group]) do
|
|
|
|
if valid_shapes[shape] then
|
|
|
|
local shape_def = api.registered_shapes[shape]
|
|
|
|
local shaped_node = api.format_name(node, shape)
|
|
|
|
local stack_max = math.min(max_offered, ItemStack(shaped_node):get_stack_max())
|
2022-06-22 20:51:58 +02:00
|
|
|
local count = math.min(stack_max, math.floor(total_value / shape_def.eighths))
|
2022-06-15 01:30:41 +02:00
|
|
|
local stack
|
|
|
|
if count > 0 then
|
|
|
|
stack = ItemStack({name = shaped_node, count = count})
|
|
|
|
else
|
|
|
|
stack = ""
|
|
|
|
end
|
2022-06-20 00:26:05 +02:00
|
|
|
inv:set_stack("stairsplus:output", i, stack)
|
2022-06-15 01:30:41 +02:00
|
|
|
i = i + 1
|
2022-06-14 01:11:20 +02:00
|
|
|
end
|
|
|
|
end
|
2022-06-15 01:30:41 +02:00
|
|
|
end
|
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
for j = i, inv:get_size("stairsplus:output") do
|
|
|
|
inv:set_stack("stairsplus:output", j, "")
|
2022-06-14 01:11:20 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
-- Moving the inventory of the station around is not allowed because it
|
|
|
|
-- is a fictional inventory. Moving inventory around would be rather
|
|
|
|
-- impractical and make things more difficult to calculate:
|
2022-06-22 20:51:58 +02:00
|
|
|
function station.allow_inventory_move(meta, inv, from_list, from_index, to_list, to_index, count, player)
|
2022-06-15 01:30:41 +02:00
|
|
|
return 0
|
|
|
|
end
|
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
function station.allow_inventory_put(meta, inv, listname, index, stack, player)
|
2022-06-22 20:51:58 +02:00
|
|
|
if listname == "stairsplus:output" then
|
2022-06-14 01:11:20 +02:00
|
|
|
return 0
|
|
|
|
end
|
|
|
|
|
2022-06-22 20:51:58 +02:00
|
|
|
local to_put_node = resolve_aliases(stack:get_name())
|
|
|
|
local node = api.get_node_of_shaped_node(to_put_node)
|
|
|
|
local shape = api.get_shape_of_shaped_node(to_put_node)
|
2022-06-15 01:30:41 +02:00
|
|
|
|
|
|
|
if not (node and shape) then
|
|
|
|
return 0
|
|
|
|
end
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
local current_node = station.get_current_node(inv)
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-22 20:51:58 +02:00
|
|
|
local input_stack = inv:get_stack("stairsplus:input", 1)
|
|
|
|
local micro_stack = inv:get_stack("stairsplus:micro", 1)
|
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
if current_node and node ~= current_node then
|
2022-06-22 20:51:58 +02:00
|
|
|
if (
|
|
|
|
(input_stack:is_empty() and listname == "stairsplus:micro") or
|
|
|
|
(micro_stack:is_empty() and listname == "stairsplus:input")
|
|
|
|
) then
|
|
|
|
return stack:get_count()
|
|
|
|
else
|
|
|
|
return 0
|
|
|
|
end
|
2022-06-15 01:30:41 +02:00
|
|
|
end
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
local count = stack:get_count()
|
2022-06-22 20:51:58 +02:00
|
|
|
local cost = station.get_cost(to_put_node)
|
2022-06-15 01:30:41 +02:00
|
|
|
|
|
|
|
local current_value = 8 * input_stack:get_count() + micro_stack:get_count()
|
|
|
|
local max_value = 8 * ItemStack(node):get_stack_max() + 7
|
|
|
|
|
|
|
|
local available_value = max_value - current_value
|
|
|
|
local available_count = math.floor(available_value / cost)
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
return math.min(count, available_count)
|
|
|
|
end
|
|
|
|
|
2022-06-22 20:51:58 +02:00
|
|
|
function station.on_inventory_put(meta, inv, listname, index, stack, player, update_metadata)
|
|
|
|
station.update_inventory(meta, inv)
|
|
|
|
if update_metadata then
|
|
|
|
update_metadata(meta, inv)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function station.on_inventory_take(meta, inv, listname, index, stack, player, update_metadata)
|
|
|
|
if listname == "stairsplus:output" then
|
|
|
|
station.update_inventory(meta, inv, stack)
|
|
|
|
else
|
|
|
|
station.update_inventory(meta, inv)
|
|
|
|
end
|
|
|
|
|
|
|
|
if update_metadata then
|
|
|
|
update_metadata(meta, inv)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-06-20 23:29:13 +02:00
|
|
|
function station.initialize_metadata(meta, inv, shape_groups, build_formspec, update_metadata)
|
2022-06-20 00:26:05 +02:00
|
|
|
meta:set_string("stairsplus:shape_groups", minetest.write_json(shape_groups))
|
2022-06-20 23:29:13 +02:00
|
|
|
|
|
|
|
if meta:get_int("max_offered") ~= 0 then
|
|
|
|
meta:set_int("stairsplus:max_offered", meta:get_int("max_offered"))
|
|
|
|
|
|
|
|
elseif meta:get_int("stairsplus:max_offered") == 0 then
|
2022-06-20 00:26:05 +02:00
|
|
|
meta:set_int("stairsplus:max_offered", default_stack_max)
|
|
|
|
end
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
if build_formspec then
|
|
|
|
meta:set_string("formspec", build_formspec(meta, inv))
|
|
|
|
end
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-20 23:29:13 +02:00
|
|
|
if update_metadata then
|
|
|
|
update_metadata(meta, inv)
|
2022-06-20 00:26:05 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2022-06-20 23:29:13 +02:00
|
|
|
function station.initialize_inventory(inv, shape_groups)
|
|
|
|
local output_size = 0
|
|
|
|
for _, group in ipairs(shape_groups) do
|
|
|
|
output_size = output_size + #api.shapes_by_group[group]
|
|
|
|
end
|
|
|
|
|
2022-06-20 00:26:05 +02:00
|
|
|
inv:set_size("stairsplus:input", 1)
|
|
|
|
inv:set_size("stairsplus:micro", 1)
|
|
|
|
inv:set_size("stairsplus:recycle", 1)
|
2022-06-20 23:29:13 +02:00
|
|
|
inv:set_size("stairsplus:output", output_size)
|
2022-06-20 02:08:21 +02:00
|
|
|
|
|
|
|
-- get rid of old lists
|
|
|
|
for _, listname in ipairs({"input", "micro", "recycle", "output"}) do
|
|
|
|
if inv:get_size(listname) > 0 then
|
|
|
|
inv:set_list(("stairsplus:%s"):format(listname), inv:get_list(listname))
|
|
|
|
inv:set_size(listname, 0)
|
|
|
|
end
|
|
|
|
end
|
2022-06-20 00:26:05 +02:00
|
|
|
end
|
2022-06-15 01:30:41 +02:00
|
|
|
|
2022-06-20 23:29:13 +02:00
|
|
|
function station.on_construct(pos, shape_groups, build_formspec, update_metadata)
|
2022-06-20 00:26:05 +02:00
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local inv = meta:get_inventory()
|
2022-06-14 01:11:20 +02:00
|
|
|
|
2022-06-20 23:29:13 +02:00
|
|
|
station.initialize_inventory(inv, shape_groups)
|
|
|
|
station.initialize_metadata(meta, inv, shape_groups, build_formspec, update_metadata)
|
|
|
|
station.update_inventory(meta, inv)
|
2022-06-14 01:11:20 +02:00
|
|
|
end
|
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
function station.after_place_node(pos, placer)
|
2022-06-14 01:11:20 +02:00
|
|
|
local meta = minetest.get_meta(pos)
|
2022-06-15 01:30:41 +02:00
|
|
|
if minetest.is_player(placer) then
|
|
|
|
meta:set_string("owner", placer:get_player_name())
|
2022-06-14 01:11:20 +02:00
|
|
|
end
|
|
|
|
end
|
2022-06-15 01:30:41 +02:00
|
|
|
|
2022-06-20 23:29:13 +02:00
|
|
|
function api.register_station(name, def)
|
|
|
|
local shape_groups = def.shape_groups
|
|
|
|
local build_formspec = def.build_formspec
|
|
|
|
local update_metadata = def.update_metadata
|
|
|
|
|
|
|
|
if not shape_groups then
|
|
|
|
error("station requires shape_groups defined")
|
|
|
|
end
|
|
|
|
|
|
|
|
def.shape_groups = nil
|
|
|
|
def.build_formspec = nil
|
|
|
|
def.update_metadata = nil
|
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
def.after_place_node = def.after_place_node or station.after_place_node
|
2022-06-20 00:26:05 +02:00
|
|
|
def.on_construct = def.on_construct or
|
|
|
|
function(pos)
|
2022-06-20 23:29:13 +02:00
|
|
|
return station.on_construct(pos, shape_groups, build_formspec, update_metadata)
|
2022-06-20 00:26:05 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def.can_dig = def.can_dig or
|
|
|
|
function(pos, player)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local inv = meta:get_inventory()
|
|
|
|
return station.can_dig(meta, inv, player)
|
|
|
|
end
|
|
|
|
|
|
|
|
def.on_receive_fields = def.on_receive_fields or
|
|
|
|
function(pos, formname, fields, sender)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local inv = meta:get_inventory()
|
|
|
|
return station.on_receive_fields(
|
2022-06-20 23:29:13 +02:00
|
|
|
meta, inv, formname, fields, sender, build_formspec, update_metadata
|
2022-06-20 00:26:05 +02:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def.allow_metadata_inventory_move = def.allow_metadata_inventory_move or
|
|
|
|
function(pos, from_list, from_index, to_list, to_index, count, player)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local inv = meta:get_inventory()
|
|
|
|
return station.allow_inventory_move(meta, inv, from_list, from_index, to_list, to_index, count, player)
|
|
|
|
end
|
|
|
|
|
|
|
|
def.allow_metadata_inventory_put = def.allow_metadata_inventory_put or
|
|
|
|
function(pos, listname, index, stack, player)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local inv = meta:get_inventory()
|
|
|
|
return station.allow_inventory_put(meta, inv, listname, index, stack, player)
|
|
|
|
end
|
|
|
|
|
|
|
|
def.on_metadata_inventory_put = def.on_metadata_inventory_put or
|
|
|
|
function(pos, listname, index, stack, player)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local inv = meta:get_inventory()
|
2022-06-20 23:29:13 +02:00
|
|
|
return station.on_inventory_put(meta, inv, listname, index, stack, player, update_metadata)
|
2022-06-20 00:26:05 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def.on_metadata_inventory_take = def.on_metadata_inventory_take or
|
|
|
|
function(pos, listname, index, stack, player)
|
|
|
|
local meta = minetest.get_meta(pos)
|
|
|
|
local inv = meta:get_inventory()
|
2022-06-20 23:29:13 +02:00
|
|
|
return station.on_inventory_take(meta, inv, listname, index, stack, player, update_metadata)
|
2022-06-20 00:26:05 +02:00
|
|
|
end
|
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
def._stairsplus_shape_groups = shape_groups
|
|
|
|
|
2022-06-20 02:08:21 +02:00
|
|
|
def.groups = table.copy(def.groups or {})
|
|
|
|
def.groups.stairsplus_station = 1
|
|
|
|
|
2022-06-15 01:30:41 +02:00
|
|
|
minetest.register_node(name, def)
|
|
|
|
end
|
|
|
|
|
|
|
|
api.station = station
|