Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Medical - Rework wound handling #8278

Merged
merged 41 commits into from
Feb 17, 2022
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
b2526f3
Reworked wound handling
pterolatypus Jun 7, 2021
a6e8012
Actually use damage multiplier
pterolatypus Jun 7, 2021
4165ec8
Add pain and fracture modifiers
pterolatypus Jun 7, 2021
4d6aac6
Improved some comments
pterolatypus Jun 7, 2021
8eeb830
Tweaked comments again
pterolatypus Jun 7, 2021
4de9a04
Reset config to mirror old behaviour, for testing
pterolatypus Jun 7, 2021
ada3a5b
Fixed some typos and bugs
pterolatypus Jun 8, 2021
f56693c
Freakin tabs every time
pterolatypus Jun 8, 2021
4a632b8
More tabs
pterolatypus Jun 8, 2021
7cd79d8
Fix and cleanup handleDamage, add burning
pterolatypus Jun 9, 2021
c198825
Clean up unused code
pterolatypus Jun 11, 2021
07fb3a5
Removed old config entries
pterolatypus Jun 11, 2021
76c07c6
Moved body part loop inside wound handler, improved handling of burning
pterolatypus Jun 15, 2021
31c6a93
Always with the tabs
pterolatypus Jun 15, 2021
ff65a85
Added explosive testing function
pterolatypus Jun 18, 2021
f49713b
Started medical framework documentation
pterolatypus Jun 19, 2021
47f3cdc
Tweaking wound size & thresholds
pterolatypus Jun 20, 2021
7eba141
Fixed some woundReceived calls
pterolatypus Jun 23, 2021
2e6ae52
Tweaks to damage types
pterolatypus Jun 29, 2021
6c2bf76
Cleanup hitpoint macro
pterolatypus Jun 29, 2021
2ba0448
Clean up
pterolatypus Jun 29, 2021
155898f
Handling for vehicle explosions
pterolatypus Jun 29, 2021
b469796
Removed vehicle explosion handling
pterolatypus Jul 6, 2021
a6bd605
Improved some comments
pterolatypus Jul 16, 2021
69157c9
Fix fnc_addDamageToUnit
pterolatypus Aug 7, 2021
bdd7ff4
Convert burning to use structural damage
pterolatypus Aug 15, 2021
dce5206
Improve comment on hitpoint macro
pterolatypus Sep 25, 2021
720a39a
Add support for #7565 burning damage
pterolatypus Oct 12, 2021
bf722bb
Added strings for burns, disabled logging
pterolatypus Oct 12, 2021
95f68e1
Merge latest
pterolatypus Dec 20, 2021
c8fc95d
Fix duplicate definition in medical injuries
pterolatypus Dec 20, 2021
b4da037
Doh
pterolatypus Dec 21, 2021
0f4cb63
Implemented stackable damage handlers
pterolatypus Jan 2, 2022
bdf7bb7
Stackable handlers support inheritance, and updated docs
pterolatypus Jan 4, 2022
da82e25
Improved random rounding
pterolatypus Jan 5, 2022
61d4174
Bugfix/cleanup in HandleDamage
pterolatypus Jan 10, 2022
26c7d36
Moved selection-specific check inside wound handler
pterolatypus Jan 25, 2022
bdd59c7
Fix, review suggestions, docs check
pterolatypus Jan 30, 2022
7b0c325
Improve sorting of large hits
pterolatypus Feb 7, 2022
2e56694
Apply code style suggestions from review
kymckay Feb 15, 2022
37009b9
Remove unused final param
kymckay Feb 15, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 3 additions & 7 deletions addons/medical/functions/fnc_addDamageToUnit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
* 2: Body part ("Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg") <STRING>
* 3: Projectile Type <STRING>
* 4: Source <OBJECT>
* 5: Non-directional damage source array <ARRAY> (default: [])
* 5: Unused parameter maintained for backwards compatibility <ARRAY> (default: [])
* 6: Override Invulnerability <BOOL> (default: true)
*
* Return Value:
Expand All @@ -29,7 +29,7 @@ params [
["_bodyPart", "", [""]],
["_typeOfDamage", "", [""]],
["_instigator", objNull, [objNull]],
["_damageSelectionArray", [], [[]]],
"",
["_overrideInvuln", true, [true]]
];
TRACE_7("addDamageToUnit",_unit,_damageToAdd,_bodyPart,_typeOfDamage,_instigator,_damageSelectionArray,_overrideInvuln);
Expand All @@ -48,10 +48,6 @@ if (!_overrideInvuln && {!((isDamageAllowed _unit) && {_unit getVariable [QEGVAR
// Extension is case sensitive and expects this format (different from ALL_BODY_PARTS)
_bodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] select _bodyPartIndex;

if (_damageSelectionArray isEqualTo []) then { // this will only be used if damage type is not location specific
_damageSelectionArray = [HITPOINT_INDEX_HEAD, 1, HITPOINT_INDEX_BODY, 1, HITPOINT_INDEX_LARM, 1, HITPOINT_INDEX_RARM, 1, HITPOINT_INDEX_LLEG, 1, HITPOINT_INDEX_RLEG, 1];
};

if (!isNull _instigator) then {
_unit setVariable [QEGVAR(medical,lastDamageSource), _instigator];
_unit setVariable [QEGVAR(medical,lastInstigator), _instigator];
Expand All @@ -62,7 +58,7 @@ private _startDmg = +(_unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,
private _startPain = GET_PAIN(_unit);
#endif

[QEGVAR(medical,woundReceived), [_unit, _bodyPart, _damageToAdd, _instigator, _typeOfDamage, _damageSelectionArray]] call CBA_fnc_localEvent;
[QEGVAR(medical,woundReceived), [_unit, [[_damageToAdd, _bodyPart, _damageToAdd]], _instigator, _typeOfDamage]] call CBA_fnc_localEvent;

#ifdef DEBUG_TESTRESULTS
private _endDmg = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]];
Expand Down
3 changes: 2 additions & 1 deletion addons/medical_blood/functions/fnc_handleWoundReceived.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
* Public: No
*/

params ["_unit", "", "_damage", "_shooter"];
params ["_unit", "_allDamages", "_shooter"];
(_allDamages select 0) params ["_damage", ""];

// Don't bleed when players only and a non-player unit is wounded
if (GVAR(enabledFor) == BLOOD_ONLY_PLAYERS && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {};
Expand Down
237 changes: 200 additions & 37 deletions addons/medical_damage/ACE_Medical_Injuries.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,136 +7,299 @@ class ACE_Medical_Injuries {
// Source: Scarle
// Also called scrapes, they occur when the skin is rubbed away by friction against another rough surface (e.g. rope burns and skinned knees).
class Abrasion {
causes[] = {"falling", "ropeburn", "vehiclecrash", "collision", "unknown"};
bleeding = 0.001;
pain = 0.4;
minDamage = 0.01;
maxDamage = 0.30;
};
// Occur when an entire structure or part of it is forcibly pulled away, such as the loss of a permanent tooth or an ear lobe. Explosions, gunshots, and animal bites may cause avulsions.
class Avulsion {
causes[] = {"explosive", "vehiclecrash", "collision", "grenade", "shell", "bullet", "backblast", "bite"};
bleeding = 0.1;
pain = 1.0;
minDamage = 0.01;
causeLimping = 1;
};
// Also called bruises, these are the result of a forceful trauma that injures an internal structure without breaking the skin. Blows to the chest, abdomen, or head with a blunt instrument (e.g. a football or a fist) can cause contusions.
class Contusion {
causes[] = {"bullet", "backblast", "punch", "vehiclecrash", "collision", "falling"};
bleeding = 0;
pain = 0.3;
minDamage = 0.02;
maxDamage = 0.35;
};
// Occur when a heavy object falls onto a person, splitting the skin and shattering or tearing underlying structures.
class Crush {
causes[] = {"falling", "vehiclecrash", "collision", "punch", "unknown"};
bleeding = 0.05;
pain = 0.8;
minDamage = 0.1;
causeLimping = 1;
causeFracture = 1;
};
// Slicing wounds made with a sharp instrument, leaving even edges. They may be as minimal as a paper cut or as significant as a surgical incision.
class Cut {
causes[] = {"vehiclecrash", "collision", "grenade", "explosive", "shell", "backblast", "stab", "unknown"};
bleeding = 0.01;
pain = 0.1;
minDamage = 0.1;
};
// Also called tears, these are separating wounds that produce ragged edges. They are produced by a tremendous force against the body, either from an internal source as in childbirth, or from an external source like a punch.
class Laceration {
causes[] = {"vehiclecrash", "collision", "punch"};
bleeding = 0.05;
pain = 0.2;
minDamage = 0.01;
};
// Also called velocity wounds, they are caused by an object entering the body at a high speed, typically a bullet or small peices of shrapnel.
class VelocityWound {
causes[] = {"bullet", "grenade","explosive", "shell", "unknown"};
bleeding = 0.2;
pain = 0.9;
minDamage = 0.35;
causeLimping = 1;
causeFracture = 1;
};
// Deep, narrow wounds produced by sharp objects such as nails, knives, and broken glass.
class PunctureWound {
causes[] = {"stab", "grenade"};
bleeding = 0.05;
pain = 0.4;
minDamage = 0.02;
causeLimping = 1;
};
// Pain wound that is caused by making or being in contact with heat
class ThermalBurn {
causes[] = {"burn"};
bleeding = 0;
pain = 0.7;
minDamage = 0;
};
};

class damageTypes {
// thresholds[] {{<min damage>, <max number of wounds>}, {...}}
// thresholds[] {{<damage>, <number of wounds>}, {...}}
// if damage is between two points, number is interpolated and then rounded by chance based on the decimal part
// e.g. a value of 2.7 has 70% chance to give 3 and 30% to give 2
// put damage values in descending order; uses the first value found that is below the wound damage, and the point immediately before that
thresholds[] = {{0.1, 1}};

// if 1, wounds are only applied to the hitpoint that took the most damage. othewrise, wounds are applied to all damaged hitpoints
selectionSpecific = 1;

// list of damage handlers, which will be called in reverse order
// each entry should be a SQF expression that returns a function
// this can also be overridden for each damage type
class woundHandlers {
ADDON = QFUNC(woundsHandlerActive);
};

class bullet {
// above damage, amount. Put the highest threshold to the left and lower the threshold with the elements to the right of it.
thresholds[] = {{0.1, 1}};
// bullets only create multiple wounds when the damage is very high
thresholds[] = {{20, 10}, {4.5, 2}, {3, 1}, {0, 1}};
selectionSpecific = 1;

class Avulsion {
// at damage, weight. between points, weight is interpolated then wound is chosen by weighted random.
// as with thresholds, but result is not rounded (decimal values used as-is)
weighting[] = {{1, 1}, {0.35, 0}};
/*
damageMultiplier = 1;
sizeMultiplier = 1;
bleedingMultiplier = 1;
painMultiplier = 1;
fractureMultiplier = 1;
*/
};
class Contusion {
weighting[] = {{0.35, 0}, {0.35, 1}};
// bruises caused by bullets hitting the plate are big
sizeMultiplier = 3.2;
// tone down the pain a tiny bit to compensate
painMultiplier = 0.8;
};
class VelocityWound {
// velocity wounds are only in the 0.35-1.5 range
weighting[] = {{1.5, 0}, {1.5, 1}, {0.35, 1}, {0.35, 0}};
// velocity wounds will tend to be medium or large
sizeMultiplier = 0.9;
};
};
class grenade {
thresholds[] = {{0.1, 3}, {0, 1}};
// at low damage numbers, chance to create no wounds - makes it a bit more random instead of consistently covering people in bruises
thresholds[] = {{20, 10}, {10, 5}, {4, 3}, {1.5, 2}, {0.8, 2}, {0.3, 1}, {0, 0}};
selectionSpecific = 0;
class Avulsion {
weighting[] = {{1.5, 1}, {1.1, 0}};
};
class VelocityWound {
weighting[] = {{1.5, 0}, {1.1, 1}, {0.7, 0}};
};
class PunctureWound {
weighting[] = {{0.9, 0}, {0.7, 1}, {0.35, 0}};
};
class Cut {
weighting[] = {{0.7, 0}, {0.35, 1}, {0.35, 0}};
};
class Contusion {
weighting[] = {{0.5, 0}, {0.35, 1}};
sizeMultiplier = 2;
painMultiplier = 0.9;
};
};
class explosive {
thresholds[] = {{1, 6}, {0.1, 4}, {0, 1}};
// explosives create more and smaller wounds than grenades
thresholds[] = {{20, 15}, {8, 7}, {2, 3}, {1.2, 2}, {0.4, 1}, {0,0}};
selectionSpecific = 0;
class Avulsion {
weighting[] = {{1, 1}, {0.8, 0}};
};
class Cut {
weighting[] = {{1.5, 0}, {0.35, 1}, {0, 0}};
};
class Contusion {
weighting[] = {{0.5, 0}, {0.35, 1}};
sizeMultiplier = 2;
painMultiplier = 0.9;
};
};
class shell {
thresholds[] = {{1, 7}, {0.1, 5}, {0, 1}};
// shells tend to involve big pieces of shrapnel, so create fewer and larger wounds
thresholds[] = {{20, 10}, {10, 5}, {4.5, 2}, {2, 2}, {0.8, 1}, {0.2, 1}, {0, 0}};
selectionSpecific = 0;
class Avulsion {
weighting[] = {{1.5, 1}, {1.1, 0}};
};
class VelocityWound {
weighting[] = {{1.5, 0}, {1.1, 1}, {0.7, 0}};
};
class PunctureWound {
weighting[] = {{0.9, 0}, {0.7, 1}, {0.35, 0}};
};
class Cut {
weighting[] = {{0.7, 0}, {0.35, 1}, {0.35, 0}};
};
class Contusion {
weighting[] = {{0.5, 0}, {0.35, 1}};
sizeMultiplier = 2;
painMultiplier = 0.9;
};
};
class vehiclecrash {
thresholds[] = {{1.5, 3}, {1, 2}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered
thresholds[] = {{1.5, 3}, {1.5, 2}, {1, 2}, {1, 1}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered
selectionSpecific = 0;
class woundHandlers: woundHandlers {
GVAR(vehiclecrash) = QFUNC(woundsHandlerVehiclecrash);
};
class Abrasion {
weighting[] = {{0.30, 0}, {0.30, 1}};
};
class Avulsion {
weighting[] = {{0.01, 1}, {0.01, 0}};
};
class Contusion {
weighting[] = {{0.35, 0}, {0.35, 1}};
};
class Crush {
weighting[] = {{0.1, 1}, {0.1, 0}};
};
class Cut {
weighting[] = {{0.1, 1}, {0.1, 0}};
};
class Laceration {

};
};
class collision {
thresholds[] = {{1.5, 3}, {1, 2}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered
thresholds[] = {{1.5, 3}, {1.5, 2}, {1, 2}, {1, 1}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered
selectionSpecific = 0;
class Abrasion {
weighting[] = {{0.30, 0}, {0.30, 1}};
};
class Avulsion {
weighting[] = {{1, 2}, {0.5, 0.5}, {0.5, 0}};
};
class Contusion {
weighting[] = {{0.35, 0}, {0.35, 1}};
};
class Crush {
weighting[] = {{0.1, 1}, {0.1, 0}};
};
class Cut {
weighting[] = {{0.1, 1}, {0.1, 0}};
};
class Laceration {

};
};
class backblast {
thresholds[] = {{1, 6}, {0.55, 5}, {0, 2}};
thresholds[] = {{1, 6}, {1, 5}, {0.55, 5}, {0.55, 2}, {0, 2}};
selectionSpecific = 0;
class Avulsion {
weighting[] = {{0.30, 0}, {0.30, 1}};
};
class Contusion {
weighting[] = {{0.35, 0}, {0.35, 1}};
};
class Cut {
weighting[] = {{0.1, 1}, {0.1, 0}};
};
};
class stab {
thresholds[] = {{0.1, 1}};
thresholds[] = {{0.1, 1}, {0.1, 0}};
selectionSpecific = 1;
class Cut {
weighting[] = {{0.1, 1}, {0.1, 0}};
};
class PunctureWound {
weighting[] = {{0.02, 1}, {0.02, 0}};
};
};
class punch {
thresholds[] = {{0.1, 1}};
thresholds[] = {{0.1, 1}, {0.1, 0}};
selectionSpecific = 1;
class Contusion {
weighting[] = {{0.35, 0}, {0.35, 1}};
};
class Crush {
weighting[] = {{0.1, 1}, {0.1, 0}};
};
class Laceration {

};
};
class falling {
thresholds[] = {{1.5, 3}, {1, 2}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered
thresholds[] = {{1.5, 3}, {1.5, 2}, {1, 2}, {1, 1}, {0.05, 1}}; // prevent subdividing wounds past FRACTURE_DAMAGE_THRESHOLD to ensure limp/fractue is triggered
selectionSpecific = 0;
class Abrasion {
weighting[] = {{0.30, 0}, {0.30, 1}};
};
class Contusion {
weighting[] = {{0.35, 0}, {0.35, 1}};
};
class Crush {
weighting[] = {{0.1, 1}, {0.1, 0}};
};
};
class ropeburn {
thresholds[] = {{0.1, 1}};
thresholds[] = {{0.1, 1}, {0.1, 0}};
selectionSpecific = 1;
class Abrasion {
weighting[] = {{0.30, 1}};
};
};
class drowning {
//No related wounds as drowning should not cause wounds/bleeding. Can be extended for internal injuries if they are added.
thresholds[] = {{0, 0}};
class woundHandlers {};
};
class fire {
// custom handling for environmental fire sources
// passes damage to "burn" so doesn't need its own wound stats
class woundHandlers {
ADDON = QFUNC(woundsHandlerBurning);
};
};
class burn {
pterolatypus marked this conversation as resolved.
Show resolved Hide resolved
thresholds[] = {{0, 1}};
selectionSpecific = 0;
};
//No related wounds as drowning should not cause wounds/bleeding. Can be extended for internal injuries if they are added.
class drowning {
thresholds[] = {{0, 0}};
class ThermalBurn {
weighting[] = {{0, 1}};
};
};
class unknown {
thresholds[] = {{0.1, 1}};
thresholds[] = {{0.1, 1}, {0.1, 0}};
class Abrasion {
weighting[] = {{0.30, 0}, {0.30, 1}};
};
class Cut {
weighting[] = {{0.1, 1}, {0.1, 0}};
};
class VelocityWound {
weighting[] = {{0.35, 1}, {0.35, 0}};
};
};
};
};
6 changes: 6 additions & 0 deletions addons/medical_damage/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
PREP(debug_explosiveTest);
PREP(determineIfFatal);
PREP(getTypeOfDamage);
PREP(handleIncapacitation);
PREP(interpolatePoints);
PREP(parseConfigForInjuries);
PREP(parseWoundHandlersCfg);
PREP(woundReceived);
PREP(woundsHandler);
PREP(woundsHandlerBurning);
PREP(woundsHandlerSQF);
PREP(woundsHandlerVehiclecrash);
Loading