forked from VoxeLibre/VoxeLibre
139 lines
4.3 KiB
Lua
139 lines
4.3 KiB
Lua
mcl_inventory = {}
|
|
|
|
dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/creative.lua")
|
|
dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/survival.lua")
|
|
|
|
--local mod_player = minetest.get_modpath("mcl_player")
|
|
--local mod_craftguide = minetest.get_modpath("mcl_craftguide")
|
|
|
|
---Returns a single itemstack in the given inventory to the main inventory, or drop it when there's no space left.
|
|
---@param itemstack mt.ItemStack
|
|
---@param dropper mt.ObjectRef
|
|
---@param pos mt.Vector
|
|
---@param inv mt.InvRef
|
|
local function return_item(itemstack, dropper, pos, inv)
|
|
if dropper:is_player() then
|
|
-- Return to main inventory
|
|
if inv:room_for_item("main", itemstack) then
|
|
inv:add_item("main", itemstack)
|
|
else
|
|
-- Drop item on the ground
|
|
local v = dropper:get_look_dir()
|
|
local p = vector.offset(pos, 0, 1.2, 0)
|
|
p.x = p.x + (math.random(1, 3) * 0.2)
|
|
p.z = p.z + (math.random(1, 3) * 0.2)
|
|
local obj = minetest.add_item(p, itemstack)
|
|
if obj then
|
|
v.x = v.x * 4
|
|
v.y = v.y * 4 + 2
|
|
v.z = v.z * 4
|
|
obj:set_velocity(v)
|
|
obj:get_luaentity()._insta_collect = false
|
|
end
|
|
end
|
|
else
|
|
-- Fallback for unexpected cases
|
|
minetest.add_item(pos, itemstack)
|
|
end
|
|
return itemstack
|
|
end
|
|
|
|
---Return items in the given inventory list (name) to the main inventory, or drop them if there is no space left.
|
|
---@param player mt.PlayerObjectRef
|
|
---@param name string
|
|
local function return_fields(player, name)
|
|
local inv = player:get_inventory()
|
|
|
|
local list = inv:get_list(name)
|
|
if not list then return end
|
|
for i, stack in ipairs(list) do
|
|
return_item(stack, player, player:get_pos(), inv)
|
|
stack:clear()
|
|
inv:set_stack(name, i, stack)
|
|
end
|
|
end
|
|
|
|
---@param player mt.PlayerObjectRef
|
|
---@param armor_change_only? boolean
|
|
local function set_inventory(player, armor_change_only)
|
|
if minetest.is_creative_enabled(player:get_player_name()) then
|
|
if armor_change_only then
|
|
-- Stay on survival inventory plage if only the armor has been changed
|
|
mcl_inventory.set_creative_formspec(player, 0, 0, nil, nil, "inv")
|
|
else
|
|
mcl_inventory.set_creative_formspec(player, 0, 1)
|
|
end
|
|
return
|
|
end
|
|
|
|
player:set_inventory_formspec(mcl_inventory.build_survival_formspec(player))
|
|
end
|
|
|
|
-- Drop items in craft grid and reset inventory on closing
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if fields.quit then
|
|
return_fields(player, "craft")
|
|
return_fields(player, "enchanting_lapis")
|
|
return_fields(player, "enchanting_item")
|
|
if not minetest.is_creative_enabled(player:get_player_name()) and (formname == "" or formname == "main") then
|
|
set_inventory(player)
|
|
end
|
|
end
|
|
end)
|
|
|
|
|
|
function mcl_inventory.update_inventory_formspec(player)
|
|
set_inventory(player)
|
|
end
|
|
|
|
-- Drop crafting grid items on leaving
|
|
minetest.register_on_leaveplayer(function(player)
|
|
return_fields(player, "craft")
|
|
return_fields(player, "enchanting_lapis")
|
|
return_fields(player, "enchanting_item")
|
|
end)
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
--init inventory
|
|
local inv = player:get_inventory()
|
|
|
|
inv:set_width("main", 9)
|
|
inv:set_size("main", 36)
|
|
inv:set_size("offhand", 1)
|
|
|
|
--set hotbar size
|
|
player:hud_set_hotbar_itemcount(9)
|
|
--add hotbar images
|
|
player:hud_set_hotbar_image("mcl_inventory_hotbar.png")
|
|
player:hud_set_hotbar_selected_image("mcl_inventory_hotbar_selected.png")
|
|
|
|
-- In Creative Mode, the initial inventory setup is handled in creative.lua
|
|
if not minetest.is_creative_enabled(player:get_player_name()) then
|
|
set_inventory(player)
|
|
end
|
|
|
|
--[[ Make sure the crafting grid is empty. Why? Because the player might have
|
|
items remaining in the crafting grid from the previous join; this is likely
|
|
when the server has been shutdown and the server didn't clean up the player
|
|
inventories. ]]
|
|
return_fields(player, "craft")
|
|
return_fields(player, "enchanting_item")
|
|
return_fields(player, "enchanting_lapis")
|
|
end)
|
|
|
|
---@param player mt.PlayerObjectRef
|
|
function mcl_inventory.update_inventory(player)
|
|
local player_gamemode = mcl_gamemode.get_gamemode(player)
|
|
if player_gamemode == "creative" then
|
|
mcl_inventory.set_creative_formspec(player)
|
|
elseif player_gamemode == "survival" then
|
|
player:set_inventory_formspec(mcl_inventory.build_survival_formspec(player))
|
|
end
|
|
end
|
|
|
|
mcl_gamemode.register_on_gamemode_change(function(player, old_gamemode, new_gamemode)
|
|
set_inventory(player)
|
|
end)
|
|
|
|
mcl_player.register_on_visual_change(mcl_inventory.update_inventory_formspec)
|