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";
value = 1;
};
class GVAR(painCoefficient) {
typeName = "SCALAR";
value = 1;
};
class GVAR(enableAirway) {
typeName = "BOOL";
value = false;
@ -50,10 +54,10 @@ class ACE_Settings {
typeName = "SCALAR";
value = 1;
};
class GVAR(enableUnsconsiousnessAI) {
class GVAR(enableUnconsiousnessAI) {
value = 1;
typeName = "SCALAR";
values[] = {"Disabled", "Enabled", "50/50"};
values[] = {"Disabled", "50/50", "Enabled"};
};
class GVAR(preventInstaDeath) {
typeName = "BOOL";

View File

@ -87,7 +87,7 @@ class CfgVehicles {
typeName = "NUMBER";
defaultValue = 1;
};
class enableUnsconsiousnessAI {
class enableUnconsiousnessAI {
displayName = "AI Unconsciousness";
description = "Allow AI to go unconscious";
typeName = "NUMBER";
@ -97,12 +97,12 @@ class CfgVehicles {
value = 0;
};
class normal {
name = "Enabled";
name = "50/50";
value = 1;
default = 1;
};
class full {
name = "50/50";
class full {
name = "Enabled";
value = 2;
};
};
@ -119,6 +119,12 @@ class CfgVehicles {
typeName = "NUMBER";
defaultValue = 1;
};
class painCoefficient {
displayName = "Pain coefficient";
description = "Coefficient to modify the pain intensity";
typeName = "NUMBER";
defaultValue = 1;
};
class keepLocalSettingsSynced {
displayName = "Sync status";
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
if (_bleeding > 0 and GVAR(effectTimeBlood) + 3.5 < time) then {
GVAR(effectTimeBlood) = time;
@ -169,7 +169,7 @@ GVAR(lastHeartBeatSound) = time;
// Pain effect
_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 {
GVAR(effectPainCC) ppEffectEnable false;
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(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(inCardiacArrest), false])},
{((_this select 0) getvariable ["ACE_isDead", false])},

View File

@ -8,7 +8,13 @@ if !(local _unit) exitWith {};
[_unit] call FUNC(init);
//Reset captive status for respawning unit
// Reset captive status for respawning unit
if (!(_unit getVariable ["ACE_isUnconscious", false])) then {
[_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
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).
_unit = _this select 0;
_totalBloodLoss = 0;
// Advanced medical bloodloss handling
if (GVAR(level) >= 2) then {
_tourniquets = _this getvariable [QGVAR(tourniquets), [0,0,0,0,0,0]];
_openWounds = _this getvariable [QGVAR(openWounds), []];
//_cardiacOutput = [_this] call FUNC(getCardiacOutput);
_tourniquets = _unit getvariable [QGVAR(tourniquets), [0,0,0,0,0,0]];
_openWounds = _unit getvariable [QGVAR(openWounds), []];
//_cardiacOutput = [_unit] call FUNC(getCardiacOutput);
{
if ((_tourniquets select (_x select 2)) == 0) then {
@ -34,7 +36,7 @@ if (GVAR(level) >= 2) then {
};
}foreach _openWounds;
_internalWounds = _this getvariable [QGVAR(internalWounds), []];
_internalWounds = _unit getvariable [QGVAR(internalWounds), []];
{
_totalBloodLoss = _totalBloodLoss + ((_x select 4) * (_x select 3));
}foreach _internalWounds;
@ -42,6 +44,6 @@ if (GVAR(level) >= 2) then {
// cap the blood loss to be no greater as the current cardiac output
//(_totalBloodLoss min _cardiacOutput);
} 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;
_bloodVolume = _unit getvariable [QGVAR(bloodVolume), 100];
_bloodVolumeChange = -(_unit call FUNC(getBloodLoss));
_bloodVolumeChange = -([_unit] call FUNC(getBloodLoss));
if (_bloodVolume < 100.0) then {
{

View File

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

View File

@ -17,12 +17,12 @@
#include "script_component.hpp"
private ["_unit", "_selection", "_damage", "_shooter", "_projectile", "_damageReturn", "_typeOfDamage", "_minLethalDamage", "_newDamage", "_typeIndex"];
_unit = _this select 0;
_selection = _this select 1;
_damage = _this select 2;
_shooter = _this select 3;
_projectile = _this select 4;
private ["_unit", "_selection", "_damage", "_shooter", "_projectile", "_damageReturn", "_typeOfDamage", "_minLethalDamage", "_newDamage", "_typeIndex", "_preventDeath"];
_unit = _this select 0;
_selection = _this select 1;
_damage = _this select 2;
_shooter = _this select 3;
_projectile = _this select 4;
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 !(_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;
if (GVAR(level) < 2) then {
_damageReturn = _this call FUNC(handleDamage_basic);
@ -73,26 +97,30 @@ if (GVAR(level) < 2) then {
};
[_unit] call FUNC(addToInjuredCollection);
if (_unit getVariable [QGVAR(preventInstaDeath), GVAR(preventInstaDeath)]) exitWith {
if (_damageReturn >= 0.9 && {_selection in ["", "head", "body"]}) exitWith {
if (_unit getvariable ["ACE_isUnconscious", false]) exitwith {
// Prevent death if necessary
if (_unit getVariable QGVAR(preventDeath)) then {
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);
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 {
if (vehicle _unit != _unit and {damage (vehicle _unit) >= 1}) then {
// @todo
// [_unit] call FUNC(unload);
// Temporarily disable all damage to prevent stuff like
// being killed during the animation etc.
if (!_wasUnconscious and (_unit getVariable ["ACE_isUnconscious", false])) then {
_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

View File

@ -26,22 +26,28 @@
private ["_unit", "_selectionName", "_damage", "_shooter", "_projectile", "_damage", "_armdamage", "_hitPoint", "_index", "_legdamage", "_newDamage", "_otherDamage", "_pain", "_restore"];
_unit = _this select 0;
_selectionName = _this select 1;
_damage = _this select 2;
_shooter = _this select 3;
_projectile = _this select 4;
_unit = _this select 0;
_selectionName = _this select 1;
_damage = _this select 2;
_shooter = _this select 3;
_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.
// Note: sometimes handleDamage spans over 2 or even 3 frames.
if (diag_frameno > (_unit getVariable [QGVAR(frameNo), -3]) + 2) then {
_unit setVariable [QGVAR(frameNo), diag_frameno];
if (diag_frameno > (_unit getVariable [QGVAR(basic_frameNo), -3]) + 2) then {
_unit setVariable [QGVAR(basic_frameNo), diag_frameno];
_unit setVariable [QGVAR(isFalling), false];
_unit setVariable [QGVAR(projectiles), []];
_unit setVariable [QGVAR(hitPoints), []];
_unit setVariable [QGVAR(damages), []];
_unit setVariable [QGVAR(structDamage), 0];
_unit setVariable [QGVAR(preventDeath), false];
// Assign orphan structural damage to torso
[{
private ["_unit", "_damagesum"];
@ -172,11 +178,7 @@ if (_selectionName == "" and
_damage < 1 and
!(_unit getVariable ["ACE_isUnconscious", False]
)) then {
if (_unit getVariable [QGVAR(allowUnconscious), ([_unit] call EFUNC(common,isPlayer)) or random 1 > 0.3]) then {
[_unit, true] call FUNC(setUnconscious);
} else {
_damage = 1;
};
[_unit, true] call FUNC(setUnconscious);
};
_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 {
_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(playerDamageThreshold), "playerDamageThreshold"] 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(bleedingCoefficient), "bleedingCoefficient"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(painCoefficient), "painCoefficient"] 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};
_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 {
_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 (!([_unit] call EFUNC(common,IsPlayer)) && (GVAR(enableUnsconsiousnessAI) == 0 || (GVAR(enableUnsconsiousnessAI) == 2 && random(1) <= 0.5))) exitwith {
[_unit, true] call FUNC(setDead); // force, to avoid getting into a loop in case revive is enabled.
if !([_unit] call EFUNC(common,isPlayer)) then {
_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,
// therefor we force it to select the primairy weapon before going unconscious
if ((vehicle _unit) isKindOf "StaticWeapon") then {
moveOut _unit;
unassignVehicle _unit;
//_unit action ["eject", vehicle _unit];
[_unit] call EFUNC(common,unloadPerson);
};
if (animationState _unit in ["ladderriflestatic","laddercivilstatic"]) then {
_unit action ["ladderOff", (nearestBuilding _unit)];
@ -62,8 +66,6 @@ if (vehicle _unit == _unit) then {
_unit addWeapon "ACE_FakePrimaryWeapon";
};
_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
@ -80,7 +82,15 @@ if (GVAR(moveUnitsFromGroupOnUnconscious)) then {
};
[_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;