1
0
mirror of https://github.com/minetest-mods/3d_armor.git synced 2025-06-29 06:40:41 +02:00

17 Commits

Author SHA1 Message Date
656bcf30bc Bump version to 0.4.12 2018-06-10 19:39:38 +01:00
579e64a5e7 Code tidy 2018-06-02 22:13:41 +01:00
6f99803d2d Return invalid items in singleplayer mode 2018-06-02 20:46:44 +01:00
f960fc1a41 Only validate armor inventory after user changes 2018-06-02 18:59:32 +01:00
af4a381433 Update screenshot image 2018-05-24 19:25:34 +01:00
1f11a28ad4 More armor callback fixes 2018-05-24 19:06:27 +01:00
a5ddc3e60a Move comment :) 2018-05-23 21:40:06 +01:00
83f3e01efa Run callbacks based on validated inventory 2018-05-23 20:15:09 +01:00
7d30bc25a3 Allow replacing similar armor in the same slot 2018-05-22 18:40:24 +01:00
e4b12558d4 Ammendment to 21b5c68505 2018-05-19 21:35:15 +01:00
21b5c68505 Validate and clean armor inventory before saving 2018-05-19 20:25:27 +01:00
21716ffd31 Display correct heal attribute level, fixes #137 2018-05-13 16:52:29 +01:00
cc6fff2b04 Shields: Fix positional sound effects 2018-05-13 16:31:51 +01:00
4210cafff3 add POVA support (#138)
* add POVA support

Add support for POVA player overrides.

* add POVA support

Add support for POVA player overrides.
2018-05-07 14:41:40 +01:00
579d245a00 Fix crash with UI but no technic 2018-02-23 18:00:43 +00:00
c812e0ac56 Shields: Add option to disable sound effects 2018-02-18 20:35:49 +00:00
4baed2ca22 Remove on_punch effects from admin armor, closes #131 2018-02-18 20:24:35 +00:00
8 changed files with 122 additions and 73 deletions

View File

@ -4,6 +4,7 @@ local S = armor_i18n.gettext
local skin_previews = {} local skin_previews = {}
local use_player_monoids = minetest.global_exists("player_monoids") local use_player_monoids = minetest.global_exists("player_monoids")
local use_armor_monoid = minetest.global_exists("armor_monoid") local use_armor_monoid = minetest.global_exists("armor_monoid")
local use_pova_mod = minetest.get_modpath("pova")
local armor_def = setmetatable({}, { local armor_def = setmetatable({}, {
__index = function() __index = function()
return setmetatable({ return setmetatable({
@ -73,7 +74,7 @@ armor = {
on_destroy = {}, on_destroy = {},
}, },
migrate_old_inventory = true, migrate_old_inventory = true,
version = "0.4.11", version = "0.4.12",
} }
armor.config = { armor.config = {
@ -269,7 +270,8 @@ armor.set_player_armor = function(self, player)
change[group] = groups[group] / base change[group] = groups[group] / base
end end
for _, attr in pairs(self.attributes) do for _, attr in pairs(self.attributes) do
self.def[name][attr] = attributes[attr] local mult = attr == "heal" and self.config.heal_multiplier or 1
self.def[name][attr] = attributes[attr] * mult
end end
for _, phys in pairs(self.physics) do for _, phys in pairs(self.physics) do
self.def[name][phys] = physics[phys] self.def[name][phys] = physics[phys]
@ -286,6 +288,14 @@ armor.set_player_armor = function(self, player)
"3d_armor:physics") "3d_armor:physics")
player_monoids.gravity:add_change(player, physics.gravity, player_monoids.gravity:add_change(player, physics.gravity,
"3d_armor:physics") "3d_armor:physics")
elseif use_pova_mod then
-- only add the changes, not the default 1.0 for each physics setting
pova.add_override(name, "3d_armor", {
speed = physics.speed - 1,
jump = physics.jump - 1,
gravity = physics.gravity - 1,
})
pova.do_override(player)
else else
player:set_physics_override(physics) player:set_physics_override(physics)
end end
@ -428,6 +438,14 @@ armor.get_armor_formspec = function(self, name, listring)
return formspec return formspec
end end
armor.get_element = function(self, item_name)
for _, element in pairs(armor.elements) do
if minetest.get_item_group(item_name, "armor_"..element) > 0 then
return element
end
end
end
armor.serialize_inventory_list = function(self, list) armor.serialize_inventory_list = function(self, list)
local list_table = {} local list_table = {}
for _, stack in ipairs(list) do for _, stack in ipairs(list) do
@ -446,37 +464,23 @@ armor.deserialize_inventory_list = function(self, list_string)
end end
armor.load_armor_inventory = function(self, player) armor.load_armor_inventory = function(self, player)
local msg = "[load_armor_inventory]" local _, inv = self:get_valid_player(player, "[load_armor_inventory]")
local name = player:get_player_name() if inv then
if not name then
minetest.log("warning", S("3d_armor: Player name is nil @1", msg))
return
end
local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
if not armor_inv then
minetest.log("warning", S("3d_armor: Detached armor inventory is nil @1", msg))
return
end
local armor_list_string = player:get_attribute("3d_armor_inventory") local armor_list_string = player:get_attribute("3d_armor_inventory")
if armor_list_string then if armor_list_string then
armor_inv:set_list("armor", self:deserialize_inventory_list(armor_list_string)) inv:set_list("armor",
self:deserialize_inventory_list(armor_list_string))
return true return true
end end
end
end end
armor.save_armor_inventory = function(self, player) armor.save_armor_inventory = function(self, player)
local msg = "[save_armor_inventory]" local _, inv = self:get_valid_player(player, "[save_armor_inventory]")
local name = player:get_player_name() if inv then
if not name then player:set_attribute("3d_armor_inventory",
minetest.log("warning", S("3d_armor: Player name is nil @1", msg)) self:serialize_inventory_list(inv:get_list("armor")))
return
end end
local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
if not armor_inv then
minetest.log("warning", S("3d_armor: Detached armor inventory is nil @1", msg))
return
end
player:set_attribute("3d_armor_inventory", self:serialize_inventory_list(armor_inv:get_list("armor")))
end end
armor.update_inventory = function(self, player) armor.update_inventory = function(self, player)
@ -484,19 +488,11 @@ armor.update_inventory = function(self, player)
end end
armor.set_inventory_stack = function(self, player, i, stack) armor.set_inventory_stack = function(self, player, i, stack)
local msg = "[set_inventory_stack]" local _, inv = self:get_valid_player(player, "[set_inventory_stack]")
local name = player:get_player_name() if inv then
if not name then inv:set_stack("armor", i, stack)
minetest.log("warning", S("3d_armor: Player name is nil @1", msg))
return
end
local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"})
if not armor_inv then
minetest.log("warning", S("3d_armor: Detached armor inventory is nil @1", msg))
return
end
armor_inv:set_stack("armor", i, stack)
self:save_armor_inventory(player) self:save_armor_inventory(player)
end
end end
armor.get_valid_player = function(self, player, msg) armor.get_valid_player = function(self, player, msg)

View File

@ -1,6 +1,7 @@
default default
player_monoids? player_monoids?
armor_monoid? armor_monoid?
pova?
fire? fire?
ethereal? ethereal?
bakedclay? bakedclay?

View File

@ -109,6 +109,57 @@ armor:register_on_destroy(function(player, index, stack)
end end
end) end)
local function validate_armor_inventory(player)
-- Workaround for detached inventory swap exploit
local _, inv = armor:get_valid_player(player, "[validate_armor_inventory]")
if not inv then
return
end
local armor_prev = {}
local armor_list_string = player:get_attribute("3d_armor_inventory")
if armor_list_string then
local armor_list = armor:deserialize_inventory_list(armor_list_string)
for i, stack in ipairs(armor_list) do
if stack:get_count() > 0 then
armor_prev[stack:get_name()] = i
end
end
end
local elements = {}
local player_inv = player:get_inventory()
for i = 1, 6 do
local stack = inv:get_stack("armor", i)
if stack:get_count() > 0 then
local item = stack:get_name()
local element = armor:get_element(item)
if element and not elements[element] then
if armor_prev[item] then
armor_prev[item] = nil
else
-- Item was not in previous inventory
armor:run_callbacks("on_equip", player, i, stack)
end
elements[element] = true;
else
inv:remove_item("armor", stack)
-- The following code returns invalid items to the player's main
-- inventory but could open up the possibity for a hacked client
-- to receive items back they never really had. I am not certain
-- so remove the is_singleplayer check at your own risk :]
if minetest.is_singleplayer() and player_inv and
player_inv:room_for_item("main", stack) then
player_inv:add_item("main", stack)
end
end
end
end
for item, i in pairs(armor_prev) do
local stack = ItemStack(item)
-- Previous item is not in current inventory
armor:run_callbacks("on_unequip", player, i, stack)
end
end
local function init_player_armor(player) local function init_player_armor(player)
local name = player:get_player_name() local name = player:get_player_name()
local pos = player:getpos() local pos = player:getpos()
@ -117,34 +168,34 @@ local function init_player_armor(player)
end end
local armor_inv = minetest.create_detached_inventory(name.."_armor", { local armor_inv = minetest.create_detached_inventory(name.."_armor", {
on_put = function(inv, listname, index, stack, player) on_put = function(inv, listname, index, stack, player)
validate_armor_inventory(player)
armor:save_armor_inventory(player) armor:save_armor_inventory(player)
armor:run_callbacks("on_equip", player, index, stack)
armor:set_player_armor(player) armor:set_player_armor(player)
end, end,
on_take = function(inv, listname, index, stack, player) on_take = function(inv, listname, index, stack, player)
validate_armor_inventory(player)
armor:save_armor_inventory(player) armor:save_armor_inventory(player)
armor:run_callbacks("on_unequip", player, index, stack)
armor:set_player_armor(player) armor:set_player_armor(player)
end, end,
on_move = function(inv, from_list, from_index, to_list, to_index, count, player) on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
validate_armor_inventory(player)
armor:save_armor_inventory(player) armor:save_armor_inventory(player)
armor:set_player_armor(player) armor:set_player_armor(player)
end, end,
allow_put = function(inv, listname, index, stack, player) allow_put = function(inv, listname, index, put_stack, player)
local def = stack:get_definition() or {} local element = armor:get_element(put_stack:get_name())
local allowed = 0 if not element then
for _, element in pairs(armor.elements) do return 0
if def.groups["armor_"..element] then end
allowed = 1
for i = 1, 6 do for i = 1, 6 do
local item = inv:get_stack("armor", i):get_name() local stack = inv:get_stack("armor", i)
if minetest.get_item_group(item, "armor_"..element) > 0 then local def = stack:get_definition() or {}
if def.groups and def.groups["armor_"..element]
and i ~= index then
return 0 return 0
end end
end end
end return 1
end
return allowed
end, end,
allow_take = function(inv, listname, index, stack, player) allow_take = function(inv, listname, index, stack, player)
return stack:get_count() return stack:get_count()
@ -166,8 +217,10 @@ local function init_player_armor(player)
end end
for i=1, 6 do for i=1, 6 do
local stack = armor_inv:get_stack("armor", i) local stack = armor_inv:get_stack("armor", i)
if stack:get_count() > 0 then
armor:run_callbacks("on_equip", player, i, stack) armor:run_callbacks("on_equip", player, i, stack)
end end
end
armor.def[name] = { armor.def[name] = {
init_time = minetest.get_gametime(), init_time = minetest.get_gametime(),
level = 0, level = 0,
@ -269,10 +322,11 @@ if armor.config.drop == true or armor.config.destroy == true then
local stack = armor_inv:get_stack("armor", i) local stack = armor_inv:get_stack("armor", i)
if stack:get_count() > 0 then if stack:get_count() > 0 then
table.insert(drop, stack) table.insert(drop, stack)
armor:set_inventory_stack(player, i, nil)
armor:run_callbacks("on_unequip", player, i, stack) armor:run_callbacks("on_unequip", player, i, stack)
armor_inv:set_stack("armor", i, nil)
end end
end end
armor:save_armor_inventory(player)
armor:set_player_armor(player) armor:set_player_armor(player)
local pos = player:getpos() local pos = player:getpos()
if pos and armor.config.destroy == false then if pos and armor.config.destroy == false then
@ -323,7 +377,6 @@ minetest.register_on_player_hpchange(function(player, hp_change)
local name = player:get_player_name() local name = player:get_player_name()
if name then if name then
local heal = armor.def[name].heal local heal = armor.def[name].heal
heal = heal * armor.config.heal_multiplier
if heal >= math.random(100) then if heal >= math.random(100) then
hp_change = 0 hp_change = 0
end end

View File

@ -1,6 +1,7 @@
-- support for i18n -- support for i18n
local S = armor_i18n.gettext local S = armor_i18n.gettext
local F = armor_i18n.fgettext local F = armor_i18n.fgettext
local has_technic = minetest.get_modpath("technic") ~= nil
if not minetest.global_exists("unified_inventory") then if not minetest.global_exists("unified_inventory") then
minetest.log("warning", S("3d_armor_ui: Mod loaded but unused.")) minetest.log("warning", S("3d_armor_ui: Mod loaded but unused."))
@ -43,7 +44,7 @@ unified_inventory.register_page("armor", {
formspec = formspec.."label[5.0,"..(fy + 1.0)..";".. formspec = formspec.."label[5.0,"..(fy + 1.0)..";"..
F("Fire")..": "..armor.def[name].fire.."]" F("Fire")..": "..armor.def[name].fire.."]"
end end
if minetest.global_exists("technic") then if has_technic then
formspec = formspec.."label[5.0,"..(fy + 1.5)..";".. formspec = formspec.."label[5.0,"..(fy + 1.5)..";"..
F("Radiation")..": "..armor.def[name].groups["radiation"].."]" F("Radiation")..": "..armor.def[name].groups["radiation"].."]"
end end

View File

@ -1,4 +1,4 @@
Modpack - 3d Armor [0.4.11] Modpack - 3d Armor [0.4.12]
=========================== ===========================
### Table of Contents ### Table of Contents
@ -17,7 +17,7 @@ Modpack - 3d Armor [0.4.11]
[mod] Visible Player Armor [3d_armor] [mod] Visible Player Armor [3d_armor]
------------------------------------- -------------------------------------
Minetest Version: 0.4.16 Minetest Version: 0.4.16 - 0.4.17.1
Game: minetest_game and many derivatives Game: minetest_game and many derivatives

Binary file not shown.

Before

Width:  |  Height:  |  Size: 145 KiB

After

Width:  |  Height:  |  Size: 65 KiB

View File

@ -7,3 +7,10 @@ Depends: 3d_armor
Originally a part of 3d_armor, shields have been re-included as an optional extra. Originally a part of 3d_armor, shields have been re-included as an optional extra.
If you do not what shields then simply remove the shields folder from the modpack. If you do not what shields then simply remove the shields folder from the modpack.
Shields Configuration
---------------------
Override the following default settings by adding them to your minetest.conf file.
shields_disable_sounds = false

View File

@ -1,14 +1,14 @@
-- support for i18n -- support for i18n
local S = armor_i18n.gettext local S = armor_i18n.gettext
local disable_sounds = minetest.settings:get_bool("shields_disable_sounds")
local use_moreores = minetest.get_modpath("moreores") local use_moreores = minetest.get_modpath("moreores")
local function play_sound_effect(player, name) local function play_sound_effect(player, name)
if player then if not disable_sounds and player then
local pos = player:getpos() local pos = player:getpos()
if pos then if pos then
minetest.sound_play({ minetest.sound_play(name, {
pos = pos, pos = pos,
name = name,
max_hear_distance = 10, max_hear_distance = 10,
gain = 0.5, gain = 0.5,
}) })
@ -28,15 +28,6 @@ armor:register_armor("shields:shield_admin", {
description = S("Admin Shield"), description = S("Admin Shield"),
inventory_image = "shields_inv_shield_admin.png", inventory_image = "shields_inv_shield_admin.png",
groups = {armor_shield=1000, armor_heal=100, armor_use=0, not_in_creative_inventory=1}, groups = {armor_shield=1000, armor_heal=100, armor_use=0, not_in_creative_inventory=1},
on_punched = function(player, hitter, time_from_last_punch, tool_capabilities)
if type(hitter) == "userdata" then
if hitter:is_player() then
hitter:set_wielded_item("")
end
play_sound_effect(player, "default_dig_metal")
end
return false
end,
}) })
minetest.register_alias("adminshield", "shields:shield_admin") minetest.register_alias("adminshield", "shields:shield_admin")