Merge pull request #300 from KoffeinFlummi/medicalImprovements

Medical Litter & other additions
This commit is contained in:
Glowbal 2015-04-04 22:52:05 +02:00
commit b18d704686
44 changed files with 471 additions and 123 deletions

View File

@ -36,11 +36,7 @@ if (count _this > 3) then {
};
// don't overwrite more important animations
if (_unit getVariable ["ACE_isUnconscious", false] && {!_force}) exitWith {
if (_animation != "Unconscious") then {
[_unit, "Unconscious", 2] call FUNC(doAnimation);
};
};
if (_unit getVariable ["ACE_isUnconscious", false] && {(_animation != "Unconscious")} && {!_force}) exitWith {};
// don't go unconscious if the unit isn't unconscious
if (_animation == "Unconscious" && {!((_unit getVariable ["ACE_isUnconscious", false]) || (_unit getVariable ["ACE_isDead", false]))}) exitWith {};

View File

@ -22,4 +22,4 @@ if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false};
// a static weapon has to be empty for dragging
if ((typeOf _target) isKindOf "StaticWeapon" && {count crew _target > 0}) exitWith {false};
alive _target && {_target getVariable [QGVAR(canCarry), false]} && {animationState _target in ["", "unconscious"]}
alive _target && {_target getVariable [QGVAR(canCarry), false]} && {animationState _target in ["", "unconscious"] || (_target getvariable ["ACE_isUnconscious", false])}

View File

@ -22,4 +22,4 @@ if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false};
// a static weapon has to be empty for dragging
if ((typeOf _target) isKindOf "StaticWeapon" && {count crew _target > 0}) exitWith {false};
alive _target && {_target getVariable [QGVAR(canDrag), false]} && {animationState _target in ["", "unconscious"]}
alive _target && {_target getVariable [QGVAR(canDrag), false]} && {animationState _target in ["", "unconscious"] || (_target getvariable ["ACE_isUnconscious", false])}

View File

@ -18,10 +18,13 @@ class ACE_Medical_Actions {
callbackProgress = "";
animationPatient = "";
animationCaller = "AinvPknlMstpSnonWnonDnon_medic4";
animationPatientUnconscious = "AinjPpneMstpSnonWrflDnon_rolltoback";
animationPatientUnconsciousExcludeOn[] = {"ainjppnemstpsnonwrfldnon"};
animationCaller = "AinvPknlMstpSlayWnonDnon_medic";
animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
animationCallerSelf = "AinvPknlMstpSlayW[wpn]Dnon_medic";
animationCallerSelfProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
litter[] = { {"All", "", {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}} };
};
class Morphine: Bandage {
displayName = "$STR_ACE_Medical_Inject_Morphine";
@ -30,6 +33,7 @@ class ACE_Medical_Actions {
items[] = {"ACE_morphine"};
callbackSuccess = QUOTE(DFUNC(treatmentBasic_morphine));
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = { {"All", "", {"ACE_MedicalLitter_morphine"}} };
};
class Epinephrine: Bandage {
displayName = "$STR_ACE_Medical_Inject_Epinephrine";
@ -39,6 +43,7 @@ class ACE_Medical_Actions {
items[] = {"ACE_epinephrine"};
callbackSuccess = QUOTE(DFUNC(treatmentBasic_epipen));
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = { {"All", "", {"ACE_MedicalLitter_epinephrine"}} };
};
class BloodIV: Bandage {
displayName = "$STR_ACE_Medical_Transfuse_Blood";
@ -48,6 +53,7 @@ class ACE_Medical_Actions {
items[] = {{"ACE_bloodIV", "ACE_bloodIV_500", "ACE_bloodIV_250"}};
callbackSuccess = QUOTE(DFUNC(treatmentBasic_bloodbag));
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = {};
};
class Tourniquet: Bandage {
displayName = "$STR_ACE_Medical_Apply_Tourniquet";
@ -56,6 +62,7 @@ class ACE_Medical_Actions {
treatmentTime = 6;
callbackSuccess = QUOTE(DFUNC(treatmentTourniquet));
condition = QUOTE(!([ARR_2(_this select 1, _this select 2)] call FUNC(hasTourniquetAppliedTo)));
litter[] = {};
};
class BodyBag: Bandage {
displayName = "$STR_ACE_MEDICAL_PlaceInBodyBag";
@ -69,8 +76,22 @@ class ACE_Medical_Actions {
callbackFailure = "";
callbackProgress = "";
animationPatient = "";
animationPatientUnconscious = "";
itemConsumed = 0;
litter[] = {};
};
/*class PersonalAidKit: Bandage {
displayName = "";
displayNameProgress = "";
items[] = {"ACE_personalAidKit"};
treatmentLocations[] = {"All"};
requiredMedic = 1;
treatmentTime = 15;
callbackSuccess = QUOTE(DFUNC(treatmentAdvanced_fullHeal));
itemConsumed = 0;
animationCaller = "AinvPknlMstpSlayW[wpn]Dnon_medic";
litter[] = { {"All", "", {"ACE_MedicalLitter_gloves"}}, {"All", "", {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}, {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}} };
};*/
};
class Advanced {
@ -92,10 +113,13 @@ class ACE_Medical_Actions {
callbackProgress = "";
itemConsumed = 1;
animationPatient = "";
animationCaller = "AinvPknlMstpSnonWnonDnon_medic4";
animationPatientUnconscious = "AinjPpneMstpSnonWrflDnon_rolltoback";
animationPatientUnconsciousExcludeOn[] = {"ainjppnemstpsnonwrfldnon"};
animationCaller = "AinvPknlMstpSlayWnonDnon_medic";
animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
animationCallerSelf = "AinvPknlMstpSlayW[wpn]Dnon_medic";
animationCallerSelfProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
litter[] = { {"All", "", {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}} };
};
class PackingBandage: fieldDressing {
items[] = {"ACE_packingBandage"};
@ -113,6 +137,7 @@ class ACE_Medical_Actions {
treatmentTime = 6;
callbackSuccess = QUOTE(DFUNC(treatmentTourniquet));
condition = QUOTE(!([ARR_2(_this select 1, _this select 2)] call FUNC(hasTourniquetAppliedTo)));
litter[] = {};
};
class Morphine: fieldDressing {
displayName = "$STR_ACE_Medical_Inject_Morphine";
@ -121,16 +146,19 @@ class ACE_Medical_Actions {
treatmentTime = 3;
callbackSuccess = QUOTE(DFUNC(treatmentAdvanced_medication));
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = { {"All", "", {"ACE_MedicalLitter_morphine"}} };
};
class Atropine: Morphine {
displayName = "$STR_ACE_Medical_Inject_Atropine";
displayNameProgress = "$STR_ACE_Medical_Injecting_Atropine";
items[] = {"ACE_atropine"};
litter[] = { {"All", "", {"ACE_MedicalLitter_atropine"}} };
};
class Epinephrine: Morphine {
displayName = "$STR_ACE_Medical_Inject_Epinephrine";
displayNameProgress = "$STR_ACE_Medical_Injecting_Epinephrine";
items[] = {"ACE_epinephrine"};
litter[] = { {"All", "", {"ACE_MedicalLitter_epinephrine"}} };
};
class BloodIV: fieldDressing {
displayName = "$STR_ACE_Medical_Transfuse_Blood";
@ -140,6 +168,7 @@ class ACE_Medical_Actions {
treatmentTime = 7;
callbackSuccess = QUOTE(DFUNC(treatmentIV));
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = {};
};
class BloodIV_500: BloodIV {
items[] = {"ACE_bloodIV_500"};
@ -176,22 +205,29 @@ class ACE_Medical_Actions {
displayNameProgress = "";
items[] = {"ACE_surgicalKit"};
treatmentLocations[] = {"MedicalFacility", "MedicalVehicle"};
requiredMedic = 2;
treatmentTime = 15;
requiredMedic = QGVAR(medicSetting_SurgicalKit);
treatmentTime = 10;
callbackSuccess = QUOTE(DFUNC(treatmentAdvanced_surgicalKit));
itemConsumed = 0;
itemConsumed = QGVAR(consumeItem_SurgicalKit);
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = { {"All", "", {"ACE_MedicalLitter_gloves"} }};
};
class PersonalAidKit: fieldDressing {
displayName = "";
displayNameProgress = "";
items[] = {"ACE_personalAidKit"};
treatmentLocations[] = {"All"};
requiredMedic = 1;
treatmentTime = 15;
requiredMedic = QGVAR(medicSetting_PAK);
treatmentTime = 10;
callbackSuccess = QUOTE(DFUNC(treatmentAdvanced_fullHeal));
itemConsumed = 0;
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
itemConsumed = QGVAR(consumeItem_PAK);
animationPatient = "";
animationPatientUnconscious = "AinjPpneMstpSnonWrflDnon_rolltoback";
animationCaller = "AinvPknlMstpSlayWnonDnon_medic";
animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
animationCallerSelf = "";
animationCallerSelfProne = "";
litter[] = { {"All", "", {"ACE_MedicalLitter_gloves"}}, {"All", "", {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}} }, {"All", "", {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}} };
};
class CheckPulse: fieldDressing {
displayName = "";
@ -206,6 +242,7 @@ class ACE_Medical_Actions {
animationPatient = "";
animationCaller = ""; // TODO
itemConsumed = 0;
litter[] = {};
};
class CheckBloodPressure: CheckPulse {
callbackSuccess = QUOTE(DFUNC(actionCheckBloodPressure));
@ -223,15 +260,20 @@ class ACE_Medical_Actions {
displayNameProgress = "Performing CPR";
treatmentLocations[] = {"All"};
requiredMedic = 0;
treatmentTime = 25;
treatmentTime = 15;
items[] = {};
condition = "((_this select 1) getvariable ['ACE_medical_inCardiacArrest', false])";
callbackSuccess = QUOTE(DFUNC(treatmentAdvanced_CPR));
callbackFailure = "";
callbackProgress = "";
callbackProgress = "((_this select 1) getvariable ['ACE_medical_inCardiacArrest', false])";
animationPatient = "";
animationCaller = ""; // TODO
animationPatientUnconscious = "AinjPpneMstpSnonWrflDnon_rolltoback";
animationCaller = "AinvPknlMstpSlayWnonDnon_medic";
animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
animationCallerSelf = "";
animationCallerSelfProne = "";
itemConsumed = 0;
litter[] = {};
};
class BodyBag: fieldDressing {
displayName = "$STR_ACE_MEDICAL_PlaceInBodyBag";
@ -245,7 +287,9 @@ class ACE_Medical_Actions {
callbackFailure = "";
callbackProgress = "";
animationPatient = "";
animationPatientUnconscious = "";
itemConsumed = 0;
litter[] = {};
};
};
};

View File

@ -14,16 +14,12 @@ class ACE_Settings {
typeName = "SCALAR";
values[] = {"Players only", "Players and AI"};
};
class GVAR(maxRevives) {
typeName = "NUMBER";
value = 1;
};
class GVAR(enableOverdosing) {
typeName = "BOOL";
value = true;
};
class GVAR(bleedingCoefficient) {
typeName = "NUMBER";
typeName = "SCALAR";
value = 1;
};
@ -48,16 +44,16 @@ class ACE_Settings {
value = true;
};
class GVAR(playerDamageThreshold) {
typeName = "NUMBER";
typeName = "SCALAR";
value = 1;
};
class GVAR(AIDamageThreshold) {
typeName = "NUMBER";
typeName = "SCALAR";
value = 1;
};
class GVAR(enableUnsconsiousnessAI) {
value = 1;
typeName = "NUMBER";
typeName = "SCALAR";
values[] = {"Disabled", "Enabled", "50/50"};
};
class GVAR(preventInstaDeath) {
@ -65,11 +61,39 @@ class ACE_Settings {
value = false;
};
class GVAR(maxReviveTime) {
typeName = "NUMBER";
typeName = "SCALAR";
value = 120;
};
class GVAR(amountOfReviveLives) {
typeName = "SCALAR";
value = -1;
};
class GVAR(allowDeadBodyMovement) {
typeName = "BOOL";
value = false;
};
class GVAR(allowLitterCreation) {
typeName = "BOOL";
value = true;
};
class GVAR(litterCleanUpDelay) {
typeName = "SCALAR";
value = 1800;
};
class GVAR(medicSetting_PAK) {
typeName = "SCALAR";
value = 1;
};
class GVAR(medicSetting_SurgicalKit) {
typeName = "SCALAR";
value = 1;
};
class GVAR(consumeItem_PAK) {
typeName = "SCALAR";
value = 0;
};
class GVAR(consumeItem_SurgicalKit) {
typeName = "SCALAR";
value = 0;
};
};

View File

@ -122,6 +122,12 @@ class CfgVehicles {
typeName = "BOOL";
defaultValue = 0;
};
class bleedingCoefficient {
displayName = "Bleeding coefficient";
description = "Coefficient to modify the bleeding speed";
typeName = "NUMBER";
defaultValue = 1;
};
};
class ModuleDescription {
description = "Provides a medical system for both players and AI.";
@ -131,7 +137,7 @@ class CfgVehicles {
class ACE_moduleTreatmentConfiguration: ACE_Module {
scope = 2;
displayName = "Treatment Configuration [ACE]";
displayName = "Treatment Settings [ACE]";
icon = QUOTE(PATHTOF(UI\Icon_Module_Medical_ca.paa));
category = "ACE_medical";
function = QUOTE(FUNC(moduleTreatmentConfiguration));
@ -161,17 +167,17 @@ class CfgVehicles {
};
};
};
class maxRevives {
displayName = "Max revives";
description = "Max amount of revives available (when preventing death)";
typeName = "NUMBER";
defaultValue = 1;
};
class maxReviveTime {
displayName = "Max Revive time";
description = "Max amount of seconds a unit can spend in revive state";
typeName = "NUMBER";
defaultValue = 1;
defaultValue = 120;
};
class amountOfReviveLives {
displayName = "Max Revive lives";
description = "Max amount of lives a unit. 0 or -1 is disabled.";
typeName = "NUMBER";
defaultValue = -1;
};
class enableOverdosing {
displayName = "Enable Overdosing";
@ -179,12 +185,46 @@ class CfgVehicles {
typeName = "BOOL";
defaultValue = 1;
};
class bleedingCoefficient {
displayName = "Bleeding coefficient";
description = "Coefficient to modify the bleeding speed";
typeName = "NUMBER";
class allowLitterCreation {
displayName = "Enable Litter";
description = "Enable litter being created upon treatment";
typeName = "BOOL";
defaultValue = 1;
};
class litterCleanUpDelay {
displayName = "Life time of litter objects";
description = "How long should litter objects stay? In seconds. -1 is forever.";
typeName = "NUMBER";
defaultValue = 1800;
};
class medicSetting_PAK {
displayName = "Allow PAK";
description = "Who can use the PAK for full heal?";
typeName = "NUMBER";
class values {
class anyone { name = "Anyone"; value = 0; };
class Medic { name = "Medics only"; value = 1; default = 1; };
class Special { name = "Doctors only (Adv)"; value = 2; };
};
};
class consumeItem_PAK {
displayName = "Remove PAK on use";
description = "Should PAK be removed on usage?";
typeName = "NUMBER";
class values {
class keep { name = "No"; value = 0; };
class remove { name = "Yes"; value = 1; default = 1; };
};
};
class medicSetting_SurgicalKit: medicSetting_PAK {
displayName = "Allow Surgical kit";
description = "Who can use the surgical kit?";
};
class consumeItem_SurgicalKit: consumeItem_PAK {
displayName = "Remove Surgical kit";
description = "Should Surgical kit be removed on usage?";
};
};
class ModuleDescription {
description = "Configure the treatment settings from ACE Medical";
@ -227,7 +267,6 @@ class CfgVehicles {
class doctor {
name = "Doctor (Only Advanced Medics)";
value = 1;
default = 1;
};
};
};
@ -259,8 +298,18 @@ class CfgVehicles {
class enabled {
displayName = "Is Medical Vehicle";
description = "Whatever or not the objects in the list will be a medical vehicle.";
typeName = "BOOL";
defaultValue = 1;
typeName = "NUMBER";
class values {
class none {
name = "No";
value = 0;
};
class medic {
name = "Yes";
value = 1;
default = 1;
};
};
};
};
class ModuleDescription {
@ -1689,6 +1738,40 @@ class CfgVehicles {
icon = "";
displayName = $STR_ACE_MEDICAL_BODYBAG_DISPLAY;
};
// Medical litter classes
class Thing;
class ACE_MedicalLitterBase: Thing {
scope = 1;
displayName = " ";
destrType = "DestructNo";
model = QUOTE(PATHTOF(data\littergeneric.p3d));
};
class ACE_MedicalLitter_bandage1: ACE_MedicalLitterBase {
model = QUOTE(PATHTOF(data\littergeneric_bandages1.p3d));
};
class ACE_MedicalLitter_bandage2: ACE_MedicalLitterBase {
model = QUOTE(PATHTOF(data\littergeneric_bandages2.p3d));
};
class ACE_MedicalLitter_bandage3: ACE_MedicalLitterBase {
model = QUOTE(PATHTOF(data\littergeneric_bandages3.p3d));
};
class ACE_MedicalLitter_packingBandage: ACE_MedicalLitterBase {
model = QUOTE(PATHTOF(data\litter_packingBandage.p3d));
};
class ACE_MedicalLitter_gloves: ACE_MedicalLitterBase {
model = QUOTE(PATHTOF(data\littergeneric_gloves.p3d));
};
class ACE_MedicalLitter_atropine: ACE_MedicalLitterBase {
model = QUOTE(PATHTOF(data\litter_atropine.p3d));
};
class ACE_MedicalLitter_epinephrine: ACE_MedicalLitterBase {
model = QUOTE(PATHTOF(data\litter_epinephrine.p3d));
};
class ACE_MedicalLitter_morphine: ACE_MedicalLitterBase {
model = QUOTE(PATHTOF(data\litter_morphine.p3d));
};
class Item_Base_F;
class ACE_fieldDressingItem: Item_Base_F {
scope = 2;

View File

@ -25,7 +25,7 @@ class CfgWeapons {
class ACE_ItemCore;
class ACE_fieldDressing: ACE_ItemCore {
scope = 2;
model = "\A3\Structures_F_EPA\Items\Medical\Bandage_F.p3d";
model = QUOTE(PATHTOF(data\bandage.p3d));
picture = QUOTE(PATHTOF(ui\items\fieldDressing.paa));
displayName = $STR_ACE_MEDICAL_BANDAGE_BASIC_DISPLAY;
descriptionShort = $STR_ACE_MEDICAL_BANDAGE_BASIC_DESC_SHORT;

View File

@ -237,6 +237,7 @@ if (USE_WOUND_EVENT_SYNC) then {
{(((_this select 0) getvariable [QGVAR(pain), 0]) > 0.9)},
{(((_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])},
{(((_this select 0) getvariable [QGVAR(airwayStatus), 100]) < 80)}
] call FUNC(addUnconsciousCondition);

View File

@ -23,6 +23,7 @@ PREP(canAccessMedicalEquipment);
PREP(canTreat);
PREP(canTreatCached);
PREP(canCarry);
PREP(createLitter);
PREP(determineIfFatal);
PREP(getBloodLoss);
PREP(getBloodPressure);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -30,7 +30,15 @@ if (GVAR(level)>=2) then {
};
if !(isClass _config) exitwith {false};
_medicRequired = getNumber (_config >> "requiredMedic");
_medicRequired = if (isNumber (_config >> "requiredMedic")) then {
getNumber (_config >> "requiredMedic");
} else {
// Check for required class
if (isText (_config >> "requiredMedic")) exitwith {
missionNamespace getvariable [(getText (_config >> "requiredMedic")), 0];
};
0;
};
if !([_caller, _medicRequired] call FUNC(isMedic)) exitwith {false};
_items = getArray (_config >> "items");

View File

@ -0,0 +1,110 @@
/*
* Author: Glowbal
* Spawns litter for the treatment action on the ground around the target
*
* Arguments:
* 0: The target <OBJECT>
* 1: The treatment classname <STRING>
*
* Return Value:
*
*
* Public: No
*/
#include "script_component.hpp"
#define MIN_ENTRIES_LITTER_CONFIG 3
private ["_target", "_className", "_config", "_litter", "_createLitter", "_litterObject", "_position", "_createdLitter"];
_caller = _this select 0;
_target = _this select 1;
_selectionName = _this select 2;
_className = _this select 3;
_usersOfItems = _this select 5;
if !(GVAR(allowLitterCreation)) exitwith {};
_config = (configFile >> "ACE_Medical_Actions" >> "Basic" >> _className);
if (GVAR(level) >= 2) then {
_config = (configFile >> "ACE_Medical_Actions" >> "Advanced" >> _className);
};
if !(isClass _config) exitwith {false};
if !(isArray (_config >> "litter")) exitwith {};
_litter = getArray (_config >> "litter");
_createLitter = {
_position = getPos (_this select 0);
_litterClass = _this select 1;
_litterObject = createVehicle [_litterClass, _position, [], 0, "NONE"];
if (random(1) >= 0.5) then {
_litterObject setPos [(_position select 0) + random 2, (_position select 1) + random 2, _position select 2];
} else {
_litterObject setPos [(_position select 0) - random 2, (_position select 1) - random 2, _position select 2];
};
_litterObject setDir (random 360);
_litterObject;
};
if (isnil QGVAR(allCreatedLitter)) then {
GVAR(allCreatedLitter) = [];
GVAR(litterPFHRunning) = false;
};
_createdLitter = [];
{
if (typeName _x == "ARRAY") then {
if (count _x < MIN_ENTRIES_LITTER_CONFIG) exitwith {};
private ["_selection", "_litterCondition", "_litterOptions"];
_selection = _x select 0;
if (toLower _selection in [toLower _selectionName, "all"]) then { // in is case sensitve. We can be forgiving here, so lets use toLower.
_litterCondition = _x select 1;
_litterOptions = _x select 2;
if (isnil _litterCondition) then {
_litterCondition = if (_litterCondition != "") then {compile _litterCondition} else {{true}};
} else {
_litterCondition = missionNamespace getvariable _litterCondition;
};
if !([_caller, _target, _selectionName, _className, _usersOfItems] call _litterCondition) exitwith {};
if (typeName _litterOptions == "ARRAY") then {
// Loop through through the litter options and place the litter
{
if (typeName _x == "ARRAY" && {(count _x > 0)}) then {
_createdLitter pushback ([_target, _x select (floor(random(count _x)))] call _createLitter);
};
if (typeName _x == "STRING") then {
_createdLitter pushback ([_target, _x] call _createLitter);
};
}foreach _litterOptions;
};
};
};
}foreach _litter;
if (GVAR(litterCleanUpDelay) >= 0) then {
GVAR(allCreatedLitter) pushback [time, GVAR(litterCleanUpDelay), _createdLitter];
};
if !(GVAR(litterPFHRunning)) then {
GVAR(litterPFHRunning) = true;
[{
{
if (time - (_x select 0) >= (_x select 1)) then {
{
deleteVehicle _x;
}foreach (_this select 2);
GVAR(allCreatedLitter) set[_foreachIndex, objNull];
};
}foreach GVAR(allCreatedLitter);
GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull];
if (count GVAR(allCreatedLitter) == 0) exitwith {
GVAR(litterPFHRunning) = false;
[_this select 1] call CBA_fnc_removePerFrameHandler;
};
}, 30, []] call CBA_fnc_addPerFrameHandler;
};

View File

@ -44,7 +44,7 @@ if (GVAR(level) >= 2) then {
if !([_unit] call FUNC(hasMedicalEnabled)) exitwith {
// Because of the config changes, we cannot properly disable the medical system for a unit.
// lets use basic for the time being..
_this call FUNC(handleDamage_basic);
_damageReturn = _this call FUNC(handleDamage_basic);
};
[_unit, _selection, _damage, _source, _projectile] call FUNC(handleDamage_caching);
@ -60,7 +60,7 @@ if (GVAR(level) >= 2) then {
_newDamage = _damage - (_unit getHitPointDamage (_hitPoints select (_hitSelections find _selection)));
};
if ((_minLethalDamage <= _newDamage) && {[_unit, [_selection] call FUNC(selectionNameToNumber), _newDamage] call FUNC(determineIfFatal)}) then {
if ((_minLethalDamage <= _newDamage) && {[_unit, [_selection] call FUNC(selectionNameToNumber), _newDamage] call FUNC(determineIfFatal)} && {_selection in ["", "head", "body"]}) then {
if ([_unit] call FUNC(setDead)) then {
_damageReturn = 1;
} else {
@ -73,11 +73,13 @@ if (GVAR(level) >= 2) then {
};
[_unit] call FUNC(addToInjuredCollection);
if (_unit getVariable [QGVAR(preventDeath), GVAR(preventInstaDeath)] && {_damageReturn >= 0.9} && {_selection in ["", "head", "body"]}) exitWith {
if ((_unit getVariable [QGVAR(preventInstaDeath), GVAR(preventInstaDeath)]) && {_damageReturn >= 0.9} && {_selection in ["", "head", "body"]}) exitWith {
if (vehicle _unit != _unit and {damage _vehicle >= 1}) then {
// @todo
// [_unit] call FUNC(unload);
};
[_unit] call FUNC(setDead);
0.89
};

View File

@ -61,6 +61,7 @@ _unit setVariable ["ACE_isUnconscious", false, true];
_unit setvariable [QGVAR(hasLostBlood), false, true];
_unit setvariable [QGVAR(isBleeding), false, true];
_unit setvariable [QGVAR(hasPain), false, true];
_unit setvariable [QGVAR(amountOfReviveLives), GVAR(amountOfReviveLives), true];
// medication
_allUsedMedication = _unit getVariable [QGVAR(allUsedMedication), []];

View File

@ -44,7 +44,7 @@ if (!isNull _logic) then {
if (!isnil "_x") then {
if (typeName _x == typeName objNull) then {
if (local _x) then {
_x setvariable [QGVAR(isMedicalVehicle), _setting, true];
_x setvariable [QGVAR(medicClass), _setting, true];
};
};
};
@ -54,7 +54,7 @@ if (!isNull _logic) then {
if (!isnil "_x") then {
if (typeName _x == typeName objNull) then {
if (local _x) then {
_x setvariable [QGVAR(isMedicalVehicle), _setting, true];
_x setvariable [QGVAR(medicClass), _setting, true];
};
};
};

View File

@ -33,3 +33,4 @@ if !(_activated) exitWith {};
[_logic, QGVAR(AIDamageThreshold), "AIDamageThreshold"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(enableUnsconsiousnessAI), "enableUnsconsiousnessAI"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(preventInstaDeath), "preventInstaDeath"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(bleedingCoefficient), "bleedingCoefficient"] call EFUNC(common,readSettingFromModule);

View File

@ -23,7 +23,12 @@ _activated = _this select 2;
if !(_activated) exitWith {};
[_logic, QGVAR(medicSetting), "medicSetting"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(maxRevives), "maxRevives"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(maxReviveTime), "maxReviveTime"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(amountOfReviveLives), "amountOfReviveLives"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(enableOverdosing), "enableOverdosing"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(bleedingCoefficient), "bleedingCoefficient"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(allowLitterCreation), "allowLitterCreation"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(litterCleanUpDelay), "litterCleanUpDelay"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(medicSetting_PAK), "medicSetting_PAK"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(medicSetting_SurgicalKit), "medicSetting_SurgicalKit"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(consumeItem_PAK), "consumeItem_PAK"] call EFUNC(common,readSettingFromModule);
[_logic, QGVAR(consumeItem_SurgicalKit), "consumeItem_SurgicalKit"] call EFUNC(common,readSettingFromModule);

View File

@ -14,7 +14,7 @@
#include "script_component.hpp"
private ["_unit", "_modifier","_timer","_counter", "_heartRate"];
private ["_unit", "_timeInCardiacArrest"];
_unit = _this select 0;
if (_unit getvariable [QGVAR(inCardiacArrest),false]) exitwith {};
@ -23,27 +23,27 @@ _unit setvariable [QGVAR(heartRate), 0];
["Medical_onEnteredCardiacArrest", [_unit]] call ace_common_fnc_localEvent;
[_unit] call FUNC(setUnconscious);
_counter = 120 + round(random(600));
_timer = 0;
[_unit, true] call FUNC(setUnconscious);
_timeInCardiacArrest = 120 + round(random(600));
systemChat format["Unit went cardiac arrest; hr: %1", _unit getvariable [QGVAR(heartRate), -1]];
[{
private ["_args","_unit","_timer","_counter","_heartRate"];
private ["_args","_unit","_startTime","_timeInCardiacArrest","_heartRate"];
_args = _this select 0;
_unit = _args select 0;
_timer = _args select 1;
_counter = _args select 2;
_startTime = _args select 1;
_timeInCardiacArrest = _args select 2;
_heartRate = _unit getvariable [QGVAR(heartRate), 0];
if (_heartRate > 0 || !alive _unit) exitwith {
_unit setvariable [QGVAR(inCardiacArrest), nil,true];
systemChat format["Unit no longer cardiac arrest; hr: %1", _unit getvariable [QGVAR(heartRate), -1]];
[(_this select 1)] call cba_fnc_removePerFrameHandler;
_unit setvariable [QGVAR(inCardiacArrest), nil,true];
};
if (_counter - _timer < 1) exitwith {
if (time - _startTime >= _timeInCardiacArrest) exitwith {
[(_this select 1)] call cba_fnc_removePerFrameHandler;
_unit setvariable [QGVAR(inCardiacArrest), nil,true];
[_unit] call FUNC(setDead);
[(_this select 1)] call cba_fnc_removePerFrameHandler;
_unit setvariable [QGVAR(inCardiacArrest), nil,true];
};
_args set[1, _timer + 1];
}, 1, [_unit, _timer, _counter] ] call CBA_fnc_addPerFrameHandler;
}, 1, [_unit, time, _timeInCardiacArrest] ] call CBA_fnc_addPerFrameHandler;

View File

@ -26,8 +26,18 @@ if (!local _unit) exitwith {
false;
};
if ((_unit getVariable [QGVAR(preventDeath), GVAR(preventInstaDeath)]) && !_force) exitwith {
if (_unit getvariable [QGVAR(inReviveState), false]) exitwith {false}; // already in revive state
if ((_unit getVariable [QGVAR(preventInstaDeath), GVAR(preventInstaDeath)]) && !_force) exitwith {
if (_unit getvariable [QGVAR(inReviveState), false]) exitwith {
if (GVAR(amountOfReviveLives) > 0) then {
_lifesLeft = _unit getvariable[QGVAR(amountOfReviveLives), GVAR(amountOfReviveLives)];
if (_lifesLeft == 0) then {
[_unit, true] call FUNC(setDead);
};
};
false;
};
_unit setvariable [QGVAR(inReviveState), true, true];
_unit setvariable [QGVAR(reviveStartTime), time];
[_unit, true] call FUNC(setUnconscious);
@ -42,11 +52,16 @@ if ((_unit getVariable [QGVAR(preventDeath), GVAR(preventInstaDeath)]) && !_forc
[(_this select 1)] call cba_fnc_removePerFrameHandler;
_unit setvariable [QGVAR(inReviveState), nil, true];
_unit setvariable [QGVAR(reviveStartTime), nil];
[_unit, true] call FUNC(setDead);
};
if !(_unit getvariable [QGVAR(inReviveState), false]) exitwith {
// revived without dieing, so in case we have lifes, remove one.
if (GVAR(amountOfReviveLives) > 0) then {
_lifesLeft = _unit getvariable[QGVAR(amountOfReviveLives), GVAR(amountOfReviveLives)];
_unit setvariable [QGVAR(amountOfReviveLives), _lifesLeft - 1, true];
};
_unit setvariable [QGVAR(reviveStartTime), nil];
[(_this select 1)] call cba_fnc_removePerFrameHandler;
};

View File

@ -29,7 +29,7 @@ _damage = _this select 2;
// Unit isn't local, give function to machine where it is.
if !(local _unit) exitWith {
[_this, "ace_medical_fnc_setHitPointDamage", _unit] call EFUNC(common,execRemoteFnc);
[_this, QUOTE(DFUNC(setHitPointDamage)), _unit] call EFUNC(common,execRemoteFnc);
};
// Check if overall damage adjustment is disabled
@ -72,9 +72,13 @@ if (_damageOld > 0) then {
_damageNew = _damageOld * (_damageSumNew / _damageSumOld);
};
// @todo: prevent death
_unit setDamage _damageNew;
// prevent death
if (_damageNew >= 0.9) then {
_unit setDamage 0.9;
[_unit] call FUNC(setDead);
} else {
_unit setDamage _damageNew;
};
{
_damageFinal = (_damages select _forEachIndex);
@ -88,7 +92,7 @@ if (_legdamage >= LEGDAMAGETRESHOLD1) then {
} else {
if (_unit getHitPointDamage "HitLegs" != 0) then {_unit setHitPointDamage ["HitLegs", 0]};
};
// @ŧodo: force prone for completely fucked up legs.
// @todo: force prone for completely fucked up legs.
// Arm Damage

View File

@ -99,7 +99,12 @@ _startingTime = time;
// Wait until the unit isn't being carried anymore, so we won't end up with wierd animations
if !(([_unit] call FUNC(isBeingCarried)) || ([_unit] call FUNC(isBeingDragged))) then {
if (vehicle _unit == _unit) then {
[_unit,"amovppnemstpsnonwnondnon", 2] call EFUNC(common,doAnimation);
if (animationState _unit == "AinjPpneMstpSnonWrflDnon") then {
[_unit,"AinjPpneMstpSnonWrflDnon_rolltofront", 2] call EFUNC(common,doAnimation);
[_unit,"amovppnemstpsnonwnondnon", 1] call EFUNC(common,doAnimation);
} else {
[_unit,"amovppnemstpsnonwnondnon", 2] call EFUNC(common,doAnimation);
};
} else {
// Switch to the units original animation, assuming
// TODO: what if the unit switched vehicle?
@ -137,9 +142,9 @@ _startingTime = time;
// A check to ensure that the animation is being played properly.
// TODO: Might no longer be necessary: Have to test this in MP.
if (vehicle _unit == _unit && {animationState _unit != "deadState" && animationState _unit != "unconscious"} && {(isNull ([_unit] call EFUNC(common,getCarriedBy)))} && (time - _startingTime >= 0.5)) then {
[_unit,([_unit] call FUNC(getDeathAnim)), 1, true] call EFUNC(common,doAnimation); // Reset animations if unit starts doing wierd things.
};
// if (vehicle _unit == _unit && {animationState _unit != "deadState" && animationState _unit != "unconscious"} && {(isNull ([_unit] call EFUNC(common,getCarriedBy)))} && (time - _startingTime >= 0.5)) then {
//[_unit,([_unit] call FUNC(getDeathAnim)), 1, true] call EFUNC(common,doAnimation); // Reset animations if unit starts doing wierd things.
//};
}, 0.1, [_unit,_animState, _originalPos, _startingTime, _minWaitingTime, false] ] call CBA_fnc_addPerFrameHandler;

View File

@ -16,12 +16,19 @@
#include "script_component.hpp"
private ["_caller", "_target", "_selectionName", "_className", "_config", "_availableLevels", "_medicRequired", "_items", "_locations", "_return", "_callbackSuccess", "_callbackFailure", "_callbackProgress", "_treatmentTime", "_callerAnim", "_patientAnim", "_iconDisplayed", "_return", "_usersOfItems"];
private ["_caller", "_target", "_selectionName", "_className", "_config", "_availableLevels", "_medicRequired", "_items", "_locations", "_return", "_callbackSuccess", "_callbackFailure", "_callbackProgress", "_treatmentTime", "_callerAnim", "_patientAnim", "_iconDisplayed", "_return", "_usersOfItems", "_consumeItems"];
_caller = _this select 0;
_target = _this select 1;
_selectionName = _this select 2;
_className = _this select 3;
// If the cursorMenu is open, the loading bar will fail. If we execute the function one frame later, it will work fine
if (uiNamespace getVariable [QEGVAR(interact_menu,cursorMenuOpened),false]) exitwith {
[{
_this call FUNC(treatment);
}, _this, 0, 0] call EFUNC(common,waitAndExecute);
};
if !(_target isKindOf "CAManBase") exitWith {false};
_config = (configFile >> "ACE_Medical_Actions" >> "Basic" >> _className);
@ -30,8 +37,16 @@ if (GVAR(level) >= 2) then {
};
if !(isClass _config) exitwith {false};
// Check for required class
_medicRequired = getNumber (_config >> "requiredMedic");
_medicRequired = if (isNumber (_config >> "requiredMedic")) then {
getNumber (_config >> "requiredMedic");
} else {
// Check for required class
if (isText (_config >> "requiredMedic")) exitwith {
missionNamespace getvariable [(getText (_config >> "requiredMedic")), 0];
};
0;
};
if !([_caller, _medicRequired] call FUNC(isMedic)) exitwith {false};
// Check item
@ -72,7 +87,16 @@ if ("All" in _locations) then {
if !(_return) exitwith {false};
_usersOfItems = [];
if (getNumber (_config >> "itemConsumed") > 0) then {
_consumeItems = if (isNumber (_config >> "itemConsumed")) then {
getNumber (_config >> "itemConsumed");
} else {
// Check for required class
if (isText (_config >> "itemConsumed")) exitwith {
missionNamespace getvariable [(getText (_config >> "itemConsumed")), 0];
};
0;
};
if (_consumeItems > 0) then {
_usersOfItems = ([_caller, _target, _items] call FUNC(useItems)) select 1;
};
@ -88,9 +112,19 @@ if (isNil _callbackProgress) then {
};
// Patient Animation
_patientAnim = getText (_confg >> "animationPatient");
_patientAnim = getText (_config >> "animationPatient");
if (_target getvariable ["ACE_isUnconscious", false]) then {
if !(animationState _target in (getArray (_config >> "animationPatientUnconsciousExcludeOn"))) then {
_patientAnim = getText (_config >> "animationPatientUnconscious");
};
};
if (_caller != _target && {vehicle _target == _target} && {_patientAnim != ""}) then {
[_target, _patientAnim] call EFUNC(common,doAnimation);
if (_target getvariable ["ACE_isUnconscious", false]) then {
[_target, _patientAnim, 2, true] call EFUNC(common,doAnimation);
} else {
[_target, _patientAnim, 1, true] call EFUNC(common,doAnimation);
};
};
// Player Animation
@ -110,8 +144,15 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then {
if (primaryWeapon _caller == "") then {
_caller addWeapon "ACE_FakePrimaryWeapon";
};
_caller selectWeapon (primaryWeapon _caller);
_caller setvariable [QGVAR(treatmentPrevAnimCaller), animationState _caller];
if (currentWeapon _caller == "") then {
_caller selectWeapon (primaryWeapon _caller); // unit always has a primary weapon here
};
if (stance _caller == "STAND") then {
_caller setvariable [QGVAR(treatmentPrevAnimCaller), "amovpknlmstpsraswrfldnon"];
} else {
_caller setvariable [QGVAR(treatmentPrevAnimCaller), animationState _caller];
};
[_caller, _callerAnim] call EFUNC(common,doAnimation);
};
@ -123,7 +164,8 @@ _treatmentTime = getNumber (_config >> "treatmentTime");
DFUNC(treatment_success),
DFUNC(treatment_failure),
getText (_config >> "displayNameProgress"),
_callbackProgress
_callbackProgress,
["isnotinside"]
] call EFUNC(common,progressBar);
// Display Icon

View File

@ -23,7 +23,8 @@ _target = _this select 1;
_selectionName = _this select 2;
_className = _this select 3;
_items = _this select 4;
_specificSpot = if (count _this > 5) then {_this select 5} else {-1};
_specificSpot = if (count _this > 6) then {_this select 6} else {-1};
if !([_target] call FUNC(hasMedicalEnabled)) exitwith {
_this call FUNC(treatmentBasic_bandage);

View File

@ -99,7 +99,7 @@ if (_impact > 0) then {
// If all wounds have been bandaged, we will reset all damage to 0, so the unit is not showing any blood on the model anymore.
if (count _openWounds == 0) then {
_target setDamage 0;
// TODO also set hitpoints to 0
// _target setvariable [QGVAR(bodyPartStatus), [0,0,0,0,0,0], true];
};
true;

View File

@ -10,59 +10,60 @@
#include "script_component.hpp"
private ["_unit", "_caller", "_allUsedMedication"];
_unit = _this select 0;
_caller = _this select 1;
private ["_target", "_caller", "_allUsedMedication"];
_caller = _this select 0;
_target = _this select 1;
if (alive _unit) exitwith {
if (alive _target) exitwith {
_unit setVariable [QGVAR(pain), 0, true];
_unit setVariable [QGVAR(morphine), 0, true];
_unit setVariable [QGVAR(bloodVolume), 100, true];
_target setVariable [QGVAR(pain), 0, true];
_target setVariable [QGVAR(morphine), 0, true];
_target setVariable [QGVAR(bloodVolume), 100, true];
// tourniquets
_unit setvariable [QGVAR(tourniquets), [0,0,0,0,0,0], true];
_target setvariable [QGVAR(tourniquets), [0,0,0,0,0,0], true];
// wounds and injuries
_unit setvariable [QGVAR(openWounds), [], true];
_unit setVariable [QGVAR(internalWounds), [], true];
_target setvariable [QGVAR(openWounds), [], true];
_target setVariable [QGVAR(internalWounds), [], true];
// vitals
_unit setVariable [QGVAR(heartRate), 80];
_unit setvariable [QGVAR(heartRateAdjustments), []];
_unit setvariable [QGVAR(bloodPressure), [80, 120]];
_unit setVariable [QGVAR(peripheralResistance), 100];
_target setVariable [QGVAR(heartRate), 80];
_target setvariable [QGVAR(heartRateAdjustments), []];
_target setvariable [QGVAR(bloodPressure), [80, 120]];
_target setVariable [QGVAR(peripheralResistance), 100];
// fractures
_unit setVariable [QGVAR(fractures), []];
_target setVariable [QGVAR(fractures), []];
// IVs
_unit setVariable [QGVAR(salineIVVolume), 0];
_unit setVariable [QGVAR(plasmaIVVolume), 0];
_unit setVariable [QGVAR(bloodIVVolume), 0];
_target setVariable [QGVAR(salineIVVolume), 0];
_target setVariable [QGVAR(plasmaIVVolume), 0];
_target setVariable [QGVAR(bloodIVVolume), 0];
// damage storage
_unit setvariable [QGVAR(bodyPartStatus), [0,0,0,0,0,0], true];
_target setvariable [QGVAR(bodyPartStatus), [0,0,0,0,0,0], true];
// airway
_unit setvariable [QGVAR(airwayStatus), 100, true];
_unit setVariable [QGVAR(airwayOccluded), false, true];
_unit setvariable [QGVAR(airwayCollapsed), false, true];
_target setvariable [QGVAR(airwayStatus), 100, true];
_target setVariable [QGVAR(airwayOccluded), false, true];
_target setvariable [QGVAR(airwayCollapsed), false, true];
// generic medical admin
_unit setvariable [QGVAR(addedToUnitLoop), false, true];
_unit setvariable [QGVAR(inCardiacArrest), false, true];
_unit setVariable ["ACE_isUnconscious", false, true];
_unit setvariable [QGVAR(hasLostBlood), false, true];
_unit setvariable [QGVAR(isBleeding), false, true];
_unit setvariable [QGVAR(hasPain), false, true];
_target setvariable [QGVAR(addedToUnitLoop), false, true];
_target setvariable [QGVAR(inCardiacArrest), false, true];
_target setvariable [QGVAR(inReviveState), false, true];
_target setVariable ["ACE_isUnconscious", false, true];
_target setvariable [QGVAR(hasLostBlood), false, true];
_target setvariable [QGVAR(isBleeding), false, true];
_target setvariable [QGVAR(hasPain), false, true];
// medication
_allUsedMedication = _unit getVariable [QGVAR(allUsedMedication), []];
_allUsedMedication = _target getVariable [QGVAR(allUsedMedication), []];
{
_unit setvariable [_x select 0, nil];
_target setvariable [_x select 0, nil];
}foreach _allUsedMedication;
// Resetting damage
_unit setDamage 0;
_target setDamage 0;
};

View File

@ -22,3 +22,7 @@ _target = _this select 1;
_className = _this select 3;
[_target, false] call FUNC(setUnconscious);
if (_target getvariable [QGVAR(inReviveState), false]) then {
_target setvariable [QGVAR(inReviveState), nil, true];
};

View File

@ -37,7 +37,3 @@ if !(_varName in GVAR(IVBags)) then {
GVAR(IVBags) pushback _varName;
publicVariable QGVAR(IVBags);
};
// TODO localization
//[_target,"treatment",format["%1 has given %4 a %2(%3ml)",[_caller] call EFUNC(common,getName),_attributes select 2,_attributes select 1,_target]] call FUNC(addActivityToLog);
//[_target,_removeItem] call FUNC(addToTriageList);

View File

@ -49,4 +49,6 @@ if (isNil _callback) then {
_callback = missionNamespace getvariable _callback;
};
_args call FUNC(createLitter);
_args call _callback;

View File

@ -43,4 +43,6 @@ if (isNil _callback) then {
_callback = missionNamespace getvariable _callback;
};
_args call FUNC(createLitter);
_args call _callback;