diff --git a/init.lua b/init.lua index 5db2411..e6a3c6c 100644 --- a/init.lua +++ b/init.lua @@ -13,23 +13,28 @@ mod.world = minetest.get_worldpath() mod.dat = {} -local worn_inv = 'worn' +local ADD_SCROLL_TO_DEFAULT_CHEST = true local sorted_items +local WORN_INV = 'worn' +local PROTECT_INVENTORY = false -- Prevent ANY inventory loss. minetest.register_craftitem(mod_name..':bag_small', { inventory_image = 'bags_small.png', stack_max = 1, + _dinv_storage_size = 8, }) minetest.register_craftitem(mod_name..':bag_medium', { inventory_image = 'bags_medium.png', stack_max = 1, + _dinv_storage_size = 16, }) minetest.register_craftitem(mod_name..':bag_large', { inventory_image = 'bags_large.png', stack_max = 1, + _dinv_storage_size = 24, }) minetest.register_tool(mod_name..':leather_armor', { @@ -61,7 +66,25 @@ minetest.register_tool(mod_name..':steel_helmet', { description = 'Steel Helmet', _dinv_armor = 0.8, _dinv_location = 'head', - --_dinv_texture = '', + _dinv_texture = 'dinv_char_steel_helm.png', +}) + +minetest.register_tool(mod_name..':ring_protection_9', { + inventory_image = 'anvil.png', + description = 'Ring of Protection', + _dinv_armor = 0.9, +}) + +minetest.register_tool(mod_name..':ring_flight', { + inventory_image = 'glass.png', + description = 'Ring of Flight', + _dinv_wears_out = 10000, + _dinv_on_wear = function(player) + mod.modify_privs(player, { fly = true, noclip = 0 }) + end, + _dinv_on_remove = function(player) + mod.modify_privs(player, { fly = 0, noclip = 0 }) + end, }) minetest.register_tool(mod_name..':wood_shield', { @@ -77,7 +100,7 @@ minetest.register_tool(mod_name..':steel_shield', { description = 'Steel Shield', _dinv_armor = 0.7, _dinv_location = 'arm', - --_dinv_texture = '', + _dinv_texture = 'dinv_char_steel_shield.png', }) minetest.register_tool(mod_name..':chain_armor', { @@ -93,7 +116,7 @@ minetest.register_tool(mod_name..':plate_armor', { description = 'Plate Mail', _dinv_armor = 0.6, _dinv_location = 'body', - --_dinv_texture = '', + _dinv_texture = 'dinv_char_plate_armor.png', }) minetest.register_tool(mod_name..':diamond_plate_armor', { @@ -101,7 +124,7 @@ minetest.register_tool(mod_name..':diamond_plate_armor', { description = 'Diamond Plate Mail', _dinv_armor = 0.45, _dinv_location = 'body', - --_dinv_texture = '', + _dinv_texture = 'dinv_char_diamond_plate_armor.png', }) minetest.register_tool(mod_name..':fur_cloak', { @@ -110,7 +133,7 @@ minetest.register_tool(mod_name..':fur_cloak', { _dinv_armor = 0.98, _dinv_warmth = 2, _dinv_location = 'back', - --_dinv_texture = '', + _dinv_texture = 'dinv_char_fur_cloak.png', }) --print(dump(minetest.registered_tools[mod_name..':plate_armor'])) @@ -272,28 +295,6 @@ minetest.register_craft({ }) -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', @@ -302,7 +303,6 @@ local force_rep = { ['wool'] = 'wool:white', } - -- This tables looks up groups that aren't already stored. mod.group_rep = setmetatable({}, { __index = function(t, k) @@ -334,6 +334,7 @@ mod.group_rep = setmetatable({}, { local group_rep = mod.group_rep + -- iterator over worn inventory function mod.worn_items(player) if not player then @@ -345,12 +346,14 @@ function mod.worn_items(player) return end - local flist = pinv:get_list(worn_inv) + local flist = pinv:get_list(WORN_INV) return pairs(flist) end local worn_items = mod.worn_items + +-- Formspec definitions are confusing. 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;]' @@ -361,6 +364,172 @@ mod.recipe_buttons = 'image_button[3,3;1,1;transparent_button.png;dinv_recipe_ba mod.worn_items_inv = 'list[current_player;worn;9.25,4;2,4;]' +-- All this is necessary to add scroll buttons to chests. +if ADD_SCROLL_TO_DEFAULT_CHEST Then + function default.chest.get_chest_formspec(pos, player) + local scroll_to = 8 + if player and player.get_player_name then + local player_name = player:get_player_name() + if mod.dat[player_name].scroll_main_to then + scroll_to = mod.dat[player_name].scroll_main_to + end + end + + local spos = pos.x .. ',' .. pos.y .. ',' .. pos.z + local formspec = + 'size[9,9]' .. + 'list[nodemeta:' .. spos .. ';main;0,0.3;8,4;]' .. + 'list[current_player;main;0,4.85;8,1;]' .. + 'list[current_player;main;0,6.08;8,3;' .. scroll_to .. ']' .. + 'listring[nodemeta:' .. spos .. ';main]' .. + 'listring[current_player;main]' .. + 'image_button[8,6.08;1,1;transparent_button.png;dinv_chest_main_inventory_up;Up]' .. + 'image_button[8,8.08;1,1;transparent_button.png;dinv_chest_main_inventory_down;Down]' .. + default.get_hotbar_bg(0,4.85) + return formspec + end + + + local original_chest_functions = {} + for _, nd in pairs({ 'default:chest', 'default:chest_locked' }) do + original_chest_functions[nd] = {} + original_chest_functions[nd].on_rightclick = minetest.registered_items[nd].on_rightclick + + minetest.override_item(nd, { + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + if clicker.get_player_name then + local player_name = clicker:get_player_name() + local dat = mod.dat[player_name] + if dat then + dat.chest_opened = pos + end + end + + original_chest_functions[nd].on_rightclick(pos, node, clicker, itemstack, pointed_thing) + end + }) + end + + + minetest.register_on_player_receive_fields(function(player, formname, fields) + if formname ~= 'default:chest' then + return + end + + if not (player and fields) then + return + end + + if not ( + fields['dinv_chest_main_inventory_up'] + or fields['dinv_chest_main_inventory_down'] + ) then + return + end + + local player_name = player:get_player_name() + + local dat = mod.dat[player_name] or {} + local pos = dat.chest_opened + if not pos then + return + end + + local pinv = player:get_inventory() + local main_inventory_size = pinv:get_size('main') + + if fields['dinv_chest_main_inventory_up'] then + dat['scroll_main_to'] = math.max(8, (dat['scroll_main_to'] or 8) - 16) + minetest.show_formspec(player_name, 'default:chest', default.chest.get_chest_formspec(pos, player)) + elseif fields['dinv_chest_main_inventory_down'] then + dat['scroll_main_to'] = (dat['scroll_main_to'] or 8) + 16 + if dat['scroll_main_to'] >= main_inventory_size then + dat['scroll_main_to'] = 8 + end + minetest.show_formspec(player_name, 'default:chest', default.chest.get_chest_formspec(pos, player)) + end + end) +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) + mod.set_armor_textures(player) + end + end + end +end + + +-- Calculate how big the main inventory should be. +function mod.get_main_size_by_bags(player) + local isize = 32 + + for k, v in worn_items(player) do + local vs = v:get_name() + local it = minetest.registered_items[vs] + if it._dinv_storage_size then + isize = isize + it._dinv_storage_size + end + end + + return isize +end + + +-- Any warmth over zero is sufficient at the moment. +function mod.get_warmth(player) + if not player then + return + end + + local warmth = 0 + + for k, v in worn_items(player) do + local vs = v:get_name() + local it = minetest.registered_items[vs] + if it._dinv_warmth then + warmth = warmth + it._dinv_warmth + end + end + + return warmth +end + + +-- Check if there are any stacks in the given inventory, +-- at the given positions. This is important to avoid losing +-- those items when a bag is removed. +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 + + +-- The main formspec... function mod.make_inventory_spec(player) if not player then return @@ -387,91 +556,50 @@ function mod.make_inventory_spec(player) end -function default.chest.get_chest_formspec(pos, player) - local scroll_to = 8 - if player and player.get_player_name then - local player_name = player:get_player_name() - if mod.dat[player_name].scroll_main_to then - scroll_to = mod.dat[player_name].scroll_main_to - end - end - - local spos = pos.x .. ',' .. pos.y .. ',' .. pos.z - local formspec = - 'size[9,9]' .. - 'list[nodemeta:' .. spos .. ';main;0,0.3;8,4;]' .. - 'list[current_player;main;0,4.85;8,1;]' .. - 'list[current_player;main;0,6.08;8,3;' .. scroll_to .. ']' .. - 'listring[nodemeta:' .. spos .. ';main]' .. - 'listring[current_player;main]' .. - 'image_button[8,6.08;1,1;transparent_button.png;dinv_chest_main_inventory_up;Up]' .. - 'image_button[8,8.08;1,1;transparent_button.png;dinv_chest_main_inventory_down;Down]' .. - default.get_hotbar_bg(0,4.85) - return formspec -end - - -local original_chest_functions = {} -for _, nd in pairs({ 'default:chest', 'default:chest_locked' }) do - original_chest_functions[nd] = {} - original_chest_functions[nd].on_rightclick = minetest.registered_items[nd].on_rightclick - - minetest.override_item(nd, { - on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - if clicker.get_player_name then - local player_name = clicker:get_player_name() - local dat = mod.dat[player_name] - if dat then - dat.chest_opened = pos - end - end - - original_chest_functions[nd].on_rightclick(pos, node, clicker, itemstack, pointed_thing) - end - }) -end - - -minetest.register_on_player_receive_fields(function(player, formname, fields) - if formname ~= 'default:chest' then - return - end - - if not (player and fields) then - return - end - - if not ( - fields['dinv_chest_main_inventory_up'] - or fields['dinv_chest_main_inventory_down'] - ) then - return - end - +-- Change one or more privileges. Set a privilege value +-- to 0, in the input table, to remove it. +----------------------------------------------- +-- Note that this can remove granted privileges. +----------------------------------------------- +function mod.modify_privs(player, p) local player_name = player:get_player_name() + local privs = minetest.get_player_privs(player_name) or {} - local dat = mod.dat[player_name] or {} - local pos = dat.chest_opened - if not pos then - return - end - - local pinv = player:get_inventory() - local main_inventory_size = pinv:get_size('main') - - if fields['dinv_chest_main_inventory_up'] then - dat['scroll_main_to'] = math.max(8, (dat['scroll_main_to'] or 8) - 16) - minetest.show_formspec(player_name, 'default:chest', default.chest.get_chest_formspec(pos, player)) - elseif fields['dinv_chest_main_inventory_down'] then - dat['scroll_main_to'] = (dat['scroll_main_to'] or 8) + 16 - if dat['scroll_main_to'] >= main_inventory_size then - dat['scroll_main_to'] = 8 + for k, v in pairs(p) do + if v == 0 then + privs[k] = nil + else + privs[k] = v end - minetest.show_formspec(player_name, 'default:chest', default.chest.get_chest_formspec(pos, player)) end + + minetest.set_player_privs(player_name, privs) +end + + +-- Quick table of all wearable items. +----------------------------------------------------- +-- Populating this after the game starts might cause +-- problems, so I do it twice, just in case. +----------------------------------------------------- +mod.wearable = { } +function mod.populate_wearable_table() + for k, v in pairs(minetest.registered_items) do + if v._dinv_armor or v._dinv_storage_size + or v._dinv_on_wear or v._dinv_on_remove then + mod.wearable[k] = true + end + end +end +mod.populate_wearable_table() +minetest.after(0, function() + mod.populate_wearable_table() end) +-- Return a 3 x 3 grid of images matching the selected recipe. +-- This appears over then actual craft grid, but won't interfere +-- with it. function mod.recipe_grid(player) local player_name = player:get_player_name() local dat = mod.dat[player_name] @@ -544,6 +672,7 @@ function mod.recipe_grid(player) end +-- Return a listbox filled with items that can be crafted. function mod.recipe_list(player) if not sorted_items then sorted_items = {} @@ -577,6 +706,8 @@ function mod.recipe_list(player) end +-- Recreate the inventory formspec when the player scrolls +-- up or down in the main inventory. function mod.scroll_main(player, amount, max) if not (player and amount) then return @@ -599,20 +730,63 @@ function mod.scroll_main(player, amount, max) end -function mod.get_main_size_by_bags(player) - local isize = 32 +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() - if mod.bag_sizes[vs] then - isize = isize + mod.bag_sizes[vs] + local it = minetest.registered_items[vs] + if it._dinv_armor then + armor = armor * it._dinv_armor end end - return isize + local player_name = player:get_player_name() + if player_name then + minetest.chat_send_player(player_name, 'Your armor: ' .. armor) + end + + local armor_g = player:get_armor_groups() + if not (armor_g and armor_g.fleshy) then + return + end + + armor_g.fleshy = armor + player:set_armor_groups(armor_g) end +----------------------------------------------- +-- Todo: Handle different character textures. +----------------------------------------------- +function mod.set_armor_textures(player) + local prop = player:get_properties() + local textures = prop.textures + --local tex = (textures and textures[1] or 'character.png') + local tex = 'character.png' + local pile = {} + for k, v in worn_items(player) do + local vs = v:get_name() + local it = minetest.registered_items[vs] + if it._dinv_location and it._dinv_texture then + pile[it._dinv_location] = it._dinv_texture + end + end + for _, loc in pairs({ 'body', 'feet', 'head', 'arm', 'back' }) do + if pile[loc] then + tex = tex .. '^' .. pile[loc] + end + end + textures = { tex } + player_api.set_textures(player, textures) +end + + +-- Set the size of the main inventory. function mod.set_main_size_by_bags(player) if not player then return @@ -626,35 +800,21 @@ function mod.set_main_size_by_bags(player) 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') + if PROTECT_INVENTORY and isize < prsize then + print(mod_name..': *** Preventing lost inventory from reducing bag sizes') isize = prsize end - --]] + if not pinv:set_size('main', isize) then - print('*** ERROR setting inventory size.') + print(mod_name..': *** 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) - mod.set_armor_textures(player) - player:set_inventory_formspec(mod.make_inventory_spec(player)) -end) - - +-- Recreate the inventory formspec to show a recipe given +-- by the return value from the recipe list. function mod.show_recipe(player, field) if not (player and field) then return @@ -676,6 +836,8 @@ function mod.show_recipe(player, field) end +-- Recreate the inventory formspec to show a different recipe +-- for the current item (if it has more than one). function mod.switch_recipe(player, amount) if not (player and amount) then return @@ -700,6 +862,197 @@ function mod.switch_recipe(player, amount) end +-- Return true if there's an item at that body location. +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 + + + +-- Check for BAD THINGS if a player moves/adds/removes this item. +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 + + 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 item_from_it._dinv_storage_size then + local prsize = mod.get_main_size_by_bags(player) + local isize = prsize + if inventory_info.to_list == WORN_INV then + isize = isize + item_from_it._dinv_storage_size + elseif inventory_info.from_list == WORN_INV then + isize = isize - item_from_it._dinv_storage_size + 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) + + +-- Damage items that can only be worn for a limited time. +local last_wear_check = 0 +minetest.register_globalstep(function(dtime) + local time = minetest.get_gametime() + if type(time) ~= 'number' then + return + end + + if time - last_wear_check < 5 then + return + end + + local players = minetest.get_connected_players() + + for i = 1, #players do + local player = players[i] + + for k, v in worn_items(player) do + local vs = v:get_name() + local it = minetest.registered_items[vs] + if it._dinv_wears_out then + local ow = v:get_wear() + local wear = it._dinv_wears_out + v:add_wear(wear) + player:get_inventory():set_stack(WORN_INV, k, v) + if ow + wear > 65535 then + if it._dinv_on_remove then + it._dinv_on_remove(player) + end + --[[ + mod.set_armor(player) + mod.set_armor_textures(player) + --]] + end + end + end + end + + last_wear_check = minetest.get_gametime() +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) + mod.set_armor_textures(player) + player:set_inventory_formspec(mod.make_inventory_spec(player)) +end) + + +-- Handle inventory moves (change armor, etc.). +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) + mod.set_armor_textures(player) + + local it = minetest.registered_items[item_s] + if inventory_info.to_list == inventory_info.from_list then + -- nop + elseif it._dinv_on_wear and inventory_info.to_list == WORN_INV then + it._dinv_on_wear(player) + elseif it._dinv_on_remove and inventory_info.from_list == WORN_INV then + it._dinv_on_remove(player) + end +end) + + +-- Get input from the formspec buttons/list. minetest.register_on_player_receive_fields(function(player, formname, fields) if not (player and fields) then return @@ -732,238 +1085,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) 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.get_warmth(player) - if not player then - return - end - - local warmth = 0 - - for k, v in worn_items(player) do - local vs = v:get_name() - local it = minetest.registered_items[vs] - if it._dinv_warmth then - warmth = warmth + it._dinv_warmth - end - end - - return warmth -end - - -function mod.set_armor_textures(player) - local prop = player:get_properties() - local textures = prop.textures - --local tex = (textures and textures[1] or 'character.png') - local tex = 'character.png' - local pile = {} - for k, v in worn_items(player) do - local vs = v:get_name() - local it = minetest.registered_items[vs] - if it._dinv_location and it._dinv_texture then - pile[it._dinv_location] = it._dinv_texture - end - end - for _, loc in pairs({ 'body', 'feet', 'head', 'arm', 'back' }) do - if pile[loc] then - tex = tex .. '^' .. pile[loc] - end - end - textures = { tex } - player_api.set_textures(player, textures) -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) - mod.set_armor_textures(player) - end - end - end -end - - +-- Every time the player gets punched, armor is damaged, +-- even if no damage is done to the player. 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) - mod.set_armor_textures(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 diff --git a/textures/anvil.png b/textures/anvil.png new file mode 100644 index 0000000..2ca8b2c Binary files /dev/null and b/textures/anvil.png differ diff --git a/textures/dinv_char_chain_armor.png b/textures/dinv_char_chain_armor.png index f18b2da..9936796 100644 Binary files a/textures/dinv_char_chain_armor.png and b/textures/dinv_char_chain_armor.png differ diff --git a/textures/dinv_char_diamond_plate_armor.png b/textures/dinv_char_diamond_plate_armor.png new file mode 100644 index 0000000..c673a50 Binary files /dev/null and b/textures/dinv_char_diamond_plate_armor.png differ diff --git a/textures/dinv_char_fur_cloak.png b/textures/dinv_char_fur_cloak.png new file mode 100644 index 0000000..1968fdc Binary files /dev/null and b/textures/dinv_char_fur_cloak.png differ diff --git a/textures/dinv_char_plate_armor.png b/textures/dinv_char_plate_armor.png new file mode 100644 index 0000000..bbac7fc Binary files /dev/null and b/textures/dinv_char_plate_armor.png differ diff --git a/textures/dinv_char_steel_helm.png b/textures/dinv_char_steel_helm.png new file mode 100644 index 0000000..117ecfb Binary files /dev/null and b/textures/dinv_char_steel_helm.png differ diff --git a/textures/dinv_char_steel_shield.png b/textures/dinv_char_steel_shield.png new file mode 100644 index 0000000..8b96d97 Binary files /dev/null and b/textures/dinv_char_steel_shield.png differ diff --git a/textures/glass.png b/textures/glass.png new file mode 100644 index 0000000..cab2229 Binary files /dev/null and b/textures/glass.png differ