diff --git a/addons/medical/functions/fnc_displayPatientInformation.sqf b/addons/medical/functions/fnc_displayPatientInformation.sqf index 1489e27288..5f90c0ea2b 100644 --- a/addons/medical/functions/fnc_displayPatientInformation.sqf +++ b/addons/medical/functions/fnc_displayPatientInformation.sqf @@ -93,10 +93,10 @@ if (_show) then { // Collect the text to be displayed for this injury [ Select injury class type definition - select the classname DisplayName (6th), amount of injuries for this] if (_amountOf >= 1) then { // TODO localization - _allInjuryTexts pushback [format["%2x %1", (GVAR(AllWoundInjuryTypes) select _x1) select 6, ceil _amountOf], [1,1,1,1]]; + _allInjuryTexts pushback [format["%2x %1", (EGVAR(medical_damage,woundsData) select _x1) select 6, ceil _amountOf], [1,1,1,1]]; } else { // TODO localization - _allInjuryTexts pushback [format["Partial %1", (GVAR(AllWoundInjuryTypes) select _x1) select 6], [1,1,1,1]]; + _allInjuryTexts pushback [format["Partial %1", (EGVAR(medical_damage,woundsData) select _x1) select 6], [1,1,1,1]]; }; }; }; @@ -114,10 +114,10 @@ if (_show) then { if (_amountOf > 0) then { if (_amountOf >= 1) then { // TODO localization - _allInjuryTexts pushback [format["[B] %2x %1", (GVAR(AllWoundInjuryTypes) select (_x select 1)) select 6, ceil _amountOf], [0.88,0.7,0.65,1]]; + _allInjuryTexts pushback [format["[B] %2x %1", (EGVAR(medical_damage,woundsData) select (_x select 1)) select 6, ceil _amountOf], [0.88,0.7,0.65,1]]; } else { // TODO localization - _allInjuryTexts pushback [format["[B] Partial %1", (GVAR(AllWoundInjuryTypes) select (_x select 1)) select 6], [0.88,0.7,0.65,1]]; + _allInjuryTexts pushback [format["[B] Partial %1", (EGVAR(medical_damage,woundsData) select (_x select 1)) select 6], [0.88,0.7,0.65,1]]; }; }; }; diff --git a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf index 3233a7a179..5a4930f473 100644 --- a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf +++ b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf @@ -1,9 +1,10 @@ /* - * Author: Glowbal + * Author: Glowbal, commy2 * Parse the ACE_Medical_Advanced config for all injury types. * * Arguments: * None + * * ReturnValue: * None * @@ -11,183 +12,170 @@ */ #include "script_component.hpp" -private _injuriesRootConfig = (configFile >> "ACE_Medical_Injuries"); -private _allFoundDamageTypes = []; -private _configDamageTypes = (_injuriesRootConfig >> "damageTypes"); - -// minimum lethal damage collection, mapped to damageTypes -private _defaultMinLethalDamage = getNumber (_configDamageTypes >> "lethalDamage"); -GVAR(minLethalDamages) = []; -// Collect all available damage types from the config -for "_i" from 0 to (count _configDamageTypes -1) /* step +1 */ do { - // Only get the subclasses in damageType class - if (isClass(_configDamageTypes select _i)) then { - _allFoundDamageTypes pushBack (configName (_configDamageTypes select _i)); - private _minLethalDamage = if (isNumber((_configDamageTypes select _i) >> "lethalDamage")) then { - getNumber((_configDamageTypes select _i) >> "lethalDamage"); - } else { - _defaultMinLethalDamage - }; - - GVAR(minLethalDamages) pushBack _minLethalDamage; - }; -}; -GVAR(allAvailableDamageTypes) = _allFoundDamageTypes; -GVAR(woundClassNames) = []; -GVAR(fractureClassNames) = []; - -private _getIfInConfig = { +private _fnc_getAnyFromConfig = { params ["_config", "_default"]; + if (_default isEqualType []) exitWith { - if (isArray(_config)) then { getArray(_config)} else { _default }; + GET_ARRAY(_config,_default) }; + if (_default isEqualType 0) exitWith { - if (isNumber(_config)) then { getNumber(_config)} else { _default }; + GET_NUMBER(_config,_default) }; + if (_default isEqualType "") exitWith { - if (isText(_config)) then { getText(_config)} else { _default }; + GET_STRING(_config,_default) }; - _default; + + _default }; -// Parsing the wounds -// function for parsing a sublcass of an injury -private _parseForSubClassWounds = { +private _fnc_parseSubClassWounds = { params ["_subClass"]; - if (isClass (_entry >> _subClass)) exitWith { - private _subClassConfig = (_entry >> _subClass); - private _subClassselections = [_subClassConfig >> "selections", _selections] call _getIfInConfig; - private _subClasscauses = [_subClassConfig >> "causes", _causes] call _getIfInConfig; - if (count _subClassselections > 0 && {count _subClasscauses > 0}) then { + private _subClassConfig = _entry >> _subClass; + + if (isClass _subClassConfig) exitWith { + private _subClassSelections = [_subClassConfig >> "selections", _selections] call _fnc_getAnyFromConfig; + private _subClassCauses = [_subClassConfig >> "causes", _causes] call _fnc_getAnyFromConfig; + + if (count _subClassSelections > 0 && {count _subClassCauses > 0}) then { // constructs a type name, such as: 'woundMinor' - GVAR(woundClassNames) pushBack (_classType + (configName _subClassConfig)); - _allWoundClasses pushBack [ + GVAR(woundClassNames) pushBack (_className + configName _subClassConfig); + GVAR(woundsData) pushBack [ _classID, - _subClassselections, - [_subClassConfig >> "bleedingRate", _bloodLoss] call _getIfInConfig, - [_subClassConfig >> "pain", _pain] call _getIfInConfig, - [[_subClassConfig >> "minDamage", _minDamage] call _getIfInConfig, [_subClassConfig >> "maxDamage", _maxDamage] call _getIfInConfig], - _subClasscauses, - [_subClassConfig >> "name", (_classDisplayName + " " + _subClass)] call _getIfInConfig + _subClassSelections, + [_subClassConfig >> "bleedingRate", _bleedingRate] call _fnc_getAnyFromConfig, + [_subClassConfig >> "pain", _pain] call _fnc_getAnyFromConfig, + [[_subClassConfig >> "minDamage", _minDamage] call _fnc_getAnyFromConfig, [_subClassConfig >> "maxDamage", _maxDamage] call _fnc_getAnyFromConfig], + _subClassCauses, + [_subClassConfig >> "name", _displayName + " " + _subClass] call _fnc_getAnyFromConfig ]; + _classID = _classID + 1; }; - true; + + true }; - false; + + false }; -// TODO classTypes are strings currently. Convert them to unqiue IDs instead. -private _woundsConfig = (_injuriesRootConfig >> "wounds"); -private _allWoundClasses = []; +private _injuriesConfigRoot = configFile >> "ACE_Medical_Injuries"; + +// --- parse wounds +GVAR(woundClassNames) = []; +GVAR(woundsData) = []; // @todo classTypes are strings currently. Convert them to unqiue IDs instead. + +private _woundsConfig = _injuriesConfigRoot >> "wounds"; private _classID = 0; -if (isClass _woundsConfig) then { - private _amountOf = count _woundsConfig; - for "_i" from 0 to (_amountOf -1) /* step +1 */ do { - private _entry = _woundsConfig select _i; - if (isClass _entry) then { - private _classType = (ConfigName _entry); - private _selections = if (isArray(_entry >> "selections")) then { getArray(_entry >> "selections");} else {[]}; - private _bloodLoss = if (isNumber(_entry >> "bleedingRate")) then { getNumber(_entry >> "bleedingRate");} else {0}; - private _pain = if (isNumber(_entry >> "pain")) then { getNumber(_entry >> "pain");} else {0}; - private _minDamage = if (isNumber(_entry >> "minDamage")) then { getNumber(_entry >> "minDamage");} else {0}; - private _maxDamage = if (isNumber(_entry >> "maxDamage")) then { getNumber(_entry >> "maxDamage");} else {-1}; - private _causes = if (isArray(_entry >> "causes")) then { getArray(_entry >> "causes");} else {[]}; - private _classDisplayName = if (isText(_entry >> "name")) then { getText(_entry >> "name");} else {_classType}; - // TODO instead of hardcoding minor, medium and large just go through all sub classes recursively until none are found - if (["Minor"] call _parseForSubClassWounds || ["Medium"] call _parseForSubClassWounds || ["Large"] call _parseForSubClassWounds) exitWith {}; // continue to the next one - - // There were no subclasses, so we will add this one instead. - if (count _selections > 0 && count _causes > 0) then { - GVAR(woundClassNames) pushBack _classType; - _allWoundClasses pushBack [_classID, _selections, _bloodLoss, _pain, [_minDamage, _maxDamage], _causes, _classDisplayName]; - _classID = _classID + 1; - }; - true; - }; - }; -}; -GVAR(AllWoundInjuryTypes) = _allWoundClasses; - -// Linking injuries to the woundInjuryType variables. -private _damageTypesConfig = (_injuriesRootConfig >> "damageTypes"); -private _thresholds = getArray(_damageTypesConfig >> "thresholds"); -private _selectionSpecific = getNumber(_damageTypesConfig >> "selectionSpecific"); { - private _varName = format[QGVAR(woundInjuryType_%1),_x]; + private _entry = _x; + private _className = configName _entry; + + private _selections = GET_ARRAY(_entry >> "selections",[]); + private _bleedingRate = GET_NUMBER(_entry >> "bleedingRate",0); + private _pain = GET_NUMBER(_entry >> "pain",0); + private _minDamage = GET_NUMBER(_entry >> "minDamage",0); + private _maxDamage = GET_NUMBER(_entry >> "maxDamage",-1); + private _causes = GET_ARRAY(_entry >> "causes",[]); + private _displayName = GET_STRING(_entry >> "name",_className); + + // TODO instead of hardcoding minor, medium and large just go through all sub classes recursively until none are found + if ("Minor" call _fnc_parseSubClassWounds || "Medium" call _fnc_parseSubClassWounds || "Large" call _fnc_parseSubClassWounds) exitWith {}; // continue to the next one + + // There were no subclasses, so we will add this one instead. + if (count _selections > 0 && count _causes > 0) then { + GVAR(woundClassNames) pushBack _className; + GVAR(woundsData) pushBack [_classID, _selections, _bleedingRate, _pain, [_minDamage, _maxDamage], _causes, _displayName]; + _classID = _classID + 1; + }; +} forEach configProperties [_woundsConfig, "isClass _x"]; + +// --- parse fractures +//GVAR(fractureClassNames) = []; // unused + +// --- parse damage types +GVAR(allDamageTypes) = []; // @todo, currently unused by handle damage (was GVAR(allAvailableDamageTypes)) +GVAR(lethalDamages) = []; // @todo, currently unused by handle damage (was GVAR(minLethalDamages)) +GVAR(allDamageTypesData) = [] call CBA_fnc_createNamespace; + +// minimum lethal damage collection, mapped to damageTypes +private _damageTypesConfig = _injuriesConfigRoot >> "damageTypes"; +private _lethalDamageDefault = getNumber (_damageTypesConfig >> "lethalDamage"); +private _thresholdsDefault = getArray (_damageTypesConfig >> "thresholds"); +private _selectionSpecificDefault = getNumber (_damageTypesConfig >> "selectionSpecific"); + +// Collect all available damage types from the config +{ + private _entry = _x; + private _className = configName _entry; + + GVAR(allDamageTypes) pushBack _className; + GVAR(lethalDamages) pushBack GET_NUMBER(_entry >> "lethalDamage",_lethalDamageDefault); + + // Check if this type is in the causes of a wound class, if so, we will store the wound types for this damage type private _woundTypes = []; - private _type = _x; { - // Check if this type is in the causes of a wound class, if so, we will store the wound types for this damage type - if (_type in (_x select 5)) then { + if (_className in (_x select 5)) then { _woundTypes pushBack _x; }; - } forEach _allWoundClasses; - private _typeThresholds = _thresholds; - private _selectionSpecificType = _selectionSpecific; - if (isClass(_damageTypesConfig >> _x)) then { - if (isArray(_damageTypesConfig >> _x >> "thresholds")) then { _typeThresholds = getArray(_damageTypesConfig >> _x >> "thresholds");}; - if (isNumber(_damageTypesConfig >> _x >> "selectionSpecific")) then { _selectionSpecificType = getNumber(_damageTypesConfig >> _x >> "selectionSpecific");}; - }; + } forEach GVAR(woundsData); - // TODO use CBA namespace - missionNamespace setVariable [_varName, [_typeThresholds, _selectionSpecificType > 0, _woundTypes]]; + private _damageTypeSubClassConfig = _damageTypesConfig >> _className; + + private _thresholds = GET_ARRAY(_damageTypeSubClassConfig >> "thresholds",_thresholdsDefault); + private _selectionSpecific = GET_NUMBER(_damageTypeSubClassConfig >> "selectionSpecific",_selectionSpecificDefault); + + GVAR(allDamageTypesData) setVariable [_className, [_thresholds, _selectionSpecific > 0, _woundTypes]]; // extension loading - private _minDamageThresholds = ""; - private _amountThresholds = ""; - { - _minDamageThresholds = _minDamageThresholds + str(_x select 0); - _amountThresholds = _amountThresholds + str(_x select 1); - if (_forEachIndex < (count _typeThresholds) - 1) then { - _minDamageThresholds = _minDamageThresholds + ":"; - _amountThresholds = _amountThresholds + ":"; - }; - } forEach _typeThresholds; + private _minDamageThresholds = (_thresholds apply {str (_x select 0)}) joinString ":"; + private _amountThresholds = (_thresholds apply {str (_x select 1)}) joinString ":"; // load in the damage types into the medical extension - private _extensionRes = "ace_medical" callExtension format ["addDamageType,%1,%2,%3,%4,%5", - _type, - GVAR(minLethalDamages) select _forEachIndex, + private _extensionRes = "ace_medical" callExtension format [ + "addDamageType,%1,%2,%3,%4,%5", + _className, + GVAR(lethalDamages) select _forEachIndex, _minDamageThresholds, _amountThresholds, - _selectionSpecificType + _selectionSpecific ]; TRACE_1("",_extensionRes); -} forEach _allFoundDamageTypes; +} forEach configProperties [_damageTypesConfig, "isClass _x"]; // Extension loading { - _x params ["_classID", "_selections", "_bloodLoss", "_pain", "_damage", "_causesArray", "_classDisplayName"]; - _damage params ["_minDamage", "_maxDamage"]; + _x params ["_classID", "_selections", "_bleedingRate", "_pain", "_damageExtrema", "_causes", "_displayName"]; + _damageExtrema params ["_minDamage", "_maxDamage"]; private _className = GVAR(woundClassNames) select _forEachIndex; - if (_classDisplayName == "") then {_classDisplayName = _className; }; // fall back - private _allowedSelections = ""; - { - _allowedSelections = _allowedSelections + _x; - if (_forEachIndex < (count _selections) - 1) then { - _allowedSelections = _allowedSelections + ":"; - }; - } forEach _selections; + if (_displayName isEqualTo "") then { + _displayName = _className; + }; - private _causes = ""; - { - _causes = _causes + _x; - if (_forEachIndex < (count _causesArray) - 1) then { - _causes = _causes + ":"; - }; - } forEach _causesArray; + private _selections = _selections joinString ":"; + private _causes = _causes joinString ":"; - private _extensionArgs = format ["addInjuryType,%1,%2,%3,%4,%5,%6,%7,%8,%9", _classID, _className, _allowedSelections, _bloodLoss, _pain, _minDamage, _maxDamage, _causes, _classDisplayName]; + private _extensionArgs = format [ + "addInjuryType,%1,%2,%3,%4,%5,%6,%7,%8,%9", + _classID, + _className, + _selections, + _bleedingRate, + _pain, + _minDamage, + _maxDamage, + _causes, + _displayName + ]; TRACE_1("",_extensionArgs); private _extensionRes = "ace_medical" callExtension _extensionArgs; TRACE_1("",_extensionRes); - -} forEach _allWoundClasses; +} forEach GVAR(woundsData); "ace_medical" callExtension "ConfigComplete"; diff --git a/addons/medical_damage/functions/fnc_woundsHandlerSqf.sqf b/addons/medical_damage/functions/fnc_woundsHandlerSqf.sqf index 693730e353..978458952a 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerSqf.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerSqf.sqf @@ -29,7 +29,7 @@ if (_bodyPartn < 0) exitWith {}; if (_typeOfDamage == "") then {_typeOfDamage = "unknown";}; // Get the injury type information. Format: [typeDamage thresholds, selectionSpecific, woundTypes] -_injuryTypeInfo = missionNamespace getVariable [format[QGVAR(woundInjuryType_%1), _typeOfDamage],[[], false, []]]; +_injuryTypeInfo = [GVAR(allDamageTypesData) getVariable _typeOfDamage] param [0, [[], false, []]]; // This are the available injuries for this damage type. Format [[classtype, selections, bloodloss, minimalDamage, pain], ..] _allInjuriesForDamageType = _injuryTypeInfo select 2; diff --git a/addons/medical_damage/script_component.hpp b/addons/medical_damage/script_component.hpp index fed195ddfa..4688366caa 100644 --- a/addons/medical_damage/script_component.hpp +++ b/addons/medical_damage/script_component.hpp @@ -16,3 +16,7 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#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}) diff --git a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf index e13bdf1ea9..74e53aadac 100644 --- a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf +++ b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf @@ -22,7 +22,7 @@ private ["_className", "_reopeningChance", "_reopeningMinDelay", "_reopeningMaxD params ["_target", "_impact", "_part", "_injuryIndex", "_injury", "_bandage"]; private _classID = _injury select 1; -private _className = EGVAR(medical,woundClassNames) select _classID; +private _className = EGVAR(medical_damage,woundClassNames) select _classID; // default, just in case.. private _reopeningChance = 0.1; diff --git a/addons/medical_treatment/functions/fnc_treatmentAdvanced_bandageLocal.sqf b/addons/medical_treatment/functions/fnc_treatmentAdvanced_bandageLocal.sqf index 922b4b41f1..4394231084 100644 --- a/addons/medical_treatment/functions/fnc_treatmentAdvanced_bandageLocal.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentAdvanced_bandageLocal.sqf @@ -50,7 +50,7 @@ private _exit = false; private _woundEffectiveness = _effectiveness; // Select the classname from the wound classname storage - private _className = EGVAR(medical,woundClassNames) select _classID; + private _className = EGVAR(medical_damage,woundClassNames) select _classID; // Check if this wound type has attributes specified for the used bandage if (isClass (_config >> _className)) then {