From f74a52df62fdf9e1372f8f65737c28b1915915cc Mon Sep 17 00:00:00 2001 From: stujones11 Date: Fri, 17 Mar 2017 20:05:55 +0000 Subject: [PATCH] Code re-organisation This should make it easier to merge features from the now out-dated development branch. --- 3d_armor/admin.lua | 45 -- 3d_armor/api.lua | 267 ++++++++++++ 3d_armor/armor.lua | 1012 +++++++++++++------------------------------- 3d_armor/init.lua | 677 ++++++++++++++++++----------- 4 files changed, 998 insertions(+), 1003 deletions(-) delete mode 100644 3d_armor/admin.lua create mode 100644 3d_armor/api.lua diff --git a/3d_armor/admin.lua b/3d_armor/admin.lua deleted file mode 100644 index f499987..0000000 --- a/3d_armor/admin.lua +++ /dev/null @@ -1,45 +0,0 @@ -minetest.register_alias("adminboots","3d_armor:boots_admin") -minetest.register_alias("adminhelmet","3d_armor:helmet_admin") -minetest.register_alias("adminchestplate","3d_armor:chestplate_admin") -minetest.register_alias("adminleggings","3d_armor:leggings_admin") - -minetest.register_tool("3d_armor:helmet_admin", { - description = "Admin Helmet", - inventory_image = "3d_armor_inv_helmet_admin.png", - groups = {armor_head=1000, armor_heal=1000, armor_use=0, armor_water=1, not_in_creative_inventory=1}, - wear = 0, - on_drop = function(itemstack, dropper, pos) - return - end, -}) - -minetest.register_tool("3d_armor:chestplate_admin", { - description = "Admin Chestplate", - inventory_image = "3d_armor_inv_chestplate_admin.png", - groups = {armor_torso=1000, armor_heal=1000, armor_use=0, not_in_creative_inventory=1}, - wear = 0, - on_drop = function(itemstack, dropper, pos) - return - end, -}) - -minetest.register_tool("3d_armor:leggings_admin", { - description = "Admin Leggings", - inventory_image = "3d_armor_inv_leggings_admin.png", - groups = {armor_legs=1000, armor_heal=1000, armor_use=0, not_in_creative_inventory=1}, - wear = 0, - on_drop = function(itemstack, dropper, pos) - return - end, -}) - -minetest.register_tool("3d_armor:boots_admin", { - description = "Admin Boots", - inventory_image = "3d_armor_inv_boots_admin.png", - groups = {armor_feet=1000, armor_heal=1000, armor_use=0, not_in_creative_inventory=1}, - wear = 0, - on_drop = function(itemstack, dropper, pos) - return - end, -}) - diff --git a/3d_armor/api.lua b/3d_armor/api.lua new file mode 100644 index 0000000..2e2e396 --- /dev/null +++ b/3d_armor/api.lua @@ -0,0 +1,267 @@ +local skin_previews = {} +local use_player_monoids = minetest.global_exists("player_monoids") +local use_armor_monoid = minetest.global_exists("armor_monoid") + +armor = { + timer = 0, + elements = {"head", "torso", "legs", "feet"}, + physics = {"jump","speed","gravity"}, + formspec = "size[8,8.5]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + default.get_hotbar_bg(0,4.25).. + "image[2,0.5;2,4;armor_preview]".. + "list[current_player;main;0,4.25;8,1;]".. + "list[current_player;main;0,5.5;8,3;8]".. + "list[current_player;craft;4,0.5;3,3;]".. + "list[current_player;craftpreview;7,1.5;1,1;]".. + "listring[current_player;main]".. + "listring[current_player;craft]", + def = {}, + textures = {}, + default_skin = "character", + version = "0.4.8", +} + +armor.update_player_visuals = function(self, player) + if not player then + return + end + local name = player:get_player_name() + if self.textures[name] then + default.player_set_textures(player, { + self.textures[name].skin, + self.textures[name].armor, + self.textures[name].wielditem, + }) + end +end + +armor.set_player_armor = function(self, player) + local name, player_inv = armor:get_valid_player(player, "[set_player_armor]") + if not name then + return + end + local armor_texture = "3d_armor_trans.png" + local armor_level = 0 + local armor_heal = 0 + local armor_fire = 0 + local armor_water = 0 + local armor_radiation = 0 + local state = 0 + local items = 0 + local elements = {} + local textures = {} + local physics_o = {speed=1,gravity=1,jump=1} + local material = {type=nil, count=1} + local preview = armor:get_preview(name) + for _,v in ipairs(self.elements) do + elements[v] = false + end + for i=1, 6 do + local stack = player_inv:get_stack("armor", i) + local item = stack:get_name() + if stack:get_count() == 1 then + local def = stack:get_definition() + for k, v in pairs(elements) do + if v == false then + local level = def.groups["armor_"..k] + if level then + local texture = def.texture or item:gsub("%:", "_") + table.insert(textures, texture..".png") + preview = preview.."^"..texture.."_preview.png" + armor_level = armor_level + level + state = state + stack:get_wear() + items = items + 1 + armor_heal = armor_heal + (def.groups["armor_heal"] or 0) + armor_fire = armor_fire + (def.groups["armor_fire"] or 0) + armor_water = armor_water + (def.groups["armor_water"] or 0) + armor_radiation = armor_radiation + (def.groups["armor_radiation"] or 0) + for kk,vv in ipairs(self.physics) do + local o_value = def.groups["physics_"..vv] + if o_value then + physics_o[vv] = physics_o[vv] + o_value + end + end + local mat = string.match(item, "%:.+_(.+)$") + if material.type then + if material.type == mat then + material.count = material.count + 1 + end + else + material.type = mat + end + elements[k] = true + end + end + end + end + end + if minetest.get_modpath("shields") then + armor_level = armor_level * 0.9 + end + if material.type and material.count == #self.elements then + armor_level = armor_level * 1.1 + end + armor_level = armor_level * ARMOR_LEVEL_MULTIPLIER + armor_heal = armor_heal * ARMOR_HEAL_MULTIPLIER + armor_radiation = armor_radiation * ARMOR_RADIATION_MULTIPLIER + if #textures > 0 then + armor_texture = table.concat(textures, "^") + end + local armor_groups = {fleshy=100} + if armor_level > 0 then + armor_groups.level = math.floor(armor_level / 20) + armor_groups.fleshy = 100 - armor_level + armor_groups.radiation = 100 - armor_radiation + end + if use_armor_monoid then + armor_monoid.monoid:add_change(player, { + fleshy = armor_groups.fleshy / 100 + }, "3d_armor:armor") + else + player:set_armor_groups(armor_groups) + end + if use_player_monoids then + player_monoids.speed:add_change(player, physics_o.speed, + "3d_armor:physics") + player_monoids.jump:add_change(player, physics_o.jump, + "3d_armor:physics") + player_monoids.gravity:add_change(player, physics_o.gravity, + "3d_armor:physics") + else + player:set_physics_override(physics_o) + end + self.textures[name].armor = armor_texture + self.textures[name].preview = preview + self.def[name].state = state + self.def[name].count = items + self.def[name].level = armor_level + self.def[name].heal = armor_heal + self.def[name].jump = physics_o.jump + self.def[name].speed = physics_o.speed + self.def[name].gravity = physics_o.gravity + self.def[name].fire = armor_fire + self.def[name].water = armor_water + self.def[name].radiation = armor_radiation + self:update_player_visuals(player) +end + +armor.get_player_skin = function(self, name) + local skin = nil + if self.skin_mod == "skins" or self.skin_mod == "simple_skins" then + skin = skins.skins[name] + elseif self.skin_mod == "u_skins" then + skin = u_skins.u_skins[name] + elseif self.skin_mod == "wardrobe" then + skin = string.gsub(wardrobe.playerSkins[name], "%.png$","") + end + return skin or armor.default_skin +end + +armor.add_preview = function(self, preview) + skin_previews[preview] = true +end + +armor.get_preview = function(self, name) + local preview = armor:get_player_skin(name).."_preview.png" + if skin_previews[preview] then + return preview + end + return "character_preview.png" +end + +armor.get_armor_formspec = function(self, name, listring) + if not armor.textures[name] then + minetest.log("error", "3d_armor: Player texture["..name.."] is nil [get_armor_formspec]") + return "" + end + if not armor.def[name] then + minetest.log("error", "3d_armor: Armor def["..name.."] is nil [get_armor_formspec]") + return "" + end + local formspec = armor.formspec.."list[detached:"..name.."_armor;armor;0,0.5;2,3;]" + if listring == true then + formspec = formspec.."listring[current_player;main]".. + "listring[detached:"..name.."_armor;armor]" + end + formspec = formspec:gsub("armor_preview", armor.textures[name].preview) + formspec = formspec:gsub("armor_level", armor.def[name].level) + formspec = formspec:gsub("armor_heal", armor.def[name].heal) + formspec = formspec:gsub("armor_fire", armor.def[name].fire) + formspec = formspec:gsub("armor_radiation", armor.def[name].radiation) + formspec = formspec:gsub("player_name", armor.def[name].radiation) + return formspec +end + +armor.update_inventory = function(self, player) + local name = armor:get_valid_player(player, "[set_player_armor]") + if not name or self.inv_mod == "inventory_enhanced" then + return + end + if self.inv_mod == "smart_inventory" then + local state = smart_inventory.get_page_state("player", name) + if state then + state:get("update_hook"):submit() + end + elseif self.inv_mod == "sfinv" then + if sfinv.set_page then + sfinv.set_page(player, "3d_armor:armor") + else + -- Backwards compat + sfinv.set_player_inventory_formspec(player, { + page = "3d_armor:armor" + }) + end + elseif self.inv_mod == "unified_inventory" then + if unified_inventory.current_page[name] == "armor" then + unified_inventory.set_inventory_formspec(player, "armor") + end + else + if self.inv_mod == "inventory_plus" then + local formspec = armor:get_armor_formspec(name, true) + local page = player:get_inventory_formspec() + if page:find("detached:"..name.."_armor") then + inventory_plus.set_inventory_formspec(player, formspec) + end + elseif not core.setting_getbool("creative_mode") then + local formspec = armor:get_armor_formspec(name) + player:set_inventory_formspec(formspec) + end + end +end + +armor.get_valid_player = function(self, player, msg) + msg = msg or "" + if not player then + minetest.log("error", "3d_armor: Player reference is nil "..msg) + return + end + local name = player:get_player_name() + if not name then + minetest.log("error", "3d_armor: Player name is nil "..msg) + return + end + local pos = player:getpos() + local player_inv = player:get_inventory() + local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"}) + if not pos then + minetest.log("error", "3d_armor: Player position is nil "..msg) + return + elseif not player_inv then + minetest.log("error", "3d_armor: Player inventory is nil "..msg) + return + elseif not armor_inv then + minetest.log("error", "3d_armor: Detached armor inventory is nil "..msg) + return + end + return name, player_inv, armor_inv, pos +end + +armor.drop_armor = function(pos, stack) + local obj = minetest.add_item(pos, stack) + if obj then + obj:setvelocity({x=math.random(-1, 1), y=5, z=math.random(-1, 1)}) + end +end diff --git a/3d_armor/armor.lua b/3d_armor/armor.lua index 764af51..06a560f 100644 --- a/3d_armor/armor.lua +++ b/3d_armor/armor.lua @@ -1,727 +1,299 @@ -ARMOR_INIT_DELAY = 1 -ARMOR_INIT_TIMES = 1 -ARMOR_BONES_DELAY = 1 -ARMOR_UPDATE_TIME = 1 -ARMOR_DROP = minetest.get_modpath("bones") ~= nil -ARMOR_DESTROY = false -ARMOR_LEVEL_MULTIPLIER = 1 -ARMOR_HEAL_MULTIPLIER = 1 -ARMOR_RADIATION_MULTIPLIER = 1 -ARMOR_MATERIALS = { - wood = "group:wood", - cactus = "default:cactus", - steel = "default:steel_ingot", - bronze = "default:bronze_ingot", - diamond = "default:diamond", - gold = "default:gold_ingot", - mithril = "moreores:mithril_ingot", - crystal = "ethereal:crystal_ingot", -} -ARMOR_FIRE_PROTECT = minetest.get_modpath("ethereal") ~= nil -ARMOR_FIRE_NODES = { - {"default:lava_source", 5, 8}, - {"default:lava_flowing", 5, 8}, - {"fire:basic_flame", 3, 4}, - {"fire:permanent_flame", 3, 4}, - {"ethereal:crystal_spike", 2, 1}, - {"ethereal:fire_flower", 2, 1}, - {"default:torch", 1, 1}, - {"default:torch_ceiling", 1, 1}, - {"default:torch_wall", 1, 1}, -} +minetest.register_alias("adminboots","3d_armor:boots_admin") +minetest.register_alias("adminhelmet","3d_armor:helmet_admin") +minetest.register_alias("adminchestplate","3d_armor:chestplate_admin") +minetest.register_alias("adminleggings","3d_armor:leggings_admin") -local skin_mod = nil -local inv_mod = nil -local use_player_monoids = minetest.global_exists("player_monoids") -local use_armor_monoid = minetest.global_exists("armor_monoid") -local preview_textures = {} - -local modpath = minetest.get_modpath(ARMOR_MOD_NAME) -local worldpath = minetest.get_worldpath() -local input = io.open(modpath.."/armor.conf", "r") -if input then - dofile(modpath.."/armor.conf") - input:close() - input = nil -end -input = io.open(worldpath.."/armor.conf", "r") -if input then - dofile(worldpath.."/armor.conf") - input:close() - input = nil -end -if not minetest.get_modpath("moreores") then - ARMOR_MATERIALS.mithril = nil -end -if not minetest.get_modpath("ethereal") then - ARMOR_MATERIALS.crystal = nil -end - -armor = { - timer = 0, - elements = {"head", "torso", "legs", "feet"}, - physics = {"jump","speed","gravity"}, - formspec = "size[8,8.5]".. - default.gui_bg.. - default.gui_bg_img.. - default.gui_slots.. - default.get_hotbar_bg(0,4.25).. - "image[2,0.5;2,4;armor_preview]".. - "list[current_player;main;0,4.25;8,1;]".. - "list[current_player;main;0,5.5;8,3;8]".. - "list[current_player;craft;4,0.5;3,3;]".. - "list[current_player;craftpreview;7,1.5;1,1;]".. - "listring[current_player;main]".. - "listring[current_player;craft]", - textures = {}, - default_skin = "character", - version = "0.4.8", -} - -local armor_formpage = "image[2.5,0;2,4;armor_preview]".. - default.gui_bg.. - default.gui_bg_img.. - default.gui_slots.. - default.get_hotbar_bg(0, 4.7).. - "label[5,1;Level: armor_level]".. - "label[5,1.5;Heal: armor_heal]".. - "list[current_player;main;0,4.7;8,1;]".. - "list[current_player;main;0,5.85;8,3;8]" -if ARMOR_FIRE_PROTECT then - armor_formpage = armor_formpage.."label[5,2;Fire: armor_fire]" -end -if minetest.global_exists("technic") then - armor_formpage = armor_formpage.."label[5,2.5;Radiation: armor_radiation]" -end -if minetest.get_modpath("inventory_plus") then - inv_mod = "inventory_plus" - armor.formspec = "size[8,8.5]button[6,0;2,0.5;main;Back]"..armor_formpage - if minetest.get_modpath("crafting") then - inventory_plus.get_formspec = function(player, page) - end - end -elseif minetest.get_modpath("unified_inventory") and not unified_inventory.sfinv_compat_layer then - inv_mod = "unified_inventory" - unified_inventory.register_button("armor", { - type = "image", - image = "inventory_plus_armor.png", - }) - unified_inventory.register_page("armor", { - get_formspec = function(player, perplayer_formspec) - local fy = perplayer_formspec.formspec_y - local name = player:get_player_name() - local formspec = "background[0.06,"..fy..";7.92,7.52;3d_armor_ui_form.png]".. - "label[0,0;Armor]".. - "list[detached:"..name.."_armor;armor;0,"..fy..";2,3;]".. - "image[2.5,"..(fy - 0.25)..";2,4;"..armor.textures[name].preview.."]".. - "label[5.0,"..(fy + 0.0)..";Level: "..armor.def[name].level.."]".. - "label[5.0,"..(fy + 0.5)..";Heal: "..armor.def[name].heal.."]".. - "listring[current_player;main]".. - "listring[detached:"..name.."_armor;armor]" - if ARMOR_FIRE_PROTECT then - formspec = formspec.."label[5.0,"..(fy + 1.0).. - ";Fire: "..armor.def[name].fire.."]" - end - if minetest.global_exists("technic") then - formspec = formspec.."label[5.0,"..(fy + 1.5).. - ";Radiation: "..armor.def[name].radiation.."]" - end - return {formspec=formspec} - end, - }) -elseif minetest.get_modpath("inventory_enhanced") then - inv_mod = "inventory_enhanced" -elseif minetest.get_modpath("smart_inventory") then - inv_mod = "smart_inventory" -elseif minetest.get_modpath("sfinv") then - inv_mod = "sfinv" - armor.formspec = armor_formpage - sfinv.register_page("3d_armor:armor", { - title = "Armor", - get = function(self, player, context) - local name = player:get_player_name() - local formspec = armor:get_armor_formspec(name, true) - return sfinv.make_formspec(player, context, formspec, false) - end - }) -end - -local skin_mods = {"skins", "u_skins", "simple_skins", "wardrobe"} -for _, mod in pairs(skin_mods) do - local path = minetest.get_modpath(mod) - if path then - local dir_list = minetest.get_dir_list(path.."/textures") - for _, fn in pairs(dir_list) do - if fn:find("_preview.png$") then - preview_textures[fn] = true - end - end - skin_mod = mod - end -end - -armor.def = { - state = 0, - count = 0, -} - -armor.update_player_visuals = function(self, player) - if not player then +minetest.register_tool("3d_armor:helmet_admin", { + description = "Admin Helmet", + inventory_image = "3d_armor_inv_helmet_admin.png", + groups = {armor_head=1000, armor_heal=1000, armor_use=0, armor_water=1, + not_in_creative_inventory=1}, + wear = 0, + on_drop = function(itemstack, dropper, pos) return - end - local name = player:get_player_name() - if self.textures[name] then - default.player_set_textures(player, { - self.textures[name].skin, - self.textures[name].armor, - self.textures[name].wielditem, - }) - end -end - -armor.set_player_armor = function(self, player) - local name, player_inv = armor:get_valid_player(player, "[set_player_armor]") - if not name then - return - end - local armor_texture = "3d_armor_trans.png" - local armor_level = 0 - local armor_heal = 0 - local armor_fire = 0 - local armor_water = 0 - local armor_radiation = 0 - local state = 0 - local items = 0 - local elements = {} - local textures = {} - local physics_o = {speed=1,gravity=1,jump=1} - local material = {type=nil, count=1} - local preview = armor:get_preview(name) - for _,v in ipairs(self.elements) do - elements[v] = false - end - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - local item = stack:get_name() - if stack:get_count() == 1 then - local def = stack:get_definition() - for k, v in pairs(elements) do - if v == false then - local level = def.groups["armor_"..k] - if level then - local texture = def.texture or item:gsub("%:", "_") - table.insert(textures, texture..".png") - preview = preview.."^"..texture.."_preview.png" - armor_level = armor_level + level - state = state + stack:get_wear() - items = items + 1 - armor_heal = armor_heal + (def.groups["armor_heal"] or 0) - armor_fire = armor_fire + (def.groups["armor_fire"] or 0) - armor_water = armor_water + (def.groups["armor_water"] or 0) - armor_radiation = armor_radiation + (def.groups["armor_radiation"] or 0) - for kk,vv in ipairs(self.physics) do - local o_value = def.groups["physics_"..vv] - if o_value then - physics_o[vv] = physics_o[vv] + o_value - end - end - local mat = string.match(item, "%:.+_(.+)$") - if material.type then - if material.type == mat then - material.count = material.count + 1 - end - else - material.type = mat - end - elements[k] = true - end - end - end - end - end - if minetest.get_modpath("shields") then - armor_level = armor_level * 0.9 - end - if material.type and material.count == #self.elements then - armor_level = armor_level * 1.1 - end - armor_level = armor_level * ARMOR_LEVEL_MULTIPLIER - armor_heal = armor_heal * ARMOR_HEAL_MULTIPLIER - armor_radiation = armor_radiation * ARMOR_RADIATION_MULTIPLIER - if #textures > 0 then - armor_texture = table.concat(textures, "^") - end - local armor_groups = {fleshy=100} - if armor_level > 0 then - armor_groups.level = math.floor(armor_level / 20) - armor_groups.fleshy = 100 - armor_level - armor_groups.radiation = 100 - armor_radiation - end - if use_armor_monoid then - armor_monoid.monoid:add_change(player, { - fleshy = armor_groups.fleshy / 100 - }, "3d_armor:armor") - else - player:set_armor_groups(armor_groups) - end - if use_player_monoids then - player_monoids.speed:add_change(player, physics_o.speed, - "3d_armor:physics") - player_monoids.jump:add_change(player, physics_o.jump, - "3d_armor:physics") - player_monoids.gravity:add_change(player, physics_o.gravity, - "3d_armor:physics") - else - player:set_physics_override(physics_o) - end - self.textures[name].armor = armor_texture - self.textures[name].preview = preview - self.def[name].state = state - self.def[name].count = items - self.def[name].level = armor_level - self.def[name].heal = armor_heal - self.def[name].jump = physics_o.jump - self.def[name].speed = physics_o.speed - self.def[name].gravity = physics_o.gravity - self.def[name].fire = armor_fire - self.def[name].water = armor_water - self.def[name].radiation = armor_radiation - self:update_player_visuals(player) -end - -armor.update_armor = function(self, player) - -- Legacy support: Called when armor levels are changed - -- Other mods can hook on to this function, see hud mod for example -end - -armor.get_player_skin = function(self, name) - local skin = nil - if skin_mod == "skins" or skin_mod == "simple_skins" then - skin = skins.skins[name] - elseif skin_mod == "u_skins" then - skin = u_skins.u_skins[name] - elseif skin_mod == "wardrobe" then - skin = string.gsub(wardrobe.playerSkins[name], "%.png$","") - end - return skin or armor.default_skin -end - -armor.get_preview = function(self, name) - local preview = armor:get_player_skin(name).."_preview.png" - if preview_textures[preview] then - return preview - end - return "character_preview.png" -end - -armor.get_armor_formspec = function(self, name, listring) - if not armor.textures[name] then - minetest.log("error", "3d_armor: Player texture["..name.."] is nil [get_armor_formspec]") - return "" - end - if not armor.def[name] then - minetest.log("error", "3d_armor: Armor def["..name.."] is nil [get_armor_formspec]") - return "" - end - local formspec = armor.formspec.."list[detached:"..name.."_armor;armor;0,0.5;2,3;]" - if listring == true then - formspec = formspec.."listring[current_player;main]".. - "listring[detached:"..name.."_armor;armor]" - end - formspec = formspec:gsub("armor_preview", armor.textures[name].preview) - formspec = formspec:gsub("armor_level", armor.def[name].level) - formspec = formspec:gsub("armor_heal", armor.def[name].heal) - formspec = formspec:gsub("armor_fire", armor.def[name].fire) - formspec = formspec:gsub("armor_radiation", armor.def[name].radiation) - formspec = formspec:gsub("player_name", armor.def[name].radiation) - return formspec -end - -armor.update_inventory = function(self, player) - local name = armor:get_valid_player(player, "[set_player_armor]") - if not name or inv_mod == "inventory_enhanced" then - return - end - if inv_mod == "smart_inventory" then - local state = smart_inventory.get_page_state("player", name) - if state then - state:get("update_hook"):submit() - end - elseif inv_mod == "sfinv" then - if sfinv.set_page then - sfinv.set_page(player, "3d_armor:armor") - else - -- Backwards compat - sfinv.set_player_inventory_formspec(player, { - page = "3d_armor:armor" - }) - end - elseif inv_mod == "unified_inventory" then - if unified_inventory.current_page[name] == "armor" then - unified_inventory.set_inventory_formspec(player, "armor") - end - else - if inv_mod == "inventory_plus" then - local formspec = armor:get_armor_formspec(name, true) - local page = player:get_inventory_formspec() - if page:find("detached:"..name.."_armor") then - inventory_plus.set_inventory_formspec(player, formspec) - end - elseif not core.setting_getbool("creative_mode") then - local formspec = armor:get_armor_formspec(name) - player:set_inventory_formspec(formspec) - end - end -end - -armor.get_valid_player = function(self, player, msg) - msg = msg or "" - if not player then - minetest.log("error", "3d_armor: Player reference is nil "..msg) - return - end - local name = player:get_player_name() - if not name then - minetest.log("error", "3d_armor: Player name is nil "..msg) - return - end - local pos = player:getpos() - local player_inv = player:get_inventory() - local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"}) - if not pos then - minetest.log("error", "3d_armor: Player position is nil "..msg) - return - elseif not player_inv then - minetest.log("error", "3d_armor: Player inventory is nil "..msg) - return - elseif not armor_inv then - minetest.log("error", "3d_armor: Detached armor inventory is nil "..msg) - return - end - return name, player_inv, armor_inv, pos -end - -armor.drop_armor = function(pos, stack) - local obj = minetest.add_item(pos, stack) - if obj then - obj:setvelocity({x=math.random(-1, 1), y=5, z=math.random(-1, 1)}) - end -end - --- Register Player Model - -default.player_register_model("3d_armor_character.b3d", { - animation_speed = 30, - textures = { - armor.default_skin..".png", - "3d_armor_trans.png", - "3d_armor_trans.png", - }, - animations = { - stand = {x=0, y=79}, - lay = {x=162, y=166}, - walk = {x=168, y=187}, - mine = {x=189, y=198}, - walk_mine = {x=200, y=219}, - sit = {x=81, y=160}, - }, -}) - --- Register Callbacks - -minetest.register_on_player_receive_fields(function(player, formname, fields) - local name = armor:get_valid_player(player, "[on_player_receive_fields]") - if not name or inv_mod == "inventory_enhanced" then - return - end - if inv_mod == "inventory_plus" and fields.armor then - local formspec = armor:get_armor_formspec(name, true) - inventory_plus.set_inventory_formspec(player, formspec) - return - end - for field, _ in pairs(fields) do - if string.find(field, "skins_set") then - minetest.after(0, function(player) - local skin = armor:get_player_skin(name) - armor.textures[name].skin = skin..".png" - armor:set_player_armor(player) - end, player) - end - end -end) - -minetest.register_on_joinplayer(function(player) - default.player_set_model(player, "3d_armor_character.b3d") - local name = player:get_player_name() - local player_inv = player:get_inventory() - local armor_inv = minetest.create_detached_inventory(name.."_armor", { - on_put = function(inv, listname, index, stack, player) - player:get_inventory():set_stack(listname, index, stack) - armor:set_player_armor(player) - armor:update_inventory(player) - end, - on_take = function(inv, listname, index, stack, player) - player:get_inventory():set_stack(listname, index, nil) - armor:set_player_armor(player) - armor:update_inventory(player) - end, - on_move = function(inv, from_list, from_index, to_list, to_index, count, player) - local plaver_inv = player:get_inventory() - local stack = inv:get_stack(to_list, to_index) - player_inv:set_stack(to_list, to_index, stack) - player_inv:set_stack(from_list, from_index, nil) - armor:set_player_armor(player) - armor:update_inventory(player) - end, - allow_put = function(inv, listname, index, stack, player) - return 1 - end, - allow_take = function(inv, listname, index, stack, player) - return stack:get_count() - end, - allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) - return count - end, - }, name) - if inv_mod == "inventory_plus" then - inventory_plus.register_button(player,"armor", "Armor") - end - armor_inv:set_size("armor", 6) - player_inv:set_size("armor", 6) - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - armor_inv:set_stack("armor", i, stack) - end - armor.def[name] = { - state = 0, - count = 0, - level = 0, - heal = 0, - jump = 1, - speed = 1, - gravity = 1, - fire = 0, - water = 0, - radiation = 0, - } - armor.textures[name] = { - skin = armor.default_skin..".png", - armor = "3d_armor_trans.png", - wielditem = "3d_armor_trans.png", - preview = armor.default_skin.."_preview.png", - } - if skin_mod == "skins" then - local skin = skins.skins[name] - if skin and skins.get_type(skin) == skins.type.MODEL then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "simple_skins" then - local skin = skins.skins[name] - if skin then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "u_skins" then - local skin = u_skins.u_skins[name] - if skin and u_skins.get_type(skin) == u_skins.type.MODEL then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "wardrobe" then - local skin = wardrobe.playerSkins[name] - if skin then - armor.textures[name].skin = skin - end - end - local texture_path = minetest.get_modpath("player_textures") - if texture_path then - local dir_list = minetest.get_dir_list(texture_path.."/textures") - for _, fn in pairs(dir_list) do - if fn == "player_"..name..".png" then - armor.textures[name].skin = fn - break - end - end - end - for i=1, ARMOR_INIT_TIMES do - minetest.after(ARMOR_INIT_DELAY * i, function(player) - armor:set_player_armor(player) - if not inv_mod then - armor:update_inventory(player) - end - end, player) - end -end) - -if ARMOR_DROP == true or ARMOR_DESTROY == true then - minetest.register_on_dieplayer(function(player) - local name, player_inv, armor_inv, pos = armor:get_valid_player(player, "[on_dieplayer]") - if not name then - return - end - local drop = {} - for i=1, player_inv:get_size("armor") do - local stack = armor_inv:get_stack("armor", i) - if stack:get_count() > 0 then - table.insert(drop, stack) - armor_inv:set_stack("armor", i, nil) - player_inv:set_stack("armor", i, nil) - end - end - armor:set_player_armor(player) - if inv_mod == "unified_inventory" then - unified_inventory.set_inventory_formspec(player, "craft") - elseif inv_mod == "inventory_plus" then - local formspec = inventory_plus.get_formspec(player,"main") - inventory_plus.set_inventory_formspec(player, formspec) - else - armor:update_inventory(player) - end - if ARMOR_DESTROY == false then - minetest.after(ARMOR_BONES_DELAY, function() - local meta = nil - local maxp = vector.add(pos, 8) - local minp = vector.subtract(pos, 8) - local bones = minetest.find_nodes_in_area(minp, maxp, {"bones:bones"}) - for _, p in pairs(bones) do - local m = minetest.get_meta(p) - if m:get_string("owner") == name then - meta = m - break - end - end - if meta then - local inv = meta:get_inventory() - for _,stack in ipairs(drop) do - if inv:room_for_item("main", stack) then - inv:add_item("main", stack) - else - armor.drop_armor(pos, stack) - end - end - else - for _,stack in ipairs(drop) do - armor.drop_armor(pos, stack) - end - end - end) - end - end) -end - -minetest.register_on_player_hpchange(function(player, hp_change) - local name, player_inv, armor_inv = armor:get_valid_player(player, "[on_hpchange]") - if name and hp_change < 0 then - - -- used for insta kill tools/commands like /kill (doesnt damage armor) - if hp_change < -100 then - return hp_change - end - - local heal_max = 0 - local state = 0 - local items = 0 - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - if stack:get_count() > 0 then - local use = stack:get_definition().groups["armor_use"] or 0 - local heal = stack:get_definition().groups["armor_heal"] or 0 - local item = stack:get_name() - stack:add_wear(use) - armor_inv:set_stack("armor", i, stack) - player_inv:set_stack("armor", i, stack) - state = state + stack:get_wear() - items = items + 1 - if stack:get_count() == 0 then - local desc = minetest.registered_items[item].description - if desc then - minetest.chat_send_player(name, "Your "..desc.." got destroyed!") - end - armor:set_player_armor(player) - armor:update_inventory(player) - end - heal_max = heal_max + heal - end - end - armor.def[name].state = state - armor.def[name].count = items - heal_max = heal_max * ARMOR_HEAL_MULTIPLIER - if heal_max > math.random(100) then - hp_change = 0 - end - armor:update_armor(player) - end - return hp_change -end, true) - --- Fire Protection and water breating, added by TenPlus1 - -if ARMOR_FIRE_PROTECT == true then - -- override hot nodes so they do not hurt player anywhere but mod - for _, row in pairs(ARMOR_FIRE_NODES) do - if minetest.registered_nodes[row[1]] then - minetest.override_item(row[1], {damage_per_second = 0}) - end - end -else - print ("[3d_armor] Fire Nodes disabled") -end - -minetest.register_globalstep(function(dtime) - armor.timer = armor.timer + dtime - if armor.timer < ARMOR_UPDATE_TIME then - return - end - for _,player in pairs(minetest.get_connected_players()) do - local name = player:get_player_name() - local pos = player:getpos() - local hp = player:get_hp() - -- water breathing - if name and armor.def[name].water > 0 then - if player:get_breath() < 10 then - player:set_breath(10) - end - end - -- fire protection - if ARMOR_FIRE_PROTECT == true - and name and pos and hp then - pos.y = pos.y + 1.4 -- head level - local node_head = minetest.get_node(pos).name - pos.y = pos.y - 1.2 -- feet level - local node_feet = minetest.get_node(pos).name - -- is player inside a hot node? - for _, row in pairs(ARMOR_FIRE_NODES) do - -- check fire protection, if not enough then get hurt - if row[1] == node_head or row[1] == node_feet then - if hp > 0 and armor.def[name].fire < row[2] then - hp = hp - row[3] * ARMOR_UPDATE_TIME - player:set_hp(hp) - break - end - end - end - end - end - armor.timer = 0 -end) - --- kill player when command issued -minetest.register_chatcommand("kill", { - params = "", - description = "Kills player instantly", - privs = {ban=true}, - func = function(name, param) - local player = minetest.get_player_by_name(param) - if player then - player:set_hp(0) - end end, }) -minetest.register_chatcommand("killme", { - description = "Kill yourself instantly", - func = function(name) - local player = minetest.get_player_by_name(name) - if player then - player:set_hp(-1001) - end +minetest.register_tool("3d_armor:chestplate_admin", { + description = "Admin Chestplate", + inventory_image = "3d_armor_inv_chestplate_admin.png", + groups = {armor_torso=1000, armor_heal=1000, armor_use=0, + not_in_creative_inventory=1}, + wear = 0, + on_drop = function(itemstack, dropper, pos) + return end, }) + +minetest.register_tool("3d_armor:leggings_admin", { + description = "Admin Leggings", + inventory_image = "3d_armor_inv_leggings_admin.png", + groups = {armor_legs=1000, armor_heal=1000, armor_use=0, + not_in_creative_inventory=1}, + wear = 0, + on_drop = function(itemstack, dropper, pos) + return + end, +}) + +minetest.register_tool("3d_armor:boots_admin", { + description = "Admin Boots", + inventory_image = "3d_armor_inv_boots_admin.png", + groups = {armor_feet=1000, armor_heal=1000, armor_use=0, + not_in_creative_inventory=1}, + wear = 0, + on_drop = function(itemstack, dropper, pos) + return + end, +}) + +if ARMOR_MATERIALS.wood then + minetest.register_tool("3d_armor:helmet_wood", { + description = "Wood Helmet", + inventory_image = "3d_armor_inv_helmet_wood.png", + groups = {armor_head=5, armor_heal=0, armor_use=2000}, + wear = 0, + }) + minetest.register_tool("3d_armor:chestplate_wood", { + description = "Wood Chestplate", + inventory_image = "3d_armor_inv_chestplate_wood.png", + groups = {armor_torso=10, armor_heal=0, armor_use=2000}, + wear = 0, + }) + minetest.register_tool("3d_armor:leggings_wood", { + description = "Wood Leggings", + inventory_image = "3d_armor_inv_leggings_wood.png", + groups = {armor_legs=5, armor_heal=0, armor_use=2000}, + wear = 0, + }) + minetest.register_tool("3d_armor:boots_wood", { + description = "Wood Boots", + inventory_image = "3d_armor_inv_boots_wood.png", + groups = {armor_feet=5, armor_heal=0, armor_use=2000}, + wear = 0, + }) +end + +if ARMOR_MATERIALS.cactus then + minetest.register_tool("3d_armor:helmet_cactus", { + description = "Cactus Helmet", + inventory_image = "3d_armor_inv_helmet_cactus.png", + groups = {armor_head=5, armor_heal=0, armor_use=1000}, + wear = 0, + }) + minetest.register_tool("3d_armor:chestplate_cactus", { + description = "Cactus Chestplate", + inventory_image = "3d_armor_inv_chestplate_cactus.png", + groups = {armor_torso=10, armor_heal=0, armor_use=1000}, + wear = 0, + }) + minetest.register_tool("3d_armor:leggings_cactus", { + description = "Cactus Leggings", + inventory_image = "3d_armor_inv_leggings_cactus.png", + groups = {armor_legs=5, armor_heal=0, armor_use=1000}, + wear = 0, + }) + minetest.register_tool("3d_armor:boots_cactus", { + description = "Cactus Boots", + inventory_image = "3d_armor_inv_boots_cactus.png", + groups = {armor_feet=5, armor_heal=0, armor_use=1000}, + wear = 0, + }) +end + +if ARMOR_MATERIALS.steel then + minetest.register_tool("3d_armor:helmet_steel", { + description = "Steel Helmet", + inventory_image = "3d_armor_inv_helmet_steel.png", + groups = {armor_head=10, armor_heal=0, armor_use=500}, + wear = 0, + }) + minetest.register_tool("3d_armor:chestplate_steel", { + description = "Steel Chestplate", + inventory_image = "3d_armor_inv_chestplate_steel.png", + groups = {armor_torso=15, armor_heal=0, armor_use=500}, + wear = 0, + }) + minetest.register_tool("3d_armor:leggings_steel", { + description = "Steel Leggings", + inventory_image = "3d_armor_inv_leggings_steel.png", + groups = {armor_legs=15, armor_heal=0, armor_use=500}, + wear = 0, + }) + minetest.register_tool("3d_armor:boots_steel", { + description = "Steel Boots", + inventory_image = "3d_armor_inv_boots_steel.png", + groups = {armor_feet=10, armor_heal=0, armor_use=500}, + wear = 0, + }) +end + +if ARMOR_MATERIALS.bronze then + minetest.register_tool("3d_armor:helmet_bronze", { + description = "Bronze Helmet", + inventory_image = "3d_armor_inv_helmet_bronze.png", + groups = {armor_head=10, armor_heal=6, armor_use=250}, + wear = 0, + }) + minetest.register_tool("3d_armor:chestplate_bronze", { + description = "Bronze Chestplate", + inventory_image = "3d_armor_inv_chestplate_bronze.png", + groups = {armor_torso=15, armor_heal=6, armor_use=250}, + wear = 0, + }) + minetest.register_tool("3d_armor:leggings_bronze", { + description = "Bronze Leggings", + inventory_image = "3d_armor_inv_leggings_bronze.png", + groups = {armor_legs=15, armor_heal=6, armor_use=250}, + wear = 0, + }) + minetest.register_tool("3d_armor:boots_bronze", { + description = "Bronze Boots", + inventory_image = "3d_armor_inv_boots_bronze.png", + groups = {armor_feet=10, armor_heal=6, armor_use=250}, + wear = 0, + }) +end + +if ARMOR_MATERIALS.diamond then + minetest.register_tool("3d_armor:helmet_diamond", { + description = "Diamond Helmet", + inventory_image = "3d_armor_inv_helmet_diamond.png", + groups = {armor_head=15, armor_heal=12, armor_use=100}, + wear = 0, + }) + minetest.register_tool("3d_armor:chestplate_diamond", { + description = "Diamond Chestplate", + inventory_image = "3d_armor_inv_chestplate_diamond.png", + groups = {armor_torso=20, armor_heal=12, armor_use=100}, + wear = 0, + }) + minetest.register_tool("3d_armor:leggings_diamond", { + description = "Diamond Leggings", + inventory_image = "3d_armor_inv_leggings_diamond.png", + groups = {armor_legs=20, armor_heal=12, armor_use=100}, + wear = 0, + }) + minetest.register_tool("3d_armor:boots_diamond", { + description = "Diamond Boots", + inventory_image = "3d_armor_inv_boots_diamond.png", + groups = {armor_feet=15, armor_heal=12, armor_use=100}, + wear = 0, + }) +end + +if ARMOR_MATERIALS.gold then + minetest.register_tool("3d_armor:helmet_gold", { + description = "Gold Helmet", + inventory_image = "3d_armor_inv_helmet_gold.png", + groups = {armor_head=10, armor_heal=6, armor_use=250}, + wear = 0, + }) + minetest.register_tool("3d_armor:chestplate_gold", { + description = "Gold Chestplate", + inventory_image = "3d_armor_inv_chestplate_gold.png", + groups = {armor_torso=15, armor_heal=6, armor_use=250}, + wear = 0, + }) + minetest.register_tool("3d_armor:leggings_gold", { + description = "Gold Leggings", + inventory_image = "3d_armor_inv_leggings_gold.png", + groups = {armor_legs=15, armor_heal=6, armor_use=250}, + wear = 0, + }) + minetest.register_tool("3d_armor:boots_gold", { + description = "Gold Boots", + inventory_image = "3d_armor_inv_boots_gold.png", + groups = {armor_feet=10, armor_heal=6, armor_use=250}, + wear = 0, + }) +end + +if ARMOR_MATERIALS.mithril then + minetest.register_tool("3d_armor:helmet_mithril", { + description = "Mithril Helmet", + inventory_image = "3d_armor_inv_helmet_mithril.png", + groups = {armor_head=15, armor_heal=12, armor_use=50}, + wear = 0, + }) + minetest.register_tool("3d_armor:chestplate_mithril", { + description = "Mithril Chestplate", + inventory_image = "3d_armor_inv_chestplate_mithril.png", + groups = {armor_torso=20, armor_heal=12, armor_use=50}, + wear = 0, + }) + minetest.register_tool("3d_armor:leggings_mithril", { + description = "Mithril Leggings", + inventory_image = "3d_armor_inv_leggings_mithril.png", + groups = {armor_legs=20, armor_heal=12, armor_use=50}, + wear = 0, + }) + minetest.register_tool("3d_armor:boots_mithril", { + description = "Mithril Boots", + inventory_image = "3d_armor_inv_boots_mithril.png", + groups = {armor_feet=15, armor_heal=12, armor_use=50}, + wear = 0, + }) +end + +if ARMOR_MATERIALS.crystal then + minetest.register_tool("3d_armor:helmet_crystal", { + description = "Crystal Helmet", + inventory_image = "3d_armor_inv_helmet_crystal.png", + groups = {armor_head=15, armor_heal=12, armor_use=50, armor_fire=1}, + wear = 0, + }) + minetest.register_tool("3d_armor:chestplate_crystal", { + description = "Crystal Chestplate", + inventory_image = "3d_armor_inv_chestplate_crystal.png", + groups = {armor_torso=20, armor_heal=12, armor_use=50, armor_fire=1}, + wear = 0, + }) + minetest.register_tool("3d_armor:leggings_crystal", { + description = "Crystal Leggings", + inventory_image = "3d_armor_inv_leggings_crystal.png", + groups = {armor_legs=20, armor_heal=12, armor_use=50, armor_fire=1}, + wear = 0, + }) + minetest.register_tool("3d_armor:boots_crystal", { + description = "Crystal Boots", + inventory_image = "3d_armor_inv_boots_crystal.png", + groups = {armor_feet=15, armor_heal=12, armor_use=50, physics_speed=1, physics_jump=0.5, armor_fire=1}, + wear = 0, + }) +end + +for k, v in pairs(ARMOR_MATERIALS) do + minetest.register_craft({ + output = "3d_armor:helmet_"..k, + recipe = { + {v, v, v}, + {v, "", v}, + {"", "", ""}, + }, + }) + minetest.register_craft({ + output = "3d_armor:chestplate_"..k, + recipe = { + {v, "", v}, + {v, v, v}, + {v, v, v}, + }, + }) + minetest.register_craft({ + output = "3d_armor:leggings_"..k, + recipe = { + {v, v, v}, + {v, "", v}, + {v, "", v}, + }, + }) + minetest.register_craft({ + output = "3d_armor:boots_"..k, + recipe = { + {v, "", v}, + {v, "", v}, + }, + }) +end + diff --git a/3d_armor/init.lua b/3d_armor/init.lua index ec0d635..f32c865 100644 --- a/3d_armor/init.lua +++ b/3d_armor/init.lua @@ -1,254 +1,455 @@ ARMOR_MOD_NAME = minetest.get_current_modname() +ARMOR_INIT_DELAY = 1 +ARMOR_INIT_TIMES = 1 +ARMOR_BONES_DELAY = 1 +ARMOR_UPDATE_TIME = 1 +ARMOR_DROP = minetest.get_modpath("bones") ~= nil +ARMOR_DESTROY = false +ARMOR_LEVEL_MULTIPLIER = 1 +ARMOR_HEAL_MULTIPLIER = 1 +ARMOR_RADIATION_MULTIPLIER = 1 +ARMOR_MATERIALS = { + wood = "group:wood", + cactus = "default:cactus", + steel = "default:steel_ingot", + bronze = "default:bronze_ingot", + diamond = "default:diamond", + gold = "default:gold_ingot", + mithril = "moreores:mithril_ingot", + crystal = "ethereal:crystal_ingot", +} +ARMOR_FIRE_PROTECT = minetest.get_modpath("ethereal") ~= nil +ARMOR_FIRE_NODES = { + {"default:lava_source", 5, 8}, + {"default:lava_flowing", 5, 8}, + {"fire:basic_flame", 3, 4}, + {"fire:permanent_flame", 3, 4}, + {"ethereal:crystal_spike", 2, 1}, + {"ethereal:fire_flower", 2, 1}, + {"default:torch", 1, 1}, + {"default:torch_ceiling", 1, 1}, + {"default:torch_wall", 1, 1}, +} + +local modpath = minetest.get_modpath(ARMOR_MOD_NAME) +local worldpath = minetest.get_worldpath() +local input = io.open(modpath.."/armor.conf", "r") +if input then + dofile(modpath.."/armor.conf") + input:close() + input = nil +end +input = io.open(worldpath.."/armor.conf", "r") +if input then + dofile(worldpath.."/armor.conf") + input:close() + input = nil +end + +dofile(minetest.get_modpath(ARMOR_MOD_NAME).."/api.lua") dofile(minetest.get_modpath(ARMOR_MOD_NAME).."/armor.lua") -dofile(minetest.get_modpath(ARMOR_MOD_NAME).."/admin.lua") -if ARMOR_MATERIALS.wood then - minetest.register_tool("3d_armor:helmet_wood", { - description = "Wood Helmet", - inventory_image = "3d_armor_inv_helmet_wood.png", - groups = {armor_head=5, armor_heal=0, armor_use=2000}, - wear = 0, +-- Mod Compatibility + +local armor_formpage = "image[2.5,0;2,4;armor_preview]".. + default.gui_bg.. + default.gui_bg_img.. + default.gui_slots.. + default.get_hotbar_bg(0, 4.7).. + "label[5,1;Level: armor_level]".. + "label[5,1.5;Heal: armor_heal]".. + "list[current_player;main;0,4.7;8,1;]".. + "list[current_player;main;0,5.85;8,3;8]" +if ARMOR_FIRE_PROTECT then + armor_formpage = armor_formpage.."label[5,2;Fire: armor_fire]" +end +if minetest.global_exists("technic") then + armor_formpage = armor_formpage.."label[5,2.5;Radiation: armor_radiation]" +end +if minetest.get_modpath("inventory_plus") then + armor.inv_mod = "inventory_plus" + armor.formspec = "size[8,8.5]button[6,0;2,0.5;main;Back]"..armor_formpage + if minetest.get_modpath("crafting") then + inventory_plus.get_formspec = function(player, page) + end + end +elseif minetest.get_modpath("unified_inventory") and not unified_inventory.sfinv_compat_layer then + armor.inv_mod = "unified_inventory" + unified_inventory.register_button("armor", { + type = "image", + image = "inventory_plus_armor.png", }) - minetest.register_tool("3d_armor:chestplate_wood", { - description = "Wood Chestplate", - inventory_image = "3d_armor_inv_chestplate_wood.png", - groups = {armor_torso=10, armor_heal=0, armor_use=2000}, - wear = 0, + unified_inventory.register_page("armor", { + get_formspec = function(player, perplayer_formspec) + local fy = perplayer_formspec.formspec_y + local name = player:get_player_name() + local formspec = "background[0.06,"..fy..";7.92,7.52;3d_armor_ui_form.png]".. + "label[0,0;Armor]".. + "list[detached:"..name.."_armor;armor;0,"..fy..";2,3;]".. + "image[2.5,"..(fy - 0.25)..";2,4;"..armor.textures[name].preview.."]".. + "label[5.0,"..(fy + 0.0)..";Level: "..armor.def[name].level.."]".. + "label[5.0,"..(fy + 0.5)..";Heal: "..armor.def[name].heal.."]".. + "listring[current_player;main]".. + "listring[detached:"..name.."_armor;armor]" + if ARMOR_FIRE_PROTECT then + formspec = formspec.."label[5.0,"..(fy + 1.0).. + ";Fire: "..armor.def[name].fire.."]" + end + if minetest.global_exists("technic") then + formspec = formspec.."label[5.0,"..(fy + 1.5).. + ";Radiation: "..armor.def[name].radiation.."]" + end + return {formspec=formspec} + end, }) - minetest.register_tool("3d_armor:leggings_wood", { - description = "Wood Leggings", - inventory_image = "3d_armor_inv_leggings_wood.png", - groups = {armor_legs=5, armor_heal=0, armor_use=2000}, - wear = 0, - }) - minetest.register_tool("3d_armor:boots_wood", { - description = "Wood Boots", - inventory_image = "3d_armor_inv_boots_wood.png", - groups = {armor_feet=5, armor_heal=0, armor_use=2000}, - wear = 0, +elseif minetest.get_modpath("inventory_enhanced") then + armor.inv_mod = "inventory_enhanced" +elseif minetest.get_modpath("smart_inventory") then + armor.inv_mod = "smart_inventory" +elseif minetest.get_modpath("sfinv") then + armor.inv_mod = "sfinv" + armor.formspec = armor_formpage + sfinv.register_page("3d_armor:armor", { + title = "Armor", + get = function(self, player, context) + local name = player:get_player_name() + local formspec = armor:get_armor_formspec(name, true) + return sfinv.make_formspec(player, context, formspec, false) + end }) end - -if ARMOR_MATERIALS.cactus then - minetest.register_tool("3d_armor:helmet_cactus", { - description = "Cactus Helmet", - inventory_image = "3d_armor_inv_helmet_cactus.png", - groups = {armor_head=5, armor_heal=0, armor_use=1000}, - wear = 0, - }) - minetest.register_tool("3d_armor:chestplate_cactus", { - description = "Cactus Chestplate", - inventory_image = "3d_armor_inv_chestplate_cactus.png", - groups = {armor_torso=10, armor_heal=0, armor_use=1000}, - wear = 0, - }) - minetest.register_tool("3d_armor:leggings_cactus", { - description = "Cactus Leggings", - inventory_image = "3d_armor_inv_leggings_cactus.png", - groups = {armor_legs=5, armor_heal=0, armor_use=1000}, - wear = 0, - }) - minetest.register_tool("3d_armor:boots_cactus", { - description = "Cactus Boots", - inventory_image = "3d_armor_inv_boots_cactus.png", - groups = {armor_feet=5, armor_heal=0, armor_use=1000}, - wear = 0, - }) +local skin_mods = {"skins", "u_skins", "simple_skins", "wardrobe"} +for _, mod in pairs(skin_mods) do + local path = minetest.get_modpath(mod) + if path then + local dir_list = minetest.get_dir_list(path.."/textures") + for _, fn in pairs(dir_list) do + if fn:find("_preview.png$") then + armor:add_preview(fn) + end + end + armor.skin_mod = mod + end +end +if not minetest.get_modpath("moreores") then + ARMOR_MATERIALS.mithril = nil +end +if not minetest.get_modpath("ethereal") then + ARMOR_MATERIALS.crystal = nil end -if ARMOR_MATERIALS.steel then - minetest.register_tool("3d_armor:helmet_steel", { - description = "Steel Helmet", - inventory_image = "3d_armor_inv_helmet_steel.png", - groups = {armor_head=10, armor_heal=0, armor_use=500}, - wear = 0, - }) - minetest.register_tool("3d_armor:chestplate_steel", { - description = "Steel Chestplate", - inventory_image = "3d_armor_inv_chestplate_steel.png", - groups = {armor_torso=15, armor_heal=0, armor_use=500}, - wear = 0, - }) - minetest.register_tool("3d_armor:leggings_steel", { - description = "Steel Leggings", - inventory_image = "3d_armor_inv_leggings_steel.png", - groups = {armor_legs=15, armor_heal=0, armor_use=500}, - wear = 0, - }) - minetest.register_tool("3d_armor:boots_steel", { - description = "Steel Boots", - inventory_image = "3d_armor_inv_boots_steel.png", - groups = {armor_feet=10, armor_heal=0, armor_use=500}, - wear = 0, - }) +-- Armor Player Model + +default.player_register_model("3d_armor_character.b3d", { + animation_speed = 30, + textures = { + armor.default_skin..".png", + "3d_armor_trans.png", + "3d_armor_trans.png", + }, + animations = { + stand = {x=0, y=79}, + lay = {x=162, y=166}, + walk = {x=168, y=187}, + mine = {x=189, y=198}, + walk_mine = {x=200, y=219}, + sit = {x=81, y=160}, + }, +}) + +minetest.register_on_player_receive_fields(function(player, formname, fields) + local name = armor:get_valid_player(player, "[on_player_receive_fields]") + if not name or armor.inv_mod == "inventory_enhanced" then + return + end + if armor.inv_mod == "inventory_plus" and fields.armor then + local formspec = armor:get_armor_formspec(name, true) + inventory_plus.set_inventory_formspec(player, formspec) + return + end + for field, _ in pairs(fields) do + if string.find(field, "skins_set") then + minetest.after(0, function(player) + local skin = armor:get_player_skin(name) + armor.textures[name].skin = skin..".png" + armor:set_player_armor(player) + end, player) + end + end +end) + +minetest.register_on_joinplayer(function(player) + default.player_set_model(player, "3d_armor_character.b3d") + local name = player:get_player_name() + local player_inv = player:get_inventory() + local armor_inv = minetest.create_detached_inventory(name.."_armor", { + on_put = function(inv, listname, index, stack, player) + player:get_inventory():set_stack(listname, index, stack) + armor:set_player_armor(player) + armor:update_inventory(player) + end, + on_take = function(inv, listname, index, stack, player) + player:get_inventory():set_stack(listname, index, nil) + armor:set_player_armor(player) + armor:update_inventory(player) + end, + on_move = function(inv, from_list, from_index, to_list, to_index, count, player) + local plaver_inv = player:get_inventory() + local stack = inv:get_stack(to_list, to_index) + player_inv:set_stack(to_list, to_index, stack) + player_inv:set_stack(from_list, from_index, nil) + armor:set_player_armor(player) + armor:update_inventory(player) + end, + allow_put = function(inv, listname, index, stack, player) + return 1 + end, + allow_take = function(inv, listname, index, stack, player) + return stack:get_count() + end, + allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + return count + end, + }, name) + if armor.inv_mod == "inventory_plus" then + inventory_plus.register_button(player,"armor", "Armor") + end + armor_inv:set_size("armor", 6) + player_inv:set_size("armor", 6) + for i=1, 6 do + local stack = player_inv:get_stack("armor", i) + armor_inv:set_stack("armor", i, stack) + end + armor.def[name] = { + state = 0, + count = 0, + level = 0, + heal = 0, + jump = 1, + speed = 1, + gravity = 1, + fire = 0, + water = 0, + radiation = 0, + } + armor.textures[name] = { + skin = armor.default_skin..".png", + armor = "3d_armor_trans.png", + wielditem = "3d_armor_trans.png", + preview = armor.default_skin.."_preview.png", + } + if armor.skin_mod == "skins" then + local skin = skins.skins[name] + if skin and skins.get_type(skin) == skins.type.MODEL then + armor.textures[name].skin = skin..".png" + end + elseif armor.skin_mod == "simple_skins" then + local skin = skins.skins[name] + if skin then + armor.textures[name].skin = skin..".png" + end + elseif armor.skin_mod == "u_skins" then + local skin = u_skins.u_skins[name] + if skin and u_skins.get_type(skin) == u_skins.type.MODEL then + armor.textures[name].skin = skin..".png" + end + elseif armor.skin_mod == "wardrobe" then + local skin = wardrobe.playerSkins[name] + if skin then + armor.textures[name].skin = skin + end + end + local texture_path = minetest.get_modpath("player_textures") + if texture_path then + local dir_list = minetest.get_dir_list(texture_path.."/textures") + for _, fn in pairs(dir_list) do + if fn == "player_"..name..".png" then + armor.textures[name].skin = fn + break + end + end + end + for i=1, ARMOR_INIT_TIMES do + minetest.after(ARMOR_INIT_DELAY * i, function(player) + armor:set_player_armor(player) + if not armor.inv_mod then + armor:update_inventory(player) + end + end, player) + end +end) + +if ARMOR_DROP == true or ARMOR_DESTROY == true then + minetest.register_on_dieplayer(function(player) + local name, player_inv, armor_inv, pos = armor:get_valid_player(player, "[on_dieplayer]") + if not name then + return + end + local drop = {} + for i=1, player_inv:get_size("armor") do + local stack = armor_inv:get_stack("armor", i) + if stack:get_count() > 0 then + table.insert(drop, stack) + armor_inv:set_stack("armor", i, nil) + player_inv:set_stack("armor", i, nil) + end + end + armor:set_player_armor(player) + if armor.inv_mod == "unified_inventory" then + unified_inventory.set_inventory_formspec(player, "craft") + elseif armor.inv_mod == "inventory_plus" then + local formspec = inventory_plus.get_formspec(player,"main") + inventory_plus.set_inventory_formspec(player, formspec) + else + armor:update_inventory(player) + end + if ARMOR_DESTROY == false then + minetest.after(ARMOR_BONES_DELAY, function() + local meta = nil + local maxp = vector.add(pos, 8) + local minp = vector.subtract(pos, 8) + local bones = minetest.find_nodes_in_area(minp, maxp, {"bones:bones"}) + for _, p in pairs(bones) do + local m = minetest.get_meta(p) + if m:get_string("owner") == name then + meta = m + break + end + end + if meta then + local inv = meta:get_inventory() + for _,stack in ipairs(drop) do + if inv:room_for_item("main", stack) then + inv:add_item("main", stack) + else + armor.drop_armor(pos, stack) + end + end + else + for _,stack in ipairs(drop) do + armor.drop_armor(pos, stack) + end + end + end) + end + end) end -if ARMOR_MATERIALS.bronze then - minetest.register_tool("3d_armor:helmet_bronze", { - description = "Bronze Helmet", - inventory_image = "3d_armor_inv_helmet_bronze.png", - groups = {armor_head=10, armor_heal=6, armor_use=250}, - wear = 0, - }) - minetest.register_tool("3d_armor:chestplate_bronze", { - description = "Bronze Chestplate", - inventory_image = "3d_armor_inv_chestplate_bronze.png", - groups = {armor_torso=15, armor_heal=6, armor_use=250}, - wear = 0, - }) - minetest.register_tool("3d_armor:leggings_bronze", { - description = "Bronze Leggings", - inventory_image = "3d_armor_inv_leggings_bronze.png", - groups = {armor_legs=15, armor_heal=6, armor_use=250}, - wear = 0, - }) - minetest.register_tool("3d_armor:boots_bronze", { - description = "Bronze Boots", - inventory_image = "3d_armor_inv_boots_bronze.png", - groups = {armor_feet=10, armor_heal=6, armor_use=250}, - wear = 0, - }) +minetest.register_on_player_hpchange(function(player, hp_change) + local name, player_inv, armor_inv = armor:get_valid_player(player, "[on_hpchange]") + if name and hp_change < 0 then + + -- used for insta kill tools/commands like /kill (doesnt damage armor) + if hp_change < -100 then + return hp_change + end + + local heal_max = 0 + local state = 0 + local items = 0 + for i=1, 6 do + local stack = player_inv:get_stack("armor", i) + if stack:get_count() > 0 then + local use = stack:get_definition().groups["armor_use"] or 0 + local heal = stack:get_definition().groups["armor_heal"] or 0 + local item = stack:get_name() + stack:add_wear(use) + armor_inv:set_stack("armor", i, stack) + player_inv:set_stack("armor", i, stack) + state = state + stack:get_wear() + items = items + 1 + if stack:get_count() == 0 then + local desc = minetest.registered_items[item].description + if desc then + minetest.chat_send_player(name, "Your "..desc.." got destroyed!") + end + armor:set_player_armor(player) + armor:update_inventory(player) + end + heal_max = heal_max + heal + end + end + armor.def[name].state = state + armor.def[name].count = items + heal_max = heal_max * ARMOR_HEAL_MULTIPLIER + if heal_max > math.random(100) then + hp_change = 0 + end + end + return hp_change +end, true) + +-- Fire Protection and water breating, added by TenPlus1 + +if ARMOR_FIRE_PROTECT == true then + -- override hot nodes so they do not hurt player anywhere but mod + for _, row in pairs(ARMOR_FIRE_NODES) do + if minetest.registered_nodes[row[1]] then + minetest.override_item(row[1], {damage_per_second = 0}) + end + end +else + print ("[3d_armor] Fire Nodes disabled") end -if ARMOR_MATERIALS.diamond then - minetest.register_tool("3d_armor:helmet_diamond", { - description = "Diamond Helmet", - inventory_image = "3d_armor_inv_helmet_diamond.png", - groups = {armor_head=15, armor_heal=12, armor_use=100}, - wear = 0, - }) - minetest.register_tool("3d_armor:chestplate_diamond", { - description = "Diamond Chestplate", - inventory_image = "3d_armor_inv_chestplate_diamond.png", - groups = {armor_torso=20, armor_heal=12, armor_use=100}, - wear = 0, - }) - minetest.register_tool("3d_armor:leggings_diamond", { - description = "Diamond Leggings", - inventory_image = "3d_armor_inv_leggings_diamond.png", - groups = {armor_legs=20, armor_heal=12, armor_use=100}, - wear = 0, - }) - minetest.register_tool("3d_armor:boots_diamond", { - description = "Diamond Boots", - inventory_image = "3d_armor_inv_boots_diamond.png", - groups = {armor_feet=15, armor_heal=12, armor_use=100}, - wear = 0, - }) -end +minetest.register_globalstep(function(dtime) + armor.timer = armor.timer + dtime + if armor.timer < ARMOR_UPDATE_TIME then + return + end + for _,player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local pos = player:getpos() + local hp = player:get_hp() + -- water breathing + if name and armor.def[name].water > 0 then + if player:get_breath() < 10 then + player:set_breath(10) + end + end + -- fire protection + if ARMOR_FIRE_PROTECT == true + and name and pos and hp then + pos.y = pos.y + 1.4 -- head level + local node_head = minetest.get_node(pos).name + pos.y = pos.y - 1.2 -- feet level + local node_feet = minetest.get_node(pos).name + -- is player inside a hot node? + for _, row in pairs(ARMOR_FIRE_NODES) do + -- check fire protection, if not enough then get hurt + if row[1] == node_head or row[1] == node_feet then + if hp > 0 and armor.def[name].fire < row[2] then + hp = hp - row[3] * ARMOR_UPDATE_TIME + player:set_hp(hp) + break + end + end + end + end + end + armor.timer = 0 +end) -if ARMOR_MATERIALS.gold then - minetest.register_tool("3d_armor:helmet_gold", { - description = "Gold Helmet", - inventory_image = "3d_armor_inv_helmet_gold.png", - groups = {armor_head=10, armor_heal=6, armor_use=250}, - wear = 0, - }) - minetest.register_tool("3d_armor:chestplate_gold", { - description = "Gold Chestplate", - inventory_image = "3d_armor_inv_chestplate_gold.png", - groups = {armor_torso=15, armor_heal=6, armor_use=250}, - wear = 0, - }) - minetest.register_tool("3d_armor:leggings_gold", { - description = "Gold Leggings", - inventory_image = "3d_armor_inv_leggings_gold.png", - groups = {armor_legs=15, armor_heal=6, armor_use=250}, - wear = 0, - }) - minetest.register_tool("3d_armor:boots_gold", { - description = "Gold Boots", - inventory_image = "3d_armor_inv_boots_gold.png", - groups = {armor_feet=10, armor_heal=6, armor_use=250}, - wear = 0, - }) -end +-- kill player when command issued -if ARMOR_MATERIALS.mithril then - minetest.register_tool("3d_armor:helmet_mithril", { - description = "Mithril Helmet", - inventory_image = "3d_armor_inv_helmet_mithril.png", - groups = {armor_head=15, armor_heal=12, armor_use=50}, - wear = 0, - }) - minetest.register_tool("3d_armor:chestplate_mithril", { - description = "Mithril Chestplate", - inventory_image = "3d_armor_inv_chestplate_mithril.png", - groups = {armor_torso=20, armor_heal=12, armor_use=50}, - wear = 0, - }) - minetest.register_tool("3d_armor:leggings_mithril", { - description = "Mithril Leggings", - inventory_image = "3d_armor_inv_leggings_mithril.png", - groups = {armor_legs=20, armor_heal=12, armor_use=50}, - wear = 0, - }) - minetest.register_tool("3d_armor:boots_mithril", { - description = "Mithril Boots", - inventory_image = "3d_armor_inv_boots_mithril.png", - groups = {armor_feet=15, armor_heal=12, armor_use=50}, - wear = 0, - }) -end - -if ARMOR_MATERIALS.crystal then - minetest.register_tool("3d_armor:helmet_crystal", { - description = "Crystal Helmet", - inventory_image = "3d_armor_inv_helmet_crystal.png", - groups = {armor_head=15, armor_heal=12, armor_use=50, armor_fire=1}, - wear = 0, - }) - minetest.register_tool("3d_armor:chestplate_crystal", { - description = "Crystal Chestplate", - inventory_image = "3d_armor_inv_chestplate_crystal.png", - groups = {armor_torso=20, armor_heal=12, armor_use=50, armor_fire=1}, - wear = 0, - }) - minetest.register_tool("3d_armor:leggings_crystal", { - description = "Crystal Leggings", - inventory_image = "3d_armor_inv_leggings_crystal.png", - groups = {armor_legs=20, armor_heal=12, armor_use=50, armor_fire=1}, - wear = 0, - }) - minetest.register_tool("3d_armor:boots_crystal", { - description = "Crystal Boots", - inventory_image = "3d_armor_inv_boots_crystal.png", - groups = {armor_feet=15, armor_heal=12, armor_use=50, physics_speed=1, physics_jump=0.5, armor_fire=1}, - wear = 0, - }) -end - -for k, v in pairs(ARMOR_MATERIALS) do - minetest.register_craft({ - output = "3d_armor:helmet_"..k, - recipe = { - {v, v, v}, - {v, "", v}, - {"", "", ""}, - }, - }) - minetest.register_craft({ - output = "3d_armor:chestplate_"..k, - recipe = { - {v, "", v}, - {v, v, v}, - {v, v, v}, - }, - }) - minetest.register_craft({ - output = "3d_armor:leggings_"..k, - recipe = { - {v, v, v}, - {v, "", v}, - {v, "", v}, - }, - }) - minetest.register_craft({ - output = "3d_armor:boots_"..k, - recipe = { - {v, "", v}, - {v, "", v}, - }, - }) -end +minetest.register_chatcommand("kill", { + params = "", + description = "Kills player instantly", + privs = {ban=true}, + func = function(name, param) + local player = minetest.get_player_by_name(param) + if player then + player:set_hp(0) + end + end, +}) +minetest.register_chatcommand("killme", { + description = "Kill yourself instantly", + func = function(name) + local player = minetest.get_player_by_name(name) + if player then + player:set_hp(-1001) + end + end, +})