diff --git a/addons/medical/config.cpp b/addons/medical/config.cpp index d50eb49494..17ff62dbac 100644 --- a/addons/medical/config.cpp +++ b/addons/medical/config.cpp @@ -23,3 +23,7 @@ class CfgPatches { #include "CfgFactionClasses.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" + +class ACE_Extensions { + extensions[] += {"ace_medical"}; +}; diff --git a/addons/medical_damage/XEH_PREP.hpp b/addons/medical_damage/XEH_PREP.hpp index 35678974ce..463549874a 100644 --- a/addons/medical_damage/XEH_PREP.hpp +++ b/addons/medical_damage/XEH_PREP.hpp @@ -5,4 +5,4 @@ PREP(internalInjuriesHandler); PREP(parseConfigForInjuries); PREP(woundsHandler); -PREP(woundsHandlerSqf); +PREP(woundsHandlerSQF); diff --git a/addons/medical_damage/XEH_preInit.sqf b/addons/medical_damage/XEH_preInit.sqf index 6d77922974..3cef94eb8b 100644 --- a/addons/medical_damage/XEH_preInit.sqf +++ b/addons/medical_damage/XEH_preInit.sqf @@ -6,14 +6,20 @@ ADDON = false; call FUNC(parseConfigForInjuries); +// decide which woundsHandler to use by whether the extension is present or not +if ("ace_medical" callExtension "version" != "") then { + DFUNC(woundsHandlerActive) = FUNC(woundsHandler); +} else { + DFUNC(woundsHandlerActive) = FUNC(woundsHandlerSQF); +}; + [QEGVAR(medical_engine,woundReceived), { params ["_unit", "_woundedHitPoint", "_receivedDamage", "", "_ammo"]; - // private _selectionName = EGVAR(medical,SELECTIONS) select (EGVAR(medical,HITPOINTS) find _woundedHitPoint); // @todo private _typeOfDamage = _ammo call FUNC(getTypeOfDamage); - [_unit, _woundedHitPoint, _receivedDamage, _ammo, _typeOfDamage] call FUNC(woundsHandler); // TODO also support the sqf variant + [_unit, _woundedHitPoint, _receivedDamage, _ammo, _typeOfDamage] call FUNC(woundsHandlerActive); // TODO also support the sqf variant - [_unit, EGVAR(medical,STATE_MACHINE)] call EFUNC(medical,addStateHandler); + ///[_unit, EGVAR(medical,STATE_MACHINE)] call EFUNC(medical,addStateHandler); // @todo disable for now }] call CBA_fnc_addEventHandler; ADDON = true; diff --git a/addons/medical_damage/functions/fnc_woundsHandler.sqf b/addons/medical_damage/functions/fnc_woundsHandler.sqf index cbdc8901dc..4def1e0b7a 100644 --- a/addons/medical_damage/functions/fnc_woundsHandler.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandler.sqf @@ -1,5 +1,5 @@ /* - * Author: Glowbal + * Author: Glowbal, commy2 * Handling of the open wounds & injuries upon the handleDamage eventhandler. * * Arguments: @@ -16,31 +16,37 @@ */ #include "script_component.hpp" -params ["_unit", "_selectionName", "_damage", "_typeOfProjectile", "_typeOfDamage"]; -TRACE_6("ACE_DEBUG: woundshandler",_unit, _selectionName, _damage, _shooter, _typeOfProjectile,_typeOfDamage); +params ["_unit", "_bodyPart", "_damage", "_typeOfProjectile", "_typeOfDamage"]; +TRACE_5("start",_unit,_bodyPart,_damage,_typeOfProjectile,_typeOfDamage); -systemChat format["input: %1", _this]; +///// DELETE THIS AFTER EXTENSION HAS BEEN UPDATED +_bodyPart = EGVAR(medical,SELECTIONS) select (ALL_BODY_PARTS find _bodyPart); +///// -if (_typeOfDamage == "") then {_typeOfDamage = "unknown";}; +if (_typeOfDamage isEqualTo "") then { + _typeOfDamage = "unknown"; +}; // Administration for open wounds and ids -private _openWounds = _unit getVariable[QEGVAR(medical,openWounds), []]; -private _woundID = _unit getVariable[QEGVAR(medical,lastUniqueWoundID), 1]; +private _openWounds = _unit getVariable [QEGVAR(medical,openWounds), []]; +private _woundID = _unit getVariable [QEGVAR(medical,lastUniqueWoundID), 1]; -private _extensionOutput = "ace_medical" callExtension format ["HandleDamageWounds,%1,%2,%3,%4", _selectionName, _damage, _typeOfDamage, _woundID]; -diag_log format["Extension _extensionOutput: %1", _extensionOutput]; +private _extensionOutput = "ace_medical" callExtension format ["HandleDamageWounds,%1,%2,%3,%4", _bodyPart, _damage, _typeOfDamage, _woundID]; +TRACE_1("",_extensionOutput); +// these are default values and modified by _extensionOutput private _painToAdd = 0; private _woundsCreated = []; call compile _extensionOutput; + { - _x params ["", "_toAddClassID", "_bodyPartNToAdd"]; + _x params ["", "_woundClassIDToAdd", "_bodyPartNToAdd"]; + _foundIndex = -1; { - _x params ["", "_compareId", "_comparyBodyPartN"]; // Check if we have an id of the given class on the given bodypart already - if (_compareId == _toAddClassID && {_comparyBodyPartN2 == _bodyPartNToAdd}) exitWith { + if ((_woundClassIDToAdd isEqualTo (_x select 1)) && {_bodyPartNToAdd isEqualTo (_x select 2)}) exitWith { _foundIndex = _forEachIndex; }; } forEach _openWounds; @@ -66,4 +72,4 @@ if (count _woundsCreated > 0) then { private _painLevel = _unit getVariable [QEGVAR(medical,pain), 0]; _unit setVariable [QEGVAR(medical,pain), _painLevel + _painToAdd]; -TRACE_6("ACE_DEBUG: woundsHandler",_unit, _painLevel, _painToAdd, _unit getVariable QEGVAR(medical,pain), _unit getVariable QEGVAR(medical,openWounds),_woundsCreated); +TRACE_6("exit",_unit, _painLevel, _painToAdd, _unit getVariable QEGVAR(medical,pain), _unit getVariable QEGVAR(medical,openWounds),_woundsCreated); diff --git a/addons/medical_damage/functions/fnc_woundsHandlerSqf.sqf b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf similarity index 50% rename from addons/medical_damage/functions/fnc_woundsHandlerSqf.sqf rename to addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf index 978458952a..870925317b 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerSqf.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerSQF.sqf @@ -1,5 +1,5 @@ /* - * Author: Glowbal + * Author: Glowbal, commy2 * Handling of the open wounds & injuries upon the handleDamage eventhandler. * * Arguments: @@ -10,55 +10,48 @@ * 4: Type of the damage done * * Return Value: - * None + * None * * Public: No */ - #include "script_component.hpp" -private ["_bodyPartn", "_injuryTypeInfo", "_allInjuriesForDamageType", "_allPossibleInjuries", "_highestPossibleDamage", "_highestPossibleSpot", "_minDamage", "_openWounds", "_woundID", "_toAddInjury", "_painToAdd", "_bloodLoss", "_bodyPartNToAdd", "_classType", "_damageLevels", "_foundIndex", "_i", "_injury", "_maxDamage", "_pain", "_painLevel", "_selections", "_toAddClassID", "_woundsCreated"]; -params ["_unit", "_selectionName", "_damage", "_typeOfProjectile", "_typeOfDamage"]; -TRACE_6("ACE_DEBUG: HandleDamage_WoundsOLD Called",_unit, _selectionName, _damage, _shooter, _typeOfProjectile,_typeOfDamage); +params ["_unit", "_bodyPart", "_damage", "_typeOfProjectile", "_typeOfDamage"]; +TRACE_5("start",_unit,_bodyPart,_damage,_typeOfProjectile,_typeOfDamage); -systemChat format["input: %1", _this]; // Convert the selectionName to a number and ensure it is a valid selection. -_bodyPartn = EGVAR(medical,HITPOINTS) find _selectionName; //[_selectionName] call EFUNC(medical,selectionNameToNumber); -if (_bodyPartn < 0) exitWith {}; +private _bodyPartN = ALL_BODY_PARTS find _bodyPart; +if (_bodyPartN < 0) exitWith {}; -if (_typeOfDamage == "") then {_typeOfDamage = "unknown";}; +if (_typeOfDamage isEqualTo "") then { + _typeOfDamage = "unknown"; +}; -// Get the injury type information. Format: [typeDamage thresholds, selectionSpecific, woundTypes] -_injuryTypeInfo = [GVAR(allDamageTypesData) getVariable _typeOfDamage] param [0, [[], false, []]]; +// Get the damage type information. Format: [typeDamage thresholds, selectionSpecific, woundTypes] +// WoundTypes are the available wounds for this damage type. Format [[classID, selections, bleedingRate, pain], ..] +private _damageTypeInfo = [GVAR(allDamageTypesData) getVariable _typeOfDamage] param [0, [[], false, []]]; +_damageTypeInfo params ["_thresholds", "_isSelectionSpecific", "_woundTypes"]; -// This are the available injuries for this damage type. Format [[classtype, selections, bloodloss, minimalDamage, pain], ..] -_allInjuriesForDamageType = _injuryTypeInfo select 2; // It appears we are dealing with an unknown type of damage. - -if (count _allInjuriesForDamageType == 0) then { +if (count _woundTypes == 0) then { // grabbing the configuration for unknown damage type - _injuryTypeInfo = missionNamespace getVariable [QGVAR(woundInjuryType_unknown),[[], false, []]]; - _allInjuriesForDamageType = _injuryTypeInfo select 2; + _damageTypeInfo = [GVAR(allDamageTypesData) getVariable "unknown"] param [0, [[], false, []]]; + _woundTypes = _damageTypeInfo select 2; }; // find the available injuries for this damage type and damage amount -_highestPossibleSpot = -1; -_highestPossibleDamage = -1; -_allPossibleInjuries = []; +private _highestPossibleSpot = -1; +private _highestPossibleDamage = -1; +private _allPossibleInjuries = []; + { - _damageLevels = _x select 4; - _minDamage = _damageLevels select 0; - _maxDamage = _damageLevels select 1; + _x params ["", "_selections", "", "", "_damageExtrema"]; + _damageExtrema params ["_minDamage", "_maxDamage"]; // Check if the damage is higher as the min damage for the specific injury if (_damage >= _minDamage && {_damage <= _maxDamage || _maxDamage < 0}) then { - //_classType = _x select 0; - _selections = _x select 1; - //_bloodLoss = _x select 2; - //_pain = _x select 3; - // Check if the injury can be applied to the given selection name - if ("All" in _selections || _selectionName in _selections) then { + if ("All" in _selections || _bodyPart in _selections) then { // @todo, this is case sensitive! // Find the wound which has the highest minimal damage, so we can use this later on for adding the correct injuries if (_minDamage > _highestPossibleDamage) then { @@ -70,41 +63,48 @@ _allPossibleInjuries = []; _allPossibleInjuries pushBack _x; }; }; -} forEach _allInjuriesForDamageType; +} forEach _woundTypes; // No possible wounds available for this damage type or damage amount. if (_highestPossibleSpot < 0) exitWith {}; // Administration for open wounds and ids -_openWounds = _unit getVariable[QGVAR(openWounds), []]; -_woundID = _unit getVariable[QGVAR(lastUniqueWoundID), 1]; +private _openWounds = _unit getVariable [QGVAR(openWounds), []]; +private _woundID = _unit getVariable [QGVAR(lastUniqueWoundID), 1]; + +private _painToAdd = 0; +private _woundsCreated = []; -_painToAdd = 0; -_woundsCreated = []; { if (_x select 0 <= _damage) exitWith { for "_i" from 0 to ((_x select 1)-1) do { - // Find the injury we are going to add. Format [ classID, allowdSelections, bloodloss, painOfInjury, minimalDamage] - _toAddInjury = if (random(1) >= 0.85) then {_allInjuriesForDamageType select _highestPossibleSpot} else {selectRandom _allPossibleInjuries}; - _toAddClassID = _toAddInjury select 0; - _foundIndex = -1; + // Find the injury we are going to add. Format [ classID, allowdSelections, bleedingRate, injuryPain] + private _oldInjury = if (random 1 >= 0.85) then { + _woundTypes select _highestPossibleSpot + } else { + selectRandom _allPossibleInjuries + }; + + _oldInjury params ["_woundClassIDToAdd", "", "_injuryBleedingRate", "_injuryPain"]; + + private _bodyPartNToAdd = [floor random 6, _bodyPartN] select _isSelectionSpecific; // 6 == count ALL_BODY_PARTS - _bodyPartNToAdd = if (_injuryTypeInfo select 1) then {_bodyPartn} else {floor(random(6))}; // If the injury type is selection part specific, we will check if one of those injury types already exists and find the spot for it.. - if ((_injuryTypeInfo select 1)) then { + private _foundIndex = -1; + if (_isSelectionSpecific) then { { // Check if we have an id of the given class on the given bodypart already - if (_x select 1 == _toAddClassID && {_x select 2 == _bodyPartNToAdd}) exitWith { + if ((_woundClassIDToAdd isEqualTo (_x select 1)) && {_bodyPartNToAdd isEqualTo (_x select 2)}) exitWith { _foundIndex = _forEachIndex; }; } forEach _openWounds; }; - _injury = []; + private _injury = []; if (_foundIndex < 0) then { - // Create a new injury. Format [ID, classID, bodypart, percentage treated, bloodloss rate] - _injury = [_woundID, _toAddInjury select 0, _bodyPartNToAdd, 1, _toAddInjury select 2]; + // Create a new injury. Format [ID, classID, bodypart, percentage treated, bleeding rate] + _injury = [_woundID, _woundClassIDToAdd, _bodyPartNToAdd, 1, _injuryBleedingRate]; // Since it is a new injury, we will have to add it to the open wounds array to store it _openWounds pushBack _injury; @@ -116,14 +116,15 @@ _woundsCreated = []; _injury = _openWounds select _foundIndex; _injury set [3, (_injury select 3) + 1]; }; + // Store the injury so we can process it later correctly. _woundsCreated pushBack _injury; // Collect the pain that is caused by this injury - _painToAdd = _painToAdd + (_toAddInjury select 3); + _painToAdd = _injuryPain + _painToAdd; }; }; -} forEach (_injuryTypeInfo select 0); // forEach damage thresholds +} forEach _thresholds; _unit setVariable [QGVAR(openWounds), _openWounds, true]; @@ -132,6 +133,7 @@ if (count _woundsCreated > 0) then { _unit setVariable [QGVAR(lastUniqueWoundID), _woundID, true]; }; -_painLevel = _unit getVariable [QGVAR(pain), 0]; +private _painLevel = _unit getVariable [QGVAR(pain), 0]; _unit setVariable [QGVAR(pain), _painLevel + _painToAdd]; -TRACE_6("ACE_DEBUG: HandleDamage_WoundsOLD",_unit, _painLevel, _painToAdd, _unit getVariable QGVAR(pain), _unit getVariable QGVAR(openWounds),_woundsCreated); + +TRACE_6("exit",_unit, _painLevel, _painToAdd, _unit getVariable QGVAR(pain), _unit getVariable QGVAR(openWounds),_woundsCreated); diff --git a/addons/medical_damage/script_component.hpp b/addons/medical_damage/script_component.hpp index 4688366caa..b43c12dd0b 100644 --- a/addons/medical_damage/script_component.hpp +++ b/addons/medical_damage/script_component.hpp @@ -20,3 +20,5 @@ #define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) #define GET_STRING(config,default) (if (isText (config)) then {getText (config)} else {default}) #define GET_ARRAY(config,default) (if (isArray (config)) then {getArray (config)} else {default}) + +#define ALL_BODY_PARTS ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] diff --git a/addons/medical_engine/script_macros_medical.hpp b/addons/medical_engine/script_macros_medical.hpp index b2dba69a35..9e66568df1 100644 --- a/addons/medical_engine/script_macros_medical.hpp +++ b/addons/medical_engine/script_macros_medical.hpp @@ -55,7 +55,7 @@ armor = 1;\ material = -1;\ name = "head";\ - passThrough = 1;\ + passThrough = 0;\ radius = 1;\ explosionShielding = 1;\ visual = "";\