mirror of
https://github.com/minetest-mods/moreblocks.git
synced 2025-07-16 06:40:34 +02:00
invsaw
This commit is contained in:
30
invsaw/.luacheckrc
Normal file
30
invsaw/.luacheckrc
Normal 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
12
invsaw/README.md
Normal 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
34
invsaw/api.lua
Normal 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
80
invsaw/formspec.lua
Normal 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
30
invsaw/init.lua
Normal 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
76
invsaw/inventory.lua
Normal 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
3
invsaw/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = invsaw
|
||||
description = "circular saw in the unified inventory"
|
||||
depends = stairsplus, unified_inventory
|
61
invsaw/privs.lua
Normal file
61
invsaw/privs.lua
Normal 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
7
invsaw/settings.lua
Normal 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"
|
||||
}
|
40
invsaw/unified_inventory.lua
Normal file
40
invsaw/unified_inventory.lua
Normal 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
|
Reference in New Issue
Block a user