2020-03-25 18:46:35 +01:00
|
|
|
--[[
|
2019-06-16 10:26:40 +02:00
|
|
|
Bags for Minetest
|
2012-12-02 10:08:32 +01:00
|
|
|
|
2019-06-16 10:26:40 +02:00
|
|
|
Copyright (c) 2012 cornernote, Brett O'Donnell <cornernote@gmail.com>
|
|
|
|
License: GPLv3
|
|
|
|
--]]
|
2012-12-02 10:08:32 +01:00
|
|
|
|
2019-09-19 14:00:26 +02:00
|
|
|
local S = minetest.get_translator("unified_inventory")
|
2018-04-02 13:33:36 +02:00
|
|
|
local F = minetest.formspec_escape
|
2021-03-07 14:18:17 +01:00
|
|
|
local ui = unified_inventory
|
2014-06-21 12:44:31 +02:00
|
|
|
|
2021-03-07 14:18:17 +01:00
|
|
|
ui.register_page("bags", {
|
2023-01-10 01:41:36 +01:00
|
|
|
get_formspec = function(player, perplayer_formspec)
|
2013-09-29 00:15:37 +02:00
|
|
|
local player_name = player:get_player_name()
|
2023-01-10 01:41:36 +01:00
|
|
|
local std_inv_x = perplayer_formspec.std_inv_x
|
|
|
|
local formspec = {
|
|
|
|
perplayer_formspec.standard_inv_bg,
|
|
|
|
"label[", perplayer_formspec.form_header_x, ",",
|
|
|
|
perplayer_formspec.form_header_y, ";", F(S("Bags")), "]",
|
2019-03-31 11:26:02 +02:00
|
|
|
"listcolors[#00000000;#00000000]",
|
2023-01-10 01:41:36 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
for i = 1, 4 do
|
|
|
|
local x = std_inv_x + i * 2.5
|
|
|
|
formspec[#formspec + 1] = ui.single_slot(x - 1.875, 1.5)
|
|
|
|
formspec[#formspec + 1] = string.format("list[detached:%s_bags;bag%i;%.3f,1.65;1,1;]",
|
|
|
|
F(player_name), i, x - 1.725)
|
|
|
|
formspec[#formspec + 1] = string.format("button[%.4f,2.75;1.875,0.75;bag%i;%s]",
|
|
|
|
x - 2.1875, i, F(S("Bag @1", i)))
|
|
|
|
end
|
|
|
|
|
|
|
|
return { formspec = table.concat(formspec) }
|
2013-09-29 00:15:37 +02:00
|
|
|
end,
|
|
|
|
})
|
|
|
|
|
2021-03-07 14:18:17 +01:00
|
|
|
ui.register_button("bags", {
|
2013-09-29 00:15:37 +02:00
|
|
|
type = "image",
|
|
|
|
image = "ui_bags_icon.png",
|
2015-10-05 10:24:01 +02:00
|
|
|
tooltip = S("Bags"),
|
2013-09-29 00:15:37 +02:00
|
|
|
})
|
|
|
|
|
2018-06-21 21:23:21 +02:00
|
|
|
local function get_player_bag_stack(player, i)
|
|
|
|
return minetest.get_inventory({
|
|
|
|
type = "detached",
|
|
|
|
name = player:get_player_name() .. "_bags"
|
|
|
|
}):get_stack("bag" .. i, 1)
|
|
|
|
end
|
|
|
|
|
2019-03-31 11:26:02 +02:00
|
|
|
for bag_i = 1, 4 do
|
2021-03-07 14:18:17 +01:00
|
|
|
ui.register_page("bag" .. bag_i, {
|
2023-01-10 01:41:36 +01:00
|
|
|
get_formspec = function(player, perplayer_formspec)
|
2019-03-31 11:26:02 +02:00
|
|
|
local stack = get_player_bag_stack(player, bag_i)
|
2013-09-29 00:15:37 +02:00
|
|
|
local image = stack:get_definition().inventory_image
|
Use 9-slicing to build inventory-type backgrounds
This way the slots are all nice and crisp regardless of GUI scale or
image size, and we only need the single slot and its bright version.
This also makes the standard crafting grid into a style table entry that
can be referenced to insert the crafting grid at its proper
style-specific position in any formspec.
And it also makes the craft grid arrow, its X position, and the crafting
grid's result slot X position into style table entries.
Includes a few public helper functions to do most of the work:
`ui.single_slot(xpos, ypos, bright)`
Does just what it sounds like: it returns a single slot image.
`xpos` and `ypos` are normal coordinates in slots, as you'd use in
`image[]` element. `bright` is a flag that switches to the brighter
version of the slot image.
`ui.make_trash_slot(xpos, ypos)`
Creates a single slot, with a one-item `list[]` and a trash can icon
overlay.
`ui.make_inv_img_grid(xpos, ypos, width, height, bright)`
Generates a `width` by `height` grid of slot images, using the
single_slot function above, starting at (`xpos`,`ypos`) for the
top-left. Position is as in any `image[]` element, and dimensions
are in integer numbers of slots (so 8,4 would be a standard inventory).
`bright` is as above.
All three return a string that can be directly inserted into a formspec.
2021-03-08 18:14:31 +01:00
|
|
|
local slots = stack:get_definition().groups.bagslots
|
2023-01-10 01:41:36 +01:00
|
|
|
local std_inv_x = perplayer_formspec.std_inv_x
|
|
|
|
local lite_mode = perplayer_formspec.is_lite_mode
|
|
|
|
|
|
|
|
local bag_inv_y, header_x, header_y = 1.5, 0.3, 0.65
|
|
|
|
if lite_mode then
|
|
|
|
bag_inv_y = 0.5
|
|
|
|
header_x = perplayer_formspec.form_header_x
|
|
|
|
header_y = perplayer_formspec.form_header_y
|
|
|
|
end
|
Use 9-slicing to build inventory-type backgrounds
This way the slots are all nice and crisp regardless of GUI scale or
image size, and we only need the single slot and its bright version.
This also makes the standard crafting grid into a style table entry that
can be referenced to insert the crafting grid at its proper
style-specific position in any formspec.
And it also makes the craft grid arrow, its X position, and the crafting
grid's result slot X position into style table entries.
Includes a few public helper functions to do most of the work:
`ui.single_slot(xpos, ypos, bright)`
Does just what it sounds like: it returns a single slot image.
`xpos` and `ypos` are normal coordinates in slots, as you'd use in
`image[]` element. `bright` is a flag that switches to the brighter
version of the slot image.
`ui.make_trash_slot(xpos, ypos)`
Creates a single slot, with a one-item `list[]` and a trash can icon
overlay.
`ui.make_inv_img_grid(xpos, ypos, width, height, bright)`
Generates a `width` by `height` grid of slot images, using the
single_slot function above, starting at (`xpos`,`ypos`) for the
top-left. Position is as in any `image[]` element, and dimensions
are in integer numbers of slots (so 8,4 would be a standard inventory).
`bright` is as above.
All three return a string that can be directly inserted into a formspec.
2021-03-08 18:14:31 +01:00
|
|
|
|
Multiple related changes to string handling
1) Convert most formspec elements to use string.format(), when the
result would be more readable, or less messy, or at least makes the line
shorter, assuming it looked like it really needed it to begin with.
2) Convert all long `foo..","..bar..";"..baz..bleh..` types of excessive
string concatenation into tables that then get concated only once, when
their containing functions return the final formspec string.
3) In some places in the code, such tables were already being used, and
were named "formspec", while others were named "fs". I settled on just
one name, "formspec", as it's more readable, if longer.
4) There was a mix of styles of adding items to those tables:
* Some places used line after line of `t[#t + 1] = foo/bar/baz`.
* Others places used the form `t[1] = foo, t[2] = bar, ...`.
* Still others used the form `t[n] = foo, t[n+1] = bar...`,
with `n` being increased or reset every so often.
Most of them should now be of the third form, with a few of the second.
2021-03-07 16:37:20 +01:00
|
|
|
local formspec = {
|
2023-01-10 01:41:36 +01:00
|
|
|
perplayer_formspec.standard_inv_bg,
|
|
|
|
ui.make_inv_img_grid(std_inv_x, bag_inv_y, 8, slots/8),
|
|
|
|
"label[", header_x, ",", header_y, ";", F(S("Bag @1", bag_i)), "]",
|
2019-03-31 11:26:02 +02:00
|
|
|
"listcolors[#00000000;#00000000]",
|
Improve consistency of inventory (and alike) imagery
In a number of places, background[] is misused to place the
inventory backdrop images. Where appropriate, image[] is used
instead, so that "ui_form_bg.png" actually serves as the one
and only true background image.
In so doing, I was able to remake the bag inventory images,
making them only big as is actually needed to hold 1, 2, or 3
rows of inventory slots.
This, in turn, allows a standardized main inventory image to
occupy the lower part of the window, which allows for
consistent inventory image positioning and sizing from one
page to another.
I also removed ui_misc_form.png. Nothing in UI uses it, and
any external mods that used it can just use the standard
inventory and its background.
Lastly, I reduced the background image to 512x384 px. It was
unnecessarily large before, considering it has no real detail.
The larger inventory images are all 512px wide, and multiples
of 64px in height. Before, they were oddly sized.
2021-02-24 13:00:29 +01:00
|
|
|
"listring[current_player;main]",
|
Use 9-slicing to build inventory-type backgrounds
This way the slots are all nice and crisp regardless of GUI scale or
image size, and we only need the single slot and its bright version.
This also makes the standard crafting grid into a style table entry that
can be referenced to insert the crafting grid at its proper
style-specific position in any formspec.
And it also makes the craft grid arrow, its X position, and the crafting
grid's result slot X position into style table entries.
Includes a few public helper functions to do most of the work:
`ui.single_slot(xpos, ypos, bright)`
Does just what it sounds like: it returns a single slot image.
`xpos` and `ypos` are normal coordinates in slots, as you'd use in
`image[]` element. `bright` is a flag that switches to the brighter
version of the slot image.
`ui.make_trash_slot(xpos, ypos)`
Creates a single slot, with a one-item `list[]` and a trash can icon
overlay.
`ui.make_inv_img_grid(xpos, ypos, width, height, bright)`
Generates a `width` by `height` grid of slot images, using the
single_slot function above, starting at (`xpos`,`ypos`) for the
top-left. Position is as in any `image[]` element, and dimensions
are in integer numbers of slots (so 8,4 would be a standard inventory).
`bright` is as above.
All three return a string that can be directly inserted into a formspec.
2021-03-08 18:14:31 +01:00
|
|
|
string.format("list[current_player;bag%icontents;%f,%f;8,3;]",
|
2023-01-10 01:41:36 +01:00
|
|
|
bag_i, std_inv_x + ui.list_img_offset, bag_inv_y + ui.list_img_offset),
|
|
|
|
"listring[current_name;bag", bag_i, "contents]",
|
2019-03-31 11:26:02 +02:00
|
|
|
}
|
2023-01-10 01:41:36 +01:00
|
|
|
|
|
|
|
if lite_mode then
|
|
|
|
return { formspec = table.concat(formspec) }
|
|
|
|
end
|
|
|
|
|
Use 9-slicing to build inventory-type backgrounds
This way the slots are all nice and crisp regardless of GUI scale or
image size, and we only need the single slot and its bright version.
This also makes the standard crafting grid into a style table entry that
can be referenced to insert the crafting grid at its proper
style-specific position in any formspec.
And it also makes the craft grid arrow, its X position, and the crafting
grid's result slot X position into style table entries.
Includes a few public helper functions to do most of the work:
`ui.single_slot(xpos, ypos, bright)`
Does just what it sounds like: it returns a single slot image.
`xpos` and `ypos` are normal coordinates in slots, as you'd use in
`image[]` element. `bright` is a flag that switches to the brighter
version of the slot image.
`ui.make_trash_slot(xpos, ypos)`
Creates a single slot, with a one-item `list[]` and a trash can icon
overlay.
`ui.make_inv_img_grid(xpos, ypos, width, height, bright)`
Generates a `width` by `height` grid of slot images, using the
single_slot function above, starting at (`xpos`,`ypos`) for the
top-left. Position is as in any `image[]` element, and dimensions
are in integer numbers of slots (so 8,4 would be a standard inventory).
`bright` is as above.
All three return a string that can be directly inserted into a formspec.
2021-03-08 18:14:31 +01:00
|
|
|
local n = #formspec + 1
|
2023-01-10 01:41:36 +01:00
|
|
|
formspec[n] = "image[" .. std_inv_x + 8.9 .. ",0.4;1,1;" .. image .. "]"
|
|
|
|
n = n + 1
|
2021-03-05 16:58:18 +01:00
|
|
|
|
2017-03-01 23:28:40 +01:00
|
|
|
local player_name = player:get_player_name() -- For if statement.
|
2021-03-07 14:18:17 +01:00
|
|
|
if ui.trash_enabled
|
Use 9-slicing to build inventory-type backgrounds
This way the slots are all nice and crisp regardless of GUI scale or
image size, and we only need the single slot and its bright version.
This also makes the standard crafting grid into a style table entry that
can be referenced to insert the crafting grid at its proper
style-specific position in any formspec.
And it also makes the craft grid arrow, its X position, and the crafting
grid's result slot X position into style table entries.
Includes a few public helper functions to do most of the work:
`ui.single_slot(xpos, ypos, bright)`
Does just what it sounds like: it returns a single slot image.
`xpos` and `ypos` are normal coordinates in slots, as you'd use in
`image[]` element. `bright` is a flag that switches to the brighter
version of the slot image.
`ui.make_trash_slot(xpos, ypos)`
Creates a single slot, with a one-item `list[]` and a trash can icon
overlay.
`ui.make_inv_img_grid(xpos, ypos, width, height, bright)`
Generates a `width` by `height` grid of slot images, using the
single_slot function above, starting at (`xpos`,`ypos`) for the
top-left. Position is as in any `image[]` element, and dimensions
are in integer numbers of slots (so 8,4 would be a standard inventory).
`bright` is as above.
All three return a string that can be directly inserted into a formspec.
2021-03-08 18:14:31 +01:00
|
|
|
or ui.is_creative(player_name)
|
|
|
|
or minetest.get_player_privs(player_name).give then
|
|
|
|
formspec[n] = ui.make_trash_slot(7.8, 0.25)
|
|
|
|
n = n + 1
|
2017-03-01 23:28:40 +01:00
|
|
|
end
|
2017-03-22 15:44:18 +01:00
|
|
|
local inv = player:get_inventory()
|
|
|
|
for i = 1, 4 do
|
2018-06-21 21:23:21 +02:00
|
|
|
local def = get_player_bag_stack(player, i):get_definition()
|
2017-03-22 15:44:18 +01:00
|
|
|
if def.groups.bagslots then
|
2019-03-31 11:26:02 +02:00
|
|
|
local list_name = "bag" .. i .. "contents"
|
2017-03-22 15:44:18 +01:00
|
|
|
local size = inv:get_size(list_name)
|
|
|
|
local used = 0
|
|
|
|
for si = 1, size do
|
|
|
|
local stk = inv:get_stack(list_name, si)
|
|
|
|
if not stk:is_empty() then
|
|
|
|
used = used + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
local img = def.inventory_image
|
2019-03-31 11:26:02 +02:00
|
|
|
local label = F(S("Bag @1", i)) .. "\n" .. used .. "/" .. size
|
Multiple related changes to string handling
1) Convert most formspec elements to use string.format(), when the
result would be more readable, or less messy, or at least makes the line
shorter, assuming it looked like it really needed it to begin with.
2) Convert all long `foo..","..bar..";"..baz..bleh..` types of excessive
string concatenation into tables that then get concated only once, when
their containing functions return the final formspec string.
3) In some places in the code, such tables were already being used, and
were named "formspec", while others were named "fs". I settled on just
one name, "formspec", as it's more readable, if longer.
4) There was a mix of styles of adding items to those tables:
* Some places used line after line of `t[#t + 1] = foo/bar/baz`.
* Others places used the form `t[1] = foo, t[2] = bar, ...`.
* Still others used the form `t[n] = foo, t[n+1] = bar...`,
with `n` being increased or reset every so often.
Most of them should now be of the third form, with a few of the second.
2021-03-07 16:37:20 +01:00
|
|
|
formspec[n] = string.format("image_button[%f,0.4;1,1;%s;bag%i;%s]",
|
2021-03-05 16:58:18 +01:00
|
|
|
(i + 1.35)*1.25, img, i, label)
|
Multiple related changes to string handling
1) Convert most formspec elements to use string.format(), when the
result would be more readable, or less messy, or at least makes the line
shorter, assuming it looked like it really needed it to begin with.
2) Convert all long `foo..","..bar..";"..baz..bleh..` types of excessive
string concatenation into tables that then get concated only once, when
their containing functions return the final formspec string.
3) In some places in the code, such tables were already being used, and
were named "formspec", while others were named "fs". I settled on just
one name, "formspec", as it's more readable, if longer.
4) There was a mix of styles of adding items to those tables:
* Some places used line after line of `t[#t + 1] = foo/bar/baz`.
* Others places used the form `t[1] = foo, t[2] = bar, ...`.
* Still others used the form `t[n] = foo, t[n+1] = bar...`,
with `n` being increased or reset every so often.
Most of them should now be of the third form, with a few of the second.
2021-03-07 16:37:20 +01:00
|
|
|
n = n + 1
|
2017-03-22 15:44:18 +01:00
|
|
|
end
|
|
|
|
end
|
Multiple related changes to string handling
1) Convert most formspec elements to use string.format(), when the
result would be more readable, or less messy, or at least makes the line
shorter, assuming it looked like it really needed it to begin with.
2) Convert all long `foo..","..bar..";"..baz..bleh..` types of excessive
string concatenation into tables that then get concated only once, when
their containing functions return the final formspec string.
3) In some places in the code, such tables were already being used, and
were named "formspec", while others were named "fs". I settled on just
one name, "formspec", as it's more readable, if longer.
4) There was a mix of styles of adding items to those tables:
* Some places used line after line of `t[#t + 1] = foo/bar/baz`.
* Others places used the form `t[1] = foo, t[2] = bar, ...`.
* Still others used the form `t[n] = foo, t[n+1] = bar...`,
with `n` being increased or reset every so often.
Most of them should now be of the third form, with a few of the second.
2021-03-07 16:37:20 +01:00
|
|
|
return { formspec = table.concat(formspec) }
|
2013-09-29 00:15:37 +02:00
|
|
|
end,
|
|
|
|
})
|
2016-10-08 11:07:41 +02:00
|
|
|
end
|
2013-09-29 00:15:37 +02:00
|
|
|
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
2013-12-04 16:43:49 +01:00
|
|
|
if formname ~= "" then
|
|
|
|
return
|
|
|
|
end
|
2013-09-29 00:15:37 +02:00
|
|
|
for i = 1, 4 do
|
2019-03-31 11:26:02 +02:00
|
|
|
if fields["bag" .. i] then
|
2018-06-21 21:23:21 +02:00
|
|
|
local stack = get_player_bag_stack(player, i)
|
2013-09-29 00:15:37 +02:00
|
|
|
if not stack:get_definition().groups.bagslots then
|
|
|
|
return
|
|
|
|
end
|
2021-03-07 14:18:17 +01:00
|
|
|
ui.set_inventory_formspec(player, "bag" .. i)
|
2013-09-29 00:15:37 +02:00
|
|
|
return
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
2022-09-15 12:53:41 +02:00
|
|
|
-- Player slots are preserved when unified_inventory is disabled. Do not allow modification.
|
|
|
|
-- Fix: use a detached inventory and store the data separately.
|
2018-06-21 21:23:21 +02:00
|
|
|
local function save_bags_metadata(player, bags_inv)
|
|
|
|
local is_empty = true
|
|
|
|
local bags = {}
|
|
|
|
for i = 1, 4 do
|
2019-03-31 11:26:02 +02:00
|
|
|
local bag = "bag" .. i
|
2018-06-21 21:23:21 +02:00
|
|
|
if not bags_inv:is_empty(bag) then
|
|
|
|
-- Stack limit is 1, otherwise use stack:to_string()
|
|
|
|
bags[i] = bags_inv:get_stack(bag, 1):get_name()
|
|
|
|
is_empty = false
|
|
|
|
end
|
|
|
|
end
|
2019-06-16 10:26:40 +02:00
|
|
|
local meta = player:get_meta()
|
2018-06-21 21:23:21 +02:00
|
|
|
if is_empty then
|
2024-06-29 16:52:32 +02:00
|
|
|
meta:set_string("unified_inventory:bags", "")
|
2018-06-21 21:23:21 +02:00
|
|
|
else
|
2019-06-16 10:26:40 +02:00
|
|
|
meta:set_string("unified_inventory:bags",
|
2018-06-21 21:23:21 +02:00
|
|
|
minetest.serialize(bags))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
local function load_bags_metadata(player, bags_inv)
|
|
|
|
local player_inv = player:get_inventory()
|
2019-06-16 10:26:40 +02:00
|
|
|
local meta = player:get_meta()
|
2021-03-09 11:12:50 +01:00
|
|
|
local bags_meta = meta:get("unified_inventory:bags")
|
2018-06-21 21:23:21 +02:00
|
|
|
local bags = bags_meta and minetest.deserialize(bags_meta) or {}
|
|
|
|
local dirty_meta = false
|
|
|
|
if not bags_meta then
|
|
|
|
-- Backwards compatiblity
|
|
|
|
for i = 1, 4 do
|
2019-03-31 11:26:02 +02:00
|
|
|
local bag = "bag" .. i
|
2018-06-21 21:23:21 +02:00
|
|
|
if not player_inv:is_empty(bag) then
|
|
|
|
-- Stack limit is 1, otherwise use stack:to_string()
|
|
|
|
bags[i] = player_inv:get_stack(bag, 1):get_name()
|
|
|
|
dirty_meta = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
-- Fill detached slots
|
|
|
|
for i = 1, 4 do
|
2019-03-31 11:26:02 +02:00
|
|
|
local bag = "bag" .. i
|
2018-06-21 21:23:21 +02:00
|
|
|
bags_inv:set_size(bag, 1)
|
|
|
|
bags_inv:set_stack(bag, 1, bags[i] or "")
|
|
|
|
end
|
|
|
|
|
|
|
|
if dirty_meta then
|
|
|
|
-- Requires detached inventory to be set up
|
|
|
|
save_bags_metadata(player, bags_inv)
|
|
|
|
end
|
|
|
|
|
2022-09-15 12:53:41 +02:00
|
|
|
-- Legacy: Clean up old player lists
|
2018-06-21 21:23:21 +02:00
|
|
|
for i = 1, 4 do
|
2019-03-31 11:26:02 +02:00
|
|
|
local bag = "bag" .. i
|
2018-06-21 21:23:21 +02:00
|
|
|
player_inv:set_size(bag, 0)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-12-02 10:08:32 +01:00
|
|
|
minetest.register_on_joinplayer(function(player)
|
2016-11-26 19:32:21 +01:00
|
|
|
local player_name = player:get_player_name()
|
2022-09-15 12:53:41 +02:00
|
|
|
local bags_inv = minetest.create_detached_inventory(player_name .. "_bags", {
|
2012-12-02 10:08:32 +01:00
|
|
|
allow_put = function(inv, listname, index, stack, player)
|
2016-02-29 06:34:13 +01:00
|
|
|
local new_slots = stack:get_definition().groups.bagslots
|
2018-06-21 21:23:21 +02:00
|
|
|
if not new_slots then
|
2022-09-15 12:53:41 +02:00
|
|
|
return 0 -- ItemStack is not a bag.
|
2018-06-21 21:23:21 +02:00
|
|
|
end
|
2016-02-29 06:34:13 +01:00
|
|
|
|
2022-09-15 12:53:41 +02:00
|
|
|
-- The execution order of `allow_put`/`allow_take` is not defined.
|
|
|
|
-- We do not know the replacement ItemStack if the items are swapped.
|
|
|
|
-- Hence, bag slot upgrades and downgrades are not possible with the
|
|
|
|
-- current API.
|
2018-06-21 21:23:21 +02:00
|
|
|
|
2022-09-15 12:53:41 +02:00
|
|
|
if not player:get_inventory():is_empty(listname .. "contents") then
|
|
|
|
-- Legacy: in case `allow_take` is not executed on old Minetest versions.
|
|
|
|
return 0
|
2018-06-21 21:23:21 +02:00
|
|
|
end
|
2022-09-15 12:53:41 +02:00
|
|
|
return 1
|
|
|
|
end,
|
|
|
|
on_put = function(inv, listname, index, stack, player)
|
|
|
|
player:get_inventory():set_size(listname .. "contents",
|
|
|
|
stack:get_definition().groups.bagslots)
|
|
|
|
save_bags_metadata(player, inv)
|
2012-12-02 10:08:32 +01:00
|
|
|
end,
|
|
|
|
allow_take = function(inv, listname, index, stack, player)
|
2019-03-31 11:26:02 +02:00
|
|
|
if player:get_inventory():is_empty(listname .. "contents") then
|
2012-12-02 10:08:32 +01:00
|
|
|
return stack:get_count()
|
|
|
|
end
|
2018-06-21 21:23:21 +02:00
|
|
|
return 0
|
2012-12-02 10:08:32 +01:00
|
|
|
end,
|
2018-06-21 21:23:21 +02:00
|
|
|
on_take = function(inv, listname, index, stack, player)
|
2019-03-31 11:26:02 +02:00
|
|
|
player:get_inventory():set_size(listname .. "contents", 0)
|
2018-06-21 21:23:21 +02:00
|
|
|
save_bags_metadata(player, inv)
|
2023-06-18 18:48:15 +02:00
|
|
|
if listname == ui.current_page[player:get_player_name()] then
|
|
|
|
-- Bag is currently open: avoid follow-up issues by navigating back
|
|
|
|
-- Trick: the list name is the same as the registered page name
|
|
|
|
ui.set_inventory_formspec(player, "bags")
|
|
|
|
end
|
2018-06-21 21:23:21 +02:00
|
|
|
end,
|
|
|
|
allow_move = function()
|
2012-12-02 10:08:32 +01:00
|
|
|
return 0
|
|
|
|
end,
|
2016-11-26 19:32:21 +01:00
|
|
|
}, player_name)
|
2018-06-21 21:23:21 +02:00
|
|
|
|
|
|
|
load_bags_metadata(player, bags_inv)
|
2012-12-02 10:08:32 +01:00
|
|
|
end)
|
|
|
|
|
2022-09-15 12:53:41 +02:00
|
|
|
|
|
|
|
minetest.register_allow_player_inventory_action(function(player, action, inventory, info)
|
|
|
|
-- From detached inventory -> player inventory: put & take callbacks
|
|
|
|
if action ~= "put" or not info.listname:find("bag%dcontents") then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if info.stack:get_definition().groups.bagslots then
|
|
|
|
-- Problem 1: empty bags could be moved into their own slots
|
|
|
|
-- Problem 2: cannot reliably keep track of ItemStack ownership due to
|
|
|
|
--> Disallow all external bag movements into this list
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
|
2012-12-02 10:08:32 +01:00
|
|
|
-- register bag tools
|
|
|
|
minetest.register_tool("unified_inventory:bag_small", {
|
2014-06-21 12:44:31 +02:00
|
|
|
description = S("Small Bag"),
|
2012-12-02 10:08:32 +01:00
|
|
|
inventory_image = "bags_small.png",
|
|
|
|
groups = {bagslots=8},
|
|
|
|
})
|
2013-09-21 21:40:20 +02:00
|
|
|
|
2012-12-02 10:08:32 +01:00
|
|
|
minetest.register_tool("unified_inventory:bag_medium", {
|
2014-06-21 12:44:31 +02:00
|
|
|
description = S("Medium Bag"),
|
2012-12-02 10:08:32 +01:00
|
|
|
inventory_image = "bags_medium.png",
|
|
|
|
groups = {bagslots=16},
|
|
|
|
})
|
2013-09-21 21:40:20 +02:00
|
|
|
|
2012-12-02 10:08:32 +01:00
|
|
|
minetest.register_tool("unified_inventory:bag_large", {
|
2014-06-21 12:44:31 +02:00
|
|
|
description = S("Large Bag"),
|
2012-12-02 10:08:32 +01:00
|
|
|
inventory_image = "bags_large.png",
|
|
|
|
groups = {bagslots=24},
|
|
|
|
})
|
|
|
|
|
|
|
|
-- register bag crafts
|
2016-08-06 17:44:37 +02:00
|
|
|
if minetest.get_modpath("farming") ~= nil then
|
|
|
|
minetest.register_craft({
|
|
|
|
output = "unified_inventory:bag_small",
|
|
|
|
recipe = {
|
2020-03-21 18:57:53 +01:00
|
|
|
{"", "farming:string", ""},
|
2016-08-06 17:44:37 +02:00
|
|
|
{"group:wool", "group:wool", "group:wool"},
|
|
|
|
{"group:wool", "group:wool", "group:wool"},
|
|
|
|
},
|
|
|
|
})
|
2013-09-21 21:40:20 +02:00
|
|
|
|
2016-08-06 17:44:37 +02:00
|
|
|
minetest.register_craft({
|
|
|
|
output = "unified_inventory:bag_medium",
|
|
|
|
recipe = {
|
|
|
|
{"", "", ""},
|
2020-03-21 18:57:53 +01:00
|
|
|
{"farming:string", "unified_inventory:bag_small", "farming:string"},
|
|
|
|
{"farming:string", "unified_inventory:bag_small", "farming:string"},
|
2016-08-06 17:44:37 +02:00
|
|
|
},
|
|
|
|
})
|
2013-09-21 21:40:20 +02:00
|
|
|
|
2016-08-06 17:44:37 +02:00
|
|
|
minetest.register_craft({
|
|
|
|
output = "unified_inventory:bag_large",
|
|
|
|
recipe = {
|
|
|
|
{"", "", ""},
|
2020-03-21 18:57:53 +01:00
|
|
|
{"farming:string", "unified_inventory:bag_medium", "farming:string"},
|
|
|
|
{"farming:string", "unified_inventory:bag_medium", "farming:string"},
|
2016-08-06 17:44:37 +02:00
|
|
|
},
|
|
|
|
})
|
|
|
|
end
|