05-13-2012, 11:46 AM
This idea would be a major change, so it's best I ask before I start coding. Nexuiz and Xonotic have been stuck with the ancient ways of calculating player damage, based entirely on the bounding box and not on how the body works. I've been thinking of changing that, and adding limb-based damage to Xonotic. This means that damage would no longer be calculated by a simple "bounding box was hit" check, but by using bones on the animation skeleton to deal the appropriate damage for each body part. To explain better, here's a comparison with the current system.
Current way: If a bullet hits the player's bounding box it deals a fixed amount of X damage. If a splash damage projectile hits the player, it deals X damage modified by distance between the player and where the explosion took place (the closer you are the more damage you take).
New way: Hitting the bounding box would not deal any damage by itself (just apply force). Whenever a projectile hits the player, the code runs a loop through all skeleton bones of the player model, detecting how close each one is to the impact point. Bones cvared as "damage bones" (explained below) are fetched, and the damage of each bone applied to the player. This is the same system that my Damage Effects use (particles sticking to player limbs after they are shot).
The cvar system would work as follows: You register each bone by its name in a numbered list of cvars. A bone's cvar would contain the damage modifier, specifying how much of the dealt damage is translated by that bone. 0.5 would mean half, 2 would mean twice. Bones which aren't registered deal no damage (so parts like the fingers are counted out). Example:
g_bonedamage 1 "use bone damage system over the old system"
g_bonedamage_1_name arm.L "name of the armature bone"
g_bonedamage_1_offset 0.5 "how much of the damage this bone translates"
g_bonedamage_2_name arm.R "name of the armature bone"
g_bonedamage_2_offset 0.5 "how much of the damage this bone translates"
g_bonedamage_3_name torso "name of the armature bone"
g_bonedamage_3_offset 1 "how much of the damage this bone translates"
g_bonedamage_4_name head "name of the armature bone"
g_bonedamage_4_offset 2 "how much of the damage this bone translates"
...
The cvars would be read in a loop, so you can add as many as you want using this architecture. What the example above would mean is: The arms translate 0.5 of the damage, the torso translates 1 (unmodified) and the head translates 2 times the damage. For splash damage, the closer each bone is to the impact point the more damage it translates. For hitscan weapons (since they don't have a radius) they probably translate the damage of the single closest bone at its full intensity.
This would add some very fun and realistic damage to Xonotic, and get us out of the simple "hit the player's bounding box and deal fixed damage" functionality. For added fun, the player's animation at the moment of impact would also influence the position of damage points (since they are the bones). However, it would have several downsides, such as:
- All player models must have the same bone names to work properly. eg: If a model would name the right arm arm_R instead of arm.R, that model would be broken for gameplay. I believe this is ok with current Xonotic models, and likely custom models as well if they use the same skeleton.
- The player model you select will cause you to be damaged differently. This again shouldn't make a noticeable difference with the default models, but custom models would need to be checked closely. eg: If your custom model has his head oriented down by default (like a monk or something), a rocket exploding on the top of the bounding box will deal less damage than on an ordinary player.
This does not affect custom models as long as they use the default skeleton (that Ignis and all others do). The rest should be fine... just a matter of getting used to and balancing. But because of how unsafe this would be, I doubt the feature will get defaulted (even if I'd like that). Still, I'm asking what exactly you prefer I do (see the pool). Should this be default, should it be a mutator, or should I not even bother to code it? I like the idea, and really believe Xonotic needs area-based damage at least to make headshots more harmful for all weapons. The bone system would be the most realistic and advanced way to go, but at the same time could mess with the gameplay if a model uses a custom skeleton that isn't checked.
Current way: If a bullet hits the player's bounding box it deals a fixed amount of X damage. If a splash damage projectile hits the player, it deals X damage modified by distance between the player and where the explosion took place (the closer you are the more damage you take).
New way: Hitting the bounding box would not deal any damage by itself (just apply force). Whenever a projectile hits the player, the code runs a loop through all skeleton bones of the player model, detecting how close each one is to the impact point. Bones cvared as "damage bones" (explained below) are fetched, and the damage of each bone applied to the player. This is the same system that my Damage Effects use (particles sticking to player limbs after they are shot).
The cvar system would work as follows: You register each bone by its name in a numbered list of cvars. A bone's cvar would contain the damage modifier, specifying how much of the dealt damage is translated by that bone. 0.5 would mean half, 2 would mean twice. Bones which aren't registered deal no damage (so parts like the fingers are counted out). Example:
g_bonedamage 1 "use bone damage system over the old system"
g_bonedamage_1_name arm.L "name of the armature bone"
g_bonedamage_1_offset 0.5 "how much of the damage this bone translates"
g_bonedamage_2_name arm.R "name of the armature bone"
g_bonedamage_2_offset 0.5 "how much of the damage this bone translates"
g_bonedamage_3_name torso "name of the armature bone"
g_bonedamage_3_offset 1 "how much of the damage this bone translates"
g_bonedamage_4_name head "name of the armature bone"
g_bonedamage_4_offset 2 "how much of the damage this bone translates"
...
The cvars would be read in a loop, so you can add as many as you want using this architecture. What the example above would mean is: The arms translate 0.5 of the damage, the torso translates 1 (unmodified) and the head translates 2 times the damage. For splash damage, the closer each bone is to the impact point the more damage it translates. For hitscan weapons (since they don't have a radius) they probably translate the damage of the single closest bone at its full intensity.
This would add some very fun and realistic damage to Xonotic, and get us out of the simple "hit the player's bounding box and deal fixed damage" functionality. For added fun, the player's animation at the moment of impact would also influence the position of damage points (since they are the bones). However, it would have several downsides, such as:
- All player models must have the same bone names to work properly. eg: If a model would name the right arm arm_R instead of arm.R, that model would be broken for gameplay. I believe this is ok with current Xonotic models, and likely custom models as well if they use the same skeleton.
- The player model you select will cause you to be damaged differently. This again shouldn't make a noticeable difference with the default models, but custom models would need to be checked closely. eg: If your custom model has his head oriented down by default (like a monk or something), a rocket exploding on the top of the bounding box will deal less damage than on an ordinary player.
This does not affect custom models as long as they use the default skeleton (that Ignis and all others do). The rest should be fine... just a matter of getting used to and balancing. But because of how unsafe this would be, I doubt the feature will get defaulted (even if I'd like that). Still, I'm asking what exactly you prefer I do (see the pool). Should this be default, should it be a mutator, or should I not even bother to code it? I like the idea, and really believe Xonotic needs area-based damage at least to make headshots more harmful for all weapons. The bone system would be the most realistic and advanced way to go, but at the same time could mess with the gameplay if a model uses a custom skeleton that isn't checked.