This commit is contained in:
flux
2022-06-19 15:26:05 -07:00
parent 31f7d56a33
commit 5990d7c6a4
20 changed files with 617 additions and 144 deletions

30
invsaw/.luacheckrc Normal file
View File

@ -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",
},
}

12
invsaw/README.md Normal file
View File

@ -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.

34
invsaw/api.lua Normal file
View File

@ -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)

80
invsaw/formspec.lua Normal file
View File

@ -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)

30
invsaw/init.lua Normal file
View File

@ -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")

76
invsaw/inventory.lua Normal file
View File

@ -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)

3
invsaw/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = invsaw
description = "circular saw in the unified inventory"
depends = stairsplus, unified_inventory

61
invsaw/privs.lua Normal file
View File

@ -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

7
invsaw/settings.lua Normal file
View File

@ -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"
}

View File

@ -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