2 Commits

Author SHA1 Message Date
96b12b9dea Add immortal and fall_damage_add_percent armor groups (#3)
This change adds special handling for these armor groups, ensuring that their default values will remain as they are while also allowing mods to manage these groups via Armor Monoid.
Beware that the value range does not exactly correspond to the Luanti-provided API.
2025-04-16 19:24:11 +02:00
c5c43514f4 remove 3d_armor compatibility stuff 2017-03-05 15:30:12 -08:00
4 changed files with 65 additions and 123 deletions

View File

@ -1,11 +0,0 @@
3D Armor - Visible Player Armor
===============================
Default Item Textures (C) Cisoun - WTFPL
Armor Textures: Copyright (C) 2013 Ryan Jones - CC-BY-SA
Source Code: Copyright (C) 2013 Stuart Jones - LGPL
Special credit to Jordach and MirceaKitsune for providing the default 3d character model.

View File

@ -2,7 +2,7 @@
This mod provides a player_monoids monoid for handling armor groups. It
provides a monoid for damage resistance, and a way to register new damage types
for players. It is also compatible with 3d_armor.
for players.
Using the monoid
================
@ -28,4 +28,53 @@ armor_monoid.register_armor_group("arcane", 100)
<br/>
As you can see, the argument is not a multiplier, but the base armor group
rating. Calling this would mean players start off with an armor rating in
"arcane" of 100 (no protection).
"arcane" of 100 (no protection).
Special armor groups
====================
Luanti defines a number of [special armor groups](https://github.com/luanti-org/luanti/blob/master/doc/lua_api.md#objectref-armor-groups)
that have an engine-based effect and therefore must be handled uniquely by this
monoid.
`fall_damage_add_percent`
-------------------------
The `fall_damage_add_percent` armor group controls how much additional damage
that a player will incur when falling from a high height. The armor monoid
handles this group exactly like normal armor groups that have a base value of
100.
The armor monoid uses the following range of values for the
`fall_damage_add_percent` armor group:
- `value = 100`: player takes normal fall damage (100%)
- `value = 0`: player takes no fall damage (0%)
- `value = X`: player takes X% less fall damage (1%-99%)
- default value: 100
To grant a player fall damage reduction, use the `fall_damage_add_percent` group
as you would any normal armor group:
```lua
armor_monoid.monoid:add_change(player,{fall_damage_add_percent=0.5},"mymod:half_fall_damage")
```
`immortal`
----------
The `immortal` armor group controls whether or not a player can suffer damage
and experience drowning. Due to limitations of this monoid, the values of this
armor group are handled differently than most armor groups.
The armor monoid uses the following values for the `immortal` armor group:
- `value <= 1`: player is not immortal, subject to damage and drowning
- `value > 1`: player is immortal, will not suffer damage and cannot drown
- default value: 1
To grant a player immortality, set this group to a value greater than 1 like so:
```lua
armor_monoid.monoid:add_change(player,{immortal=2},"mymod:immortality")
```

View File

@ -1,2 +1 @@
player_monoids
3d_armor?

123
init.lua
View File

@ -1,7 +1,11 @@
armor_monoid = {}
local armor_groups = { fleshy = 100 }
local armor_groups = {
fleshy = 100,
fall_damage_add_percent = 100,
immortal = 1,
}
armor_monoid.registered_groups = armor_groups
@ -71,6 +75,15 @@ armor_monoid.monoid = player_monoids.make_monoid({
end
end
-- fall_damage_add_percent is a special armor group that has an inherent
-- value of 0 rather than 100, so its final value is offset by -100 here
final.fall_damage_add_percent = final.fall_damage_add_percent - 100
-- immortal is a special armor group that must be either 0 or 1 to indicate
-- mortality or immortality, respectively, so its final value is constrained
-- here
final.immortal = final.immortal > 1 and 1 or 0
join_handled[player:get_player_name()] = true
player:set_armor_groups(final)
@ -96,111 +109,3 @@ end)
function armor_monoid.register_armor_group(name, def)
armor_groups[name] = def
end
if not minetest.global_exists("armor") then return end
-- Armor override
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 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) or "character_preview.png"
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)
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
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
end
armor_monoid.monoid:del_change(player, "armor_monoid:compat")
player_monoids.speed:del_change(player, "armor_monoid:compat")
player_monoids.jump:del_change(player, "armor_monoid:compat")
player_monoids.gravity:del_change(player, "armor_monoid:compat")
armor_monoid.monoid:add_change(player, { fleshy = armor_groups.fleshy / 100 },
"armor_monoid:compat")
player_monoids.speed:add_change(player, physics_o.speed,
"armor_monoid:compat")
player_monoids.jump:add_change(player, physics_o.jump,
"armor_monoid:compat")
player_monoids.gravity:add_change(player, physics_o.gravity,
"armor_monoid:compat")
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:update_player_visuals(player)
end