From 5990d7c6a458cbe3822176df38551de56deca4c5 Mon Sep 17 00:00:00 2001 From: flux <25628292+fluxionary@users.noreply.github.com> Date: Sun, 19 Jun 2022 15:26:05 -0700 Subject: [PATCH] invsaw --- CHANGELOG.md | 4 +- README.md | 37 ++- TODO.md | 13 +- invsaw/.luacheckrc | 30 +++ invsaw/README.md | 12 + invsaw/api.lua | 34 +++ invsaw/formspec.lua | 80 +++++++ invsaw/init.lua | 30 +++ invsaw/inventory.lua | 76 +++++++ invsaw/mod.conf | 3 + invsaw/privs.lua | 61 +++++ invsaw/settings.lua | 7 + invsaw/unified_inventory.lua | 40 ++++ settingtypes.txt | 10 + stairsplus/api/station.lua | 211 +++++++++++------- stairsplus/circular_saw.lua | 90 +++++--- stairsplus/compat1/i3.lua | 4 +- stairsplus/compat1/unified_inventory.lua | 4 +- stairsplus/textures/stairsplus_saw_button.png | Bin 0 -> 1916 bytes stairsplus/util.lua | 15 +- 20 files changed, 617 insertions(+), 144 deletions(-) create mode 100644 invsaw/.luacheckrc create mode 100644 invsaw/README.md create mode 100644 invsaw/api.lua create mode 100644 invsaw/formspec.lua create mode 100644 invsaw/init.lua create mode 100644 invsaw/inventory.lua create mode 100644 invsaw/mod.conf create mode 100644 invsaw/privs.lua create mode 100644 invsaw/settings.lua create mode 100644 invsaw/unified_inventory.lua create mode 100644 stairsplus/textures/stairsplus_saw_button.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 6414568..8be1e8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,8 +31,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - maybe: [world aligned textures](https://github.com/minetest-mods/moreblocks/issues/179) - maybe: [Make microblocks work for nodes with layered textures](https://github.com/minetest-mods/moreblocks/issues/178) - [Make variants of nodes that can burn also burnable](https://github.com/minetest-mods/moreblocks/issues/177) -- \* [Add screenshot in README.md](https://github.com/minetest-mods/moreblocks/issues/151) -- \* [Slab back to full block](https://github.com/minetest-mods/moreblocks/issues/112) +- [Add screenshot in README.md](https://github.com/minetest-mods/moreblocks/issues/151) +- [Slab back to full block](https://github.com/minetest-mods/moreblocks/issues/112) - [Conserve left-over microblocks](https://github.com/minetest-mods/moreblocks/pull/108) - maybe some of the other bugs/PRS, but they mostly either seem to be fixed or unfixable diff --git a/README.md b/README.md index 4eecb95..c5a8f81 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ world block sandbox game. [Source repo](https://github.com/minetest-mods/moreblocks/) -## Version compatibility +## Minetest Version compatibility More Blocks is currently primarily tested with Minetest 5.5.0+. It may or may not work with newer or older versions. Issues arising in older @@ -25,28 +25,53 @@ The 3.0.0 release of moreblocks introduces a "legacy" mode, which is on by defau allow new servers to not commit to creating as many nodes as older versions, while not breaking anything on existing servers. See `settingtypes.txt` for available settings. -## Mods in the pack +# Mods in the pack -### moreblocks +## moreblocks Defines a bunch of new kinds of nodes. Provides an API for creating variants of some nodes. -### stairsplus +## stairsplus Allows the creation of 49 new shapes for registered nodes. -### stairsplus_legacy +## stairsplus_legacy Stairs+ registrations for various mods which were formerly done automatically as part of moreblocks. -## License +## invsaw + + +# Documentation + +## for plaers + +## for admins + +## for mod makers + +see moreblocks/API.md and stairsplus/API.md + +# License + +## moreblocks, stairsplus, stairsplus legacy Copyright © 2011-2022 Hugo Locurcio and contributors - More Blocks code is licensed under the zlib license, see [`LICENSE.md`](LICENSE.md) for details. - This is an altered version of the code which is not distributed by Hugo Locurcio. + - Unless otherwise specified, More Blocks textures are licensed under [CC BY-SA 3.0 Unported](https://creativecommons.org/licenses/by-sa/3.0/). - `moreblocks_copperpatina.png` was created by pithydon, and is licensed under [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/). +- `stairsplus_saw_button.png` CC BY-SA 3.0 Unported + +## invsaw + +Copyright © ?-2022 cheapie and contributors + +- invsaw code is licensed under the zlib license, see + [`LICENSE.md`](LICENSE.md) for details. +- This is an altered version of the code which is not distributed by cheapie. diff --git a/TODO.md b/TODO.md index 932ce4c..0d55db5 100644 --- a/TODO.md +++ b/TODO.md @@ -1,17 +1,8 @@ -please don't accept a PR with this file, this is meant to be a checklist of things that i think need to be done before -\[wip] status can be removed - -### ag TODO - -``` -stairsplus/API.md -3:TODO: write new API docs -``` ### other things -* finish updating documentation, for both users and API -* update translations (i18n, locale) +* finish updating documentation, for both admins and mod makers +* update translations (i18n) * finish testing (and creating) legacy support * ? create a way to analyze and reduce node_count diff --git a/invsaw/.luacheckrc b/invsaw/.luacheckrc new file mode 100644 index 0000000..ce63fdd --- /dev/null +++ b/invsaw/.luacheckrc @@ -0,0 +1,30 @@ +std = "lua51+luajit+minetest+invsaw" +unused_args = false +max_line_length = 120 + +stds.minetest = { + read_globals = { + "DIR_DELIM", + "minetest", + "core", + "dump", + "vector", + "nodeupdate", + "VoxelManip", + "VoxelArea", + "PseudoRandom", + "ItemStack", + "default", + "table", + } +} + +stds.moreblocks = { + globals = { + "invsaw", + }, + read_globals = { + "stairsplus", + "unified_inventory", + }, +} diff --git a/invsaw/README.md b/invsaw/README.md new file mode 100644 index 0000000..975af93 --- /dev/null +++ b/invsaw/README.md @@ -0,0 +1,12 @@ +invsaw +====== + +This mod adds a button in unified_inventory that opens a formspec that works exactly like the +moreblocks circular saw. It requires that either the server is in creative mode, you have the +"creative" priv, or you have one or more circular saws (moreblocks:circular_saw) in your inventory. + +Dependencies: moreblocks, unified_inventory + +Contains large amounts of code based on Calinou's moreblocks mod, and a texture based on some textures +from the same mod. + diff --git a/invsaw/api.lua b/invsaw/api.lua new file mode 100644 index 0000000..dd01e04 --- /dev/null +++ b/invsaw/api.lua @@ -0,0 +1,34 @@ +local station = stairsplus.api.station + +function invsaw.has_saw_in_inventory(player) + local inv = player:get_inventory() + return inv:contains_item("main", invsaw.settings.saw_item) +end + +function invsaw.can_use_saw(player) + return ( + minetest.check_player_privs(player, invsaw.settings.creative_priv) or + minetest.check_player_privs(player, invsaw.settings.priv) + ) +end + +function invsaw.allow_use_saw(player) + return ( + minetest.check_player_privs(player, invsaw.settings.creative_priv) or + (minetest.check_player_privs(player, invsaw.settings.priv) and invsaw.has_saw_in_inventory(player)) + ) +end + +function invsaw.on_join(player) + local meta = player:get_meta() + local inv = player:get_inventory() + if invsaw.can_use_saw(player) then + station.initialize_metadata(meta, inv, {"legacy"}) + station.initialize_inventory(inv) + + else + invsaw.drop_inventory(player) + end +end + +minetest.register_on_joinplayer(invsaw.on_join) diff --git a/invsaw/formspec.lua b/invsaw/formspec.lua new file mode 100644 index 0000000..6614da2 --- /dev/null +++ b/invsaw/formspec.lua @@ -0,0 +1,80 @@ +local ui = unified_inventory +local get_location_string = stairsplus.util.get_location_string +local station = stairsplus.api.station +local circular_saw = stairsplus.api.circular_saw + +local S = stairsplus.S +local F = minetest.formspec_escape + +invsaw.formspec = [[ + formspec_version[4] + size[16,15] + background9[0,0;1,1;ui_formbg_9_sliced.png;true;16] + listcolors[#00000000;#FFFFFF80;#00000000] + label[0.75,1.3;%s] + %s + list[%s;stairsplus:input;3,1;1,1;] + label[0.75,3;%s] + %s + list[%s;stairsplus:micro;3,2.5;1,1;] + label[0.75,4.3;%s] + %s + list[%s;stairsplus:recycle;3,4;1,1;] + field[0.75,6;1,1;max_offered;%s:;%i] + button[2,6;1,1;Set;%s] + %s + list[%s;stairsplus:output;5,1;8,6;] + %s + %s + list[current_player;main;4,9.5;8,4;] +]] + +function invsaw.build_formspec(meta, inv) + local inv_location = get_location_string(inv) + return invsaw.formspec:format( + F(S("Nodes")), + ui.single_slot(1.88, 0.88, true), + inv_location, + F(S("Microblocks")), + ui.single_slot(1.88, 2.38), + inv_location, + F(S("Input")), + ui.single_slot(1.88, 3.88), + inv_location, + F(S("Max")), + meta:get_int("stairsplus:max_offered"), + F(S("Set")), + ui.make_inv_img_grid(3.88, 0.88, 8, 6), + inv_location, + ui.make_inv_img_grid(3.88, 9.38, 8, 1, true), + ui.make_inv_img_grid(3.88, 10.63, 8, 3) + ) +end + +function invsaw.show_formspec(player) + local name = player:get_player_name() + local meta = player:get_meta() + local inv = player:get_inventory() + + minetest.show_formspec(name, "invsaw", circular_saw.build_formspec(meta, inv)) +end + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local meta = player:get_meta() + local inv = player:get_inventory() + + if fields.saw then + if invsaw.allow_use_saw(player) then + invsaw.show_formspec(player) + end + + return true + + elseif station.on_receive_fields(meta, inv, formname, fields, player) then + if invsaw.allow_use_saw(player) then + invsaw.show_formspec(player) + end + + return true + end +end) diff --git a/invsaw/init.lua b/invsaw/init.lua new file mode 100644 index 0000000..a145f80 --- /dev/null +++ b/invsaw/init.lua @@ -0,0 +1,30 @@ +local modname = minetest.get_current_modname() +local modpath = minetest.get_modpath(modname) +local S = minetest.get_translator(modname) + +invsaw = { + version = {3, 0, 0}, + fork = "minetest_mods", + + modname = modname, + modpath = modpath, + + S = S, + + log = function(level, messagefmt, ...) + return minetest.log(level, ("[%s] %s"):format(modname, messagefmt:format(...))) + end, + + dofile = function(...) + return dofile(table.concat({modpath, ...}, DIR_DELIM) .. ".lua") + end, +} + +invsaw.users = {} + +invsaw.dofile("settings") +invsaw.dofile("privs") +invsaw.dofile("api") +invsaw.dofile("inventory") +invsaw.dofile("formspec") +invsaw.dofile("unified_inventory") diff --git a/invsaw/inventory.lua b/invsaw/inventory.lua new file mode 100644 index 0000000..7ded029 --- /dev/null +++ b/invsaw/inventory.lua @@ -0,0 +1,76 @@ +local station = stairsplus.api.station + +function invsaw.drop_inventory(player) + local pos = player:get_pos() + local inv = player:get_inventory() + for _, listname in ipairs({"stairsplus:input", "stairsplus:micro", "stairsplus:recycle"}) do + for i = 1, inv:get_size(listname) do + local item = inv:get_stack(listname, i) + if not item:is_empty() then + minetest.add_item(pos, item) + end + end + inv:set_size(listname, 0) + end + inv:set_size("stairsplus:output", 0) +end + +local function is_stairsplus_inventory(listname) + return ( + listname == "stairsplus:input" or + listname == "stairsplus:micro" or + listname == "stairsplus:recycle" or + listname == "stairsplus:output" + ) +end + +local get_location_string = stairsplus.util.get_location_string + +minetest.register_allow_player_inventory_action(function(player, action, inv, info) + local meta = player:get_meta() + if action == "move" and is_stairsplus_inventory(info.from_list) and is_stairsplus_inventory(info.to_list) then + return station.allow_inventory_move( + meta, inv, info.from_list, info.from_index, info.to_list, info.to_index, info.count, player + ) + + elseif action == "move" and is_stairsplus_inventory(info.to_list) then + local stack = inv:get_stack(info.from_list, info.from_index) + return station.allow_inventory_put( + meta, inv, info.to_list, info.to_index, stack, player + ) + + elseif action == "put" and is_stairsplus_inventory(info.listname) then + return station.allow_inventory_put( + meta, inv, info.listname, info.index, info.stack, player + ) + end +end) + +minetest.register_on_player_inventory_action(function(player, action, inv, info) + local meta = player:get_meta() + if action == "move" and is_stairsplus_inventory(info.from_list) and is_stairsplus_inventory(info.to_list) then + + elseif action == "move" and is_stairsplus_inventory(info.from_list) then + local stack = inv:get_stack(info.to_list, info.to_index) + stack:set_count(info.count) + station.on_inventory_take( + meta, inv, info.from_list, info.from_index, stack, player + ) + + elseif action == "move" and is_stairsplus_inventory(info.to_list) then + local stack = inv:get_stack(info.from_list, info.from_index) + station.on_inventory_put( + meta, inv, info.to_list, info.to_index, stack, player + ) + + elseif action == "put" and is_stairsplus_inventory(info.listname) then + station.on_inventory_put( + meta, inv, info.listname, info.index, info.stack, player + ) + + elseif action == "take" and is_stairsplus_inventory(info.listname) then + station.on_inventory_take( + meta, inv, info.listname, info.index, info.stack, player + ) + end +end) diff --git a/invsaw/mod.conf b/invsaw/mod.conf new file mode 100644 index 0000000..eefb84e --- /dev/null +++ b/invsaw/mod.conf @@ -0,0 +1,3 @@ +name = invsaw +description = "circular saw in the unified inventory" +depends = stairsplus, unified_inventory diff --git a/invsaw/privs.lua b/invsaw/privs.lua new file mode 100644 index 0000000..c2c237b --- /dev/null +++ b/invsaw/privs.lua @@ -0,0 +1,61 @@ +local creative_priv = invsaw.settings.creative_priv +local priv = invsaw.settings.priv + +local function on_priv_change(name) + local player = minetest.get_player_by_name(name) + if player then + invsaw.on_join(player) + end +end + +if minetest.registered_privileges[priv] then + local def = minetest.registered_privileges[priv] + local old_on_grant = def.on_grant + local old_on_revoke = def.on_revoke + def.on_grant = function(name, cause) + on_priv_change(name) + if old_on_grant then + old_on_grant(name, cause) + end + end + def.on_revoke = function(name, cause) + on_priv_change(name) + if old_on_revoke then + old_on_revoke(name, cause) + end + end +else + minetest.register_privilege(priv, { + description = "Allow use of the circular saw in inventory", + give_to_singleplayer = true, + give_to_admin = false, + on_grant = on_priv_change, + on_revoke = on_priv_change, + }) +end + +if minetest.registered_privileges[creative_priv] then + local def = minetest.registered_privileges[creative_priv] + local old_on_grant = def.on_grant + local old_on_revoke = def.on_revoke + def.on_grant = function(name, cause) + on_priv_change(name) + if old_on_grant then + old_on_grant(name, cause) + end + end + def.on_revoke = function(name, cause) + on_priv_change(name) + if old_on_revoke then + old_on_revoke(name, cause) + end + end +else + minetest.register_privilege(creative_priv, { + description = "Allow use of the inventory saw creatively", + give_to_singleplayer = true, + give_to_admin = false, + on_grant = on_priv_change, + on_revoke = on_priv_change, + }) +end diff --git a/invsaw/settings.lua b/invsaw/settings.lua new file mode 100644 index 0000000..bef7e71 --- /dev/null +++ b/invsaw/settings.lua @@ -0,0 +1,7 @@ +local s = minetest.settings + +invsaw.settings = { + priv = s:get("invsaw.priv") or "interact", + creative_priv = s:get("invsaw.creative_priv") or "creative", + saw_item = s:get("invsaw.saw_item") or "stairsplus:circular_saw" +} diff --git a/invsaw/unified_inventory.lua b/invsaw/unified_inventory.lua new file mode 100644 index 0000000..04a31c6 --- /dev/null +++ b/invsaw/unified_inventory.lua @@ -0,0 +1,40 @@ +local ui = unified_inventory + +ui.register_button("saw", { + type = "image", + image = "stairsplus_saw_button.png", + tooltip = "Circular Saw", + condition = function(player) + return invsaw.allow_use_saw(player) + end, +}) + +-- this takes over 3 seconds on my machine O_O +--local old_get_formspec = ui.get_formspec +-- +--function ui.get_formspec(player, page) +-- local fs = old_get_formspec(player, page) +-- if invsaw.can_use_saw(player) then +-- return fs +-- end +-- +-- local start = minetest.get_us_time() +-- -- excise the button +-- local pre, post = fs:match( +-- "(.*)image_button%[%-?%d+%.?%d*,%-?%d+%.?%d*;%-?%d+%.?%d*,%-?%d+%.?%d*;stairsplus_saw_button.png[^%]]*](.*)" +-- ) +-- +-- if not pre and post then +-- pre, post = fs:match( +-- "(.*)image%[%-?%d+%.?%d*,%-?%d+%.?%d*;%-?%d+%.?%d*,%-?%d+%.?%d*;stairsplus_saw_button.png[^%]]*](.*)" +-- ) +-- end +-- +-- if pre and post then +-- fs = pre .. post +-- end +-- +-- minetest.chat_send_player(player:get_player_name(), ("took %s"):format((minetest.get_us_time() - start) / 1000000)) +-- +-- return fs +--end diff --git a/settingtypes.txt b/settingtypes.txt index 917c733..64ae917 100644 --- a/settingtypes.txt +++ b/settingtypes.txt @@ -1,3 +1,13 @@ +# will be created if it doesn't already exist +invsaw.priv (Priv to use the inventory saw) string interact + +# will be created if it doesn't already exist +invsaw.creative_priv (Priv to use the inventory saw w/out a saw item) string creative + +# The item that a normal player has to have to use the saw in inventory +invsaw.saw_item (Saw item) string stairsplus:circular_saw + +# stairsplus.circular_saw_crafting (Allow crafting the circular saw) bool true # Defaults to true if creative_mode is enabled. diff --git a/stairsplus/api/station.lua b/stairsplus/api/station.lua index 962b59d..7e1d2cc 100644 --- a/stairsplus/api/station.lua +++ b/stairsplus/api/station.lua @@ -6,18 +6,6 @@ local default_stack_max = tonumber(minetest.settings:get("default_stack_max")) o local station = {} -function station.update_infotext(pos) - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - return def.update_infotext(pos) -end - -function station.build_formspec(pos) - local node = minetest.get_node(pos) - local def = minetest.registered_nodes[node.name] - return def.build_formspec(pos) -end - function station.get_cost(shaped_node) if shaped_node == "" then return 0 @@ -32,59 +20,58 @@ function station.get_cost(shaped_node) return shape_def and shape_def.eighths end -function station.get_current_node(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - - local input_stack = inv:get_stack("input", 1) +function station.get_current_node(inv) + local input_stack = inv:get_stack("stairsplus:input", 1) if not input_stack:is_empty() then return input_stack:get_name() end - local micro_stack = inv:get_stack("micro", 1) + local micro_stack = inv:get_stack("stairsplus:micro", 1) if not micro_stack:is_empty() then return api.get_node_of_shaped_node(micro_stack:get_name()) end - local recycle_stack = inv:get_stack("recycle", 1) + local recycle_stack = inv:get_stack("stairsplus:recycle", 1) if not recycle_stack:is_empty() then return api.get_node_of_shaped_node(recycle_stack:get_name()) end end -function station.can_dig(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - return inv:is_empty("input") and inv:is_empty("micro") +function station.can_dig(meta, inv) + return inv:is_empty("stairsplus:input") and inv:is_empty("stairsplus:micro") end -function station.on_receive_fields(pos, formname, fields, sender) - local meta = minetest.get_meta(pos) +function station.on_receive_fields(meta, inv, formname, fields, sender, build_formspec, update_infotext) local max = tonumber(fields.max_offered) if max and max > 0 then - meta:set_int("max_offered", max) + meta:set_int("stairsplus:max_offered", max) -- Update to show the correct number of items: - station.update_inventory(pos) - station.update_infotext(pos) + station.update_inventory(meta, inv) + if update_infotext then + update_infotext(meta, inv) + end + + if build_formspec then + meta:set_string("formspec", build_formspec(meta, inv)) + end end + + return not not fields.max_offered end -function station.update_inventory(pos, taken_stack) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - - local node = station.get_current_node(pos) +function station.update_inventory(meta, inv, taken_stack) + local node = station.get_current_node(inv) if not node then - for i = 1, inv:get_size("output") do - inv:set_stack("output", i, ItemStack()) + for i = 1, inv:get_size("stairsplus:output") do + inv:set_stack("stairsplus:output", i, ItemStack()) end return end - local input_stack = inv:get_stack("input", 1) - local micro_stack = inv:get_stack("micro", 1) - local recycle_stack = inv:get_stack("recycle", 1) + 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) local current_value = 8 * input_stack:get_count() + micro_stack:get_count() local new_value = current_value + station.get_cost(recycle_stack:get_name()) * recycle_stack:get_count() @@ -94,21 +81,20 @@ function station.update_inventory(pos, taken_stack) local new_micros = new_value % 8 local new_blocks = math.floor(new_value / 8) - inv:set_stack("input", 1, ItemStack({name = node, count = new_blocks})) - inv:set_stack("micro", 1, ItemStack({name = api.get_micronode(node), count = new_micros})) - inv:set_stack("recycle", 1, ItemStack()) + inv:set_stack("stairsplus:input", 1, ItemStack({name = node, count = new_blocks})) + inv:set_stack("stairsplus:micro", 1, ItemStack({name = api.get_micronode(node), count = new_micros})) + inv:set_stack("stairsplus:recycle", 1, ItemStack()) if new_value == 0 then - for i = 1, inv:get_size("output") do - inv:set_stack("output", i, "") + for i = 1, inv:get_size("stairsplus:output") do + inv:set_stack("stairsplus:output", i, "") end return end local valid_shapes = api.shapes_by_node[node] - local shape_groups = minetest.registered_nodes[minetest.get_node(pos).name]._stairsplus_shape_groups - - local max_offered = meta:get_int("max_offered") + local max_offered = meta:get_int("stairsplus:max_offered") + local shape_groups = minetest.parse_json(meta:get_string("stairsplus:shape_groups")) local i = 1 for _, group in ipairs(shape_groups) do @@ -124,41 +110,45 @@ function station.update_inventory(pos, taken_stack) else stack = "" end - inv:set_stack("output", i, stack) + inv:set_stack("stairsplus:output", i, stack) i = i + 1 end end end - for j = i, inv:get_size("output") do - inv:set_stack("output", j, "") + for j = i, inv:get_size("stairsplus:output") do + inv:set_stack("stairsplus:output", j, "") end end -function station.on_metadata_inventory_put(pos, listname, index, stack, player) - station.update_inventory(pos) - station.update_infotext(pos) +function station.on_inventory_put(meta, inv, listname, index, stack, player, update_infotext) + station.update_inventory(meta, inv) + if update_infotext then + update_infotext(meta, inv) + end end -function station.on_metadata_inventory_take(pos, listname, index, stack, player) - if listname == "output" then - station.update_inventory(pos, stack) +function station.on_inventory_take(meta, inv, listname, index, stack, player, update_infotext) + if listname == "stairsplus:output" then + station.update_inventory(meta, inv, stack) else - station.update_inventory(pos) + station.update_inventory(meta, inv) end - station.update_infotext(pos) + if update_infotext then + update_infotext(meta, inv) + end end -- 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: -function station.allow_metadata_inventory_move() +function station.allow_inventory_move() return 0 end -function station.allow_metadata_inventory_put(pos, listname, index, stack, player) - if listname ~= "recycle" then +function station.allow_inventory_put(meta, inv, listname, index, stack, player) + if listname ~= "stairsplus:recycle" then return 0 end @@ -170,9 +160,7 @@ function station.allow_metadata_inventory_put(pos, listname, index, stack, playe return 0 end - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - local current_node = station.get_current_node(pos) + local current_node = station.get_current_node(inv) if current_node and node ~= current_node then return 0 @@ -181,8 +169,8 @@ function station.allow_metadata_inventory_put(pos, listname, index, stack, playe local count = stack:get_count() local cost = station.get_cost(shaped_node) - local input_stack = inv:get_stack("input", 1) - local micro_stack = inv:get_stack("micro", 1) + local input_stack = inv:get_stack("stairsplus:input", 1) + local micro_stack = inv:get_stack("stairsplus:micro", 1) local current_value = 8 * input_stack:get_count() + micro_stack:get_count() local max_value = 8 * ItemStack(node):get_stack_max() + 7 @@ -193,20 +181,34 @@ function station.allow_metadata_inventory_put(pos, listname, index, stack, playe return math.min(count, available_count) end -function station.on_construct(pos) +function station.initialize_metadata(meta, inv, shape_groups, build_formspec, update_infotext) + meta:set_string("stairsplus:shape_groups", minetest.write_json(shape_groups)) + if meta:get_int("stairsplus:max_offered") == 0 then + meta:set_int("stairsplus:max_offered", default_stack_max) + end + + if build_formspec then + meta:set_string("formspec", build_formspec(meta, inv)) + end + + if update_infotext then + update_infotext(meta, inv) + end +end + +function station.initialize_inventory(inv) + inv:set_size("stairsplus:input", 1) + inv:set_size("stairsplus:micro", 1) + inv:set_size("stairsplus:recycle", 1) + inv:set_size("stairsplus:output", 6 * 9) +end + +function station.on_construct(pos, shape_groups, build_formspec, update_infotext) local meta = minetest.get_meta(pos) - - meta:set_string("formspec", station.build_formspec(pos)) - meta:set_string("max_offered", default_stack_max) -- How many items of this kind are offered by default? - local inv = meta:get_inventory() - inv:set_size("input", 1) -- Input slot for full blocks of material x. - inv:set_size("micro", 1) -- Storage for 1-7 surplus microblocks. - inv:set_size("recycle", 1) -- Surplus partial blocks can be placed here. - inv:set_size("output", 6 * 9) -- 6x9 versions of stair-parts of material x. - - station.update_infotext(pos) + station.initialize_inventory(inv) + station.initialize_metadata(meta, inv, shape_groups, build_formspec, update_infotext) end function station.after_place_node(pos, placer) @@ -218,14 +220,55 @@ end function api.register_station(name, shape_groups, def) def.after_place_node = def.after_place_node or station.after_place_node - def.on_construct = def.on_construct or station.on_construct - def.can_dig = def.can_dig or station.can_dig - def.on_receive_fields = def.on_receive_fields or station.on_receive_fields - def.allow_metadata_inventory_move = def.allow_metadata_inventory_move or station.allow_metadata_inventory_move - def.allow_metadata_inventory_put = def.allow_metadata_inventory_put or station.allow_metadata_inventory_put - def.allow_metadata_inventory_take = def.allow_metadata_inventory_take or station.allow_metadata_inventory_take - def.on_metadata_inventory_put = def.on_metadata_inventory_put or station.on_metadata_inventory_put - def.on_metadata_inventory_take = def.on_metadata_inventory_take or station.on_metadata_inventory_take + def.on_construct = def.on_construct or + function(pos) + return station.on_construct(pos, shape_groups, def.build_formspec, def.update_infotext) + 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( + meta, inv, formname, fields, sender, def.build_formspec, def.update_infotext + ) + 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() + return station.on_inventory_put(meta, inv, listname, index, stack, player, def.update_infotext) + 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() + return station.on_inventory_take(meta, inv, listname, index, stack, player, def.update_infotext) + end + def._stairsplus_shape_groups = shape_groups minetest.register_node(name, def) diff --git a/stairsplus/circular_saw.lua b/stairsplus/circular_saw.lua index 1796f88..3224044 100644 --- a/stairsplus/circular_saw.lua +++ b/stairsplus/circular_saw.lua @@ -1,57 +1,75 @@ +stairsplus.api.circular_saw = {} +local circular_saw = stairsplus.api.circular_saw local api = stairsplus.api local station = api.station +local get_location_string = stairsplus.util.get_location_string + local S = stairsplus.S local F = minetest.formspec_escape local formspec_style = stairsplus.resources.formspec_style -local function update_infotext(pos) - local meta = minetest.get_meta(pos) +function circular_saw.build_formspec(meta, inv) + local inv_location = get_location_string(inv) + return ([[ + size[12,10] + %s + label[0,0;%s] + list[%s;stairsplus:input;1.7,0;1,1;] + label[0,1;%s] + list[%s;stairsplus:micro;1.7,1;1,1;] + label[0,2;%s] + list[%s;stairsplus:recycle;1.7,2;1,1;] + field[0.3,3.5;1,1;max_offered;%s:;%i] + button[1,3.2;1.7,1;Set;%s] + + list[%s;stairsplus:output;2.8,0;9,6;] + list[current_player;main;1.5,6.25;8,4;] + + listring[%s;stairsplus:output] + listring[current_player;main] + listring[%s;stairsplus:recycle] + + listring[%s;stairsplus:micro] + listring[current_player;main] + + listring[%s;stairsplus:input] + listring[current_player;main] + ]]):format( + formspec_style, + F(S("Nodes")), + inv_location, + F(S("Microblocks")), + inv_location, + F(S("Input")), + inv_location, + F(S("Max")), + meta:get_int("stairsplus:max_offered"), + F(S("Set")), + inv_location, + inv_location, + inv_location, + inv_location, + inv_location + ) +end + +function circular_saw.update_infotext(meta, inv) local parts = {} - if station.can_dig(pos) then + if station.can_dig(meta, inv) then table.insert(parts, S("Circular Saw is empty")) end local owner = meta:get_string("owner") if owner ~= "" then - table.insert(parts, S("(owned by @1)", meta:get_string("owner"))) + table.insert(parts, S("(owned by @1)", owner)) end meta:set_string("infotext", table.concat(parts, " ")) end -local function build_formspec() - return ([[ - size[12,10] - %s - label[0,0;%s] - list[current_name;input;1.7,0;1,1;] - label[0,1;%s] - list[current_name;micro;1.7,1;1,1;] - label[0,2;%s] - list[current_name;recycle;1.7,2;1,1;] - field[0.3,3.5;1,1;max_offered;%s:;${max_offered}] - button[1,3.2;1.7,1;Set;%s] - - list[current_name;output;2.8,0;9,6;] - list[current_player;main;1.5,6.25;8,4;] - - listring[current_name;output] - listring[current_player;main] - listring[current_name;recycle] - - listring[current_name;micro] - listring[current_player;main] - - listring[current_name;input] - listring[current_player;main] - ]]):format( - formspec_style, S("Nodes"), F(S("Microblocks")), F(S("Input")), F(S("Max")), F(S("Set")) - ) -end - api.register_station("stairsplus:circular_saw", {"legacy"}, { description = S("Circular Saw"), drawtype = "nodebox", @@ -79,8 +97,8 @@ api.register_station("stairsplus:circular_saw", {"legacy"}, { groups = {choppy = 2, oddly_breakable_by_hand = 2}, sounds = stairsplus.resources.sounds.wood, - build_formspec = build_formspec, - update_infotext = update_infotext, + build_formspec = circular_saw.build_formspec, + update_infotext = circular_saw.update_infotext, }) local cm = stairsplus.resources.craft_materials diff --git a/stairsplus/compat1/i3.lua b/stairsplus/compat1/i3.lua index c4bfc29..0d0e8b6 100644 --- a/stairsplus/compat1/i3.lua +++ b/stairsplus/compat1/i3.lua @@ -8,12 +8,12 @@ local api = stairsplus.api i3.register_craft_type("stairsplus:craft_schema", { description = "Stairs+ craft schema", - icon = "stairsplus_circular_saw_top.png", + icon = "stairsplus_saw_button.png", }) i3.register_craft_type("stairsplus:craft_schema", { description = "Stairs+ circular saw", - icon = "stairsplus_circular_saw_top.png", + icon = "stairsplus_saw_button.png", }) local function convert_schema_recipe_item(item) diff --git a/stairsplus/compat1/unified_inventory.lua b/stairsplus/compat1/unified_inventory.lua index c046622..5a3734c 100644 --- a/stairsplus/compat1/unified_inventory.lua +++ b/stairsplus/compat1/unified_inventory.lua @@ -10,7 +10,7 @@ unified_inventory.register_craft_type("stairsplus:craft_schema", { -- ^ Unique identifier for `register_craft` description = "Stairs+ craft schema", -- ^ Text shown below the crafting arrow - icon = "stairsplus_circular_saw_top.png", + icon = "stairsplus_saw_button.png", -- ^ Image shown above the crafting arrow width = 3, height = 3, @@ -22,7 +22,7 @@ unified_inventory.register_craft_type("stairsplus:circular_saw", { -- ^ Unique identifier for `register_craft` description = "Stairs+ circular saw", -- ^ Text shown below the crafting arrow - icon = "stairsplus_circular_saw_top.png", + icon = "stairsplus_saw_button.png", -- ^ Image shown above the crafting arrow width = 1, height = 1, diff --git a/stairsplus/textures/stairsplus_saw_button.png b/stairsplus/textures/stairsplus_saw_button.png new file mode 100644 index 0000000000000000000000000000000000000000..8ac809359f1878fdb3469517a814d69d795cc37e GIT binary patch literal 1916 zcmV-?2ZQ*DP)F@pEK;#R2-+BlDk0ygC-!(ep1F7K=NuO2-fO$I$Eod5kn&2F z?0b*j^W69R-rqTQ2A;*Uc=~Z=@w~dScwRk?+~O#cEna*Tm35xOpou(v84DK!um?*`y zcRvuH3h=9oUr_+_ZLho*ged^7r3)S;I=yR4>aGdEhxhsbTzmI@@m~S{-b-KBG(s=A zmxFk=MCHN=;vC#G^o5Ej?>*>lY|HnDKiv>d1^Cs)^J*MtbXp$0^&zgMfyX&qt5HW~ zF;&+?DaGZhKgTdM@R>7bc>T4Pv2D4TP$@n;S7&+62cBFi`wsffH_s}7PJ5R5R+SAu z!jClMYCkB)RVo!+Tk`!M|FQ%HxO3+Y0GBRZ;`P^F2H^CGrk-3t-8D&)33rzV0KE0i zbg9U_ZoKmCFDZb9&on5qZv-(2L8qy8>zR6;AFPC+6c;Z4u!Jo@3s``!esLav;V{fs zCu5vH{1;Bt%9WhvC}L+tUsR4QnQvME%+#xT5TLK!XoQJ^(LWeS`b=@9zNp z%`dK&n%5qk=?AtXsDyDWwz&$xhYxhlw>}2G?T>S37t~DErqiwiFyE@?-JkIMg06IT zO(!a3QGlztuXFO`$!(xN`Ozyh>Q3&TYqBI7KMkxPF)rZ?6_J&xpLKx{vo_cPUZf``VT`R4tu(J!_{V4#~uU{`gfBVK&0BqA>945Gq z$-`Cspu*7qU$rGwTM~pRK@cE-mGv>8b=@B&`#0UWvkR&{>u$TD0MD@i!KsA?C`AyZ zJX#%TD5*93>)*Y}uYUG}QYKraa_{jtcekv(*KX8dlHj>6AFYlE;|R;L5V`#+0o{C# ztrgx?*x&lv8D(1%CMi)0mT90Am{KB*N;xh{HNf#>H99Sip&yr0*$UoW9e`mn4#sTt za6v|rRghAHgh_@Y6{2D?j#I9^v(xIPTFB*#XA~GH6bixGhMsU?ZWe$Oo%*&N4#0C{ z*_?&nmYU5UCdk2;`%x(^p>i6P^7}vTy_v}AE^U;$h~tbT$uLcWhbseGGcLCuY41F> z(16K=PP?{Q)x0?of*?$oZ&g|D>1$FNEcdjBkMoE1Y^kd!rXx+g8^SLsGSf;sno; zgh>XI^x(iz0=A{K8YUUfpJ*}I@aYXA;yA;$DtVQ(M{fkC-dvRK@JEF+2m{-+Q2A;V zn?;gF41Jv=Ofm#8jyX6mz%bXFU{YSY_c*|wUBG5NcZrNRh5o>&Ia}qUmfSoSOq9Vy8B{72mX?<21|F-iZamA9 zSeB&Q8*;z9PJbgHj1nAMYFOZ-af6lg7`JZSVmKV4RApO!+mu9cbnpt-J(nnsQL2J% zO2)CGS(Eg7JyESz)!n;y^}y4oF${yIIlz>gHLxrVvmDIqqDVVKyII>Yrr+-ifZ5qu6{WgyjvuShnsEt} zjKYNBuw$Fss@iUNv>V>uuHxziv!sD->ff6+Ii*Kz+~PeipTpZn z!&4;@h9RzFW19w5&)oH`cQ;o7aNK+Y$oAf9yK4cBx`u8yJi<6(EyrFYn(GMdHG4{`}WlVn0{e_A@2^_Rj}G7bYr;@%DTF5{HsR0sTZ#bo(xc z_an)_UxhzuG-~z^tD5F22MNg$M`2Tis~mM4DR6f!&<&Tr*FA}|e9|~lNeuk3w5r0Q z_H&j`T@vdfeE`q?pT3m&#<|a_#fxVZ&*E7;{rC?}@g;M`VfyI+0000