Merge pull request #814 from acemod/basic-med-options

Basic medical module options
This commit is contained in:
Glowbal 2015-05-01 12:27:22 +02:00
commit f0efba09e5
12 changed files with 123 additions and 64 deletions

View File

@ -22,6 +22,10 @@ class ACE_Settings {
typeName = "SCALAR"; typeName = "SCALAR";
value = 1; value = 1;
}; };
class GVAR(painCoefficient) {
typeName = "SCALAR";
value = 1;
};
class GVAR(enableAirway) { class GVAR(enableAirway) {
typeName = "BOOL"; typeName = "BOOL";
value = false; value = false;
@ -50,10 +54,10 @@ class ACE_Settings {
typeName = "SCALAR"; typeName = "SCALAR";
value = 1; value = 1;
}; };
class GVAR(enableUnsconsiousnessAI) { class GVAR(enableUnconsiousnessAI) {
value = 1; value = 1;
typeName = "SCALAR"; typeName = "SCALAR";
values[] = {"Disabled", "Enabled", "50/50"}; values[] = {"Disabled", "50/50", "Enabled"};
}; };
class GVAR(preventInstaDeath) { class GVAR(preventInstaDeath) {
typeName = "BOOL"; typeName = "BOOL";

View File

@ -87,7 +87,7 @@ class CfgVehicles {
typeName = "NUMBER"; typeName = "NUMBER";
defaultValue = 1; defaultValue = 1;
}; };
class enableUnsconsiousnessAI { class enableUnconsiousnessAI {
displayName = "AI Unconsciousness"; displayName = "AI Unconsciousness";
description = "Allow AI to go unconscious"; description = "Allow AI to go unconscious";
typeName = "NUMBER"; typeName = "NUMBER";
@ -97,12 +97,12 @@ class CfgVehicles {
value = 0; value = 0;
}; };
class normal { class normal {
name = "Enabled"; name = "50/50";
value = 1; value = 1;
default = 1; default = 1;
}; };
class full { class full {
name = "50/50"; name = "Enabled";
value = 2; value = 2;
}; };
}; };
@ -119,6 +119,12 @@ class CfgVehicles {
typeName = "NUMBER"; typeName = "NUMBER";
defaultValue = 1; defaultValue = 1;
}; };
class painCoefficient {
displayName = "Pain coefficient";
description = "Coefficient to modify the pain intensity";
typeName = "NUMBER";
defaultValue = 1;
};
class keepLocalSettingsSynced { class keepLocalSettingsSynced {
displayName = "Sync status"; displayName = "Sync status";
description = "Keep unit status synced. Recommended on."; description = "Keep unit status synced. Recommended on.";

View File

@ -133,7 +133,7 @@ GVAR(effectTimeBlood) = time;
}; };
}; };
_bleeding = ACE_player call FUNC(getBloodLoss); _bleeding = [ACE_player] call FUNC(getBloodLoss);
// Bleeding Indicator // Bleeding Indicator
if (_bleeding > 0 and GVAR(effectTimeBlood) + 3.5 < time) then { if (_bleeding > 0 and GVAR(effectTimeBlood) + 3.5 < time) then {
GVAR(effectTimeBlood) = time; GVAR(effectTimeBlood) = time;
@ -169,7 +169,7 @@ GVAR(lastHeartBeatSound) = time;
// Pain effect // Pain effect
_strength = ACE_player getVariable [QGVAR(pain), 0]; _strength = ACE_player getVariable [QGVAR(pain), 0];
// _strength = _strength * (ACE_player getVariable [QGVAR(coefPain), GVAR(coefPain)]); @todo _strength = _strength * (ACE_player getVariable [QGVAR(painCoefficient), GVAR(painCoefficient)]);
if (GVAR(painEffectType) == 1) then { if (GVAR(painEffectType) == 1) then {
GVAR(effectPainCC) ppEffectEnable false; GVAR(effectPainCC) ppEffectEnable false;
if ((ACE_player getVariable [QGVAR(pain), 0]) > 0 && {alive ACE_player}) then { if ((ACE_player getVariable [QGVAR(pain), 0]) > 0 && {alive ACE_player}) then {
@ -253,7 +253,7 @@ if (USE_WOUND_EVENT_SYNC) then {
[ [
{(((_this select 0) getvariable [QGVAR(bloodVolume), 100]) < 65)}, {(((_this select 0) getvariable [QGVAR(bloodVolume), 100]) < 65)},
{(((_this select 0) getvariable [QGVAR(pain), 0]) > 0.9)}, {(((_this select 0) getvariable [QGVAR(pain), 0]) > 0.9)},
{(((_this select 0) call FUNC(getBloodLoss)) > 0.25)}, {(([_this select 0] call FUNC(getBloodLoss)) > 0.25)},
{((_this select 0) getvariable [QGVAR(inReviveState), false])}, {((_this select 0) getvariable [QGVAR(inReviveState), false])},
{((_this select 0) getvariable [QGVAR(inCardiacArrest), false])}, {((_this select 0) getvariable [QGVAR(inCardiacArrest), false])},
{((_this select 0) getvariable ["ACE_isDead", false])}, {((_this select 0) getvariable ["ACE_isDead", false])},

View File

@ -8,7 +8,13 @@ if !(local _unit) exitWith {};
[_unit] call FUNC(init); [_unit] call FUNC(init);
//Reset captive status for respawning unit // Reset captive status for respawning unit
if (!(_unit getVariable ["ACE_isUnconscious", false])) then { if (!(_unit getVariable ["ACE_isUnconscious", false])) then {
[_unit, QGVAR(unconscious), false] call EFUNC(common,setCaptivityStatus); [_unit, QGVAR(unconscious), false] call EFUNC(common,setCaptivityStatus);
}; };
// Remove maximum unconsciousness time handler
_maxUnconHandle = _unit getVariable [QGVAR(maxUnconTimeHandle), -1];
if (_maxUnconHandle > 0) then {
[_maxUnconHandle] call CBA_fnc_removePerFrameHandler;
};

View File

@ -15,15 +15,17 @@
#define BLOODLOSSRATE_BASIC 0.2 #define BLOODLOSSRATE_BASIC 0.2
private ["_totalBloodLoss","_tourniquets","_openWounds", "_cardiacOutput", "_internalWounds"]; private ["_unit", "_totalBloodLoss","_tourniquets","_openWounds", "_cardiacOutput", "_internalWounds"];
// TODO Only use this calculation if medium or higher, otherwise use vanilla calculations (for basic medical). // TODO Only use this calculation if medium or higher, otherwise use vanilla calculations (for basic medical).
_unit = _this select 0;
_totalBloodLoss = 0; _totalBloodLoss = 0;
// Advanced medical bloodloss handling // Advanced medical bloodloss handling
if (GVAR(level) >= 2) then { if (GVAR(level) >= 2) then {
_tourniquets = _this getvariable [QGVAR(tourniquets), [0,0,0,0,0,0]]; _tourniquets = _unit getvariable [QGVAR(tourniquets), [0,0,0,0,0,0]];
_openWounds = _this getvariable [QGVAR(openWounds), []]; _openWounds = _unit getvariable [QGVAR(openWounds), []];
//_cardiacOutput = [_this] call FUNC(getCardiacOutput); //_cardiacOutput = [_unit] call FUNC(getCardiacOutput);
{ {
if ((_tourniquets select (_x select 2)) == 0) then { if ((_tourniquets select (_x select 2)) == 0) then {
@ -34,7 +36,7 @@ if (GVAR(level) >= 2) then {
}; };
}foreach _openWounds; }foreach _openWounds;
_internalWounds = _this getvariable [QGVAR(internalWounds), []]; _internalWounds = _unit getvariable [QGVAR(internalWounds), []];
{ {
_totalBloodLoss = _totalBloodLoss + ((_x select 4) * (_x select 3)); _totalBloodLoss = _totalBloodLoss + ((_x select 4) * (_x select 3));
}foreach _internalWounds; }foreach _internalWounds;
@ -42,6 +44,6 @@ if (GVAR(level) >= 2) then {
// cap the blood loss to be no greater as the current cardiac output // cap the blood loss to be no greater as the current cardiac output
//(_totalBloodLoss min _cardiacOutput); //(_totalBloodLoss min _cardiacOutput);
} else { } else {
_totalBloodLoss = BLOODLOSSRATE_BASIC * (damage _this); _totalBloodLoss = BLOODLOSSRATE_BASIC * (damage _unit);
}; };
_totalBloodLoss * (GVAR(bleedingCoefficient) max 0); _totalBloodLoss * ((_unit getVariable [QGVAR(bleedingCoefficient), GVAR(bleedingCoefficient)]) max 0);

View File

@ -34,7 +34,7 @@ private ["_unit","_bloodVolume","_bloodVolumeChange", "_ivVolume"];
_unit = _this select 0; _unit = _this select 0;
_bloodVolume = _unit getvariable [QGVAR(bloodVolume), 100]; _bloodVolume = _unit getvariable [QGVAR(bloodVolume), 100];
_bloodVolumeChange = -(_unit call FUNC(getBloodLoss)); _bloodVolumeChange = -([_unit] call FUNC(getBloodLoss));
if (_bloodVolume < 100.0) then { if (_bloodVolume < 100.0) then {
{ {

View File

@ -20,7 +20,7 @@ _unit = _this select 0;
_hrIncrease = 0; _hrIncrease = 0;
if (!(_unit getvariable [QGVAR(inCardiacArrest),false])) then { if (!(_unit getvariable [QGVAR(inCardiacArrest),false])) then {
_heartRate = _unit getvariable [QGVAR(heartRate), 80]; _heartRate = _unit getvariable [QGVAR(heartRate), 80];
_bloodLoss = _unit call FUNC(getBloodLoss); _bloodLoss = [_unit] call FUNC(getBloodLoss);
_adjustment = _unit getvariable [QGVAR(heartRateAdjustments), []]; _adjustment = _unit getvariable [QGVAR(heartRateAdjustments), []];
{ {
@ -83,4 +83,4 @@ if (!(_unit getvariable [QGVAR(inCardiacArrest),false])) then {
_hrIncrease = _hrIncrease - HEART_RATE_MODIFIER; _hrIncrease = _hrIncrease - HEART_RATE_MODIFIER;
}; };
}; };
_hrIncrease _hrIncrease

View File

@ -17,12 +17,12 @@
#include "script_component.hpp" #include "script_component.hpp"
private ["_unit", "_selection", "_damage", "_shooter", "_projectile", "_damageReturn", "_typeOfDamage", "_minLethalDamage", "_newDamage", "_typeIndex"]; private ["_unit", "_selection", "_damage", "_shooter", "_projectile", "_damageReturn", "_typeOfDamage", "_minLethalDamage", "_newDamage", "_typeIndex", "_preventDeath"];
_unit = _this select 0; _unit = _this select 0;
_selection = _this select 1; _selection = _this select 1;
_damage = _this select 2; _damage = _this select 2;
_shooter = _this select 3; _shooter = _this select 3;
_projectile = _this select 4; _projectile = _this select 4;
if !(local _unit) exitWith {nil}; if !(local _unit) exitWith {nil};
@ -34,6 +34,30 @@ if (typeName _projectile == "OBJECT") then {
// If the damage is being weird, we just tell it to fuck off. // If the damage is being weird, we just tell it to fuck off.
if !(_selection in (GVAR(SELECTIONS) + [""])) exitWith {0}; if !(_selection in (GVAR(SELECTIONS) + [""])) exitWith {0};
// Exit if we disable damage temporarily
_damageOld = damage _unit;
if (_selection in GVAR(SELECTIONS)) then {
_damageOld = _unit getHit _selection;
};
if !(_unit getVariable [QGVAR(allowDamage), true]) exitWith {_damageOld};
// Figure out whether to prevent death before handling damage
if (diag_frameno > (_unit getVariable [QGVAR(frameNo), -3]) + 2) then {
_unit setVariable [QGVAR(frameNo), diag_frameno];
_unit setVariable [QGVAR(wasUnconscious), _unit getVariable ["ACE_isUnconscious", false]];
_preventDeath = _unit getVariable [QGVAR(preventInstaDeath), GVAR(preventInstaDeath)];
if (_unit getVariable ["ACE_isUnconscious", false]) then {
_preventDeath = _unit getVariable [QGVAR(enableRevive), GVAR(enableRevive)];
if !([_unit] call EFUNC(common,isPlayer)) then {
_preventDeath = _preventDeath - 1;
};
_preventDeath = _preventDeath > 0;
};
_unit setVariable [QGVAR(preventDeath), _preventDeath];
};
// Get return damage
_damageReturn = _damage; _damageReturn = _damage;
if (GVAR(level) < 2) then { if (GVAR(level) < 2) then {
_damageReturn = _this call FUNC(handleDamage_basic); _damageReturn = _this call FUNC(handleDamage_basic);
@ -73,26 +97,30 @@ if (GVAR(level) < 2) then {
}; };
[_unit] call FUNC(addToInjuredCollection); [_unit] call FUNC(addToInjuredCollection);
if (_unit getVariable [QGVAR(preventInstaDeath), GVAR(preventInstaDeath)]) exitWith { // Prevent death if necessary
if (_damageReturn >= 0.9 && {_selection in ["", "head", "body"]}) exitWith { if (_unit getVariable QGVAR(preventDeath)) then {
if (_unit getvariable ["ACE_isUnconscious", false]) exitwith { if (_selection in ["", "head", "body"]) then {
_damageReturn = _damageReturn min 0.89;
};
// Move the unit out of the vehicle if necessary
if (vehicle _unit != _unit and damage (vehicle _unit) == 1) then {
[_unit] call EFUNC(common,unloadPerson);
if (_unit getVariable QGVAR(wasUnconscious)) then {
[_unit] call FUNC(setDead); [_unit] call FUNC(setDead);
0.89 } else {
[_unit, true] call FUNC(setUnconscious);
}; };
[{ [_this select 0, true] call FUNC(setUnconscious); }, [_unit]] call EFUNC(common,execNextFrame);
0.89
}; };
_damageReturn min 0.89;
};
if (((_unit getVariable [QGVAR(enableRevive), GVAR(enableRevive)]) > 0) && {_damageReturn >= 0.9} && {_selection in ["", "head", "body"]}) exitWith { // Temporarily disable all damage to prevent stuff like
if (vehicle _unit != _unit and {damage (vehicle _unit) >= 1}) then { // being killed during the animation etc.
// @todo if (!_wasUnconscious and (_unit getVariable ["ACE_isUnconscious", false])) then {
// [_unit] call FUNC(unload); _unit setVariable [QGVAR(allowDamage), false];
[{
_this setVariable [QGVAR(allowDamage), true];
}, _unit, 0.7, 0] call EFUNC(common,waitAndExecute);
}; };
[_unit] call FUNC(setDead);
0.89
}; };
_damageReturn _damageReturn

View File

@ -26,22 +26,28 @@
private ["_unit", "_selectionName", "_damage", "_shooter", "_projectile", "_damage", "_armdamage", "_hitPoint", "_index", "_legdamage", "_newDamage", "_otherDamage", "_pain", "_restore"]; private ["_unit", "_selectionName", "_damage", "_shooter", "_projectile", "_damage", "_armdamage", "_hitPoint", "_index", "_legdamage", "_newDamage", "_otherDamage", "_pain", "_restore"];
_unit = _this select 0; _unit = _this select 0;
_selectionName = _this select 1; _selectionName = _this select 1;
_damage = _this select 2; _damage = _this select 2;
_shooter = _this select 3; _shooter = _this select 3;
_projectile = _this select 4; _projectile = _this select 4;
// Apply damage treshold / coefficient
_threshold = [
_unit getVariable [QGVAR(damageThreshold), GVAR(AIDamageThreshold)],
_unit getVariable [QGVAR(damageThreshold), GVAR(playerDamageThreshold)]
] select ([_unit] call EFUNC(common,isPlayer));
_damage = _damage * (1 / _threshold);
// This is a new hit, reset variables. // This is a new hit, reset variables.
// Note: sometimes handleDamage spans over 2 or even 3 frames. // Note: sometimes handleDamage spans over 2 or even 3 frames.
if (diag_frameno > (_unit getVariable [QGVAR(frameNo), -3]) + 2) then { if (diag_frameno > (_unit getVariable [QGVAR(basic_frameNo), -3]) + 2) then {
_unit setVariable [QGVAR(frameNo), diag_frameno]; _unit setVariable [QGVAR(basic_frameNo), diag_frameno];
_unit setVariable [QGVAR(isFalling), false]; _unit setVariable [QGVAR(isFalling), false];
_unit setVariable [QGVAR(projectiles), []]; _unit setVariable [QGVAR(projectiles), []];
_unit setVariable [QGVAR(hitPoints), []]; _unit setVariable [QGVAR(hitPoints), []];
_unit setVariable [QGVAR(damages), []]; _unit setVariable [QGVAR(damages), []];
_unit setVariable [QGVAR(structDamage), 0]; _unit setVariable [QGVAR(structDamage), 0];
_unit setVariable [QGVAR(preventDeath), false];
// Assign orphan structural damage to torso // Assign orphan structural damage to torso
[{ [{
private ["_unit", "_damagesum"]; private ["_unit", "_damagesum"];
@ -172,11 +178,7 @@ if (_selectionName == "" and
_damage < 1 and _damage < 1 and
!(_unit getVariable ["ACE_isUnconscious", False] !(_unit getVariable ["ACE_isUnconscious", False]
)) then { )) then {
if (_unit getVariable [QGVAR(allowUnconscious), ([_unit] call EFUNC(common,isPlayer)) or random 1 > 0.3]) then { [_unit, true] call FUNC(setUnconscious);
[_unit, true] call FUNC(setUnconscious);
} else {
_damage = 1;
};
}; };
_damage _damage

View File

@ -49,7 +49,7 @@ if (_bloodVolume < 100) then {
}; };
}; };
if ((_unit call FUNC(getBloodLoss)) > 0) then { if (([_unit] call FUNC(getBloodLoss)) > 0) then {
if !(_unit getvariable [QGVAR(isBleeding), false]) then { if !(_unit getvariable [QGVAR(isBleeding), false]) then {
_unit setvariable [QGVAR(isBleeding), true, true]; _unit setvariable [QGVAR(isBleeding), true, true];
}; };

View File

@ -29,7 +29,8 @@ if !(_activated) exitWith {};
[_logic, QGVAR(enableScreams), "enableScreams"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(enableScreams), "enableScreams"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(playerDamageThreshold), "playerDamageThreshold"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(playerDamageThreshold), "playerDamageThreshold"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(AIDamageThreshold), "AIDamageThreshold"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(AIDamageThreshold), "AIDamageThreshold"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(enableUnsconsiousnessAI), "enableUnsconsiousnessAI"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(enableUnconsiousnessAI), "enableUnconsiousnessAI"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(preventInstaDeath), "preventInstaDeath"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(preventInstaDeath), "preventInstaDeath"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(bleedingCoefficient), "bleedingCoefficient"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(bleedingCoefficient), "bleedingCoefficient"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(painCoefficient), "painCoefficient"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(keepLocalSettingsSynced), "keepLocalSettingsSynced"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(keepLocalSettingsSynced), "keepLocalSettingsSynced"] call EFUNC(common,readSettingFromModule);

View File

@ -22,6 +22,9 @@ _unit = _this select 0;
_set = if (count _this > 1) then {_this select 1} else {true}; _set = if (count _this > 1) then {_this select 1} else {true};
_minWaitingTime = if (count _this > 2) then {_this select 2} else {DEFAULT_DELAY}; _minWaitingTime = if (count _this > 2) then {_this select 2} else {DEFAULT_DELAY};
// No change, fuck off. (why is there no xor?)
if (_set isEqualTo (_unit getVariable ["ACE_isUnconscious", false])) exitWith {};
if !(_set) exitwith { if !(_set) exitwith {
_unit setvariable ["ACE_isUnconscious", false, true]; _unit setvariable ["ACE_isUnconscious", false, true];
}; };
@ -43,16 +46,17 @@ if (_unit == ACE_player) then {
}; };
// if we have unconsciousness for AI disabled, we will kill the unit instead // if we have unconsciousness for AI disabled, we will kill the unit instead
if (!([_unit] call EFUNC(common,IsPlayer)) && (GVAR(enableUnsconsiousnessAI) == 0 || (GVAR(enableUnsconsiousnessAI) == 2 && random(1) <= 0.5))) exitwith { if !([_unit] call EFUNC(common,isPlayer)) then {
[_unit, true] call FUNC(setDead); // force, to avoid getting into a loop in case revive is enabled. _enableUncon = _unit getVariable [QGVAR(enableUnconsciousnessAI), GVAR(enableUnconsciousnessAI)];
if (_enableUncon == 0 or {_enableUncon == 1 and (random 1) < 0.5}) exitWith {
[_unit, true] call FUNC(setDead);
};
}; };
// If a unit has the launcher out, it will sometimes start selecting the primairy weapon while unconscious, // If a unit has the launcher out, it will sometimes start selecting the primairy weapon while unconscious,
// therefor we force it to select the primairy weapon before going unconscious // therefor we force it to select the primairy weapon before going unconscious
if ((vehicle _unit) isKindOf "StaticWeapon") then { if ((vehicle _unit) isKindOf "StaticWeapon") then {
moveOut _unit; [_unit] call EFUNC(common,unloadPerson);
unassignVehicle _unit;
//_unit action ["eject", vehicle _unit];
}; };
if (animationState _unit in ["ladderriflestatic","laddercivilstatic"]) then { if (animationState _unit in ["ladderriflestatic","laddercivilstatic"]) then {
_unit action ["ladderOff", (nearestBuilding _unit)]; _unit action ["ladderOff", (nearestBuilding _unit)];
@ -62,8 +66,6 @@ if (vehicle _unit == _unit) then {
_unit addWeapon "ACE_FakePrimaryWeapon"; _unit addWeapon "ACE_FakePrimaryWeapon";
}; };
_unit selectWeapon (primaryWeapon _unit); _unit selectWeapon (primaryWeapon _unit);
_unit switchMove "";
_unit playmoveNow "";
}; };
// We are storing the current animation, so we can use it later on when waking the unit up inside a vehicle // We are storing the current animation, so we can use it later on when waking the unit up inside a vehicle
@ -80,7 +82,15 @@ if (GVAR(moveUnitsFromGroupOnUnconscious)) then {
}; };
[_unit, QGVAR(unconscious), true] call EFUNC(common,setCaptivityStatus); [_unit, QGVAR(unconscious), true] call EFUNC(common,setCaptivityStatus);
[_unit, [_unit] call EFUNC(common,getDeathAnim), 1, true] call EFUNC(common,doAnimation); _anim = [_unit] call EFUNC(common,getDeathAnim);
[_unit, _anim, 1, true] call EFUNC(common,doAnimation);
[{
_unit = _this select 0;
_anim = _this select 1;
if ((_unit getVariable "ACE_isUnconscious") and (animationState _unit != _anim)) then {
[_unit, _anim, 2, true] call EFUNC(common,doAnimation);
};
}, [_unit, _anim], 0.5, 0] call EFUNC(common,waitAndExecute);
_startingTime = time; _startingTime = time;