From 79ea841eebd462627047b912b68b4f363f91cdde Mon Sep 17 00:00:00 2001 From: pterolatypus Date: Wed, 8 Apr 2020 03:52:20 +0100 Subject: [PATCH] Medical Damage - Determine ammo damage type through config property (#7608) * Determine ammo damage type through config property * Tabs * Add warning when property is missing Co-Authored-By: PabstMirror * Fixed up inheritance Some classes were not editable; changes moved to relevant subclasses instead * Newlines for readability * More sensible default value * Fix mistakes I added * Update addons/medical_damage/CfgAmmo.hpp * Pre-cache special values for damage types * Support # values For backwards compatibility Co-Authored-By: PabstMirror Co-authored-by: PabstMirror --- addons/medical_damage/CfgAmmo.hpp | 93 +++++++++++++++++++ addons/medical_damage/config.cpp | 1 + .../functions/fnc_getTypeOfDamage.sqf | 38 ++++---- .../functions/fnc_parseConfigForInjuries.sqf | 4 + .../functions/fnc_handleDamage.sqf | 10 +- 5 files changed, 122 insertions(+), 24 deletions(-) create mode 100644 addons/medical_damage/CfgAmmo.hpp diff --git a/addons/medical_damage/CfgAmmo.hpp b/addons/medical_damage/CfgAmmo.hpp new file mode 100644 index 0000000000..89dfb486bb --- /dev/null +++ b/addons/medical_damage/CfgAmmo.hpp @@ -0,0 +1,93 @@ +class CfgAmmo { + class BulletCore; + class BulletBase: BulletCore { + ACE_damageType = "bullet"; + }; + class ShotgunCore; + class ShotgunBase: ShotgunCore { + ACE_damageType = "bullet"; + }; + + class Default; + class FuelExplosion: Default { + ACE_damageType = "explosive"; + }; + class Grenade: Default { + ACE_damageType = "grenade"; + }; + class GrenadeCore; + class GrenadeBase: GrenadeCore { + ACE_damageType = "grenade"; + }; + + class MineCore; + class MineBase: MineCore { + ACE_damageType = "explosive"; + }; + class PipeBombCore; + class PipeBombBase: PipeBombCore { + ACE_damageType = "explosive"; + }; + class DirectionalBombCore; + class DirectionalBombBase: DirectionalBombCore { + ACE_damageType = "explosive"; + }; + class BoundingMineCore; + class BoundingMineBase: BoundingMineCore { + ACE_damageType = "explosive"; + }; + + class RocketCore; + class RocketBase: RocketCore { + ACE_damageType = "explosive"; + }; + class MissileCore; + class MissileBase: MissileCore { + ACE_damageType = "explosive"; + }; + + class SubmunitionCore; + class SubmunitionBase: SubmunitionCore { + ACE_damageType = "explosive"; + }; + class SubmunitionBullet: SubmunitionBase { + ACE_damageType = "bullet"; + }; + + class ShellCore; + class ShellBase: ShellCore { + ACE_damageType = "shell"; + }; + + // There is no BombBase so we modify these separately + class BombCore; + class Bo_Mk82: BombCore { + ACE_damageType = "explosive"; + }; + class LaserBombCore; + class ammo_Bomb_LaserGuidedBase: LaserBombCore { + ACE_damageType = "explosive"; + }; + class BombDemine_01_Ammo_F: BombCore { + ACE_damageType = "explosive"; + }; + + // Autocannon rounds are special (#7401) + class B_19mm_HE: BulletBase { + ACE_damageType = "explosive"; + }; + class B_20mm: BulletBase { + ACE_damageType = "explosive"; + }; + class B_25mm: BulletBase { + ACE_damageType = "explosive"; + }; + class B_35mm_AA: BulletBase { + ACE_damageType = "explosive"; + }; + + // These are also special + class Gatling_30mm_HE_Plane_CAS_01_F: BulletBase { + ACE_damageType = "explosive"; + }; +}; diff --git a/addons/medical_damage/config.cpp b/addons/medical_damage/config.cpp index cc2a1106f3..c9809fdf07 100644 --- a/addons/medical_damage/config.cpp +++ b/addons/medical_damage/config.cpp @@ -17,6 +17,7 @@ class CfgPatches { #include "ACE_Settings.hpp" #include "ACE_Medical_Injuries.hpp" #include "CfgEventHandlers.hpp" +#include "CfgAmmo.hpp" /* class ACE_Extensions { diff --git a/addons/medical_damage/functions/fnc_getTypeOfDamage.sqf b/addons/medical_damage/functions/fnc_getTypeOfDamage.sqf index 53645f7b8b..f73edf580f 100644 --- a/addons/medical_damage/functions/fnc_getTypeOfDamage.sqf +++ b/addons/medical_damage/functions/fnc_getTypeOfDamage.sqf @@ -4,7 +4,7 @@ * Get the type of damage based upon the projectile. * * Arguments: - * 0: The projectile classname or object + * 0: The projectile classname OR the name of a damage type * * Return Value: * Type of damage @@ -17,24 +17,24 @@ params ["_typeOfProjectile"]; -// --- projectiles -if (_typeOfProjectile isKindOf "BulletBase") exitWith {"bullet"}; -if (_typeOfProjectile isKindOf "ShotgunBase") exitWith {"bullet"}; -if (_typeOfProjectile isKindOf "GrenadeCore") exitWith {"grenade"}; -if (_typeOfProjectile isKindOf "TimeBombCore") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "MineCore") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "FuelExplosion") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "ShellBase") exitWith {"shell"}; -if (_typeOfProjectile isKindOf "RocketBase") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "MissileBase") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "LaserBombCore") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "BombCore") exitWith {"explosive"}; -if (_typeOfProjectile isKindOf "Grenade") exitWith {"grenade"}; +private _damageType = GVAR(damageTypeCache) getVariable _typeOfProjectile; -// --- non-projectiles reported by custom handleDamge wrapper -if ((_typeOfProjectile select [0,1]) isEqualTo "#") then { - _typeOfProjectile = _typeOfProjectile select [1]; +if (isNil "_damageType") then { + if (isText (configFile >> "CfgAmmo" >> _typeOfProjectile >> "ACE_damageType")) then { + _damageType = getText (configFile >> "CfgAmmo" >> _typeOfProjectile >> "ACE_damageType"); + } else { + WARNING_1("Ammo type [%1] has no ACE_damageType",_typeOfProjectile); + _damageType = "unknown"; + }; + + // config may define an invalid damage type + if (isNil {GVAR(allDamageTypesData) getVariable _damageType}) then { + WARNING_2("Damage type [%1] for ammo [%2] not found",_typeOfDamage,_typeOfProjectile); + _damageType = "unknown"; + }; + + TRACE_2("getTypeOfDamage caching",_typeOfProjectile,_damageType); + GVAR(damageTypeCache) setVariable [_typeOfProjectile, _damageType]; }; -// --- otherwise -toLower _typeOfProjectile +_damageType // return diff --git a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf index 848c78c893..8618a41b5d 100644 --- a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf +++ b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf @@ -50,6 +50,8 @@ private _classID = 0; // --- parse damage types GVAR(allDamageTypesData) = [] call CBA_fnc_createNamespace; +// cache for ammunition -> damageType +GVAR(damageTypeCache) = [] call CBA_fnc_createNamespace; // minimum lethal damage collection, mapped to damageTypes private _damageTypesConfig = _injuriesConfigRoot >> "damageTypes"; @@ -75,6 +77,8 @@ private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionS private _selectionSpecific = GET_NUMBER(_damageTypeSubClassConfig >> "selectionSpecific",_selectionSpecificDefault); GVAR(allDamageTypesData) setVariable [_className, [_thresholds, _selectionSpecific > 0, _woundTypes]]; + GVAR(damageTypeCache) setVariable [_className, _className]; + GVAR(damageTypeCache) setVariable ["#"+_className, _className]; /* // extension loading diff --git a/addons/medical_engine/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 6cec1c473d..1975bde0c5 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -120,7 +120,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // Any collision with terrain/vehicle/object has a shooter // Check this first because burning can happen at any velocity if !(isNull _shooter) then { - _ammo = "#collision"; // non-selectionSpecific so only _damageSelectionArray matters + _ammo = "collision"; // non-selectionSpecific so only _damageSelectionArray matters /* If shooter != unit then they hit unit, otherwise it could be: @@ -130,7 +130,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { Assume fall damage for downward velocity because it's most common */ if (_shooter == _unit && {(velocity _unit select 2) < -2}) then { - _ammo = "#falling"; // non-selectionSpecific so only _damageSelectionArray matters + _ammo = "falling"; // non-selectionSpecific so only _damageSelectionArray matters _damageSelectionArray = [HITPOINT_INDEX_RLEG, 1, HITPOINT_INDEX_LLEG, 1]; TRACE_5("Fall",_unit,_shooter,_instigator,_damage,_receivedDamage); } else { @@ -152,7 +152,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { } else { // Anything else is almost guaranteed to be fire damage _damageSelectionArray = [HITPOINT_INDEX_BODY, 1, HITPOINT_INDEX_LLEG, 1, HITPOINT_INDEX_RLEG, 1];; - _ammo = "#unknown"; // non-selectionSpecific so only _damageSelectionArray matters + _ammo = "unknown"; // non-selectionSpecific so only _damageSelectionArray matters // Fire damage can occur as lots of minor damage events // Combine these until significant enough to wound @@ -194,7 +194,7 @@ if ( {getOxygenRemaining _unit <= 0.5} && {_damage isEqualTo (_oldDamage + 0.005)} ) exitWith { - [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#drowning", [HITPOINT_INDEX_BODY, 1]]] call CBA_fnc_localEvent; + [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "drowning", [HITPOINT_INDEX_BODY, 1]]] call CBA_fnc_localEvent; TRACE_5("Drowning",_unit,_shooter,_instigator,_damage,_newDamage); 0 @@ -214,7 +214,7 @@ if ( HITPOINT_INDEX_HEAD, 1, HITPOINT_INDEX_BODY, 1, HITPOINT_INDEX_LARM, 1, HITPOINT_INDEX_RARM, 1, HITPOINT_INDEX_LLEG, 1, HITPOINT_INDEX_RLEG, 1 ]; - [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "#vehiclecrash", _damageSelectionArray]] call CBA_fnc_localEvent; + [QEGVAR(medical,woundReceived), [_unit, "Body", _newDamage, _unit, "vehiclecrash", _damageSelectionArray]] call CBA_fnc_localEvent; TRACE_5("Crash",_unit,_shooter,_instigator,_damage,_newDamage); 0