Initial commit

master
Duane Robertson 2019-07-22 06:25:33 -05:00
parent 627e50c4d9
commit b7185edbf7
20 changed files with 817 additions and 1 deletions

View File

@ -1,2 +1,14 @@
# dinv
Duane's minetest inventory
Duane's Minetest Inventory
This is a basic inventory mod with recipe list, bags, and armor. It lacks a lot of the features of similar mods. All worn items, including bags and armor, are combined into one secondary inventory. Equipped bags expand your main inventory, rather than opening up extra inventories.
The source is available on github.
Code: LGPL2
Textures: strictly CC0
Mod dependencies: default
Download: https://github.com/duane-r/dinv/archive/master.zip

802
init.lua Normal file
View File

@ -0,0 +1,802 @@
-- Dinv init.lua
-- Copyright Duane Robertson (duane@duanerobertson.com), 2019
-- Distributed under the LGPLv2.1 (https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html)
mapgen = {}
local mod = mapgen
local mod_name = 'dinv'
mod.version = '20190720'
mod.path = minetest.get_modpath(minetest.get_current_modname())
mod.world = minetest.get_worldpath()
mod.dat = {}
local worn_inv = 'worn'
local sorted_items
mod.form_size = 'size[11.25,7.75]'
mod.main_inventory = 'list[current_player;main;0,4;8,4;'
mod.craft_inventory = 'list[current_player;craft;3,0;3,3;]'
mod.craft_preview = 'list[current_player;craftpreview;6,1;1,1;]'
mod.main_inventory_scroll_up = 'image_button[8,4;1,1;transparent_button.png;dinv_main_inventory_up;Up]'
mod.main_inventory_scroll_down = 'image_button[8,7;1,1;transparent_button.png;dinv_main_inventory_down;Down]'
mod.recipe_buttons = 'image_button[3,3;1,1;transparent_button.png;dinv_recipe_back;Back]image_button[5,3;1,1;transparent_button.png;dinv_recipe_fore;Fore]'
mod.worn_items_inv = 'list[current_player;worn;9.25,4;2,4;]'
minetest.register_craftitem(mod_name..':bag_small', {
inventory_image = 'bags_small.png',
stack_max = 1,
})
minetest.register_craftitem(mod_name..':bag_medium', {
inventory_image = 'bags_medium.png',
stack_max = 1,
})
minetest.register_craftitem(mod_name..':bag_large', {
inventory_image = 'bags_large.png',
stack_max = 1,
})
minetest.register_tool(mod_name..':leather_armor', {
inventory_image = 'leather_armour1.png',
description = 'Leather Armor',
_dinv_armor = 0.9,
_dinv_location = 'body',
})
minetest.register_tool(mod_name..':boots', {
inventory_image = 'boots1_brown.png',
description = 'Sturdy Boots',
_dinv_armor = 0.9,
_dinv_location = 'feet',
})
minetest.register_tool(mod_name..':leather_cap', {
inventory_image = 'elven_leather_helm.png',
description = 'Leather Cap',
_dinv_armor = 0.9,
_dinv_location = 'head',
})
minetest.register_tool(mod_name..':steel_helmet', {
inventory_image = 'helmet1.png',
description = 'Steel Helmet',
_dinv_armor = 0.8,
_dinv_location = 'head',
})
minetest.register_tool(mod_name..':wood_shield', {
inventory_image = 'buckler1.png',
description = 'Wooden Shield',
_dinv_armor = 0.8,
_dinv_location = 'arm',
})
minetest.register_tool(mod_name..':steel_shield', {
inventory_image = 'lshield_dd_dk.png',
description = 'Steel Shield',
_dinv_armor = 0.7,
_dinv_location = 'arm',
})
minetest.register_tool(mod_name..':chain_armor', {
inventory_image = 'chain_mail1.png',
description = 'Chain Mail',
_dinv_armor = 0.75,
_dinv_location = 'body',
})
minetest.register_tool(mod_name..':plate_armor', {
inventory_image = 'plate1.png',
description = 'Plate Mail',
_dinv_armor = 0.6,
_dinv_location = 'body',
})
minetest.register_tool(mod_name..':diamond_plate_armor', {
inventory_image = 'crystal_plate2.png',
description = 'Diamond Plate Mail',
_dinv_armor = 0.45,
_dinv_location = 'body',
})
--print(dump(minetest.registered_tools[mod_name..':plate_armor']))
minetest.register_craft({
output = mod_name..':bag_small',
recipe = {
{'', 'farming:cotton', ''},
{'group:wool', 'group:wool', 'group:wool'},
{'group:wool', 'group:wool', 'group:wool'},
},
})
minetest.register_craft({
output = mod_name..':bag_medium',
recipe = {
{'', '', ''},
{'farming:string', mod_name..':bag_small', 'farming:string'},
{'', mod_name..':bag_small', ''},
},
})
minetest.register_craft({
output = mod_name..':bag_large',
recipe = {
{'', '', ''},
{'farming:string', mod_name..':bag_medium', 'farming:string'},
{'', mod_name..':bag_medium', ''},
},
})
minetest.register_craft({
output = mod_name..':leather_armor',
recipe = {
{'', 'mobs:leather', ''},
{'mobs:leather', 'farming:string', 'mobs:leather'},
{'mobs:leather', 'farming:string', 'mobs:leather'},
},
})
minetest.register_craft({
output = mod_name..':leather_cap',
recipe = {
{'', 'mobs:leather', ''},
{'', 'mobs:leather', ''},
{'', 'farming:string', ''},
},
})
minetest.register_craft({
output = mod_name..':steel_helmet',
recipe = {
{'', 'default:steel_ingot', ''},
{'default:steel_ingot', 'mobs:leather', 'default:steel_ingot'},
{'', 'mobs:fur', ''},
},
})
minetest.register_craft({
output = mod_name..':boots',
recipe = {
{'', '', ''},
{'', 'farming:string', ''},
{'mobs:leather', 'farming:string', 'mobs:leather'},
},
})
minetest.register_craft({
output = mod_name..':wood_shield',
recipe = {
{'', 'group:wood', ''},
{'group:wood', 'mobs:leather', 'group:wood'},
{'', 'group:wood', ''},
},
})
minetest.register_craft({
output = mod_name..':steel_shield',
recipe = {
{'', mod_name..':steel_plate', ''},
{ mod_name..':steel_plate', 'mobs:leather', mod_name..':steel_plate'},
{'', mod_name..':steel_plate', ''},
},
})
minetest.register_craftitem(mod_name..':steel_rings', {
inventory_image = 'dinv_steel_rings.png',
})
minetest.register_craftitem(mod_name..':steel_plate', {
inventory_image = 'dinv_steel_plate.png',
})
minetest.register_craftitem(mod_name..':diamond_plate', {
inventory_image = 'dinv_diamond_plate.png',
})
minetest.register_craft({
output = mod_name..':steel_rings',
recipe = {
{'', '', ''},
{'default:steel_ingot', 'default:coal_lump', 'default:steel_ingot'},
{'', 'default:steel_ingot', ''},
},
})
minetest.register_craft({
output = mod_name..':steel_plate',
recipe = {
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
{'default:steel_ingot', 'default:coal_lump', 'default:steel_ingot'},
{'default:steel_ingot', 'default:steel_ingot', 'default:steel_ingot'},
},
})
minetest.register_craft({
output = mod_name..':diamond_plate',
recipe = {
{'default:diamond', 'default:diamond', 'default:diamond'},
{'default:diamond', 'default:mese_crystal', 'default:diamond'},
{'default:diamond', 'default:diamond', 'default:diamond'},
},
})
minetest.register_craft({
output = mod_name..':chain_armor',
recipe = {
{'', mod_name..':steel_rings', ''},
{mod_name..':steel_rings', 'mobs:leather', mod_name..':steel_rings'},
{mod_name..':steel_rings', 'mobs:leather', mod_name..':steel_rings'},
},
})
minetest.register_craft({
output = mod_name..':plate_armor',
recipe = {
{'', mod_name..':steel_plate', ''},
{mod_name..':steel_plate', mod_name..':chain_armor', mod_name..':steel_plate'},
{mod_name..':steel_plate', 'default:steel_ingot', mod_name..':steel_plate'},
},
})
minetest.register_craft({
output = mod_name..':diamond_plate_armor',
recipe = {
{'', mod_name..':diamond_plate', ''},
{mod_name..':diamond_plate', mod_name..':chain_armor', mod_name..':diamond_plate'},
{mod_name..':diamond_plate', 'default:mese', mod_name..':diamond_plate'},
},
})
mod.bag_sizes = {
[mod_name..':bag_small'] = 8,
[mod_name..':bag_medium'] = 16,
[mod_name..':bag_large'] = 24,
[mod_name..':bag_huge'] = 32,
[mod_name..':bag_hole'] = 64,
}
mod.wearable = { }
do
for k, v in pairs(mod.bag_sizes) do
mod.wearable[k] = true
end
for k, v in pairs(minetest.registered_items) do
if v._dinv_armor then
mod.wearable[k] = true
end
end
end
local force_rep = {
['wood'] = 'default:wood',
['leaves'] = 'default:leaves',
['stone'] = 'default:stone',
['wool'] = 'wool:white',
}
-- This tables looks up groups that aren't already stored.
mod.group_rep = setmetatable({}, {
__index = function(t, k)
if not (t and k and type(k) == 'string' and type(t) == 'table') then
return
end
local k = k:gsub('^group:', '')
local r
if force_rep[k] then
r = force_rep[k]
else
for a, b in pairs(minetest.registered_items) do
if b.groups and b.groups[k] then
r = a
break
end
end
end
if r then
t[k] = r
return t[k]
else
return
end
end
})
local group_rep = mod.group_rep
-- iterator over worn inventory
function mod.worn_items(player)
if not player then
return
end
local pinv = player:get_inventory()
if not pinv then
return
end
local flist = pinv:get_list(worn_inv)
return pairs(flist)
end
local worn_items = mod.worn_items
function mod.make_inventory_spec(player)
if not player then
return
end
local player_name = player:get_player_name()
local dat = mod.dat[player_name]
local scroll_main_to = dat['scroll_main_to'] or 0
local inventory = ''
inventory = inventory .. mod.form_size
inventory = inventory .. mod.main_inventory .. scroll_main_to .. ']'
inventory = inventory .. mod.craft_inventory
inventory = inventory .. 'listring[]'
inventory = inventory .. mod.recipe_buttons
inventory = inventory .. mod.craft_preview
inventory = inventory .. mod.main_inventory_scroll_up
inventory = inventory .. mod.main_inventory_scroll_down
inventory = inventory .. mod.worn_items_inv
inventory = inventory .. mod.recipe_grid(player)
inventory = inventory .. mod.recipe_list(player)
return inventory
end
function mod.recipe_grid(player)
local player_name = player:get_player_name()
local dat = mod.dat[player_name]
local craft_item_number = dat['craft_item_number']
local recipe_number = dat['recipe_number'] or 1
if not craft_item_number then
return ''
end
local craft_item = sorted_items[craft_item_number]
if not craft_item then
return ''
end
local recipes = minetest.get_all_craft_recipes(craft_item)
if not recipes then
return ''
end
if recipe_number > #recipes then
recipe_number = 1
dat['recipe_number'] = recipe_number
end
local recipe = recipes[recipe_number]
--print(dump(recipe))
local inv = ''
inv = inv .. 'container[3,0]'
local w = recipe.width or 3
if w == 0 or w > 3 then
w = 3
end
local g_s = {}
local i = 0
for y = 0, 2 do
for x = 1, w do
i = i + 1
local item, group
if recipe.type == 'normal' then
item = recipe.items[(y * w) + x]
end
if item and item:find('^group') then
--print(item)
item = group_rep[item]
if item then
g_s[i] = true
end
end
if item then
inv = inv .. 'item_image[' .. (x - 1) .. ',' .. (y) .. ';1,1;' .. item .. ']'
end
end
end
inv = inv .. 'container_end[]'
inv = inv .. 'container[3,0]'
for i = 1, 9 do
if g_s[i] then
local x = (i - 1) % w
local y = math.floor((i - 1) / w)
inv = inv .. 'image[' .. (x - 0) .. ',' .. (y) .. ';1,1;big_g.png]'
end
end
inv = inv .. 'container_end[]'
return inv
end
function mod.recipe_list(player)
if not sorted_items then
sorted_items = {}
for k, v in pairs(minetest.registered_items) do
if k and k ~= '' and minetest.get_all_craft_recipes(k) then
local recs = minetest.get_all_craft_recipes(k)
for a, b in pairs(recs) do
if b.type ~= 'cooking' then
table.insert(sorted_items, k)
break
end
end
end
end
table.sort(sorted_items)
end
local inv = ''
inv = inv .. 'textlist[7,0;4,3.5;dinv_recipe_list;'
local t
for k, v in pairs(sorted_items) do
if t then
inv = inv .. ','
end
inv = inv .. v
--print(v)
t = true
end
inv = inv .. ';'
return inv
end
function mod.scroll_main(player, amount, max)
if not (player and amount) then
return
end
local player_name = player:get_player_name()
if not player_name then
return
end
local fs = player:get_inventory_formspec()
--print('.*' .. mod.main_inventory:gsub('%[', '%%[') .. '(%d+)%].*')
local scroll = fs:gsub('.*%' .. mod.main_inventory:gsub('%[', '%%[') .. '(%d+)%].*', '%1')
--print(scroll)
if scroll then
local scroll_n = tonumber(scroll)
if scroll_n and scroll_n % 8 == 0 then
scroll_n = (scroll_n + amount)
if scroll_n > max or scroll_n < 0 then
scroll_n = 0
end
mod.dat[player_name].scroll_main_to = scroll_n
player:set_inventory_formspec(mod.make_inventory_spec(player))
end
end
end
function mod.get_main_size_by_bags(player)
local isize = 32
for k, v in worn_items(player) do
local vs = v:get_name()
if mod.bag_sizes[vs] then
isize = isize + mod.bag_sizes[vs]
end
end
return isize
end
function mod.set_main_size_by_bags(player)
if not player then
return
end
local pinv = player:get_inventory()
if not pinv then
return
end
local prsize = pinv:get_size('main')
local isize = mod.get_main_size_by_bags(player)
--[[
if isize < prsize then
print('*** Preventing lost inventory from reducing bag sizes')
isize = prsize
end
--]]
if not pinv:set_size('main', isize) then
print('*** ERROR setting inventory size.')
end
return isize
end
minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
if not mod.dat[player_name] then
mod.dat[player_name] = {}
end
local pinv = player:get_inventory()
pinv:set_size(worn_inv, 8)
mod.set_main_size_by_bags(player)
mod.set_armor(player)
player:set_inventory_formspec(mod.make_inventory_spec(player))
end)
function mod.show_recipe(player, field)
if not (player and field) then
return
end
local player_name = player:get_player_name()
if not player_name then
return
end
if field:find('CHG') then
local n = field:gsub('.*CHG:(%d+).*', '%1')
if n then
mod.dat[player_name].craft_item_number = tonumber(n)
mod.dat[player_name].recipe_number = 1
player:set_inventory_formspec(mod.make_inventory_spec(player))
end
end
end
function mod.switch_recipe(player, amount)
if not (player and amount) then
return
end
local player_name = player:get_player_name()
if not player_name then
return
end
local dat = mod.dat[player_name]
if not dat.recipe_number then
dat.recipe_number = 1
end
dat.recipe_number = dat.recipe_number + amount
if dat.recipe_number < 1 then
dat.recipe_number = 1
end
--print(dat.recipe_number)
player:set_inventory_formspec(mod.make_inventory_spec(player))
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
local pinv = player:get_inventory()
local main_inventory_size = pinv:get_size('main')
if fields and fields['dinv_main_inventory_up'] then
mod.scroll_main(player, -16, main_inventory_size)
elseif fields and fields['dinv_main_inventory_down'] then
mod.scroll_main(player, 16, main_inventory_size)
elseif fields and fields['dinv_recipe_list'] then
mod.show_recipe(player, fields['dinv_recipe_list'])
elseif fields and fields['dinv_recipe_back'] then
mod.switch_recipe(player, -1)
elseif fields and fields['dinv_recipe_fore'] then
mod.switch_recipe(player, 1)
end
end)
minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
if not (player and action and inventory and inventory_info) then
return
end
if not (inventory_info.from_list == worn_inv or inventory_info.to_list == worn_inv or inventory_info.listname == worn_inv) then
return
end
local item_from, item_from_s
if action == 'move' and inventory_info.from_list then
item_from = inventory:get_stack(inventory_info.from_list, inventory_info.from_index)
else
item_from = inventory_info.stack
end
if item_from and item_from.get_name then
item_from_s = item_from:get_name()
end
local item_to, item_to_s
if action == 'move' and inventory_info.to_list then
item_to = inventory:get_stack(inventory_info.to_list, inventory_info.to_index)
end
if item_to and item_to.get_name then
item_to_s = item_to:get_name()
end
--print(dump(inventory_info.from_list), dump(inventory_info.to_list))
--print(dump(item_from_s), dump(item_to_s))
--print(action)
if action == 'move' then
if not mod.wearable[item_from_s] then
if inventory_info.to_list == worn_inv then
return 0
else
return
end
end
if item_to_s and item_to_s ~= '' then
return 0
end
if inventory_info.to_list == inventory_info.from_list then
return
end
local item_from_it = minetest.registered_items[item_from_s]
if item_from_it._dinv_location and inventory_info.to_list == worn_inv
and mod.wearing_on_location(player, item_from_it._dinv_location) then
return 0
end
if mod.bag_sizes[item_from_s] then
local prsize = mod.get_main_size_by_bags(player)
local isize = prsize
if inventory_info.to_list == worn_inv then
isize = isize + mod.bag_sizes[item_from_s]
elseif inventory_info.from_list == worn_inv then
isize = isize - mod.bag_sizes[item_from_s]
end
if isize < prsize and mod.items_at_range(inventory, 'main', isize, prsize) then
return 0
elseif inventory_info.to_index > isize then
return 0
end
end
elseif action == 'take' and mod.wearable[item_from_s] then
return 0
elseif action == 'put' then
return 0
end
end)
function mod.wearing_on_location(player, loc)
for k, v in worn_items(player) do
local vs = v:get_name()
local it = minetest.registered_items[vs]
if it._dinv_location == loc then
return true
end
end
end
function mod.set_armor(player)
if not player then
return
end
local armor = 100
for k, v in worn_items(player) do
local vs = v:get_name()
local it = minetest.registered_items[vs]
--print(dump(it))
if it._dinv_armor then
armor = armor * it._dinv_armor
end
end
print('armor = ', armor)
local armor_g = player:get_armor_groups()
if not (armor_g and armor_g.fleshy) then
return
end
armor_g.fleshy = armor
--print(dump(armor_g))
player:set_armor_groups(armor_g)
end
function mod.damage_armor(player, damage)
local wear = (damage + 1) * 100
for k, v in worn_items(player) do
local vs = v:get_name()
local it = minetest.registered_items[vs]
if it._dinv_armor then
local ow = v:get_wear()
v:add_wear(wear)
player:get_inventory():set_stack(worn_inv, k, v)
if ow + wear > 65535 then
mod.set_armor(player)
end
end
end
end
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
mod.damage_armor(player, damage)
end)
minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info)
if not (player and action and inventory and inventory_info) then
return
end
if not (inventory_info.from_list == worn_inv or inventory_info.to_list == worn_inv or inventory_info.listname == worn_inv) then
return
end
local item
if action == 'move' then
if not (inventory_info.to_list and inventory_info.to_index) then
return
end
item = inventory:get_stack(inventory_info.to_list, inventory_info.to_index)
else
item = inventory_info.stack
end
if not item then
return
end
local item_s = item:get_name()
if not mod.wearable[item_s] then
return
end
mod.set_main_size_by_bags(player)
mod.set_armor(player)
end)
function mod.items_at_range(inv, name, i, j)
if not (inv and name and i and j) then
return
end
local a = inv:get_list(name)
if not a then
return
end
for ind = i + 1, j do
if a[ind] and a[ind]:get_name() ~= '' then
return true
end
end
end

2
mod.conf Normal file
View File

@ -0,0 +1,2 @@
name = dinv
depends = default

BIN
textures/bags_large.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

BIN
textures/bags_medium.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 427 B

BIN
textures/bags_small.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

BIN
textures/big_g.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 B

BIN
textures/boots1_brown.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 348 B

BIN
textures/buckler1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

BIN
textures/chain_mail1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 973 B

BIN
textures/crystal_plate2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 486 B

BIN
textures/helmet1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

BIN
textures/lshield_dd_dk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 352 B

BIN
textures/plate1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B