From 4b8209d9a44425156ba89a4763f63ea088daccb3 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Sun, 11 Apr 2021 15:09:37 +0000 Subject: [PATCH] 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. --- doc/lua_api.txt | 15 +++++++++++++-- src/client/clientenvironment.cpp | 26 +++++++++++++++++++------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index 6c1e46c7e..7d413a9e9 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -1730,7 +1730,15 @@ to games. * `3`: the node always gets the digging time 0 seconds (torch) * `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` -* `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 * `float`: the node will not fall through liquids * `level`: Can be used to give an additional sense of progression in the game. @@ -1750,12 +1758,15 @@ to games. `"toolrepair"` crafting recipe -### `ObjectRef` groups +### `ObjectRef` armor groups * `immortal`: Skips all damage and breath handling for an object. This group 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 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 players punching it by hand or a non-tool item, so that it can do something else than take damage. diff --git a/src/client/clientenvironment.cpp b/src/client/clientenvironment.cpp index fc7cbe254..1bdf5390d 100644 --- a/src/client/clientenvironment.cpp +++ b/src/client/clientenvironment.cpp @@ -235,7 +235,16 @@ void ClientEnvironment::step(float dtime) &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) { v3f speed_diff = info.new_speed - info.old_speed;; @@ -248,17 +257,20 @@ void ClientEnvironment::step(float dtime) speed_diff.Z = 0; f32 pre_factor = 1; // 1 hp per node/s f32 tolerance = BS*14; // 5 without damage - f32 post_factor = 1; // 1 hp per node/s if (info.type == COLLISION_NODE) { const ContentFeatures &f = m_client->ndef()-> get(m_map->getNode(info.node_p)); - // Determine fall damage multiplier - int addp = itemgroup_get(f.groups, "fall_damage_add_percent"); - pre_factor = 1.0f + (float)addp / 100.0f; + // Determine fall damage modifier + int addp_n = itemgroup_get(f.groups, "fall_damage_add_percent"); + // 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(); - 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); if (damage != 0) { damageLocalPlayer(damage, true);