Skip to content

Commit

Permalink
Player Inventory: make bag as tab; remember opened, Closes lord-serve…
Browse files Browse the repository at this point in the history
  • Loading branch information
alek13 committed Sep 28, 2024
1 parent 7817126 commit 17dcaee
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 99 deletions.
4 changes: 2 additions & 2 deletions mods/lord/Player/lord_inventory/src/inventory.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@

local PlayerForm = require('inventory.Form')
require("inventory.Form.bags_form")


--- This collection of forms passed into `inventory.Form` & replaces standard `opened_for` var of `Personal` mixin.
--- @see inventory.Form:on_register()
---
--- @type inventory.Form[]|table<string,inventory.Form>
local player_forms = {}

Expand Down
36 changes: 26 additions & 10 deletions mods/lord/Player/lord_inventory/src/inventory/Form.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
local MainTab = require('inventory.Form.MainTab')
--local AboutTab = require('inventory.Form.BagsTab') TODO #1698
local BagsTab = require('inventory.Form.BagsTab')
--local AboutTab = require('inventory.Form.AboutTab') TODO #1701


Expand All @@ -8,17 +8,26 @@ local Form = base_classes.Form:personal():with_tabs():extended({
--- @const
--- @type string
NAME = "",

--- @type string
player_name = '',

--- @type table<string,number>
tab = { MAIN = 1, ABOUT = 2, },
tab = {
MAIN = 1,
BAGS = 2,
ABOUT = 3,
},
--- @type number
current_tab = 1,
--- Replaces by player forms collection in Form.on_register callback
--- @see inventory.Form:on_register() @ below.
---
--- @type inventory.Form[]|table<string,inventory.Form>
opened_for = {},
--- We need to not clear `self.opened_for[player_name]`
--- @see inventory.Form:on_register() @ below.
---
--- @type boolean
no_cleanup_on_close = true,
})

function Form:get_spec_head()
Expand All @@ -29,6 +38,7 @@ end
function Form:instantiate(player)
self
:add_tab(MainTab:new(self))
:add_tab(BagsTab:new(self))
--:add_tab(AboutTab:new(self))
:refresh()
end
Expand All @@ -43,29 +53,35 @@ function Form:set_main_preview(preview)
return self
end

--- @return inventory.Form
function Form:refresh()
minetest.get_player_by_name(self.player_name):set_inventory_formspec(self:get_spec())
end
minetest.get_player_by_name(self.player_name)
:set_inventory_formspec(self:get_spec())

--- @param fields table
function Form:handle(fields)
return self
end


--- @param self inventory.Form
--- @param player_forms_collection inventory.Form[]|table<string,inventory.Form>
Form.on_register(function(self, player_forms_collection)
-- To open some-kind our custom inventory for player, MT provides `player:set_inventory_formspec(spec)` function.
-- And then MT by itself catch pressed `i` button & opens form with that spec.
-- So, we never/nowhere calls `Form:open()`.
-- So, we doesn't calls `Form:open()` by own code to open inventory initially.
-- But! Mixin `WithTabs` creates an instance exactly in `Form:open()` and put it into `Form.opened_for[player_name]`
-- Then this var used to get the instance of the player to handle.
-- But the `Form:open()` is never/nowhere calls.
-- But the `Form:open()` is not calls.
-- So we need to creates this instances manually and somehow put into `Form.opened_for[player_name]`.
-- We already do it in `_G.inventory.for_player`. (see `inventory.lua`)
-- And here we just replace this `Form.opened_for` array with that `player_forms_collection`.
-- So `WithTabs` mixin works with the same collection as `_G.inventory.for_player`
Form.opened_for = player_forms_collection
end)

--- @param self inventory.Form
Form.on_open(function(self)
self:refresh()
end)


return Form
15 changes: 15 additions & 0 deletions mods/lord/Player/lord_inventory/src/inventory/Form/AboutTab.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
local S = minetest.get_translator('lord_inventory')


--- @class inventory.Form.AboutTab: base_classes.Form.Element.Tab
local AboutTab = base_classes.Form.Element.Tab:extended({
title = S('About'),
})


function AboutTab:get_spec()
return ''
end


return AboutTab
112 changes: 112 additions & 0 deletions mods/lord/Player/lord_inventory/src/inventory/Form/BagsTab.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
local S = minetest.get_translator("lord_inventory")


--- @class inventory.Form.BagsTab: base_classes.Form.Element.Tab
local BagsTab = {
--- @type string
title = S('Bags'),
--- @type inventory.Form parent form
form = nil,
--- @type number currently opened bag or 0 if bags selection is opened
current_bag = 0,
}
base_classes.Form.Element.Tab:extended(BagsTab)


function BagsTab:get_spec()
local player_name = self.form.player_name
local bag = self.current_bag

-- Form with bags selection
if bag == 0 then
return "list[current_player;main;0,3.5;8,4;]"
.. "button[0,2;2,0.5;bag1;" .. S("Bag") .. " 1]"
.. "button[2,2;2,0.5;bag2;" .. S("Bag") .. " 2]"
.. "button[4,2;2,0.5;bag3;" .. S("Bag") .. " 3]"
.. "button[6,2;2,0.5;bag4;" .. S("Bag") .. " 4]"
.. "list[detached:" .. player_name .. "_bags;bag1;0.5,1;1,1;]"
.. "list[detached:" .. player_name .. "_bags;bag2;2.5,1;1,1;]"
.. "list[detached:" .. player_name .. "_bags;bag3;4.5,1;1,1;]"
.. "list[detached:" .. player_name .. "_bags;bag4;6.5,1;1,1;]"
end

-- Form with bag contents
local player = minetest.get_player_by_name(player_name)
local image = player:get_inventory():get_stack("bag" .. bag, 1):get_definition().inventory_image

return "list[current_player;main;0,4.5;8,4;]"
.. "button[0,0;2,0.5;bags;" .. S("Bags") .. "]"
.. "image[7,-0.15;1,1;" .. image .. "]"
.. "list[current_player;bag" .. bag .. "contents;0,1;8,3;]"
.. "listring[current_player;bag" .. bag .. "contents]"
.. "listring[current_player;main]"
end

--- @param fields table
--- @return nil|boolean return `true` for stop propagation of handling
function BagsTab:handle(fields)
if fields.bags then
self.current_bag = 0
self.form:open()
return true
end

for i = 1, 4 do
local page = "bag" .. i
if fields[page] then
self.current_bag = i
local item_in_slot_definition = minetest.get_player_by_name(self.form.player_name)
:get_inventory():get_stack(page, 1):get_definition()
if item_in_slot_definition.groups.bagslots == nil then
self.current_bag = 0
end

self.form:open()

return true
end
end
end

--- @param joined_player Player
minetest.register_on_joinplayer(function(joined_player, last_login)
local player_name = joined_player:get_player_name()
local player_inv = joined_player:get_inventory()

local bags_inv = minetest.create_detached_inventory(player_name .. "_bags", {
on_put = function(inv, list_name, index, stack, player)
player:get_inventory():set_stack(list_name, index, stack)
player:get_inventory():set_size(list_name .. "contents", stack:get_definition().groups.bagslots)
end,
on_take = function(inv, list_name, index, stack, player)
player:get_inventory():set_stack(list_name, index, nil)
end,
allow_put = function(inv, list_name, index, stack, player)
if stack:get_definition().groups.bagslots then
return 1
else
return 0
end
end,
allow_take = function(inv, list_name, index, stack, player)
if player:get_inventory():is_empty(list_name .. "contents") == true then
return stack:get_count()
else
return 0
end
end,
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
return 0
end,
}, player_name)

for i = 1, 4 do
local bag = "bag" .. i
player_inv:set_size(bag, 1)
bags_inv:set_size(bag, 1)
bags_inv:set_stack(bag, 1, player_inv:get_stack(bag, 1))
end
end)


return BagsTab
Original file line number Diff line number Diff line change
Expand Up @@ -80,5 +80,14 @@ function MainTab:get_spec()
return formspec
end

--- @param fields table
--- @return nil|boolean return `true` for stop propagation of handling
function MainTab:handle(fields)
if fields.bags then
self.form:switch_tab(self.form.tab.BAGS)
return true
end
end


return MainTab
87 changes: 0 additions & 87 deletions mods/lord/Player/lord_inventory/src/inventory/Form/bags_form.lua

This file was deleted.

0 comments on commit 17dcaee

Please sign in to comment.