Optimization for new wound system

This commit is contained in:
Glowbal 2015-03-03 22:13:22 +01:00
parent c5a27d3cd7
commit e4756efaa0
3 changed files with 55 additions and 14 deletions

View File

@ -71,7 +71,7 @@ if (_highestPossibleSpot < 0) exitwith {
};
};
// admin for open wounds and ids
// Administration for open wounds and ids
_openWounds = _unit getvariable[QGVAR(openWounds), []];
_woundID = _unit getvariable[QGVAR(lastUniqueWoundID), 1];
@ -81,16 +81,38 @@ _woundsCreated = [];
if (_x select 0 <= _damage) exitwith {
for "_i" from 0 to (1+ floor(random(_x select 1)-1)) /* step +1 */ do {
// Find the injury we are going to add. Format [ classType, allowdSelections, bloodloss, painOfInjury, minimalDamage]
// Find the injury we are going to add. Format [ classID, allowdSelections, bloodloss, painOfInjury, minimalDamage]
_toAddInjury = _allPossibleInjuries select (floor(random (count _allPossibleInjuries)));
_toAddClassID = _toAddInjury select 0;
_foundIndex = -1;
// Create a new injury. Format [ID, classname, bodypart, percentage treated, bloodloss rate]
_injury = [_woundID, _toAddInjury select 0, if (_injuryTypeInfo select 1) then {_bodyPartn} else {floor(random(6))}, 1, _toAddInjury select 2];
// 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 {
{
// Check if we have an id of the given class on the given bodypart already
if (_x select 0 == _toAddClassID && {_x select 2 == _bodyPartn}) exitwith {
_foundIndex = _foreachIndex;
};
}foreach _openWounds;
};
_injury = [];
if (_foundIndex < 0) then {
// Create a new injury. Format [ID, classID, bodypart, percentage treated, bloodloss rate]
_injury = [_woundID, _toAddInjury select 0, if (_injuryTypeInfo select 1) then {_bodyPartn} else {floor(random(6))}, 1, _toAddInjury select 2];
// Since it is a new injury, we will have to add it to the open wounds array to store it
_openWounds pushback _injury;
// New injuries will also increase the wound ID
_woundID = _woundID + 1;
} else {
// We already have one of these, so we are just going to increase the number that we have of it with a new one.
_injury = _openWounds select _foreachIndex;
_injury set [3, (_injury select 3) + 1];
};
// Store the injury so we can process it later correctly.
_openWounds pushback _injury;
_woundsCreated pushback _injury;
_woundID = _woundID + 1;
// Collect the pain that is caused by this injury
_painToAdd = _painToAdd + (_toAddInjury select 3);
@ -99,8 +121,13 @@ _woundsCreated = [];
}foreach (_injuryTypeInfo select 0);
_unit setvariable [QGVAR(openWounds), _openWounds];
_unit setvariable [QGVAR(lastUniqueWoundID), _woundID, true];
// Only update if new wounds have been created
if (count _woundsCreated > 0) then {
_unit setvariable [QGVAR(lastUniqueWoundID), _woundID, true];
};
// TODO Should this be done in a single broadcast?
// Broadcast the new injuries across the net in parts. One broadcast per injury. Prevents having to broadcast one massive array of injuries.
{
["medical_propagateWound", [_unit, _x]] call EFUNC(common,globalEvent);

View File

@ -17,15 +17,21 @@ private ["_injuriesRootConfig", "_woundsConfig", "_allWoundClasses", "_amountOf"
_injuriesRootConfig = (configFile >> "ACE_Medical_Advanced" >> "Injuries");
_allTypes = ["stab", "grenade", "bullet", "explosive", "shell", "punch", "vehiclecrash", "backblast", "falling", "bite", "ropeburn"];
// Collect all available damage types from the config
_allFoundDamageTypes = [];
_configDamageTypes = (_injuriesRootConfig >> "damageTypes");
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));
};
};
GVAR(allAvailableDamageTypes) = _allFoundDamageTypes;
// Creating a hash map to map wound IDs to classnames
GVAR(woundClassNameIDHash) = HASHCREATE;
// function for parsing a sublcass of an injury
_parseForSubClassWounds = {
_subClass = _this select 0;
if (isClass (_entry >> _subClass)) exitwith {
@ -37,8 +43,10 @@ _parseForSubClassWounds = {
_subClassminDamage = if (isNumber(_subClassConfig >> "minDamage")) then { getNumber(_subClassConfig >> "minDamage");} else { _minDamage };
_subClasscauses = if (isArray(_subClassConfig >> "causes")) then { getArray(_subClassConfig >> "causes");} else { _causes };
_subClassDisplayName = if (isText(_entry >> "name")) then { getText(_entry >> "name");} else {_classDisplayName + " " + _subClass};
if (count _selections > 0 && count _causes > 0) then {
_allWoundClasses pushback [_subClasstype, _subClassselections, _subClassbloodLoss, _subClasspain, _subClassminDamage, _subClasscauses, _subClassDisplayName];
if (count _selections > 0 && {count _causes > 0}) then {
HASH_SET(GVAR(woundClassNameIDHash), _classID, _subClasstype);
_allWoundClasses pushback [_classID, _subClassselections, _subClassbloodLoss, _subClasspain, _subClassminDamage, _subClasscauses, _subClassDisplayName];
_classID = _classID + 1;
};
true;
};
@ -48,6 +56,7 @@ _parseForSubClassWounds = {
// TODO classTypes are strings currently. Convert them to unqiue IDs instead.
_woundsConfig = (_injuriesRootConfig >> "wounds");
_allWoundClasses = [];
_classID = 0;
if (isClass _woundsConfig) then {
_amountOf = count _woundsConfig;
for "_i" from 0 to (_amountOf -1) /* step +1 */ do {
@ -60,11 +69,15 @@ if (isClass _woundsConfig) then {
_minDamage = if (isNumber(_entry >> "minDamage")) then { getNumber(_entry >> "minDamage");} else {0};
_causes = if (isArray(_entry >> "causes")) then { getArray(_entry >> "causes");} else {[]};
_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 {
_allWoundClasses pushback [_classType, _selections, _bloodLoss, _pain, _minDamage, _causes, _classDisplayName];
HASH_SET(GVAR(woundClassNameIDHash), _classID, _classType);
_allWoundClasses pushback [_classID, _selections, _bloodLoss, _pain, _minDamage, _causes, _classDisplayName];
_classID = _classID + 1;
};
true;
};
@ -76,6 +89,7 @@ _damageTypesConfig = (configFile >> "ACE_Medical_Advanced" >> "Injuries" >> "dam
_thresholds = getArray(_damageTypesConfig >> "thresholds");
_selectionSpecific = getNumber(_damageTypesConfig >> "selectionSpecific");
// Linking injuries to the woundInjuryType variables.
{
_varName = format[QGVAR(woundInjuryType_%1),_x];
_woundTypes = [];
@ -93,4 +107,4 @@ _selectionSpecific = getNumber(_damageTypesConfig >> "selectionSpecific");
if (isNumber(_damageTypesConfig >> _x >> "selectionSpecific")) then { _selectionSpecificType = getNumber(_damageTypesConfig >> _x >> "selectionSpecific");};
};
missionNamespace setvariable [_varName, [_typeThresholds, _selectionSpecificType > 0, _woundTypes]];
}foreach _allTypes;
}foreach _allFoundDamageTypes;

View File

@ -43,12 +43,12 @@ _mostEffectiveInjury = _openWounds select 0;
// Only parse injuries that are for the selected bodypart.
if (_x select 2 == _part) then {
_woundEffectivenss = _effectiveness;
_classID = (_x select 1);
// Check if this wound type has attributes specified for the used bandage
if (isClass (_config >> (_x select 1))) then {
if (HASH_HASKEY(GVAR(woundClassNameIDHash), _classID)) then {
// Collect the effectiveness from the used bandage for this wound type
_woundTreatmentConfig = (_config >> (_x select 1));
_woundTreatmentConfig = (_config >> (HASH_GET(GVAR(woundClassNameIDHash), _classID)));
if (isNumber (_woundTreatmentConfig >> "effectiveness")) then {
_woundEffectivenss = getNumber (_woundTreatmentConfig >> "effectiveness");
};