Modifying fall damage via armor group (#11080)

Adds a new fall_damage_add_percent armor group which influences the fall damage in addition to the existing node group.
This commit is contained in:
Wuzzy 2021-04-11 15:09:37 +00:00 committed by GitHub
parent 0abc1e98ed
commit 4b8209d9a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 9 deletions

@ -1730,7 +1730,15 @@ to games.
* `3`: the node always gets the digging time 0 seconds (torch) * `3`: the node always gets the digging time 0 seconds (torch)
* `disable_jump`: Player (and possibly other things) cannot jump from node * `disable_jump`: Player (and possibly other things) cannot jump from node
or if their feet are in the node. Note: not supported for `new_move = false` or if their feet are in the node. Note: not supported for `new_move = false`
* `fall_damage_add_percent`: damage speed = `speed * (1 + value/100)` * `fall_damage_add_percent`: modifies the fall damage suffered when hitting
the top of this node. There's also an armor group with the same name.
The final player damage is determined by the following formula:
damage =
collision speed
* ((node_fall_damage_add_percent + 100) / 100) -- node group
* ((player_fall_damage_add_percent + 100) / 100) -- player armor group
- (14) -- constant tolerance
Negative damage values are discarded as no damage.
* `falling_node`: if there is no walkable block under the node it will fall * `falling_node`: if there is no walkable block under the node it will fall
* `float`: the node will not fall through liquids * `float`: the node will not fall through liquids
* `level`: Can be used to give an additional sense of progression in the game. * `level`: Can be used to give an additional sense of progression in the game.
@ -1750,12 +1758,15 @@ to games.
`"toolrepair"` crafting recipe `"toolrepair"` crafting recipe
### `ObjectRef` groups ### `ObjectRef` armor groups
* `immortal`: Skips all damage and breath handling for an object. This group * `immortal`: Skips all damage and breath handling for an object. This group
will also hide the integrated HUD status bars for players. It is will also hide the integrated HUD status bars for players. It is
automatically set to all players when damage is disabled on the server and automatically set to all players when damage is disabled on the server and
cannot be reset (subject to change). cannot be reset (subject to change).
* `fall_damage_add_percent`: Modifies the fall damage suffered by players
when they hit the ground. It is analog to the node group with the same
name. See the node group above for the exact calculation.
* `punch_operable`: For entities; disables the regular damage mechanism for * `punch_operable`: For entities; disables the regular damage mechanism for
players punching it by hand or a non-tool item, so that it can do something players punching it by hand or a non-tool item, so that it can do something
else than take damage. else than take damage.

@ -235,7 +235,16 @@ void ClientEnvironment::step(float dtime)
&player_collisions); &player_collisions);
} }
bool player_immortal = lplayer->getCAO() && lplayer->getCAO()->isImmortal(); bool player_immortal = false;
f32 player_fall_factor = 1.0f;
GenericCAO *playercao = lplayer->getCAO();
if (playercao) {
player_immortal = playercao->isImmortal();
int addp_p = itemgroup_get(playercao->getGroups(),
"fall_damage_add_percent");
// convert armor group into an usable fall damage factor
player_fall_factor = 1.0f + (float)addp_p / 100.0f;
}
for (const CollisionInfo &info : player_collisions) { for (const CollisionInfo &info : player_collisions) {
v3f speed_diff = info.new_speed - info.old_speed;; v3f speed_diff = info.new_speed - info.old_speed;;
@ -248,17 +257,20 @@ void ClientEnvironment::step(float dtime)
speed_diff.Z = 0; speed_diff.Z = 0;
f32 pre_factor = 1; // 1 hp per node/s f32 pre_factor = 1; // 1 hp per node/s
f32 tolerance = BS*14; // 5 without damage f32 tolerance = BS*14; // 5 without damage
f32 post_factor = 1; // 1 hp per node/s
if (info.type == COLLISION_NODE) { if (info.type == COLLISION_NODE) {
const ContentFeatures &f = m_client->ndef()-> const ContentFeatures &f = m_client->ndef()->
get(m_map->getNode(info.node_p)); get(m_map->getNode(info.node_p));
// Determine fall damage multiplier // Determine fall damage modifier
int addp = itemgroup_get(f.groups, "fall_damage_add_percent"); int addp_n = itemgroup_get(f.groups, "fall_damage_add_percent");
pre_factor = 1.0f + (float)addp / 100.0f; // convert node group to an usable fall damage factor
f32 node_fall_factor = 1.0f + (float)addp_n / 100.0f;
// combine both player fall damage modifiers
pre_factor = node_fall_factor * player_fall_factor;
} }
float speed = pre_factor * speed_diff.getLength(); float speed = pre_factor * speed_diff.getLength();
if (speed > tolerance && !player_immortal) {
f32 damage_f = (speed - tolerance) / BS * post_factor; if (speed > tolerance && !player_immortal && pre_factor > 0.0f) {
f32 damage_f = (speed - tolerance) / BS;
u16 damage = (u16)MYMIN(damage_f + 0.5, U16_MAX); u16 damage = (u16)MYMIN(damage_f + 0.5, U16_MAX);
if (damage != 0) { if (damage != 0) {
damageLocalPlayer(damage, true); damageLocalPlayer(damage, true);