basik implementation
adds 4 tiers of bags, opening and storing. Content retantion on craft.
This commit is contained in:
parent
a219e6cd60
commit
15d8e0c6c8
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"diagnostics.globals": ["minetest"]
|
||||||
|
}
|
20
README.md
20
README.md
|
@ -1,3 +1,19 @@
|
||||||
# cm_bags
|
# Bags for VoxeLibre
|
||||||
|
To many items? Put them in a bag!
|
||||||
|
|
||||||
Mode for VoxeLibre game that ads bag - item with chest-like inventory.
|
This mode ads bags - items with chest-like inventory.
|
||||||
|
Right click with it in hand to open its contents.
|
||||||
|
|
||||||
|
Roadmap:
|
||||||
|
[x] Retains content on closure
|
||||||
|
[x] Retains content on craft (upgrade)
|
||||||
|
[ ] Unload content on sneak right click on chest
|
||||||
|
[ ] Implement upgrade system
|
||||||
|
[ ] Upgrade to retain bag on death
|
||||||
|
[ ] Upgrade to expand bag inventory width
|
||||||
|
[ ] Upgrade to expand bag inventory hight
|
||||||
|
[ ] Upgrade for auto-pickup items
|
||||||
|
[ ] Make own textures
|
||||||
|
|
||||||
|
Inspired by Iron Backpacks (https://github.com/gr8pefish/IronBackpacks)
|
||||||
|
Art is used from there under GNU General Public License v3.0
|
||||||
|
|
|
@ -0,0 +1,242 @@
|
||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
|
local function getBagSize(stack)
|
||||||
|
if not stack:get_definition().groups.bag_size then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
|
||||||
|
return stack:get_definition().groups.bag_size
|
||||||
|
end
|
||||||
|
|
||||||
|
local function openBag(
|
||||||
|
player,
|
||||||
|
player_name,
|
||||||
|
bag_stack,
|
||||||
|
context --[[opened equipped or inhand]]
|
||||||
|
)
|
||||||
|
--minetest.chat_send_all("Enter")
|
||||||
|
local inv_name = player_name .. "_bag_tmp"
|
||||||
|
--Chaeck if something is broken. To prevent item voiding
|
||||||
|
local inv = minetest.get_inventory({ type = "detached", name = inv_name })
|
||||||
|
if inv ~= nil then
|
||||||
|
minetest.chat_send_all("Bag is already open!")
|
||||||
|
return false, "Bag is already open!"
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.create_detached_inventory(player_name .. "_bag_tmp", {
|
||||||
|
--Forbids puting bags into bags
|
||||||
|
allow_put = function(inv, listname, index, stack, player)
|
||||||
|
if minetest.get_item_group(stack:get_name(), "bag_size") > 0 then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return stack:get_stack_max()
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
}, player_name)
|
||||||
|
inv = minetest.get_inventory({ type = "detached", name = inv_name })
|
||||||
|
inv:set_size("main", getBagSize(bag_stack) * 9)
|
||||||
|
|
||||||
|
local meta = bag_stack:get_meta()
|
||||||
|
--minetest.chat_send_all(dump(meta:to_table()))
|
||||||
|
local content = meta:get_string("bag:content")
|
||||||
|
local list = content and minetest.deserialize(content) or {}
|
||||||
|
|
||||||
|
for i, stack in ipairs(list) do
|
||||||
|
inv:set_stack("main", i, stack)
|
||||||
|
--[[if stack ~= nil then
|
||||||
|
minetest.chat_send_all(dump(stack:to_string()))
|
||||||
|
end]]
|
||||||
|
end
|
||||||
|
|
||||||
|
local form = "size[9,"
|
||||||
|
.. (getBagSize(bag_stack) + 6)
|
||||||
|
.. "]"
|
||||||
|
.. mcl_formspec.get_itemslot_bg(0, 0, 9, getBagSize(bag_stack))
|
||||||
|
.. "list[detached:"
|
||||||
|
.. inv_name
|
||||||
|
.. ";main;0,0;9,"
|
||||||
|
.. getBagSize(bag_stack)
|
||||||
|
.. ";]"
|
||||||
|
.. mcl_formspec.get_itemslot_bg(0, getBagSize(bag_stack) + 1.5, 9, 3)
|
||||||
|
.. "list[current_player;main;0,"
|
||||||
|
.. (getBagSize(bag_stack) + 1.5)
|
||||||
|
.. ";9,3;9]"
|
||||||
|
.. mcl_formspec.get_itemslot_bg(0, getBagSize(bag_stack) + 5, 9, 1)
|
||||||
|
.. "list[current_player;main;0,"
|
||||||
|
.. (getBagSize(bag_stack) + 5)
|
||||||
|
.. ";9,1;]"
|
||||||
|
.. "listring[current_player;main]"
|
||||||
|
.. "listring[detached:"
|
||||||
|
.. inv_name
|
||||||
|
.. ";main]"
|
||||||
|
.. "listring[current_player;main]"
|
||||||
|
minetest.show_formspec(player_name, "bag:" .. context, form)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
--[[ Support for special "bag" slot at player gear.
|
||||||
|
if formname == "bag:equipped" and fields.quit then
|
||||||
|
--minetest.chat_send_all("Exit")
|
||||||
|
local player_inv = player:get_inventory()
|
||||||
|
local bag_stack = player_inv:get_stack("bag", 1)
|
||||||
|
|
||||||
|
local inv_name = player:get_player_name() .. "_bag_tmp"
|
||||||
|
local inv = minetest.get_inventory({ type = "detached", name = inv_name })
|
||||||
|
local stacks = {}
|
||||||
|
for i = 0, inv:get_size("main"), 1 do
|
||||||
|
stacks[i] = inv:get_stack("main", i):to_string()
|
||||||
|
end
|
||||||
|
|
||||||
|
bag_stack:get_meta():set_string("bag:content", minetest.serialize(stacks))
|
||||||
|
player_inv:set_stack("backpack", 1, backapack_stack)
|
||||||
|
--minetest.chat_send_all(dump(meta:to_table()))
|
||||||
|
minetest.remove_detached_inventory(inv_name)
|
||||||
|
else]]
|
||||||
|
if formname == "bag:inhand" and fields.quit then
|
||||||
|
local bag_stack = player:get_wielded_item()
|
||||||
|
local inv_name = player:get_player_name() .. "_bag_tmp"
|
||||||
|
local inv = minetest.get_inventory({ type = "detached", name = inv_name })
|
||||||
|
|
||||||
|
local stacks = {}
|
||||||
|
for i = 0, inv:get_size("main"), 1 do
|
||||||
|
stacks[i] = inv:get_stack("main", i):to_string()
|
||||||
|
end
|
||||||
|
|
||||||
|
bag_stack:get_meta():set_string("bag:content", minetest.serialize(stacks))
|
||||||
|
player:set_wielded_item(bag_stack)
|
||||||
|
minetest.remove_detached_inventory(inv_name)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Forbid moving bag while it is open. To prevent item deletion on bag closure.
|
||||||
|
minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
|
||||||
|
if
|
||||||
|
action == "move"
|
||||||
|
and inventory_info.from_list == "main"
|
||||||
|
and inventory_info.from_index == player:get_wield_index()
|
||||||
|
then
|
||||||
|
local bag_inv = minetest.get_inventory({ type = "detached", name = player:get_player_name() .. "_bag_tmp" })
|
||||||
|
if bag_inv ~= nil then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if action == "take" and inventory_info.listname == "main" and inventory_info.index == player:get_wield_index() then
|
||||||
|
local bag_inv = minetest.get_inventory({ type = "detached", name = player:get_player_name() .. "_bag_tmp" })
|
||||||
|
if bag_inv ~= nil then
|
||||||
|
return 0
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
--[[
|
||||||
|
--A chat command for now. Wonna change to hot-key later.
|
||||||
|
minetest.register_chatcommand("bag", {
|
||||||
|
func = function(player_name)
|
||||||
|
local player = minetest.get_player_by_name(player_name)
|
||||||
|
local player_inv = player:get_inventory()
|
||||||
|
local backapack_stack = player_inv:get_stack("backpack", 1)
|
||||||
|
if backapack_stack:is_empty() then
|
||||||
|
return false, "No backpack equiped!"
|
||||||
|
end
|
||||||
|
|
||||||
|
openBackpack(player, player_name, backapack_stack, "equipped")
|
||||||
|
return true, ""
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
|
||||||
|
if action == "move" and inventory_info.to_list == "backpack" then
|
||||||
|
local itemstack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index)
|
||||||
|
if not (minetest.get_item_group(itemstack:get_name(), "backpack_size") > 0) then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return itemstack:get_stack_max()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
]]
|
||||||
|
|
||||||
|
local function on_bag_place(itemstack, user, pointed_thing)
|
||||||
|
openBag(user, user:get_player_name(), itemstack, "inhand")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
-- register backapack's
|
||||||
|
minetest.register_tool("cm_bags:leather", {
|
||||||
|
description = S("Leather bag"),
|
||||||
|
inventory_image = "bag_leather.png",
|
||||||
|
groups = { bag_size = 1 },
|
||||||
|
on_place = on_bag_place,
|
||||||
|
on_secondary_use = on_bag_place,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craftitem("cm_bags:iron", {
|
||||||
|
description = S("Iron bag"),
|
||||||
|
inventory_image = "bag_iron.png",
|
||||||
|
groups = { bag_size = 2 },
|
||||||
|
on_place = on_bag_place,
|
||||||
|
on_secondary_use = on_bag_place,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craftitem("cm_bags:gold", {
|
||||||
|
description = S("Gold bag"),
|
||||||
|
inventory_image = "bag_gold.png",
|
||||||
|
groups = { bag_size = 3 },
|
||||||
|
on_place = on_bag_place,
|
||||||
|
on_secondary_use = on_bag_place,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craftitem("cm_bags:diamond", {
|
||||||
|
description = S("Diamond bag"),
|
||||||
|
inventory_image = "bag_diamond.png",
|
||||||
|
groups = { bag_size = 4 },
|
||||||
|
on_place = on_bag_place,
|
||||||
|
on_secondary_use = on_bag_place,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- register bag crafts
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "cm_bags:leather",
|
||||||
|
recipe = {
|
||||||
|
{ "mcl_mobitems:leather", "mcl_mobitems:leather", "mcl_mobitems:leather" },
|
||||||
|
{ "mcl_mobitems:leather", "mcl_chests:chest", "mcl_mobitems:leather" },
|
||||||
|
{ "mcl_mobitems:leather", "mcl_mobitems:leather", "mcl_mobitems:leather" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "cm_bags:iron",
|
||||||
|
recipe = {
|
||||||
|
{ "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" },
|
||||||
|
{ "mcl_core:iron_ingot", "cm_bags:leather", "mcl_core:iron_ingot" },
|
||||||
|
{ "mcl_core:iron_ingot", "mcl_core:iron_ingot", "mcl_core:iron_ingot" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "cm_bags:gold",
|
||||||
|
recipe = {
|
||||||
|
{ "mcl_core:gold_ingot", "mcl_core:gold_ingot", "mcl_core:gold_ingot" },
|
||||||
|
{ "mcl_core:gold_ingot", "cm_bags:iron", "mcl_core:gold_ingot" },
|
||||||
|
{ "mcl_core:gold_ingot", "mcl_core:gold_ingot", "mcl_core:gold_ingot" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "cm_bags:diamond",
|
||||||
|
recipe = {
|
||||||
|
{ "mcl_core:diamond", "mcl_core:diamond", "mcl_core:diamond" },
|
||||||
|
{ "mcl_core:diamond", "cm_bags:gold", "mcl_core:diamond" },
|
||||||
|
{ "mcl_core:diamond", "mcl_core:diamond", "mcl_core:diamond" },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
--transfer content of backpack on craft
|
||||||
|
minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv)
|
||||||
|
if minetest.get_item_group(itemstack:get_name(), "bag_size") > 0 then
|
||||||
|
local content = old_craft_grid[5]:get_meta():get_string("bag:content")
|
||||||
|
itemstack:get_meta():set_string("bag:content", content)
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
end)
|
|
@ -0,0 +1,6 @@
|
||||||
|
# textdomain: mc_bags
|
||||||
|
|
||||||
|
Leather bag=Шкіряний наплічник
|
||||||
|
Iron bag=Залізний наплічник
|
||||||
|
Gold bag=Золотий наплічник
|
||||||
|
Diamond bag=Діамантовий наплічник
|
|
@ -0,0 +1,6 @@
|
||||||
|
# textdomain: mc_bags
|
||||||
|
|
||||||
|
Leather bag=
|
||||||
|
Iron bag=
|
||||||
|
Gold bag=
|
||||||
|
Diamond bag=
|
|
@ -0,0 +1,4 @@
|
||||||
|
name = cm_bags
|
||||||
|
author = Morik666
|
||||||
|
description = Mode to add bags
|
||||||
|
depends = mcl_core, mcl_formspec, mcl_mobitems, mcl_chests
|
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
Loading…
Reference in New Issue