Medical Treatment - Modernize and Cleanup (#6933)

* Modernize and cleanup medical_treatment

* One line for each old public function

* Fix litterCleanupDelay name

* Improve adjustment calcs / wound blood loss / medications

fix func descriptions

Calc wound blood loss on events

reorder includes so scritpmacroMed has global effect

trivial optimization for getCardiacOutput

Fix var

Fix wounds not reopening (nil _category)

Fix surgical kit inherting canBandage conditional

debug hitpoints

Update ACE_Medical_Treatment_Actions.hpp

Use woundBleeding for IS_BLEEDING macro

rework medication vars

comments

Reset var in init / fullHeal

Update addons/medical_treatment/functions/fnc_onMedicationUsage.sqf

Co-Authored-By: PabstMirror <pabstmirror@gmail.com>

* Change wound data array

Drop unique id and merge classId and category

* Splinting and treatment and gui

* Add arm fractures and aim effects

* localizations and event

* fix

* fix merge for renamed files

* Fixes and code review changes

* Move medical logs clearing to treatment

* More cleanup work

* cleanup

* Apply suggestions from code review

Co-Authored-By: PabstMirror <pabstmirror@gmail.com>

* formating, rename bone images

* Fix args for setDead call in actionPlaceInBodyBag

* Apply suggestions from code review

Co-Authored-By: PabstMirror <pabstmirror@gmail.com>

* disable calls to extension

* Update fnc_onMedicationUsage.sqf

* Medical - Skip unneeded setVars on initUnit (#6949)

*  Medical - Transfer state machine state on locality (#6950)

* Medical - Transfer state machine state on locality

* Fix feedback isUnconscious var

* Exclude AI

* Make UAV excludes consistant, formating

* Update fnc_treatmentFullHealLocal.sqf

* reset fractures on respawn

* Fix merge

* Add PAK time coefficient setting

* Fix medication

* Add ace_medical_replacementItems config array

* checkItems performance improvement

* Treatment - cap max animation speed (#6995)

* Treatment - cap max animation speed

and add lock to prevent AF from reseting anim

* Update fnc_getBandageTime.sqf

* Use local version of setAnimSpeedCoef

* Revert "Use local version of setAnimSpeedCoef"

This reverts commit 36c22a9047.

* Move replacementItems compiling to preInit

* Improve replacementItems compiling

* Cleanup splint functions, use macros for fractures

* Rename splintCondition to canSplint

* Add cprCreatesPulse setting

* Cleanup remaining functions

* Capitalize stringtable entry names

* getStitchTime function and fix treatment locations

* Update addons/medical_treatment/functions/fnc_getHealTime.sqf

Co-Authored-By: SilentSpike <silentspike100+Github@gmail.com>
This commit is contained in:
mharis001 2019-06-03 11:31:46 -04:00 committed by PabstMirror
parent d684a8042e
commit 44050df98b
147 changed files with 2718 additions and 3219 deletions

View File

@ -10,5 +10,6 @@ PREP_RECOMPILE_END;
GVAR(staminaBarWidth) = 10 * (((safezoneW / safezoneH) min 1.2) / 40);
GVAR(dutyList) = [[], []];
GVAR(setAnimExclusions) = [];
ADDON = true;

View File

@ -58,8 +58,9 @@ if (GVAR(ppeBlackoutLast) == 1) then {
// - Physical effects ---------------------------------------------------------
if (GVAR(isSwimming)) exitWith {
_unit setAnimSpeedCoef linearConversion [0.7, 0.9, _fatigue, 1, 0.5, true];
if (GVAR(setAnimExclusions) isEqualTo []) then {
_unit setAnimSpeedCoef linearConversion [0.7, 0.9, _fatigue, 1, 0.5, true];
};
if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then {
[_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
} else {
@ -69,7 +70,10 @@ if (GVAR(isSwimming)) exitWith {
};
};
if ((getAnimSpeedCoef _unit) != 1) then {
_unit setAnimSpeedCoef 1;
if (GVAR(setAnimExclusions) isEqualTo []) then {
TRACE_1("reset",getAnimSpeedCoef _unit);
_unit setAnimSpeedCoef 1;
};
};
if (_overexhausted) then {

View File

@ -1036,7 +1036,7 @@
<Korean>기본</Korean>
</Key>
<Key ID="STR_ACE_Common_Vehicle">
<English>Medical vehicles</English>
<English>Medical Vehicles</English>
<Russian>В медицинском транспорте</Russian>
<Polish>Pojazdy medyczne</Polish>
<Spanish>Vehiculos médicos</Spanish>

View File

@ -11,7 +11,44 @@ PREP_RECOMPILE_END;
// Add warning for old functions that were technically public, Remove at 3.14.0
{
missionNamespace setVariable [_x, compileFinal format ['diag_log text "ACE Medical WARNING: Formerly public function [%1] has no effect in medical rewrite."; nil', _x]];
} forEach ["ace_medical_fnc_actionPlaceInBodyBag","ace_medical_fnc_actionRemoveTourniquet","ace_medical_fnc_addHeartRateAdjustment","ace_medical_fnc_addToLog","ace_medical_fnc_addToTriageCard
","ace_medical_fnc_addUnconsciousCondition","ace_medical_fnc_addVitalLoop","ace_medical_fnc_canAccessMedicalEquipment","ace_medical_fnc_canTreat","ace_medical_fnc_displayTriageCard","ace_medical_fnc_dropDownTriageCard","ace_medical_fnc_getTriageStatus","ace_medical_fnc_getUnconsciousCondition","ace_medical_fnc_hasItem","ace_medical_fnc_hasItems","ace_medical_fnc_hasTourniquetAppliedTo","ace_medical_fnc_isInMedicalFacility","ace_medical_fnc_isInMedicalVehicle","ace_medical_fnc_isMedic","ace_medical_fnc_isMedicalVehicle","ace_medical_fnc_itemCheck","ace_medical_fnc_selectionNameToNumber","ace_medical_fnc_setCardiacArrest","ace_medical_fnc_setDead","ace_medical_fnc_setHitPointDamage","ace_medical_fnc_showBloodEffect","ace_medical_fnc_treatment","ace_medical_fnc_treatmentAdvanced_bandage","ace_medical_fnc_treatmentAdvanced_CPR","ace_medical_fnc_treatmentAdvanced_CPRLocal","ace_medical_fnc_treatmentAdvanced_medication","ace_medical_fnc_treatmentAdvanced_medicationLocal","ace_medical_fnc_treatmentIV","ace_medical_fnc_treatmentIVLocal","ace_medical_fnc_unconsciousPFH","ace_medical_fnc_useItem","ace_medical_fnc_useItems"];
} forEach [
QFUNC(actionPlaceInBodyBag),
QFUNC(actionRemoveTourniquet),
QFUNC(addHeartRateAdjustment),
QFUNC(addToLog),
QFUNC(addToTriageCard),
QFUNC(addUnconsciousCondition),
QFUNC(addVitalLoop),
QFUNC(canAccessMedicalEquipment),
QFUNC(canTreat),
QFUNC(displayTriageCard),
QFUNC(dropDownTriageCard),
QFUNC(getTriageStatus),
QFUNC(getUnconsciousCondition),
QFUNC(hasItem),
QFUNC(hasItems),
QFUNC(hasTourniquetAppliedTo),
QFUNC(isInMedicalFacility),
QFUNC(isInMedicalVehicle),
QFUNC(isMedic),
QFUNC(isMedicalVehicle),
QFUNC(itemCheck),
QFUNC(selectionNameToNumber),
QFUNC(setCardiacArrest),
QFUNC(setDead),
QFUNC(setHitPointDamage),
QFUNC(showBloodEffect),
QFUNC(treatment),
QFUNC(treatmentAdvanced_bandage),
QFUNC(treatmentAdvanced_CPR),
QFUNC(treatmentAdvanced_CPRLocal),
QFUNC(treatmentAdvanced_medication),
QFUNC(treatmentAdvanced_medicationLocal),
QFUNC(treatmentIV),
QFUNC(treatmentIVLocal),
QFUNC(unconsciousPFH),
QFUNC(useItem),
QFUNC(useItems)
];
ADDON = true;

View File

@ -60,7 +60,7 @@
_return pushBack format ["Hitpoints: [HHed:%1] [HBod: %2]", (_unit getHitPointDamage "HitHead") toFixed 2, (_unit getHitPointDamage "HitBody") toFixed 2];
_return pushBack format ["[HHnd:%1] [HLeg: %2] %3", (_unit getHitPointDamage "HitHands") toFixed 2, (_unit getHitPointDamage "HitLegs") toFixed 2, _limping];
private _fractures = _unit getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]];
private _fractures = GET_FRACTURES(_unit);
private _canSprint = if (isSprintAllowed _unit) then {""} else {"[<t color ='#FFCC22'>Sprint Blocked</t>]"};
_return pushBack format ["Fractures: %1 %2", _fractures, _canSprint];
@ -75,7 +75,7 @@
_return pushBack format ["%1 [Time On: %2]", ALL_SELECTIONS select _tPartNum, (CBA_missionTime - _x) toFixed 1];
};
{
_x params ["", "_medClassname", "_medPartNum"];
_x params ["_medPartNum", "_medClassname"];
if (_medPartNum == _tPartNum) then {
_return pushBack format [" - Occluded Med: %1", _medClassname];
};
@ -154,4 +154,3 @@
// Return:
_return joinString "<br/>"
}, [40]] call EFUNC(common,watchVariable);

View File

@ -2,7 +2,6 @@
/*
* Author: Glowbal
* Sets a unit in the unconscious state.
* For Public Use
*
* Arguments:
* 0: The unit that will be put in an unconscious state <OBJECT>
@ -17,7 +16,7 @@
* [bob, true] call ace_medical_fnc_setUnconscious;
* [player, true, 5, true] call ace_medical_fnc_setUnconscious;
*
* Public: yes
* Public: Yes
*/
// only run this after the settings are initialized

View File

@ -1,6 +1,6 @@
// CBA Settings [ADDON: ace_medical]:
private _categoryArray = [LELSTRING(medical,Category_DisplayName), "?"];
private _categoryArray = [LELSTRING(medical,Category), "?"];
// todo: Check the description is still accurate
[

View File

@ -2,7 +2,7 @@
#define COMPONENT_BEAUTIFIED Medical Core
#include "\z\ace\addons\main\script_mod.hpp"
// #define DEBUG_MODE_FULL
#define DEBUG_MODE_FULL
// #define DISABLE_COMPILE_CACHE
// #define ENABLE_PERFORMANCE_COUNTERS

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="ACE">
<Package name="Medical">
<Key ID="STR_ACE_Medical_Category_DisplayName">
<Key ID="STR_ACE_Medical_Category">
<English>ACE Medical</English>
<Russian>ACE: медицина</Russian>
<Polish>ACE Opcje medyczne</Polish>
@ -440,21 +440,6 @@
<Chinesesimp>设定当距离超过%1将不能使用治疗动作</Chinesesimp>
<Chinese>設定當距離超過%1將不能使用治療動作</Chinese>
</Key>
<Key ID="STR_ACE_Medical_CanNotLoaded">
<English>This person (%1) is awake and cannot be loaded</English>
<German>Diese Person (%1) ist wach und kann nicht verladen werden</German>
<Polish>Ta osoba (%1) jest przytomna i nie może zostać załadowana</Polish>
<Spanish>Esta persona (%1) está despierto y no puede ser cargado</Spanish>
<Russian>Боец (%1) в сознании и не может быть погружен</Russian>
<Portuguese>Esta pessoa (%1) está acordada e não pode ser carregada</Portuguese>
<Czech>Tato osoba (%1) je vzhůru a nemůže být naložena</Czech>
<Italian>Questa persona (%1) è sveglia e non può essere caricata.</Italian>
<French>%1 est conscient et ne peut être embarqué.</French>
<Japanese>患者 (%1) は意識があり、積み込めない</Japanese>
<Korean>이 사람 (%1) 은(는) 의식이 있어 태우지 못합니다</Korean>
<Chinesesimp>此人(%1)是清醒且不能被装载</Chinesesimp>
<Chinese>此人(%1)是清醒且不能被裝載</Chinese>
</Key>
<Key ID="STR_ACE_Medical_MedicalSettings_spontaneousWakeUpChance_DisplayName">
<English>Unconscious Wake Up Chance</English>
<Japanese>気絶から覚醒する可能性</Japanese>

View File

@ -26,7 +26,7 @@ private _animConfig = if (_isBandage) then {
configFile >> "ACE_Medical_Actions" >> "Basic" >> "Morphine";
};
private _configProperty = "animationCaller";
private _configProperty = "animationMedic";
if (_isSelfTreatment) then {
_configProperty = _configProperty + "Self";
};

View File

@ -1,6 +1,6 @@
// CBA Settings [ADDON: ace_medical_blood]:
private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)];
private _categoryArray = [LELSTRING(medical,Category), LLSTRING(subCategory)];
[
QGVAR(enabledFor), "LIST",

View File

@ -136,9 +136,9 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra
case (_causeFracture && {EGVAR(medical,fractures) > 0} && {_bodyPartNToAdd > 1} && {_woundDamage > FRACTURE_DAMAGE_THRESHOLD}): {
TRACE_1("limb fracture",_bodyPartNToAdd);
// todo: play sound?
private _fractures = _unit getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]];
private _fractures = GET_FRACTURES(_unit);
_fractures set [_bodyPartNToAdd, 1];
_unit setVariable [QEGVAR(medical,fractures), _fractures, true];
_unit setVariable [VAR_FRACTURES, _fractures, true];
[QEGVAR(medical,fracture), [_unit, _bodyPartNToAdd]] call CBA_fnc_localEvent; // local event for fracture
_updateDamageEffects = true;
};

View File

@ -1,6 +1,6 @@
// CBA Settings [ADDON: ace_medical_damage]:
private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)];
private _categoryArray = [LELSTRING(medical,Category), LLSTRING(subCategory)];
[
QEGVAR(medical,playerDamageThreshold), "SLIDER",

View File

@ -23,7 +23,7 @@ if (!local _unit) exitWith { ERROR("Unit not local or null"); };
private _isLimping = false;
if (EGVAR(medical,fractures) > 0) then {
private _fractures = _unit getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]];
private _fractures = GET_FRACTURES(_unit);
TRACE_1("",_fractures);
if (((_fractures select 4) == 1) || {(_fractures select 5) == 1}) then {
TRACE_1("limping because of fracture",_fractures);

View File

@ -2,7 +2,6 @@
// #define DISABLE_COMPILE_CACHE
// #define ENABLE_PERFORMANCE_COUNTERS
#define ALL_BODY_PARTS ["head", "body", "leftarm", "rightarm", "leftleg", "rightleg"]
#define ALL_SELECTIONS ["head", "body", "hand_l", "hand_r", "leg_l", "leg_r"]
#define ALL_HITPOINTS ["HitHead", "HitBody", "HitLeftArm", "HitRightArm", "HitLeftLeg", "HitRightLeg"]
@ -97,6 +96,8 @@
#define DEFAULT_TOURNIQUET_VALUES [0,0,0,0,0,0]
#define DEFAULT_FRACTURE_VALUES [0,0,0,0,0,0]
// Triage colors, for consistency across UIs and functions
#define TRIAGE_COLOR_NONE 0, 0, 0, 0.9
#define TRIAGE_COLOR_MINIMAL 0, 0.5, 0, 0.9
@ -110,25 +111,29 @@
#define TRIAGE_TEXT_COLOR_IMMEDIATE 1, 1, 1, 1
#define TRIAGE_TEXT_COLOR_DECEASED 1, 1, 1, 1
// Medical activity logs
#define MED_LOG_MAX_ENTRIES 8
#define MED_LOG_VARNAME(type) (format [QEGVAR(medical,log_%1), type])
// - Unit Variables ----------------------------------------------------
// These variables get stored in object space and used across components
// Defined here for easy consistency with GETVAR/SETVAR (also a list for reference)
#define VAR_BLOOD_PRESS QEGVAR(medical,bloodPressure)
#define VAR_BLOOD_VOL QEGVAR(medical,bloodVolume)
#define VAR_BLOOD_PRESS QEGVAR(medical,bloodPressure)
#define VAR_BLOOD_VOL QEGVAR(medical,bloodVolume)
#define VAR_WOUND_BLEEDING QEGVAR(medical,woundBleeding)
#define VAR_CRDC_ARRST QEGVAR(medical,inCardiacArrest)
#define VAR_HEART_RATE QEGVAR(medical,heartRate)
#define VAR_PAIN QEGVAR(medical,pain)
#define VAR_PAIN_SUPP QEGVAR(medical,painSuppress)
#define VAR_PERIPH_RES QEGVAR(medical,peripheralResistance)
#define VAR_UNCON "ACE_isUnconscious"
#define VAR_CRDC_ARRST QEGVAR(medical,inCardiacArrest)
#define VAR_HEART_RATE QEGVAR(medical,heartRate)
#define VAR_PAIN QEGVAR(medical,pain)
#define VAR_PAIN_SUPP QEGVAR(medical,painSuppress)
#define VAR_PERIPH_RES QEGVAR(medical,peripheralResistance)
#define VAR_UNCON "ACE_isUnconscious"
// These variables track gradual adjustments (from medication, etc.)
#define VAR_MEDICATIONS QEGVAR(medical,medications)
#define VAR_MEDICATIONS QEGVAR(medical,medications)
// These variables track the current state of status values above
#define VAR_HEMORRHAGE QEGVAR(medical,hemorrhage)
#define VAR_IN_PAIN QEGVAR(medical,inPain)
#define VAR_TOURNIQUET QEGVAR(medical,tourniquets)
#define VAR_HEMORRHAGE QEGVAR(medical,hemorrhage)
#define VAR_IN_PAIN QEGVAR(medical,inPain)
#define VAR_TOURNIQUET QEGVAR(medical,tourniquets)
#define VAR_FRACTURES QEGVAR(medical,fractures)
// - Unit Functions ---------------------------------------------------
// Retrieval macros for common unit values
@ -140,6 +145,7 @@
#define GET_PAIN(unit) (unit getVariable [VAR_PAIN,0])
#define GET_PAIN_SUPPRESS(unit) (unit getVariable [VAR_PAIN_SUPP,0])
#define GET_TOURNIQUETS(unit) (unit getVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES])
#define GET_FRACTURES(unit) (unit getVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES])
#define IN_CRDC_ARRST(unit) (unit getVariable [VAR_CRDC_ARRST,false])
#define IS_BLEEDING(unit) (GET_WOUND_BLEEDING(unit) > 0)
#define IS_IN_PAIN(unit) (unit getVariable [VAR_IN_PAIN,false])

View File

@ -1,6 +1,6 @@
// CBA Settings [ADDON: ace_medical_feedback]:
private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)];
private _categoryArray = [LELSTRING(medical,Category), LLSTRING(subCategory)];
[
QGVAR(painEffectType),

View File

@ -44,11 +44,11 @@ class CfgVehicles {
#include "InteractionBodyParts.hpp"
#undef ACTION_CONDITION
};
class ACE_LoadPatient {
class ACE_LoadPatient {
displayName = CSTRING(LoadPatient);
condition = QUOTE(_target getVariable [ARR_2('ACE_isUnconscious',false)] && {alive _target} && {vehicle _target == _target});
exceptions[] = {"isNotDragging", "isNotCarrying"};
statement = QUOTE([ARR_2(_player, _target)] call EFUNC(medical_treatment,actionLoadUnit));
statement = QUOTE([ARR_2(_player, _target)] call EFUNC(medical_treatment,loadUnit));
icon = QPATHTOF(ui\cross.paa);
insertChildren = QUOTE(call DEFUNC(medical_treatment,addLoadPatientActions));
};
@ -56,7 +56,7 @@ class CfgVehicles {
displayName = CSTRING(UnloadPatient);
condition = QUOTE(_target getVariable [ARR_2('ACE_isUnconscious',false)] && {vehicle _target != _target} && {vehicle _player == _player});
exceptions[] = {"isNotDragging", "isNotCarrying", "isNotInside"};
statement = QUOTE([ARR_2(_player, _target)] call EFUNC(medical_treatment,actionUnloadUnit));
statement = QUOTE([ARR_2(_player, _target)] call EFUNC(medical_treatment,unloadUnit));
icon = QPATHTOF(ui\cross.paa);
};
};

View File

@ -53,7 +53,7 @@ if (isNull _display) then {
// Update activity log
private _ctrlActivityLog = _display displayCtrl IDC_ACTIVITY;
private _activityLog = _target getVariable [QEGVAR(medical,logFile_activity_view), []];
private _activityLog = _target getVariable [MED_LOG_VARNAME("activity"), []];
[_ctrlActivityLog, _activityLog] call FUNC(updateLogList);
// Update triage status

View File

@ -44,11 +44,11 @@ private _ctrlBodyImage = _display displayCtrl IDC_BODY_GROUP;
// Update activity and quick view logs
private _ctrlActivityLog = _display displayCtrl IDC_ACTIVITY;
private _activityLog = GVAR(target) getVariable [QEGVAR(medical,logFile_activity_view), []];
private _activityLog = GVAR(target) getVariable [MED_LOG_VARNAME("activity"), []];
[_ctrlActivityLog, _activityLog] call FUNC(updateLogList);
private _ctrlQuickView = _display displayCtrl IDC_QUICKVIEW;
private _quickView = GVAR(target) getVariable [QEGVAR(medical,logFile_quick_view), []];
private _quickView = GVAR(target) getVariable [MED_LOG_VARNAME("quick_view"), []];
[_ctrlQuickView, _quickView] call FUNC(updateLogList);
// Update triage status

View File

@ -20,7 +20,7 @@ params ["_ctrlGroup", "_target"];
// Get tourniquets, damage, and blood loss for target
private _tourniquets = GET_TOURNIQUETS(_target);
private _fractures = _target getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]];
private _fractures = GET_FRACTURES(_target);
private _bodyPartDamage = _target getVariable [QEGVAR(medical,bodyPartDamage), [0, 0, 0, 0, 0, 0]];
private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0];
@ -38,18 +38,19 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0];
private _ctrlTourniquet = _ctrlGroup controlsGroupCtrl _tourniquetIDC;
_ctrlTourniquet ctrlShow _hasTourniquet;
};
// Show or hide fractrue/bones
if (_fractureIDC != -1) then {
private _ctrlBone = _ctrlGroup controlsGroupCtrl _fractureIDC;
switch (_fractures select _forEachIndex) do {
case (0): {
case 0: {
_ctrlBone ctrlShow false;
};
case (1): {
case 1: {
_ctrlBone ctrlShow true;
_ctrlBone ctrlSetTextColor [1, 0, 0, 1];
};
case (-1): {
case -1: {
if (EGVAR(medical,fractures) == 2) then {
_ctrlBone ctrlShow true;
_ctrlBone ctrlSetTextColor [0, 0, 1, 1];
@ -74,8 +75,8 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0];
} forEach [
[IDC_BODY_HEAD],
[IDC_BODY_TORSO],
[IDC_BODY_ARMLEFT, IDC_BODY_ARMLEFT_T, IDC_BODY_ARMLEFT_B],
[IDC_BODY_ARMLEFT, IDC_BODY_ARMLEFT_T, IDC_BODY_ARMLEFT_B],
[IDC_BODY_ARMRIGHT, IDC_BODY_ARMRIGHT_T, IDC_BODY_ARMRIGHT_B],
[IDC_BODY_LEGLEFT, IDC_BODY_LEGLEFT_T, IDC_BODY_LEGLEFT_B],
[IDC_BODY_LEGLEFT, IDC_BODY_LEGLEFT_T, IDC_BODY_LEGLEFT_B],
[IDC_BODY_LEGRIGHT, IDC_BODY_LEGRIGHT_T, IDC_BODY_LEGRIGHT_B]
];

View File

@ -58,10 +58,14 @@ switch (GET_HEMORRHAGE(_target)) do {
if (HAS_TOURNIQUET_APPLIED_ON(_target,_selectionN)) then {
_entries pushBack [localize LSTRING(Status_Tourniquet_Applied), [0.77, 0.51, 0.08, 1]];
};
switch ((_target getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]]) select _selectionN) do {
case (1): {_entries pushBack [localize LSTRING(Status_Fractured), [1, 0, 0, 1]];};
case (-1): {
if (EGVAR(medical,fractures) == 2) then { // Ignore if the split has no effect
// Indicate current body part fracture status
switch (GET_FRACTURES(_target) select _selectionN) do {
case 1: {
_entries pushBack [localize LSTRING(Status_Fractured), [1, 0, 0, 1]];
};
case -1: {
if (EGVAR(medical,fractures) == 2) then { // Ignore if the splint has no effect
_entries pushBack [localize LSTRING(Status_SplintApplied), [1, 1, 1, 1]];
};
};

View File

@ -21,7 +21,7 @@ params ["_ctrl", "_logs"];
lbClear _ctrl;
{
_x params ["_message", "_moment", "", "_arguments"];
_x params ["_message", "_timeStamp", "_arguments"];
// Localize message and arguments
if (isLocalized _message) then {
@ -33,5 +33,5 @@ lbClear _ctrl;
// Format message with arguments
_message = format ([_message] + _arguments);
_ctrl lbAdd format ["%1 %2", _moment, _message];
_ctrl lbAdd format ["%1 %2", _timeStamp, _message];
} forEach _logs;

View File

@ -2,7 +2,7 @@
QGVAR(enableActions),
"LIST",
[LSTRING(EnableActions_DisplayName), LSTRING(EnableActions_Description)],
LSTRING(Category),
[ELSTRING(medical,Category), LSTRING(SubCategory)],
[[0, 1, 2], [LSTRING(Selections3D), LSTRING(Radial), ELSTRING(common,Disabled)], 0],
false
] call CBA_settings_fnc_init;
@ -11,7 +11,7 @@
QGVAR(enableSelfActions),
"CHECKBOX",
[LSTRING(EnableSelfActions_DisplayName), LSTRING(EnableSelfActions_Description)],
LSTRING(Category),
[ELSTRING(medical,Category), LSTRING(SubCategory)],
true,
false
] call CBA_settings_fnc_init;
@ -20,7 +20,7 @@
QGVAR(enableMedicalMenu),
"LIST",
[LSTRING(EnableMedicalMenu_DisplayName), LSTRING(EnableMedicalMenu_Description)],
LSTRING(Category),
[ELSTRING(medical,Category), LSTRING(SubCategory)],
[[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), ELSTRING(common,VehiclesOnly)], 1],
false
] call CBA_settings_fnc_init;
@ -29,7 +29,7 @@
QGVAR(openAfterTreatment),
"CHECKBOX",
[LSTRING(OpenAfterTreatment_DisplayName), LSTRING(OpenAfterTreatment_Description)],
LSTRING(Category),
[ELSTRING(medical,Category), LSTRING(SubCategory)],
true,
false
] call CBA_settings_fnc_init;
@ -38,7 +38,7 @@
QGVAR(maxDistance),
"SLIDER",
[LSTRING(MaxDistance_DisplayName), LSTRING(MaxDistance_Description)],
LSTRING(Category),
[ELSTRING(medical,Category), LSTRING(SubCategory)],
[0, 10, 3, 1],
false
] call CBA_settings_fnc_init;

View File

@ -69,8 +69,8 @@
#define IDC_BODY_LEGRIGHT_T 6050
#define IDC_BODY_ARMLEFT_B 6055
#define IDC_BODY_ARMRIGHT_B 6060
#define IDC_BODY_LEGRIGHT_B 6065
#define IDC_BODY_LEGLEFT_B 6070
#define IDC_BODY_LEGLEFT_B 6065
#define IDC_BODY_LEGRIGHT_B 6070
#define IDC_TRIAGE_STATUS 7000
#define IDC_TRIAGE_SELECT 7100

View File

@ -1,6 +1,6 @@
// CBA Settings [ADDON: ace_medical_statemachine]:
private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)];
private _categoryArray = [LELSTRING(medical,Category), LLSTRING(subCategory)];
[
QGVAR(fatalInjuryCondition), "LIST",

View File

@ -50,7 +50,7 @@ if (_isRespawn) then {
_unit setVariable [QEGVAR(medical,bandagedWounds), [], true];
_unit setVariable [QEGVAR(medical,stitchedWounds), [], true];
_unit setVariable [QEGVAR(medical,isLimping), false, true];
_unit setVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0], true];
_unit setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true];
// - Misc ---------------------------------------------------------------------
_unit setVariable [VAR_UNCON, false, true];
@ -72,13 +72,6 @@ if (_isRespawn) then {
// medication
_unit setVariable [VAR_MEDICATIONS, [], true];
// TODO move to treatment
private _logs = _unit getVariable [QEGVAR(medical,allLogs), []];
{
_unit setVariable [_x, nil];
} forEach _logs;
_unit setVariable [QEGVAR(medical,allLogs), [], true];
};
[{

View File

@ -1,6 +1,6 @@
// CBA Settings [ADDON: ace_medical_status]:
private _categoryArray = [LELSTRING(medical,Category_DisplayName), LLSTRING(subCategory)];
private _categoryArray = [LELSTRING(medical,Category), LLSTRING(subCategory)];
[
QEGVAR(medical,bleedingCoefficient), "SLIDER",

View File

@ -582,7 +582,7 @@ class ADDON {
timeInSystem = 1800;
timeTillMaxEffect = 30;
maxDose = 4;
inCompatableMedication[] = {};
incompatibleMedication[] = {};
viscosityChange = -10;
};
class Epinephrine {
@ -593,7 +593,7 @@ class ADDON {
timeInSystem = 120;
timeTillMaxEffect = 10;
maxDose = 10;
inCompatableMedication[] = {};
incompatibleMedication[] = {};
};
class Adenosine {
painReduce = 0;
@ -603,7 +603,7 @@ class ADDON {
timeInSystem = 120;
timeTillMaxEffect = 15;
maxDose = 6;
inCompatableMedication[] = {};
incompatibleMedication[] = {};
};
class Atropine {
painReduce = 0;
@ -613,14 +613,14 @@ class ADDON {
timeInSystem = 120;
timeTillMaxEffect = 15;
maxDose = 6;
inCompatableMedication[] = {};
incompatibleMedication[] = {};
};
class PainKillers {
painReduce = 0.1;
timeInSystem = 600;
timeTillMaxEffect = 60;
maxDose = 10;
inCompatableMedication[] = {};
incompatibleMedication[] = {};
viscosityChange = 5;
};
};

View File

@ -1,39 +1,46 @@
class GVAR(Actions) {
// --- bandages
class GVAR(actions) {
// - Bandages -------------------------------------------------------------
class BasicBandage {
displayName = CSTRING(Bandage);
displayNameProgress = CSTRING(Bandaging);
icon = QPATHTOEF(medical_gui,ui\bandage.paa);
category = "bandage";
treatmentLocations[] = {"All"};
allowedSelections[] = {"All"};
allowSelfTreatment = 1;
requiredMedic = 0;
treatmentTime = QFUNC(getBandageTime);
treatmentTimeSelfCoef = 1;
items[] = {{"ACE_fieldDressing", "ACE_packingBandage", "ACE_elasticBandage", "ACE_quikclot"}};
condition = QFUNC(canBandage);
itemConsumed = 1;
callbackSuccess = QFUNC(treatmentBandage);
callbackFailure = "";
callbackProgress = "";
animationCaller = "AinvPknlMstpSlayW[wpn]Dnon_medicOther";
animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medicOther";
animationCallerSelf = "AinvPknlMstpSlayW[wpn]Dnon_medic";
animationCallerSelfProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
consumeItem = 1;
items[] = {"ACE_fieldDressing", "ACE_packingBandage", "ACE_elasticBandage", "ACE_quikclot"};
medicRequired = 0;
allowSelfTreatment = 1;
allowedSelections[] = {"All"};
condition = QFUNC(canBandage);
treatmentLocations = TREATMENT_LOCATIONS_ALL;
treatmentTime = QFUNC(getBandageTime);
treatmentTimeSelfCoef = 1; // todo: this isn't used anywhere, remove?
callbackStart = "";
callbackProgress = "";
callbackSuccess = QFUNC(bandage);
callbackFailure = "";
animationMedic = "AinvPknlMstpSlayW[wpn]Dnon_medicOther";
animationMedicProne = "AinvPpneMstpSlayW[wpn]Dnon_medicOther";
animationMedicSelf = "AinvPknlMstpSlayW[wpn]Dnon_medic";
animationMedicSelfProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
litter[] = {
{"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}},
{"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}}
{},
{"ACE_MedicalLitter_clean"},
{{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}
};
};
class FieldDressing: BasicBandage {
displayName = CSTRING(Actions_FieldDressing);
items[] = {"ACE_fieldDressing"};
litter[] = {
{"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}},
{"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}}
{},
{"ACE_MedicalLitter_clean"},
{{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}
};
};
class PackingBandage: BasicBandage {
@ -41,49 +48,51 @@ class GVAR(Actions) {
icon = QPATHTOEF(medical_gui,ui\packing_bandage.paa);
items[] = {"ACE_packingBandage"};
litter[] = {
{"All", "", {"ACE_MedicalLitter_packingBandage"}},
{"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}},
{"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}}
{"ACE_MedicalLitter_packingBandage"},
{"ACE_MedicalLitter_clean"},
{{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}
};
};
class ElasticBandage: BasicBandage {
displayName = CSTRING(Actions_ElasticBandage);
items[] = {"ACE_elasticBandage"};
litter[] = {
{"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}},
{"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}}
{},
{"ACE_MedicalLitter_clean"},
{{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}
};
};
class QuikClot: BasicBandage {
displayName = CSTRING(Actions_QuikClot);
items[] = {"ACE_quikclot"};
litter[] = {
{"All", "", {"ACE_MedicalLitter_QuickClot"}},
{"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}},
{"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}}
{"ACE_MedicalLitter_QuickClot"},
{"ACE_MedicalLitter_clean"},
{{"ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}
};
};
// --- tourniquet
class Tourniquet: BasicBandage {
// - Tourniquets ----------------------------------------------------------
class ApplyTourniquet: BasicBandage {
displayName = CSTRING(Apply_Tourniquet);
displayNameProgress = CSTRING(Applying_Tourniquet);
icon = QPATHTOEF(medical_gui,ui\tourniquet.paa);
allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"};
items[] = {"ACE_tourniquet"};
treatmentTime = 7;
callbackSuccess = QFUNC(treatmentTourniquet);
condition = QUOTE(!([ARR_2(_target,_bodyPart)] call FUNC(hasTourniquetAppliedTo)));
condition = QUOTE(!([ARR_2(_patient,_bodyPart)] call FUNC(hasTourniquetAppliedTo)));
callbackSuccess = QFUNC(tourniquet);
litter[] = {};
};
class RemoveTourniquet: Tourniquet {
class RemoveTourniquet: ApplyTourniquet {
displayName = CSTRING(Actions_RemoveTourniquet);
displayNameProgress = CSTRING(RemovingTourniquet);
items[] = {};
callbackSuccess = QFUNC(treatmentTourniquetRemove);
condition = QUOTE([ARR_2(_target,_bodyPart)] call FUNC(hasTourniquetAppliedTo));
condition = QUOTE([ARR_2(_patient,_bodyPart)] call FUNC(hasTourniquetAppliedTo));
callbackSuccess = QFUNC(tourniquetRemove);
};
// --- splint
// - Splint ---------------------------------------------------------------
class Splint: BasicBandage {
displayName = CSTRING(Apply_Splint);
displayNameProgress = CSTRING(Applying_Splint);
@ -93,11 +102,11 @@ class GVAR(Actions) {
items[] = {"ACE_splint"};
treatmentTime = 7;
callbackSuccess = QFUNC(splint);
condition = QFUNC(splintCondition);
condition = QFUNC(canSplint);
litter[] = {};
};
// --- syringes
// - Syringes -------------------------------------------------------------
class Morphine: FieldDressing {
displayName = CSTRING(Inject_Morphine);
displayNameProgress = CSTRING(Injecting_Morphine);
@ -107,35 +116,35 @@ class GVAR(Actions) {
items[] = {"ACE_morphine"};
condition = "";
treatmentTime = 5;
callbackSuccess = QFUNC(treatmentMedication);
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = { {"All", "", {"ACE_MedicalLitter_morphine"}} };
callbackSuccess = QFUNC(medication);
animationMedic = "AinvPknlMstpSnonWnonDnon_medic1";
sounds[] = {{QPATHTO_R(sounds\Inject.ogg),1,1,50}};
litter[] = {{"ACE_MedicalLitter_morphine"}};
};
class Adenosine: Morphine {
displayName = CSTRING(Inject_Adenosine);
displayNameProgress = CSTRING(Injecting_Adenosine);
condition = QGVAR(advancedMedication);
items[] = {"ACE_adenosine"};
litter[] = { {"All", "", {"ACE_MedicalLitter_adenosine"}} };
litter[] = {{"ACE_MedicalLitter_adenosine"}};
};
class Atropine: Morphine {
displayName = CSTRING(Inject_Atropine);
displayNameProgress = CSTRING(Injecting_Atropine);
condition = QGVAR(advancedMedication);
items[] = {"ACE_atropine"};
litter[] = { {"All", "", {"ACE_MedicalLitter_atropine"}} };
litter[] = {{"ACE_MedicalLitter_atropine"}};
};
class Epinephrine: Morphine {
displayName = CSTRING(Inject_Epinephrine);
displayNameProgress = CSTRING(Injecting_Epinephrine);
requiredMedic = QEGVAR(medical,medicSetting_Epi);
medicRequired = QGVAR(medicEpinephrine);
items[] = {"ACE_epinephrine"};
litter[] = { {"All", "", {"ACE_MedicalLitter_epinephrine"}} };
treatmentLocations[] = {QEGVAR(medical,useLocation_Epi)};
treatmentLocations = QGVAR(locationEpinephrine);
litter[] = {{"ACE_MedicalLitter_epinephrine"}};
};
// --- iv bags
// - IV Bags --------------------------------------------------------------
class BloodIV: BasicBandage {
displayName = CSTRING(Actions_Blood4_1000);
displayNameProgress = CSTRING(Transfusing_Blood);
@ -143,12 +152,12 @@ class GVAR(Actions) {
allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"};
allowSelfTreatment = QGVAR(allowSelfIV);
category = "advanced";
requiredMedic = 1;
medicRequired = 1;
treatmentTime = 12;
items[] = {"ACE_bloodIV"};
condition = "";
callbackSuccess = QFUNC(treatmentIV);
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
callbackSuccess = QFUNC(ivBag);
animationMedic = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = {};
};
class BloodIV_500: BloodIV {
@ -163,7 +172,7 @@ class GVAR(Actions) {
displayName = CSTRING(Actions_Plasma4_1000);
displayNameProgress = CSTRING(Transfusing_Plasma);
items[] = {"ACE_plasmaIV"};
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
animationMedic = "AinvPknlMstpSnonWnonDnon_medic1";
};
class PlasmaIV_500: PlasmaIV {
displayName = CSTRING(Actions_Plasma4_500);
@ -177,7 +186,7 @@ class GVAR(Actions) {
displayName = CSTRING(Actions_Saline4_1000);
displayNameProgress = CSTRING(Transfusing_Saline);
items[] = {"ACE_salineIV"};
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
animationMedic = "AinvPknlMstpSnonWnonDnon_medic1";
};
class SalineIV_500: SalineIV {
displayName = CSTRING(Actions_Saline4_500);
@ -188,23 +197,23 @@ class GVAR(Actions) {
items[] = {"ACE_salineIV_250"};
};
// --- diagnose
// - Diagnose -------------------------------------------------------------
class Diagnose: BasicBandage {
displayName = CSTRING(Actions_Diagnose);
displayNameProgress = CSTRING(Actions_Diagnosing);
icon = "";
category = "examine";
treatmentLocations[] = {"All"};
treatmentLocations = TREATMENT_LOCATIONS_ALL;
allowedSelections[] = {"Head", "Body"};
requiredMedic = 0;
medicRequired = 0;
treatmentTime = 2.5;
items[] = {};
condition = QUOTE(!GVAR(advancedDiagnose));
callbackSuccess = QFUNC(actionDiagnose);
callbackSuccess = QFUNC(diagnose);
callbackFailure = "";
callbackProgress = "";
animationCaller = ""; // TODO
itemConsumed = 0;
animationMedic = ""; // TODO
consumeItem = 0;
litter[] = {};
};
class CheckPulse: Diagnose {
@ -212,40 +221,38 @@ class GVAR(Actions) {
displayNameProgress = CSTRING(Check_Pulse_Content);
allowedSelections[] = {"All"};
condition = QGVAR(advancedDiagnose);
callbackSuccess = QFUNC(actionCheckPulse);
animationCallerProne = "";
animationCallerSelfProne = "";
callbackSuccess = QFUNC(checkPulse);
animationMedicProne = "";
animationMedicSelfProne = "";
};
class CheckBloodPressure: CheckPulse {
displayName = CSTRING(Actions_CheckBloodPressure);
displayNameProgress = CSTRING(Check_Bloodpressure_Content);
allowedSelections[] = {"LeftArm", "RightArm", "LeftLeg", "RightLeg"};
callbackSuccess = QFUNC(actionCheckBloodPressure);
callbackSuccess = QFUNC(checkBloodPressure);
};
class CheckResponse: CheckPulse {
displayName = CSTRING(Check_Response);
displayNameProgress = CSTRING(Check_Response_Content);
allowedSelections[] = {"Head"};
allowSelfTreatment = 0;
callbackSuccess = QFUNC(actionCheckResponse);
callbackSuccess = QFUNC(checkResponse);
};
// --- misc
// - Misc -----------------------------------------------------------------
class BodyBag: BasicBandage {
displayName = CSTRING(PlaceInBodyBag);
displayNameProgress = CSTRING(PlacingInBodyBag);
icon = QPATHTOEF(medical_gui,ui\bodybag.paa);
category = "advanced";
treatmentLocations[] = {"All"};
treatmentLocations = TREATMENT_LOCATIONS_ALL;
allowSelfTreatment = 0;
requiredMedic = 0;
medicRequired = 0;
treatmentTime = 15;
items[] = {"ACE_bodyBag"};
condition = "!alive _target";
callbackSuccess = QFUNC(actionPlaceInBodyBag);
callbackFailure = "";
callbackProgress = "";
itemConsumed = 1;
condition = QUOTE(!alive _patient);
callbackSuccess = QFUNC(placeInBodyBag);
consumeItem = 1;
litter[] = {};
};
class CPR: BasicBandage {
@ -253,62 +260,64 @@ class GVAR(Actions) {
displayNameProgress = CSTRING(Actions_PerformingCPR);
icon = "";
category = "advanced";
treatmentLocations[] = {"All"};
treatmentLocations = TREATMENT_LOCATIONS_ALL;
allowedSelections[] = {"Body"};
allowSelfTreatment = 0;
requiredMedic = 0;
medicRequired = 0;
treatmentTime = 15;
items[] = {};
condition = QUOTE(!(_target call EFUNC(common,isAwake)) && {!(_target getVariable [ARR_2('GVAR(receiveCPR)', false)])});
callbackSuccess = QFUNC(treatmentCPR);
callbackFailure = QFUNC(treatmentCPR_failure);
callbackProgress = QFUNC(treatmentCPR_progress);
callbackStart = QFUNC(treatmentCPR_start);
animationCaller = "AinvPknlMstpSlayW[wpn]Dnon_medic";
animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
animationCallerSelf = "";
animationCallerSelfProne = "";
itemConsumed = 0;
condition = QFUNC(canCPR);
callbackSuccess = QFUNC(cpr);
callbackFailure = QFUNC(cprFailure);
callbackProgress = QFUNC(cprProgress);
callbackStart = QFUNC(cprStart);
animationMedic = "AinvPknlMstpSlayW[wpn]Dnon_medic";
animationMedicProne = "AinvPpneMstpSlayW[wpn]Dnon_medic";
animationMedicSelf = "";
animationMedicSelfProne = "";
consumeItem = 0;
litter[] = {};
};
class SurgicalKit: FieldDressing {
displayName = CSTRING(Use_SurgicalKit);
displayNameProgress = CSTRING(Stitching);
icon = QPATHTOEF(medical_gui,ui\surgical_kit.paa);
category = "advanced";
items[] = {"ACE_surgicalKit"};
treatmentLocations[] = {QEGVAR(medical,useLocation_SurgicalKit)};
treatmentLocations = QGVAR(locationSurgicalKit);
allowSelfTreatment = 0;
requiredMedic = QEGVAR(medical,medicSetting_SurgicalKit);
treatmentTime = QUOTE(count (_target getVariable [ARR_2('EGVAR(medical,bandagedWounds)',[])]) * 5);
medicRequired = QGVAR(medicSurgicalKit);
treatmentTime = QFUNC(getStitchTime);
condition = QFUNC(canStitch);
callbackSuccess = "";
callbackProgress = QFUNC(treatmentSurgicalKit_onProgress);
itemConsumed = QEGVAR(medical,consumeItem_SurgicalKit);
animationCaller = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = { {"All", "", {"ACE_MedicalLitter_gloves"} }};
callbackProgress = QFUNC(surgicalKitProgress);
consumeItem = QGVAR(consumeSurgicalKit);
animationMedic = "AinvPknlMstpSnonWnonDnon_medic1";
litter[] = {{"ACE_MedicalLitter_gloves"}};
};
class PersonalAidKit: BasicBandage {
displayName = CSTRING(Use_Aid_Kit);
displayNameProgress = CSTRING(TreatmentAction);
icon = "";
category = "advanced";
condition = QUOTE(_target call EFUNC(medical_status,isInStableCondition));
condition = QUOTE(_patient call EFUNC(medical_status,isInStableCondition));
items[] = {"ACE_personalAidKit"};
treatmentLocations[] = {QEGVAR(medical,useLocation_PAK)};
requiredMedic = QEGVAR(medical,medicSetting_PAK);
treatmentTime = QUOTE(_target call FUNC(healTime));
callbackSuccess = QFUNC(treatmentFullHeal);
itemConsumed = QEGVAR(medical,consumeItem_PAK);
animationCaller = "AinvPknlMstpSlayW[wpn]Dnon_medicOther";
animationCallerProne = "AinvPpneMstpSlayW[wpn]Dnon_medicOther";
animationCallerSelf = "";
animationCallerSelfProne = "";
litter[] = { {"All", "", {"ACE_MedicalLitter_gloves"}},
{"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}},
{"All", "_bloodLossOnBodyPart > 0", {{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}}},
{"All", "_bloodLossOnBodyPart <= 0", {"ACE_MedicalLitter_clean"}}
treatmentLocations = QGVAR(locationPAK);
medicRequired = QGVAR(medicPAK);
treatmentTime = QFUNC(getHealTime);
callbackSuccess = QFUNC(fullHeal);
consumeItem = QGVAR(consumePAK);
animationMedic = "AinvPknlMstpSlayW[wpn]Dnon_medicOther";
animationMedicProne = "AinvPpneMstpSlayW[wpn]Dnon_medicOther";
animationMedicSelf = "";
animationMedicSelfProne = "";
litter[] = {
{"ACE_MedicalLitter_gloves"},
{"ACE_MedicalLitter_clean"},
{
{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"},
{"ACE_MedicalLitterBase", "ACE_MedicalLitter_bandage1", "ACE_MedicalLitter_bandage2", "ACE_MedicalLitter_bandage3"}
}
};
};
};

View File

@ -1,3 +1,10 @@
#define GRID_3DEN_W (pixelW * pixelGrid * 0.5)
#define GRID_3DEN_H (pixelH * pixelGrid * 0.5)
#define DEFAULT_IS_MEDIC (parseNumber (_this getUnitTrait 'medic'))
#define DEFAULT_IS_MEDICAL_VEHICLE (getNumber (configFile >> 'CfgVehicles' >> typeOf _this >> 'attendant') > 0)
class ctrlToolbox;
class Cfg3DEN {
@ -9,19 +16,23 @@ class Cfg3DEN {
};
};
class GVAR(isMedicControl): Title {
attributeLoad = "(_this controlsGroupCtrl 100) lbSetCurSel (((_value + 1) min 3) max 0);";
attributeSave = "(lbCurSel (_this controlsGroupCtrl 100)) - 1";
attributeLoad = QUOTE((_this controlsGroupCtrl 100) lbSetCurSel (0 max (_value + 1) min 3));
attributeSave = QUOTE(lbCurSel (_this controlsGroupCtrl 100) - 1);
class Controls: Controls {
class Title: Title{};
class Title: Title {};
class Value: ctrlToolbox {
idc = 100;
style = "0x02";
x = "48 * (pixelW * pixelGrid * 0.50)";
w = "82 * (pixelW * pixelGrid * 0.50)";
h = "5 * (pixelH * pixelGrid * 0.50)";
x = 48 * GRID_3DEN_W;
w = 82 * GRID_3DEN_W;
h = 5 * GRID_3DEN_H;
rows = 1;
columns = 4;
strings[] = {"$STR_3DEN_Attributes_Lock_Default_text", CSTRING(AssignMedicRoles_role_none), CSTRING(AssignMedicRoles_role_medic), CSTRING(AssignMedicRoles_role_doctorShort)};
strings[] = {
"$STR_3DEN_Attributes_Lock_Default_text",
CSTRING(AssignMedicRoles_role_none),
CSTRING(AssignMedicRoles_role_medic),
CSTRING(AssignMedicRoles_role_doctorShort)
};
};
};
};
@ -31,36 +42,34 @@ class Cfg3DEN {
class ace_attributes {
class Attributes {
class ace_isMedic {
property = QUOTE(ace_isMedic);
control = QGVAR(isMedicControl);
displayName = CSTRING(AssignMedicRoles_role_DisplayName);
tooltip = CSTRING(Attributes_isMedic_Description);
expression = QUOTE(if (_value > -1) then {_this setVariable [ARR_3(QQEGVAR(medical,medicClass),_value,true)];};);
typeName = "NUMBER";
property = QUOTE(ace_isMedic);
control = QGVAR(isMedicControl);
expression = QUOTE(if (_value != -1 && {_value != DEFAULT_IS_MEDIC}) then {_this setVariable [ARR_3(QQEGVAR(medical,medicClass),_value,true)]});
defaultValue = QUOTE(DEFAULT_IS_MEDIC);
condition = "objectBrain";
defaultValue = "-1";
typeName = "NUMBER";
};
class ace_isMedicalVehicle {
property = QUOTE(ace_isMedicalVehicle);
value = 0;
control = "CheckboxNumber";
displayName = CSTRING(AssignMedicVehicle_enabled_DisplayName);
tooltip = CSTRING(Attributes_isMedicalVehicle_Description);
expression = QUOTE(_this setVariable [ARR_3(QQEGVAR(medical,medicClass),_value,true)];);
typeName = "NUMBER";
property = QUOTE(ace_isMedicalVehicle);
control = "Checkbox";
expression = QUOTE(_this setVariable [ARR_3(QQEGVAR(medical,isMedicalVehicle),_value,true)]);
defaultValue = QUOTE(DEFAULT_IS_MEDICAL_VEHICLE);
condition = "objectVehicle";
defaultValue = 0;
typeName = "BOOL";
};
class ace_isMedicalFacility {
property = QUOTE(ace_isMedicalFacility);
value = 0;
control = "Checkbox";
displayName = CSTRING(AssignMedicalFacility_enabled_DisplayName);
tooltip = CSTRING(AssignMedicalFacility_enabled_Description);
property = QUOTE(ace_isMedicalFacility);
control = "Checkbox";
expression = QUOTE(_this setVariable [ARR_3(QQEGVAR(medical,isMedicalFacility),_value,true)];);
typeName = "BOOL";
condition = "(1 - objectBrain) * (1 - objectVehicle)";
defaultValue = "false";
condition = "(1 - objectBrain) * (1 - objectVehicle)";
typeName = "BOOL";
};
};
};

View File

@ -0,0 +1,17 @@
class EGVAR(medical,replacementItems) {
FirstAidKit[] = {
{"ACE_fieldDressing", 1},
{"ACE_packingBandage", 1},
{"ACE_morphine", 1},
{"ACE_tourniquet", 1}
};
Medikit[] = {
{"ACE_fieldDressing", 1},
{"ACE_packingBandage", 2},
{"ACE_epinephrine", 1},
{"ACE_morphine", 1},
{"ACE_salineIV_250", 1},
{"ACE_tourniquet", 1}
};
// todo: add GM medical items
};

View File

@ -1,32 +1,31 @@
class CfgWeapons {
class ItemCore;
class ACE_ItemCore;
class CBA_MiscItem_ItemInfo;
class InventoryFirstAidKitItem_Base_F;
class MedikitItem;
// ITEMS
class FirstAidKit: ItemCore {
type = 0;
ace_arsenal_hide = 1;
EGVAR(arsenal,hide) = 1;
class ItemInfo: InventoryFirstAidKitItem_Base_F {
mass = 4;
};
};
class Medikit: ItemCore {
type = 0;
ace_arsenal_hide = 1;
EGVAR(arsenal,hide) = 1;
class ItemInfo: MedikitItem {
mass = 60;
};
};
class ACE_ItemCore;
class ACE_fieldDressing: ACE_ItemCore {
scope = 2;
author = ECSTRING(common,ACETeam);
model = QPATHTOF(data\bandage.p3d);
picture = QPATHTOF(ui\items\fieldDressing_x_ca.paa);
picture = QPATHTOF(ui\fieldDressing_ca.paa);
displayName = CSTRING(Bandage_Basic_Display);
descriptionShort = CSTRING(Bandage_Basic_Desc_Short);
descriptionUse = CSTRING(Bandage_Basic_Desc_Use);
@ -38,7 +37,7 @@ class CfgWeapons {
scope = 2;
author = ECSTRING(common,ACETeam);
displayName = CSTRING(Packing_Bandage_Display);
picture = QPATHTOF(ui\items\packingBandage_x_ca.paa);
picture = QPATHTOF(ui\packingBandage_ca.paa);
model = QPATHTOF(data\packingbandage.p3d);
descriptionShort = CSTRING(Packing_Bandage_Desc_Short);
descriptionUse = CSTRING(Packing_Bandage_Desc_Use);
@ -50,7 +49,7 @@ class CfgWeapons {
scope = 2;
author = ECSTRING(common,ACETeam);
displayName = CSTRING(Bandage_Elastic_Display);
picture = QPATHTOF(ui\items\elasticBandage_x_ca.paa);
picture = QPATHTOF(ui\elasticBandage_ca.paa);
model = "\A3\Structures_F_EPA\Items\Medical\Bandage_F.p3d";
descriptionShort = CSTRING(Bandage_Elastic_Desc_Short);
descriptionUse = CSTRING(Bandage_Elastic_Desc_Use);
@ -62,7 +61,7 @@ class CfgWeapons {
scope = 2;
author = ECSTRING(common,ACETeam);
displayName = CSTRING(Tourniquet_Display);
picture = QPATHTOF(ui\items\tourniquet_x_ca.paa);
picture = QPATHTOF(ui\tourniquet_ca.paa);
model = QPATHTOF(data\tourniquet.p3d);
descriptionShort = CSTRING(Tourniquet_Desc_Short);
descriptionUse = CSTRING(Tourniquet_Desc_Use);
@ -74,7 +73,7 @@ class CfgWeapons {
scope = 2;
author = ECSTRING(common,ACETeam);
displayName = CSTRING(splint_Display);
picture = QPATHTOF(ui\items\tourniquet_x_ca.paa);
picture = QPATHTOF(ui\tourniquet_ca.paa);
model = QPATHTOF(data\tourniquet.p3d);
descriptionShort = CSTRING(splint_Desc_Short);
class ItemInfo: CBA_MiscItem_ItemInfo {
@ -85,7 +84,7 @@ class CfgWeapons {
scope = 2;
author = ECSTRING(common,ACETeam);
displayName = CSTRING(Morphine_Display);
picture = QPATHTOF(ui\items\morphine_x_ca.paa);
picture = QPATHTOF(ui\morphine_ca.paa);
model = QPATHTOF(data\morphine.p3d);
descriptionShort = CSTRING(Morphine_Desc_Short);
descriptionUse = CSTRING(Morphine_Desc_Use);
@ -97,7 +96,7 @@ class CfgWeapons {
scope = 2;
author = ECSTRING(common,ACETeam);
displayName = CSTRING(Adenosine_Display);
picture = QPATHTOF(ui\items\adenosine_x_ca.paa);
picture = QPATHTOF(ui\adenosine_ca.paa);
model = QPATHTOF(data\adenosine.p3d);
descriptionShort = CSTRING(adenosine_Desc_Short);
descriptionUse = CSTRING(adenosine_Desc_Use);
@ -109,7 +108,7 @@ class CfgWeapons {
scope = 2;
author = ECSTRING(common,ACETeam);
displayName = CSTRING(Atropine_Display);
picture = QPATHTOF(ui\items\atropine_x_ca.paa);
picture = QPATHTOF(ui\atropine_ca.paa);
model = QPATHTOF(data\atropine.p3d);
descriptionShort = CSTRING(Atropine_Desc_Short);
descriptionUse = CSTRING(Atropine_Desc_Use);
@ -121,7 +120,7 @@ class CfgWeapons {
scope = 2;
author = ECSTRING(common,ACETeam);
displayName = CSTRING(Epinephrine_Display);
picture = QPATHTOF(ui\items\epinephrine_x_ca.paa);
picture = QPATHTOF(ui\epinephrine_ca.paa);
model = QPATHTOF(data\epinephrine.p3d);
descriptionShort = CSTRING(Epinephrine_Desc_Short);
descriptionUse = CSTRING(Epinephrine_Desc_Use);
@ -136,8 +135,8 @@ class CfgWeapons {
displayName = CSTRING(Plasma_IV);
model = QPATHTOF(data\IVBag_1000ml.p3d);
hiddenSelections[] = {"camo"};
hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_plasma_1000ml_ca.paa) };
picture = QPATHTOF(ui\items\plasmaIV_x_ca.paa);
hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_plasma_1000ml_ca.paa)};
picture = QPATHTOF(ui\plasmaIV_ca.paa);
descriptionShort = CSTRING(Plasma_IV_Desc_Short);
descriptionUse = CSTRING(Plasma_IV_Desc_Use);
class ItemInfo: CBA_MiscItem_ItemInfo {
@ -147,7 +146,7 @@ class CfgWeapons {
class ACE_plasmaIV_500: ACE_plasmaIV {
displayName = CSTRING(Plasma_IV_500);
model = QPATHTOF(data\IVBag_500ml.p3d);
hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_plasma_500ml_ca.paa) };
hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_plasma_500ml_ca.paa)};
class ItemInfo: CBA_MiscItem_ItemInfo {
mass = 5;
};
@ -155,7 +154,7 @@ class CfgWeapons {
class ACE_plasmaIV_250: ACE_plasmaIV {
displayName = CSTRING(Plasma_IV_250);
model = QPATHTOF(data\IVBag_250ml.p3d);
hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_plasma_250ml_ca.paa) };
hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_plasma_250ml_ca.paa)};
class ItemInfo: CBA_MiscItem_ItemInfo {
mass = 2.5;
};
@ -165,9 +164,9 @@ class CfgWeapons {
author = ECSTRING(common,ACETeam);
model = QPATHTOF(data\IVBag_1000ml.p3d);
displayName = CSTRING(Blood_IV);
picture = QPATHTOF(ui\items\bloodIV_x_ca.paa);
picture = QPATHTOF(ui\bloodIV_ca.paa);
hiddenSelections[] = {"camo"};
hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_blood_1000ml_ca.paa) };
hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_blood_1000ml_ca.paa)};
descriptionShort = CSTRING(Blood_IV_Desc_Short);
descriptionUse = CSTRING(Blood_IV_Desc_Use);
class ItemInfo: CBA_MiscItem_ItemInfo {
@ -177,7 +176,7 @@ class CfgWeapons {
class ACE_bloodIV_500: ACE_bloodIV {
displayName = CSTRING(Blood_IV_500);
model = QPATHTOF(data\IVBag_500ml.p3d);
hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_blood_500ml_ca.paa) };
hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_blood_500ml_ca.paa)};
class ItemInfo: CBA_MiscItem_ItemInfo {
mass = 5;
};
@ -185,7 +184,7 @@ class CfgWeapons {
class ACE_bloodIV_250: ACE_bloodIV {
displayName = CSTRING(Blood_IV_250);
model = QPATHTOF(data\IVBag_250ml.p3d);
hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_blood_250ml_ca.paa) };
hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_blood_250ml_ca.paa)};
class ItemInfo: CBA_MiscItem_ItemInfo {
mass = 2.5;
};
@ -196,8 +195,8 @@ class CfgWeapons {
displayName = CSTRING(Saline_IV);
model = QPATHTOF(data\IVBag_1000ml.p3d);
hiddenSelections[] = {"camo"};
hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_saline_1000ml_ca.paa) };
picture = QPATHTOF(ui\items\salineIV_x_ca.paa);
hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_saline_1000ml_ca.paa)};
picture = QPATHTOF(ui\salineIV_ca.paa);
descriptionShort = CSTRING(Saline_IV_Desc_Short);
descriptionUse = CSTRING(Saline_IV_Desc_Use);
class ItemInfo: CBA_MiscItem_ItemInfo {
@ -207,7 +206,7 @@ class CfgWeapons {
class ACE_salineIV_500: ACE_salineIV {
displayName = CSTRING(Saline_IV_500);
model = QPATHTOF(data\IVBag_500ml.p3d);
hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_saline_500ml_ca.paa) };
hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_saline_500ml_ca.paa)};
class ItemInfo: CBA_MiscItem_ItemInfo {
mass = 5;
};
@ -215,7 +214,7 @@ class CfgWeapons {
class ACE_salineIV_250: ACE_salineIV {
displayName = CSTRING(Saline_IV_250);
model = QPATHTOF(data\IVBag_250ml.p3d);
hiddenSelectionsTextures[] = { QPATHTOF(data\IVBag_saline_250ml_ca.paa) };
hiddenSelectionsTextures[] = {QPATHTOF(data\IVBag_saline_250ml_ca.paa)};
class ItemInfo: CBA_MiscItem_ItemInfo {
mass = 2.5;
};
@ -225,7 +224,7 @@ class CfgWeapons {
author = ECSTRING(common,ACETeam);
displayName = CSTRING(QuikClot_Display);
model = QPATHTOF(data\QuikClot.p3d);
picture = QPATHTOF(ui\items\quickclot_x_ca.paa);
picture = QPATHTOF(ui\quickclot_ca.paa);
descriptionShort = CSTRING(QuikClot_Desc_Short);
descriptionUse = CSTRING(QuikClot_Desc_Use);
class ItemInfo: CBA_MiscItem_ItemInfo {
@ -236,7 +235,7 @@ class CfgWeapons {
scope = 2;
author = ECSTRING(common,ACETeam);
displayName = CSTRING(Aid_Kit_Display);
picture = QPATHTOF(ui\items\personal_aid_kit_x_ca.paa);
picture = QPATHTOF(ui\personal_aid_kit_ca.paa);
descriptionShort = CSTRING(Aid_Kit_Desc_Short);
descriptionUse = CSTRING(Aid_Kit_Desc_Use);
class ItemInfo: CBA_MiscItem_ItemInfo {
@ -244,11 +243,11 @@ class CfgWeapons {
};
};
class ACE_surgicalKit: ACE_ItemCore {
scope=2;
scope = 2;
author = ECSTRING(common,ACETeam);
displayName= CSTRING(SurgicalKit_Display);
model = QPATHTOF(data\surgical_kit.p3d);
picture = QPATHTOF(ui\items\surgicalKit_x_ca.paa);
picture = QPATHTOF(ui\surgicalKit_ca.paa);
descriptionShort = CSTRING(SurgicalKit_Desc_Short);
descriptionUse = CSTRING(SurgicalKit_Desc_Use);
class ItemInfo: CBA_MiscItem_ItemInfo {
@ -256,11 +255,11 @@ class CfgWeapons {
};
};
class ACE_bodyBag: ACE_ItemCore {
scope=2;
scope = 2;
author = ECSTRING(common,ACETeam);
displayName= CSTRING(Bodybag_Display);
model = QPATHTOF(data\bodybagItem.p3d);
picture = QPATHTOF(ui\items\bodybag_x_ca.paa);
picture = QPATHTOF(ui\bodybag_ca.paa);
descriptionShort = CSTRING(Bodybag_Desc_Short);
descriptionUse = CSTRING(Bodybag_Desc_Use);
class ItemInfo: CBA_MiscItem_ItemInfo {

View File

@ -1,75 +1,62 @@
// actions
PREP(actionCheckBloodPressure);
PREP(actionCheckBloodPressureLocal);
PREP(actionCheckPulse);
PREP(actionCheckPulseLocal);
PREP(actionCheckResponse);
PREP(actionDiagnose);
PREP(actionLoadUnit);
PREP(actionPlaceInBodyBag);
PREP(actionUnloadUnit);
PREP(addLoadPatientActions);
// treaments
PREP(canTreat);
PREP(canTreatCached);
PREP(treatment);
PREP(treatment_failure);
PREP(treatment_success);
PREP(treatmentBandage);
PREP(treatmentBandageLocal);
PREP(treatmentCPR);
PREP(treatmentCPR_failure);
PREP(treatmentCPR_progress);
PREP(treatmentCPR_start);
PREP(treatmentCPRLocal);
PREP(treatmentFullHeal);
PREP(treatmentFullHealLocal);
PREP(treatmentIV);
PREP(treatmentIVLocal);
PREP(treatmentMedication);
PREP(treatmentMedicationLocal);
PREP(treatmentSurgicalKit_onProgress);
PREP(treatmentTourniquet);
PREP(treatmentTourniquetLocal);
PREP(treatmentTourniquetRemove);
PREP(splint);
PREP(splintCondition);
PREP(splintLocal);
// misc
PREP(addToLog);
PREP(addToTriageCard);
PREP(bandage);
PREP(bandageLocal);
PREP(bodyCleanupLoop);
PREP(calculateBlood);
PREP(canAccessMedicalEquipment);
PREP(canBandage);
PREP(canCPR);
PREP(canSplint);
PREP(canStitch);
PREP(canTreat);
PREP(canTreatCached);
PREP(checkBloodPressure);
PREP(checkBloodPressureLocal);
PREP(checkItems);
PREP(checkPulse);
PREP(checkPulseLocal);
PREP(checkResponse);
PREP(cpr);
PREP(cprFailure);
PREP(cprLocal);
PREP(cprProgress);
PREP(cprStart);
PREP(createLitter);
PREP(createLitterServer);
PREP(diagnose);
PREP(findMostEffectiveWound);
PREP(fullHeal);
PREP(fullHealLocal);
PREP(getBandageTime);
PREP(getHealTime);
PREP(getStitchTime);
PREP(getTriageStatus);
PREP(handleBandageOpening);
PREP(hasItem);
PREP(hasTourniquetAppliedTo);
PREP(healTime);
PREP(isInMedicalFacility);
PREP(isInMedicalVehicle);
PREP(isMedic);
PREP(isMedicalVehicle);
PREP(onMedicationUsage);
PREP(serverRemoveBody);
PREP(setTriageStatus);
// items
PREP(checkItems);
PREP(hasItem);
PREP(hasItems);
PREP(useItem);
PREP(useItems);
// litter
PREP(ivBag);
PREP(ivBagLocal);
PREP(litterCleanupLoop);
PREP(litterCreate);
PREP(litterHandleCreate);
PREP(loadUnit);
PREP(medication);
PREP(medicationLocal);
PREP(onMedicationUsage);
PREP(placeInBodyBag);
PREP(removeBody);
PREP(setTriageStatus);
PREP(splint);
PREP(splintLocal);
PREP(surgicalKitProgress);
PREP(tourniquet);
PREP(tourniquetLocal);
PREP(tourniquetRemove);
PREP(treatment);
PREP(treatmentFailure);
PREP(treatmentSuccess);
PREP(unloadUnit);
PREP(useItem);

View File

@ -1,28 +1,38 @@
#include "script_component.hpp"
[QEGVAR(medical_status,initialized), FUNC(checkItems)] call CBA_fnc_addEventHandler;
[QEGVAR(medical_status,initialized), {
params ["_unit"];
// Clear all saved medical logs
{
_unit setVariable [_x, nil, true];
} forEach (_unit getVariable [QEGVAR(medical,allLogs), []]);
_unit setVariable [QEGVAR(medical,allLogs), [], true];
[_unit] call FUNC(checkItems);
}] call CBA_fnc_addEventHandler;
["loadout", FUNC(checkItems)] call CBA_fnc_addPlayerEventHandler;
// Handle bodybags and litter on server
// Handle body removal and litter on server
if (isServer) then {
[QGVAR(createLitterServer), FUNC(litterHandleCreate)] call CBA_fnc_addEventHandler;
["ace_placedInBodyBag", FUNC(serverRemoveBody)] call CBA_fnc_addEventHandler;
[QGVAR(createLitterServer), FUNC(createLitterServer)] call CBA_fnc_addEventHandler;
["ace_placedInBodyBag", FUNC(removeBody)] call CBA_fnc_addEventHandler;
};
// treatment events
[QGVAR(treatmentBandageLocal), FUNC(treatmentBandageLocal)] call CBA_fnc_addEventHandler;
[QGVAR(treatmentTourniquetLocal), FUNC(treatmentTourniquetLocal)] call CBA_fnc_addEventHandler;
[QGVAR(treatmentMedicationLocal), FUNC(treatmentMedicationLocal)] call CBA_fnc_addEventHandler;
[QGVAR(treatmentIVLocal), FUNC(treatmentIVLocal)] call CBA_fnc_addEventHandler;
[QGVAR(treatmentCPRLocal), FUNC(treatmentCPRLocal)] call CBA_fnc_addEventHandler;
[QGVAR(treatmentFullHealLocal), FUNC(treatmentFullHealLocal)] call CBA_fnc_addEventHandler;
[QGVAR(treatmentSplintLocal), FUNC(splintLocal)] call CBA_fnc_addEventHandler;
// Treatment events
[QGVAR(bandageLocal), FUNC(bandageLocal)] call CBA_fnc_addEventHandler;
[QGVAR(checkBloodPressureLocal), FUNC(checkBloodPressureLocal)] call CBA_fnc_addEventHandler;
[QGVAR(checkPulseLocal), FUNC(checkPulseLocal)] call CBA_fnc_addEventHandler;
[QGVAR(cprLocal), FUNC(cprLocal)] call CBA_fnc_addEventHandler;
[QGVAR(fullHealLocal), FUNC(fullHealLocal)] call CBA_fnc_addEventHandler;
[QGVAR(ivBagLocal), FUNC(ivBagLocal)] call CBA_fnc_addEventHandler;
[QGVAR(medicationLocal), FUNC(medicationLocal)] call CBA_fnc_addEventHandler;
[QGVAR(placeInBodyBag), FUNC(placeInBodyBag)] call CBA_fnc_addEventHandler;
[QGVAR(splintLocal), FUNC(splintLocal)] call CBA_fnc_addEventHandler;
[QGVAR(tourniquetLocal), FUNC(tourniquetLocal)] call CBA_fnc_addEventHandler;
// action events
[QGVAR(actionCheckPulseLocal), FUNC(actionCheckPulseLocal)] call CBA_fnc_addEventHandler;
[QGVAR(actionCheckBloodPressureLocal), FUNC(actionCheckBloodPressureLocal)] call CBA_fnc_addEventHandler;
[QGVAR(actionPlaceInBodyBag), FUNC(actionPlaceInBodyBag)] call CBA_fnc_addEventHandler;
// log events
[QGVAR(addToMedicalLog), FUNC(addToLog)] call CBA_fnc_addEventHandler;
// Logging events
[QGVAR(addToLog), FUNC(addToLog)] call CBA_fnc_addEventHandler;
[QGVAR(addToTriageCard), FUNC(addToTriageCard)] call CBA_fnc_addEventHandler;

View File

@ -34,4 +34,28 @@ GVAR(animDurations) = [] call CBA_fnc_createNamespace;
["AinvPknlMstpSnonWnonDnon_medic1", 10]
];
// class names of medical facilities
// global variable so it can be accessed by mission makers
GVAR(facilityClasses) = [
"TK_GUE_WarfareBFieldhHospital_Base_EP1",
"TK_GUE_WarfareBFieldhHospital_EP1",
"TK_WarfareBFieldhHospital_Base_EP1",
"TK_WarfareBFieldhHospital_EP1",
"US_WarfareBFieldhHospital_Base_EP1",
"US_WarfareBFieldhHospital_EP1",
"MASH_EP1",
"MASH",
"Land_A_Hospital",
"CDF_WarfareBFieldhHospital",
"GUE_WarfareBFieldhHospital",
"INS_WarfareBFieldhHospital",
"RU_WarfareBFieldhHospital",
"USMC_WarfareBFieldhHospital"
];
// array of medical items to replace and their ACE equivalents
GVAR(replacementItems) = configProperties [configFile >> QEGVAR(medical,replacementItems), "isArray _x"] apply {
[configName _x, getArray _x]
};
ADDON = true;

View File

@ -17,7 +17,8 @@ class CfgPatches {
#include "ACE_Medical_Treatment.hpp"
#include "ACE_Medical_Treatment_Actions.hpp"
#include "ACE_Settings.hpp"
#include "CfgEden.hpp"
#include "CfgEventHandlers.hpp"
#include "CfgReplacementItems.hpp"
#include "CfgVehicles.hpp"
#include "CfgWeapons.hpp"
#include "Cfg3DEN.hpp"

View File

@ -1,21 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Action for checking the blood pressure of the patient
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 2: Body part <STRING>
*
* Return Value:
* None
*
* Public: No
*/
params ["_caller", "_target", "_bodyPart"];
[QGVAR(actionCheckBloodPressureLocal), [_caller, _target, _bodyPart], _target] call CBA_fnc_targetEvent;
true

View File

@ -1,57 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Local callback for checking the blood pressure of a patient
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 2: Body part <STRING>
*
* Return Value:
* None
*
* Public: No
*/
params ["_caller", "_target", "_bodyPart"];
private _bloodPressure = [0, 0];
if (alive _target && {!([_target, _bodyPart] call FUNC(hasTourniquetAppliedTo))}) then {
_bloodPressure = GET_BLOOD_PRESSURE(_target);
};
private _bloodPressureOutput = ELSTRING(medical_treatment,Check_Bloodpressure_Output_6);
private _logOutPut = ELSTRING(medical_treatment,Check_Bloodpressure_NoBloodpressure);
_bloodPressure params ["_bloodPressureLow", "_bloodPressureHigh"];
if (_bloodPressureHigh > 20) then {
if (_caller call FUNC(isMedic)) then {
_bloodPressureOutput = ELSTRING(medical_treatment,Check_Bloodpressure_Output_1);
_logOutPut = format ["%1/%2", round _bloodPressureHigh, round _bloodPressureLow];
} else {
if (_bloodPressureHigh > 20) then {
_bloodPressureOutput = ELSTRING(medical_treatment,Check_Bloodpressure_Output_2);
_logOutPut = ELSTRING(medical_treatment,Check_Bloodpressure_Low);
if (_bloodPressureHigh > 100) then {
_bloodPressureOutput = ELSTRING(medical_treatment,Check_Bloodpressure_Output_3);
_logOutPut = ELSTRING(medical_treatment,Check_Bloodpressure_Normal);
if (_bloodPressureHigh > 160) then {
_bloodPressureOutput = ELSTRING(medical_treatment,Check_Bloodpressure_Output_4);
_logOutPut = ELSTRING(medical_treatment,Check_Bloodpressure_High);
};
};
};
};
};
[QEGVAR(common,displayTextStructured), [[_bloodPressureOutput, _target call EFUNC(common,getName), round _bloodPressureHigh, round _bloodPressureLow], 1.75, _caller], _caller] call CBA_fnc_targetEvent;
if (_logOutPut != "") then {
[_target, "activity", ELSTRING(medical_treatment,Check_Bloodpressure_Log), [_caller call EFUNC(common,getName), _logOutPut]] call FUNC(addToLog);
[_target, "quick_view", ELSTRING(medical_treatment,Check_Bloodpressure_Log), [_caller call EFUNC(common,getName), _logOutPut]] call FUNC(addToLog);
};

View File

@ -1,21 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Action for checking the pulse or heart rate of the patient
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 2: Body part <STRING>
*
* Return Value:
* None
*
* Public: No
*/
params ["_caller", "_target", "_bodyPart"];
[QGVAR(actionCheckPulseLocal), [_caller, _target, _bodyPart], _target] call CBA_fnc_targetEvent;
true

View File

@ -1,54 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Local callback for checking the pulse of a patient
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 2: Body part <STRING>
*
* Return Value:
* None
*
* Public: No
*/
params ["_caller", "_target", "_bodyPart"];
private _heartRate = 0;
if (alive _target && {!([_target, _bodyPart] call FUNC(hasTourniquetAppliedTo))}) then {
_heartRate = GET_HEART_RATE(_target);
};
private _heartRateOutput = ELSTRING(medical_treatment,Check_Pulse_Output_5);
private _logOutPut = ELSTRING(medical_treatment,Check_Pulse_None);
if (_heartRate > 1.0) then {
if (_caller call FUNC(isMedic)) then {
_heartRateOutput = ELSTRING(medical_treatment,Check_Pulse_Output_1);
_logOutPut = format ["%1", round(_heartRate)];
} else {
// non medical personel will only find a pulse/HR
_heartRateOutput = ELSTRING(medical_treatment,Check_Pulse_Output_2);
_logOutPut = ELSTRING(medical_treatment,Check_Pulse_Weak);
if (_heartRate > 60) then {
if (_heartRate > 100) then {
_heartRateOutput = ELSTRING(medical_treatment,Check_Pulse_Output_3);
_logOutPut = ELSTRING(medical_treatment,Check_Pulse_Strong);
} else {
_heartRateOutput = ELSTRING(medical_treatment,Check_Pulse_Output_4);
_logOutPut = ELSTRING(medical_treatment,Check_Pulse_Normal);
};
};
};
};
[QEGVAR(common,displayTextStructured), [[_heartRateOutput, _target call EFUNC(common,getName), round _heartRate], 1.5, _caller], _caller] call CBA_fnc_targetEvent;
if (_logOutPut != "") then {
[_target, "activity", ELSTRING(medical_treatment,Check_Pulse_Log), [_caller call EFUNC(common,getName), _logOutPut]] call FUNC(addToLog);
[_target, "quick_view", ELSTRING(medical_treatment,Check_Pulse_Log), [_caller call EFUNC(common,getName), _logOutPut]] call FUNC(addToLog);
};

View File

@ -1,26 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Action for checking the response status of the patient
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
*
* Return Value:
* None
*
* Example:
* [bob, kevin] call ace_medical_treatment_fnc_actionCheckResponse
*
* Public: No
*/
params ["_caller", "_target"];
private _output = [ELSTRING(medical_treatment,Check_Response_Unresponsive), ELSTRING(medical_treatment,Check_Response_Responsive)] select (_target call EFUNC(common,isAwake));
[QEGVAR(common,displayTextStructured), [[_output, _target call EFUNC(common,getName)], 2, _caller], _caller] call CBA_fnc_targetEvent;
[_target ,"activity", _output, [[_target, false, true] call EFUNC(common,getName)]] call FUNC(addToLog);
[_target, "quick_view", _output, [[_target, false, true] call EFUNC(common,getName)]] call FUNC(addToLog);

View File

@ -1,45 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Action for diagnosing in basic medical
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
*
* Return Value:
* None
*
* Public: No
*/
params ["_caller", "_target"];
private _genericMessages = [ELSTRING(medical_treatment,diagnoseMessage), _target call EFUNC(common,getName)];
if (alive _target) then {
_genericMessages pushBack ELSTRING(medical_treatment,diagnoseAlive);
} else {
_genericMessages pushBack ELSTRING(medical_treatment,diagnoseDead);
};
private _hemorrhage = GET_HEMORRHAGE(_target);
if (_hemorrhage > 0) then {
if (_hemorrhage > 1) then {
_genericMessages pushBack ELSTRING(medical_treatment,lostBloodALot);
} else {
_genericMessages pushBack ELSTRING(medical_treatment,lostBlood);
};
} else {
_genericMessages pushBack ELSTRING(medical_treatment,noBloodloss);
};
if (alive _target) then {
if IS_IN_PAIN(_target) then {
_genericMessages pushBack ELSTRING(medical_treatment,inPain);
} else {
_genericMessages pushBack ELSTRING(medical_treatment,noPain);
};
};
[QEGVAR(common,displayTextStructured), [_genericMessages, 3.0, _caller], _caller] call CBA_fnc_targetEvent;

View File

@ -1,42 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Action for loading an unconscious or dead unit in the nearest vehicle, or _vehicle if given.
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 2: The vehicle <OBJECT> (default: objNull)
*
* Return Value:
* Vehicle they are loaded into (objNull on failure) <OBJECT>
*
* Example:
* [bob, kevin] call ace_medical_treatment_treatment_fnc_actionLoadUnit
*
* Public: No
*/
params ["_caller", "_target", ["_vehicle", objNull]];
if ([_target] call EFUNC(common,isAwake)) exitWith {
[QEGVAR(common,displayTextStructured), [[ELSTRING(medical,CanNotLoaded), _target call EFUNC(common,getName)], 1.5, _caller], _caller] call CBA_fnc_targetEvent;
};
if ([_target] call EFUNC(medical_status,isBeingCarried)) then {
[_caller, _target] call EFUNC(dragging,dropObject_carry);
};
if ([_target] call EFUNC(medical_status,isBeingDragged)) then {
[_caller, _target] call EFUNC(dragging,dropObject);
};
private _vehicle = [_caller, _target, _vehicle] call EFUNC(common,loadPerson);
if (!isNull _vehicle) then {
private _hint = LSTRING(loadedInto);
private _itemName = [_target, false, true] call EFUNC(common,getName);
private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName");
[[_hint, _itemName, _vehicleName], 3.0] call EFUNC(common,displayTextStructured);
};
_vehicle

View File

@ -1,51 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Replace a (dead) body by a body bag
*
* Arguments:
* 0: The actor <OBJECT>
* 1: The patient <OBJECT>
*
* Return Value:
* body bag (will return objNull when run where target is not local) <OBJECT>
*
* Example:
* [player, cursorTarget] call ace_medical_treatment_fnc_actionPlaceInBodyBag
*
* Public: No
*/
params ["_caller", "_target"];
TRACE_2("params",_caller,_target);
if (!local _target) exitWith {
TRACE_1("running where local",local _target);
[QGVAR(actionPlaceInBodyBag), [_caller, _target], _target] call CBA_fnc_targetEvent;
objNull
};
if (alive _target) then {
TRACE_1("manually killing with setDead",_target);
[_target, true, "buried_alive"] call EFUNC(medical_status,setDead);
};
private _position = (getPosASL _target) vectorAdd [0, 0, 0.2];
private _headPos = _target modelToWorldVisual (_target selectionPosition "head");
private _spinePos = _target modelToWorldVisual (_target selectionPosition "Spine3");
private _dirVect = _headPos vectorFromTo _spinePos;
private _direction = _dirVect call CBA_fnc_vectDir;
// move the body away now, so it won't physX the bodyBag object (this setPos seems to need to be called where object is local)
_target setPosASL [-5000, -5000, 0];
private _bodyBag = createVehicle ["ACE_bodyBagObject", _position, [], 0, "NONE"];
// prevent body bag from flipping
_bodyBag setPosASL _position;
_bodyBag setDir _direction;
["ace_placedInBodyBag", [_target, _bodyBag]] call CBA_fnc_globalEvent; // hide and delete body on server
_bodyBag

View File

@ -1,26 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Action for unloading an unconscious or dead unit from a vechile
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 2: Drag after unload <BOOL> (default: false)
*
* Return Value:
* None
*
* Example:
* [bob, kevin, false] call ace_medical_treatment_fnc_actionUnloadUnit
*
* Public: No
*/
params ["_caller", "_target", ["_drag", false]];
// cannot unload a unit not in a vehicle.
if (vehicle _target == _target) exitWith {WARNING_1("Unit [%1] not in vehicle",_target);};
if (_target call EFUNC(common,isAwake)) exitWith {WARNING_1("Unit [%1] is awake",_target);};
["ace_unloadPersonEvent", [_target, vehicle _target, _caller], _target] call CBA_fnc_targetEvent;

View File

@ -1,16 +1,16 @@
#include "script_component.hpp"
/*
* Author: 654wak654
* Adds child actions to the "load patient" action for near vehicles.
* Returns children actions to the "Load Patient" action for nearby vehicles.
*
* Arguments:
* 0: Patient <OBJECT>
*
* Return Value:
* Child actions <ARRAY>
* Actions <ARRAY>
*
* Example:
* [kevin] call ace_medical_treatment_fnc_addLoadPatientActions
* [cursorObject] call ace_medical_treatment_fnc_addLoadPatientActions
*
* Public: No
*/
@ -19,7 +19,7 @@ params ["_target"];
private _statement = {
params ["_target", "_player", "_vehicle"];
[_player, _target, _vehicle] call FUNC(actionLoadUnit);
[_player, _target, _vehicle] call FUNC(loadUnit);
};
[_target call EFUNC(common,nearestVehiclesFreeSeat), _statement, _target] call EFUNC(interact_menu,createVehiclesActions)

View File

@ -1,56 +1,45 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Add an entry to the specified log
* Author: Glowbal, mharis001
* Adds an entry to the specified medical log of the unit.
*
* Arguments:
* 0: The patient <OBJECT>
* 1: The log type <STRING>
* 2: The message <STRING>
* 3: The arguments for localization <ARRAY>
* 0: Unit <OBJECT>
* 1: Log Type <STRING>
* 2: Message <STRING>
* 3: Formatting Arguments <ARRAY>
*
* Return Value:
* None
*
* Example:
* [bob, "type", "message", [_args]] call ace_medical_treatment_fnc_addToLog
* [player, "activity", "Message %1", ["Name"]] call ace_medical_treatment_fnc_addToLog
*
* Public: No
*/
params ["_unit", "_type", "_message", "_arguments"];
params ["_unit", "_logType", "_message", "_arguments"];
if (!local _unit) exitWith {
[QGVAR(addToMedicalLog), _this, _unit] call CBA_fnc_targetEvent;
[QGVAR(addToLog), _this, _unit] call CBA_fnc_targetEvent;
};
date params ["", "", "", "_hour", "_minute"];
private _timeStamp = format ["%1:%2", _hour, [_minute, 2] call CBA_fnc_formatNumber];
private _moment = format [["%1:%2", "%1:0%2"] select (_minute < 10), _hour, _minute];
private _logVarName = format [QEGVAR(medical,logFile_%1), _type];
private _logVarName = MED_LOG_VARNAME(_logType);
private _log = _unit getVariable [_logVarName, []];
if (count _log >= 8) then {
private _newLog = [];
{
// ensure the first element will not be added
if (_forEachIndex > 0) then {
_newLog pushBack _x;
};
} forEach _log;
_log = _newLog;
if (count _log >= MED_LOG_MAX_ENTRIES) then {
_log deleteAt 0;
};
_log pushBack [_message, _moment, _type, _arguments];
_log pushBack [_message, _timeStamp, _arguments, _logType];
_unit setVariable [_logVarName, _log, true];
["ace_medicalLogEntryAdded", [_unit, _type, _message, _arguments]] call CBA_fnc_localEvent;
private _logs = _unit getVariable [QEGVAR(medical,allLogs), []];
private _allLogs = _unit getVariable [QEGVAR(medical,allLogs), []];
if !(_logVarName in _logs) then {
_logs pushBack _logVarName;
_unit setVariable [QEGVAR(medical,allLogs), _logs, true];
if !(_logVarName in _allLogs) then {
_allLogs pushBack _logVarName;
_unit setVariable [QEGVAR(medical,allLogs), _allLogs, true];
};

View File

@ -1,46 +1,37 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Add an entry to the triage card
* Author: Glowbal, mharis001
* Adds an entry to the unit's triage card.
*
* Arguments:
* 0: The patient <OBJECT>
* 1: The new item class name <STRING>
* 0: Unit <OBJECT>
* 1: Item Classname <STRING>
*
* Return Value:
* None
*
* Example:
* [bob, "bandage"] call ace_medical_treatment_fnc_addToTriageCard
* [player, "ACE_morphine"] call ace_medical_treatment_fnc_addToTriageCard
*
* Public: No
*/
params ["_unit", "_newItem"];
params ["_unit", "_item"];
if (!local _unit) exitWith {
[QGVAR(addToTriageCard), _this, _unit] call CBA_fnc_targetEvent;
};
private _log = _unit getVariable [QEGVAR(medical,triageCard), []];
private _inList = false;
private _amount = 1;
private _triageCard = _unit getVariable [QEGVAR(medical,triageCard), []];
private _index = _triageCard findIf {_x select 0 == _item};
{
if (_x select 0 == _newItem) exitWith {
private _info = _log select _forEachIndex;
_info set [1, (_info select 1) + 1];
_info set [2, CBA_missionTime];
_log set [_forEachIndex, _info];
_amount = _info select 1;
_inList = true;
};
} forEach _log;
if (!_inList) then {
_log pushBack [_newItem, 1, CBA_missionTime];
if (_index == -1) then {
_triageCard pushBack [_item, 1, CBA_missionTime];
} else {
_triageCard set [_index, [_item, (_triageCard select _index select 1) + 1, CBA_missionTime]];
};
_unit setVariable [QEGVAR(medical,triageCard), _log, true];
["ace_triageCardItemAdded", [_unit, _newItem, _amount]] call CBA_fnc_localEvent;
_unit setVariable [QEGVAR(medical,triageCard), _triageCard, true];
// todo: add amount of item to event args?
["ace_triageCardItemAdded", [_unit, _item]] call CBA_fnc_localEvent;

View File

@ -0,0 +1,25 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Bandages open wounds on the given body part of the patient.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
* 3: Treatment <STRING>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject, "Head", "FieldDressing"] call ace_medical_treatment_fnc_bandage
*
* Public: No
*/
params ["_medic", "_patient", "_bodyPart", "_classname"];
[_patient, "activity", LSTRING(Activity_bandagedPatient), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog);
[QGVAR(bandageLocal), [_patient, _bodyPart, _classname], _patient] call CBA_fnc_targetEvent;

View File

@ -1,30 +1,33 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Handles the bandage of a patient.
* Local callback for bandaging a patient's open wounds.
*
* Arguments:
* 0: The patient <OBJECT>
* 1: Treatment class name <STRING>
* 2: Body part <STRING>
* 0: Patient <OBJECT>
* 1: Body Part <STRING>
* 2: Treatment <STRING>
*
* Return Value:
* Succesful treatment started <BOOL>
* None
*
* Example:
* [player, "Head", "FieldDressing"] call ace_medical_treatment_fnc_bandageLocal
*
* Public: No
*/
params ["_target", "_bandage", "_bodyPart"];
params ["_patient", "_bodyPart", "_bandage"];
private _partIndex = ALL_BODY_PARTS find toLower _bodyPart;
if (_partIndex < 0) exitWith { false };
if (_partIndex < 0) exitWith {false};
private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []];
if (_openWounds isEqualTo []) exitWith { false };
private _openWounds = _patient getVariable [QEGVAR(medical,openWounds), []];
if (_openWounds isEqualTo []) exitWith {false};
// Figure out which injury for this bodypart is the best choice to bandage
// TODO also use up the remainder on left over injuries
private _targetWound = [_target, _bandage, _partIndex] call FUNC(findMostEffectiveWound);
private _targetWound = [_patient, _bandage, _partIndex] call FUNC(findMostEffectiveWound);
_targetWound params ["_wound", "_woundIndex", "_effectiveness"];
// Everything is patched up on this body part already
@ -37,18 +40,18 @@ _amountOf = _amountOf - _impact;
_wound set [2, _amountOf];
_openWounds set [_woundIndex, _wound];
_target setVariable [QEGVAR(medical,openWounds), _openWounds, true];
_patient setVariable [QEGVAR(medical,openWounds), _openWounds, true];
[_target] call EFUNC(medical_status,updateWoundBloodLoss);
[_patient] call EFUNC(medical_status,updateWoundBloodLoss);
// Handle the reopening of bandaged wounds
if (_impact > 0 && {GVAR(advancedBandages) && {GVAR(woundReopening)}}) then {
[_target, _impact, _partIndex, _woundIndex, _wound, _bandage] call FUNC(handleBandageOpening);
[_patient, _impact, _partIndex, _woundIndex, _wound, _bandage] call FUNC(handleBandageOpening);
};
// Check if we fixed limping from this treatment
if ((EGVAR(medical,limping) == 1) && {_partIndex > 3} && {_amountOf <= 0} && {_target getVariable [QEGVAR(medical,isLimping), false]}) then {
[_target] call EFUNC(medical_engine,updateDamageEffects);
if ((EGVAR(medical,limping) == 1) && {_partIndex > 3} && {_amountOf <= 0} && {_patient getVariable [QEGVAR(medical,isLimping), false]}) then {
[_patient] call EFUNC(medical_engine,updateDamageEffects);
};
true

View File

@ -1,7 +1,7 @@
#include "script_component.hpp"
/*
* Author: Glowbal, esteldunedain
* Loop that cleans up player bodies that were replaced by bodybags
* Handles cleaning up bodies that were replaced by body bags.
*
* Arguments:
* None
@ -10,23 +10,23 @@
* None
*
* Example:
* call ace_medical_treatment_fnc_bodyCleanupLoop
* [] call ace_medical_treatment_fnc_bodyCleanupLoop
*
* Public: No
*/
{
TRACE_2("body",_x,isPlayer _x);
if ((!isNull _x) && {!isPlayer _x}) then {deleteVehicle _x};
TRACE_2("Handling body cleanup",_x,isPlayer _x);
if (!isNull _x && {!isPlayer _x}) then {deleteVehicle _x};
} forEach GVAR(bodiesToDelete);
// deleteVehicle doesn't have instant results so it won't usualy be filtered until next run
GVAR(bodiesToDelete) = GVAR(bodiesToDelete) - [objNull];
// If no more bodies remain, exit the loop
// Exit the loop if no more bodies remain
if (GVAR(bodiesToDelete) isEqualTo []) exitWith {
TRACE_1("array emptied - rem PFEH",GVAR(bodiesToDelete));
TRACE_1("Ending body cleanup loop",GVAR(bodiesToDelete));
};
// Schedule the loop to be executed again 20 sec later
[DFUNC(bodyCleanupLoop), [], 20] call CBA_fnc_waitAndExecute;
// Schedule cleanup loop to executed again
[FUNC(litterCleanupLoop), [], BODY_CLEANUP_CHECK_DELAY] call CBA_fnc_waitAndExecute;

View File

@ -1,28 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Check if caller can access targets medical equipment, based upon accessLevel.
*
* Arguments:
* 0: The caller <OBJECT>
* 1: The target <OBJECT>
*
* Return Value:
* Can Treat <BOOL>
*
* Example:
* [bob, target] call ace_medical_treatment_fnc_canAccessMedicalEquipment
*
* Public: No
*/
params ["_caller", "_target"];
private _accessLevel = _target getVariable [QGVAR(allowSharedEquipmentAccess), -1];
switch (_accessLevel) do {
case 0: { true };
case 1: { side _target == side _caller };
case 2: { group _target == group _caller };
default { false };
};

View File

@ -5,12 +5,12 @@
* Toggles between showing all or only basic bandage action for advanced setting.
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 2: Body part <STRING>
* 3: Treatment class name <STRING>
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
* 3: Treatment <STRING>
*
* ReturnValue:
* Return Value:
* Can Bandage <BOOL>
*
* Example:
@ -19,12 +19,12 @@
* Public: No
*/
params ["_medic", "_patient", "_bodypart", "_bandage"];
params ["_medic", "_patient", "_bodyPart", "_bandage"];
// Bandage type and bandage setting XNOR to show only active actions
if ((_bandage == "BasicBandage") isEqualTo GVAR(advancedBandages)) exitWith { false };
if ((_bandage == "BasicBandage") isEqualTo GVAR(advancedBandages)) exitWith {false};
private _index = ALL_BODY_PARTS find toLower _bodypart;
private _index = ALL_BODY_PARTS find toLower _bodyPart;
private _canBandage = false;
{

View File

@ -0,0 +1,21 @@
#include "script_component.hpp"
/*
* Author: mharis001
* Checks if CPR can be performed on the patient.
*
* Arguments:
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* Can CPR <BOOL>
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_canCPR
*
* Public: No
*/
params ["", "_patient"];
!(_patient call EFUNC(common,isAwake)) && {!(_patient getVariable [QGVAR(isReceivingCPR), false])}

View File

@ -1,18 +1,18 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Can apply a splint to the patient
* Checks if a splint can be applied to the patient.
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 2: Body part <STRING>
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
*
* Return Value:
* Nothing
* Can Splint <BOOL>
*
* Example:
* [player, cursorObject, "LeftLeg"] call ace_medical_treatment_fnc_splintCondition
* [player, cursorObject, "LeftLeg"] call ace_medical_treatment_fnc_canSplint
*
* Public: No
*/
@ -20,6 +20,5 @@
params ["", "_patient", "_bodyPart"];
private _partIndex = ALL_BODY_PARTS find toLower _bodyPart;
private _fractures = _patient getVariable [QEGVAR(medical,fractures), [0,0,0,0,0,0]];
(_fractures select _partIndex) == 1
(GET_FRACTURES(_patient) select _partIndex) == 1

View File

@ -1,11 +1,11 @@
#include "script_component.hpp"
/*
* Author: Katalam
* Prevents stitch actions from showing if the body is either fully stitched or has no open wounds.
* Checks if the patient can be stitched.
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
*
* ReturnValue:
* Can Stitch <BOOL>

View File

@ -1,116 +1,57 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Check if the treatment action can be performed.
* Author: Glowbal, mharis001
* Checks if the given treatment can be performed.
*
* Arguments:
* 0: The caller <OBJECT>
* 1: The target <OBJECT>
* 2: Body part <STRING>
* 3: Treatment class name <STRING>
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
* 3: Treatment <STRING>
*
* ReturnValue:
* Return Value:
* Can Treat <BOOL>
*
* Example:
* [player, cursorTarget, "Head", "SurgicalKit"] call ace_medical_treatment_fnc_canTreat
* [player, cursorObject, "Head", "SurgicalKit"] call ace_medical_treatment_fnc_canTreat
*
* Public: No
*/
params ["_caller", "_target", "_bodyPart", "_className"];
params ["_medic", "_patient", "_bodyPart", "_classname"];
if !(_target isKindOf "CAManBase") exitWith {false};
private _config = configFile >> QGVAR(actions) >> _classname;
private _config = configFile >> QGVAR(Actions) >> _className;
isClass _config
&& {_patient isKindOf "CAManBase"}
&& {_medic != _patient || {GET_NUMBER_ENTRY(_config >> "allowSelfTreatment") == 1}}
&& {[_medic, GET_NUMBER_ENTRY(_config >> "medicRequired")] call FUNC(isMedic)}
&& {
private _selections = getArray (_config >> "allowedSelections") apply {toLower _x};
"all" in _selections || {_bodyPart in _selections}
} && {
private _items = getArray (_config >> "items");
_items isEqualTo [] || {[_medic, _patient, _items] call FUNC(hasItem)}
} && {
GET_FUNCTION(_condition,_config >> "condition");
if !(isClass _config) exitWith {false};
// allow self treatment check
private _isSelf = _caller isEqualTo _target;
private _allowSelf = 0;
if (_isSelf) then {
if (isNumber (_config >> "allowSelfTreatment")) then {
_allowSelf = getNumber (_config >> "allowSelfTreatment");
} else {
if (isText (_config >> "allowSelfTreatment")) then {
_allowSelf = missionNamespace getVariable [getText (_config >> "allowSelfTreatment"), 0];
};
};
};
if (_isSelf && {_allowSelf == 0}) exitWith {false};
private _medicRequired = 0;
if (isNumber (_config >> "requiredMedic")) then {
_medicRequired = getNumber (_config >> "requiredMedic");
} else {
if (isText (_config >> "requiredMedic")) then {
_medicRequired = missionNamespace getVariable [getText (_config >> "requiredMedic"), 0];
};
};
if !([_caller, _medicRequired] call FUNC(isMedic)) exitWith {false};
// check selection
private _allowedSelections = getArray (_config >> "allowedSelections") apply {toLower _x};
if !("all" in _allowedSelections || {(_bodyPart in _allowedSelections)}) exitWith {false};
// check item
private _items = getArray (_config >> "items");
if (count _items > 0 && {!([_caller, _target, _items] call FUNC(hasItems))}) exitWith {false};
private _condition = true;
if (isText (_config >> "condition")) then {
_condition = getText (_config >> "condition");
if (_condition isEqualTo "") exitWith {
_condition = true;
};
if (isNil _condition) then {
_condition = compile _condition;
} else {
_condition = missionNamespace getVariable _condition;
};
if !(_condition isEqualType false) then {
if (_condition isEqualType {}) then {
_condition = call _condition;
};
};
if !(_condition) exitWith {false};
// check allowed locations
private _locations = getArray (_config >> "treatmentLocations") apply {toLower _x};
if ("all" in _locations) then {
_locations = true;
} else {
private _medFacility = {([_caller] call FUNC(isInMedicalFacility)) || ([_target] call FUNC(isInMedicalFacility))};
private _medVeh = {([_caller] call FUNC(isInMedicalVehicle)) || ([_target] call FUNC(isInMedicalVehicle))};
{
if (_x == "field") exitWith { _locations = true; };
if (_x == "MedicalFacility" && _medFacility) exitWith { _locations = true; };
if (_x == "MedicalVehicle" && _medVeh) exitWith { _locations = true; };
if !(isNil _x) exitWith {
_locations = missionNamespace getVariable _x;
if !(_locations isEqualType false) then {
if (_locations isEqualTo 0) exitWith { _locations = true; }; //AdvancedMedicalSettings_anywhere
if (_locations isEqualTo 1) exitWith { _locations = call _medVeh; }; //AdvancedMedicalSettings_vehicle
if (_locations isEqualTo 2) exitWith { _locations = call _medFacility; }; //AdvancedMedicalSettings_facility
if (_locations isEqualTo 3) exitWith { _locations = call _medFacility || {call _medVeh}; }; //AdvancedMedicalSettings_vehicleAndFacility
_locations = false; //Disabled
};
_condition
} && {
switch (GET_NUMBER_ENTRY(_config >> "treatmentLocations")) do {
case TREATMENT_LOCATIONS_ALL: {true};
case TREATMENT_LOCATIONS_VEHICLES: {
IN_MED_VEHICLE(_medic) || {IN_MED_VEHICLE(_patient)}
};
} forEach _locations;
};
_locations
case TREATMENT_LOCATIONS_FACILITIES: {
IN_MED_FACILITY(_medic) || {IN_MED_FACILITY(_patient)}
};
case TREATMENT_LOCATIONS_VEHICLES_AND_FACILITIES: {
IN_MED_VEHICLE(_medic) || {IN_MED_VEHICLE(_patient)} || {IN_MED_FACILITY(_medic)} || {IN_MED_FACILITY(_patient)}
};
default {false};
};
}

View File

@ -1,24 +1,23 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Cached Check if the treatment action can be performed.
* Cached check to determine if given treatment can be performed.
*
* Arguments:
* 0: The caller <OBJECT>
* 1: The target <OBJECT>
* 2: Selection name <STRING>
* 3: ACE_Medical_Treatment Classname <STRING>
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
* 3: Treatment <STRING>
*
* Return Value:
* Can Treat <BOOL>
*
* Example:
* [bob, kevin, "selection", "classname"] call ace_medical_treatment_fnc_canTreatCached
* [player, cursorObject, "Head", "SurgicalKit"] call ace_medical_treatment_fnc_canTreatCached
*
* Public: No
*/
params ["", "_target", "_selection", "_classname"];
params ["", "_patient", "_bodyPart", "_classname"];
// parameters, function, namespace, uid
[_this, DFUNC(canTreat), _target, format [QGVAR(canTreat_%1_%2), _selection, _classname], CAN_TREAT_CONDITION_CACHE_EXPIRY, QEGVAR(interact_menu,clearConditionCaches)] call EFUNC(common,cachedCall);
[_this, FUNC(canTreat), _patient, format [QGVAR(canTreat_%1_%2), _bodyPart, _classname], CAN_TREAT_CONDITION_CACHE_EXPIRY, QEGVAR(interact_menu,clearConditionCaches)] call EFUNC(common,cachedCall);

View File

@ -0,0 +1,22 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Checks the blood pressure of the patient.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject, "LeftArm"] call ace_medical_treatment_fnc_checkBloodPressure
*
* Public: No
*/
params ["_medic", "_patient", "_bodyPart"];
[QGVAR(checkBloodPressureLocal), [_medic, _patient, _bodyPart], _patient] call CBA_fnc_targetEvent;

View File

@ -0,0 +1,57 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Local callback for checking the blood pressure of a patient.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject, "LeftArm"] call ace_medical_treatment_fnc_checkBloodPressureLocal
*
* Public: No
*/
params ["_medic", "_patient", "_bodyPart"];
private _bloodPressure = [0, 0];
if (alive _patient && {!([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo))}) then {
_bloodPressure = GET_BLOOD_PRESSURE(_patient);
};
private _bloodPressureOutput = LSTRING(Check_Bloodpressure_Output_6);
private _logOutput = LSTRING(Check_Bloodpressure_NoBloodpressure);
_bloodPressure params ["_bloodPressureLow", "_bloodPressureHigh"];
if (_bloodPressureHigh > 20) then {
if (_medic call FUNC(isMedic)) then {
_bloodPressureOutput = LSTRING(Check_Bloodpressure_Output_1);
_logOutput = format ["%1/%2", round _bloodPressureHigh, round _bloodPressureLow];
} else {
if (_bloodPressureHigh > 20) then {
_bloodPressureOutput = LSTRING(Check_Bloodpressure_Output_2);
_logOutput = LSTRING(Check_Bloodpressure_Low);
if (_bloodPressureHigh > 100) then {
_bloodPressureOutput = LSTRING(Check_Bloodpressure_Output_3);
_logOutput = LSTRING(Check_Bloodpressure_Normal);
if (_bloodPressureHigh > 160) then {
_bloodPressureOutput = LSTRING(Check_Bloodpressure_Output_4);
_logOutput = LSTRING(Check_Bloodpressure_High);
};
};
};
};
};
[_patient, "quick_view", LSTRING(Check_Bloodpressure_Log), [_medic call EFUNC(common,getName), _logOutput]] call FUNC(addToLog);
[QEGVAR(common,displayTextStructured), [[_bloodPressureOutput, _patient call EFUNC(common,getName), round _bloodPressureHigh, round _bloodPressureLow], 1.75, _medic], _medic] call CBA_fnc_targetEvent;

View File

@ -1,42 +1,47 @@
#include "script_component.hpp"
/*
* Author: KoffeinFlummi, commy2
* Replaces vanilla items with ACE ones.
* Author: KoffeinFlummi, commy2, mharis001
* Handles converting vanilla medical items with ACE equivalents.
*
* Arguments:
* 0: The unit <OBJECT>
* 0: Unit <OBJECT>
*
* ReturnValue:
* Return Value:
* None
*
* Example:
* [player] call ace_medical_treatment_fnc_checkItems
*
* Public: No
*/
if (EGVAR(medical,convertItems) == 2) exitWith {};
if (GVAR(convertItems) == 2) exitWith {};
params ["_unit"];
private _countFirstAidKit = [_unit, "FirstAidKit"] call EFUNC(common,getCountOfItem);
_unit removeItems "FirstAidKit";
private _fnc_loop = if (GVAR(convertItems) == 0) then {
{
_x params ["_itemToRemove", "_replacementItems"];
private _countMedikit = [_unit, "Medikit"] call EFUNC(common,getCountOfItem);
_unit removeItems "Medikit";
private _count = [_unit, _itemToRemove] call EFUNC(common,getCountOfItem);
if (EGVAR(medical,convertItems) != 0) exitWith {};
if (_count > 0) then {
_unit removeItems _itemToRemove;
for "_i" from 1 to _countFirstAidKit do {
_unit addItem "ACE_fieldDressing";
_unit addItem "ACE_packingBandage";
_unit addItem "ACE_morphine";
_unit addItem "ACE_tourniquet";
{
_x params ["_item", "_amount"];
for "_i" from 1 to (_amount * _count) do {
_unit addItem _item;
};
} forEach _replacementItems;
};
}
} else {
{
_x params ["_itemToRemove"];
_unit removeItems _itemToRemove;
}
};
for "_i" from 1 to _countMedikit do {
_unit addItemToBackpack "ACE_fieldDressing";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_packingBandage";
_unit addItemToBackpack "ACE_epinephrine";
_unit addItemToBackpack "ACE_morphine";
_unit addItemToBackpack "ACE_salineIV_250";
_unit addItemToBackpack "ACE_tourniquet";
};
_fnc_loop forEach GVAR(replacementItems);

View File

@ -0,0 +1,22 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Checks the pulse or heart rate of the patient.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject, "Head"] call ace_medical_treatment_fnc_checkPulse
*
* Public: No
*/
params ["_medic", "_patient", "_bodyPart"];
[QGVAR(checkPulseLocal), [_medic, _patient, _bodyPart], _patient] call CBA_fnc_targetEvent;

View File

@ -0,0 +1,53 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Local callback for checking the pulse or heart rate of a patient.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject, "Head"] call ace_medical_treatment_fnc_checkPulseLocal
*
* Public: No
*/
params ["_medic", "_patient", "_bodyPart"];
private _heartRate = 0;
if (alive _patient && {!([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo))}) then {
_heartRate = GET_HEART_RATE(_patient);
};
private _heartRateOutput = LSTRING(Check_Pulse_Output_5);
private _logOutput = LSTRING(Check_Pulse_None);
if (_heartRate > 1) then {
if (_medic call FUNC(isMedic)) then {
_heartRateOutput = LSTRING(Check_Pulse_Output_1);
_logOutput = format ["%1", round _heartRate];
} else {
_heartRateOutput = LSTRING(Check_Pulse_Output_2);
_logOutput = LSTRING(Check_Pulse_Weak);
if (_heartRate > 60) then {
if (_heartRate > 100) then {
_heartRateOutput = LSTRING(Check_Pulse_Output_3);
_logOutput = LSTRING(Check_Pulse_Strong);
} else {
_heartRateOutput = LSTRING(Check_Pulse_Output_4);
_logOutput = LSTRING(Check_Pulse_Normal);
};
};
};
};
[_patient, "quick_view", LSTRING(Check_Pulse_Log), [_medic call EFUNC(common,getName), _logOutput]] call FUNC(addToLog);
[QEGVAR(common,displayTextStructured), [[_heartRateOutput, _patient call EFUNC(common,getName), round _heartRate], 1.5, _medic], _medic] call CBA_fnc_targetEvent;

View File

@ -0,0 +1,24 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Checks the response status of the patient.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_checkResponse
*
* Public: No
*/
params ["_medic", "_patient"];
private _output = [LSTRING(Check_Response_Unresponsive), LSTRING(Check_Response_Responsive)] select (_patient call EFUNC(common,isAwake));
[[_output, _patient call EFUNC(common,getName)], 2] call EFUNC(common,displayTextStructured);
[_patient, "quick_view", _output, [[_patient, false, true] call EFUNC(common,getName)]] call FUNC(addToLog);

View File

@ -0,0 +1,27 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Handles finishing performing CPR on the patient.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_cpr
*
* Public: No
*/
params ["_medic", "_patient"];
_patient setVariable [QGVAR(isReceivingCPR), false, true];
_patient setVariable [VAR_HEART_RATE, 0, true];
_patient call FUNC(calculateBlood);
if (alive _patient && {IN_CRDC_ARRST(_patient)}) then {
[QGVAR(cprLocal), [_medic, _patient], _patient] call CBA_fnc_targetEvent;
};

View File

@ -0,0 +1,28 @@
#include "script_component.hpp"
/*
* Author: Zakant
* Handles failure of the CPR treatment.
*
* Arguments:
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_cprFailure
*
* Public: No
*/
params ["", "_patient"];
if (!(_patient call EFUNC(common,isAwake)) || {IN_CRDC_ARRST(_patient)}) then {
_patient setVariable [VAR_HEART_RATE, 0, true];
};
// Patient is no longer receiving CPR
_patient setVariable [QGVAR(isReceivingCPR), false, true];
_patient call FUNC(calculateBlood);

View File

@ -0,0 +1,25 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Local callback for finishing performing CPR on the patient.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_cprLocal
*
* Public: No
*/
params ["_medic", "_patient"];
[_patient, "activity", LSTRING(Activity_CPR), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog);
if (random 1 >= 0.6) then {
[QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent;
};

View File

@ -0,0 +1,29 @@
#include "script_component.hpp"
/*
* Author: Zakant
* Handles the progress of the CPR treatment.
*
* Arguments:
* 0: Arguments <ARRAY>
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* Continue CPR <BOOL>
*
* Example:
* [[player, cursorObject]] call ace_medical_treatment_fnc_cprProgress
*
* Public: No
*/
params ["_args"];
_args params ["", "_patient"];
// Cancel CPR is patient wakes up
if (_patient getVariable EFUNC(common,isAwake) || {!IN_CRDC_ARRST(_patient)}) exitWith {false};
// Calculate blood volume, if there is no pulse nothing happens
_patient call FUNC(calculateBlood);
true

View File

@ -0,0 +1,29 @@
#include "script_component.hpp"
/*
* Author: Zakant
* Handles starting the CPR treatment.
*
* Arguments:
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_cprStart
*
* Public: No
*/
params ["", "_patient"];
// Prevent others from performing CPR
_patient setVariable [QGVAR(isReceivingCPR), true, true];
// Create a random pulse based on setting
if (GVAR(cprCreatesPulse) && {GET_HEART_RATE(_patient) == 0}) then {
_patient setVariable [VAR_HEART_RATE, round random [25, 30, 35], true];
};
_patient setVariable [QEGVAR(medical,lastTimeUpdated), CBA_missionTime, true];

View File

@ -0,0 +1,70 @@
#include "script_component.hpp"
/*
* Author: Glowbal, mharis001
* Creates litter around the patient based on the treatment.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
* 3: Treatment <STRING>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject, "Head", "BasicBandage"] call ace_medical_fnc_createLitter
*
* Public: No
*/
// Exit if litter creation is disabled
if (!GVAR(allowLitterCreation)) exitWith {};
params ["_medic", "_patient", "_bodyPart", "_classname"];
// Don't create litter if medic or patient are inside a vehicle
if (vehicle _medic != _medic || {vehicle _patient != _patient}) exitWith {};
// Determine if treated body part is bleeding
private _index = ALL_BODY_PARTS find toLower _bodyPart;
private _isBleeding = (_patient getVariable [QEGVAR(medical,openWounds), []]) findIf {
_x params ["", "_bodyPartN", "_amountOf", "_bleeding"];
_bodyPartN == _index && {_amountOf * _bleeding > 0}
} != -1;
// Get litter config for the treatment
private _litter = getArray (configFile >> QGVAR(actions) >> _classname >> "litter");
_litter params [["_alwaysLitter", [], [[]]], ["_cleanLitter", [], [[]]], ["_bloodyLitter", [], [[]]]];
private _fnc_createLitter = {
params ["_litterOptions"];
private _position = getPosASL _patient;
// For now, don't spawn litter over water to avoid floating litter
// todo: handle carriers over water
if (surfaceIsWater _position) exitWith {};
{
if (_x isEqualType []) then {
_x = selectRandom _x;
};
// Randomize position XY +/- 1 m
private _position = _position vectorAdd [
random 2 - 1,
random 2 - 1,
0
];
// Create litter on server which will also handle cleanup
[QGVAR(createLitterServer), [_x, _position, random 360]] call CBA_fnc_serverEvent;
} forEach _litterOptions;
};
private _conditionalLitter = [_cleanLitter, _bloodyLitter] select _isBleeding;
[_alwaysLitter] call _fnc_createLitter;
[_conditionalLitter] call _fnc_createLitter;

View File

@ -0,0 +1,57 @@
#include "script_component.hpp"
/*
* Author: Glowbal, mharis001
* Creates a litter object and handles its cleanup. Only execute on server.
*
* Arguments:
* 0: Litter Class <STRING>
* 1: Position ASL <ARRAY>
* 2: Direction <NUMBER>
*
* Return Value:
* None
*
* Example:
* ["Litter_1", [100, 100, 0], 90] call ace_medical_fnc_createLitterServer
*
* Public: No
*/
params ["_litterClass", "_position", "_direction"];
if (isNil QGVAR(litterObjects)) then {
GVAR(litterObjects) = [];
GVAR(litterCleanup) = false;
};
private _model = getText (configFile >> "CfgVehicles" >> _litterClass >> "model");
if (_model == "") exitWith {};
// createSimpleObject expects a path without the leading slash
if (_model select [0, 1] == "\") then {
_model = _model select [1];
};
private _object = createSimpleObject [_model, [0, 0, 0]];
_object setPosASL _position;
_object setDir _direction;
// Set the litter object's position next frame to correct HORRIBLE spacing (fixes #1112)
[{
params ["_object", "_position"];
_object setPosASL _position;
}, [_object, _position]] call CBA_fnc_execNextFrame;
// Delete oldest litter object if max count reached
if (count GVAR(litterObjects) > GVAR(maxLitterObjects)) then {
private _litterToDelete = GVAR(litterObjects) deleteAt 0;
deleteVehicle (_litterToDelete select 0);
};
GVAR(litterObjects) pushBack [_object, CBA_missionTime];
// Start cleanup loop if not already running and litter lifetime is not forever
if (!GVAR(litterCleanup) && {GVAR(litterCleanupDelay) > 0}) then {
[] call FUNC(litterCleanupLoop);
GVAR(litterCleanup) = true;
};

View File

@ -0,0 +1,49 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Action for diagnosing in basic medical
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_diagnose
*
* Public: No
*/
params ["_medic", "_patient"];
private _messages = [LSTRING(diagnoseMessage), _patient call EFUNC(common,getName)];
if (alive _patient) then {
_messages pushBack LSTRING(diagnoseAlive);
} else {
_messages pushBack LSTRING(diagnoseDead);
};
private _hemorrhage = GET_HEMORRHAGE(_patient);
if (_hemorrhage > 0) then {
if (_hemorrhage > 1) then {
_messages pushBack LSTRING(lostBloodALot);
} else {
_messages pushBack LSTRING(lostBlood);
};
} else {
_messages pushBack LSTRING(noBloodloss);
};
// todo: mirror pain visualization logic of medical_gui?
if (alive _patient) then {
if IS_IN_PAIN(_patient) then {
_messages pushBack LSTRING(inPain);
} else {
_messages pushBack LSTRING(noPain);
};
};
[_messages, 3] call EFUNC(common,displayTextStructured);

View File

@ -4,8 +4,8 @@
* Finds the wound most effective to bandage on the given bodypart of the patient for the given bandage type.
*
* Arguments:
* 0: The patient <OBJECT>
* 1: Treatment class name <STRING>
* 0: Patient <OBJECT>
* 1: Treatment classname <STRING>
* 2: Body part index <NUMBER>
*
* Return Value:

View File

@ -0,0 +1,23 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Fully heals the patient.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_fullHeal
*
* Public: No
*/
params ["_medic", "_patient"];
[_patient, "activity", LSTRING(Activity_fullHeal), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog);
[QGVAR(fullHealLocal), _patient, _patient] call CBA_fnc_targetEvent;

View File

@ -0,0 +1,84 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Local callback for fully healing a patient.
*
* Arguments:
* 0: Patient <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player] call ace_medical_treatment_fnc_fullHealLocal
*
* Public: No
*/
params ["_patient"];
if (!alive _patient) exitWith {};
// Treatment conditions would normally limit full heal to non-unconscious units
// However, this may be called externally (through Zeus)
if IN_CRDC_ARRST(_patient) then {
TRACE_1("Exiting cardiac arrest",_patient);
[QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent;
};
if IS_UNCONSCIOUS(_patient) then {
TRACE_1("Waking up",_patient);
// Wake patient up first or unconscious variables will be reset
[QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent;
};
_patient setVariable [VAR_PAIN, 0, true];
_patient setVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME, true];
// Tourniquets
_patient setVariable [VAR_TOURNIQUET, DEFAULT_TOURNIQUET_VALUES, true];
_patient setVariable [QGVAR(occludedMedications), nil, true];
// Wounds and Injuries
_patient setVariable [QEGVAR(medical,openWounds), [], true];
_patient setVariable [QEGVAR(medical,bandagedWounds), [], true];
_patient setVariable [QEGVAR(medical,stitchedWounds), [], true];
_patient setVariable [QEGVAR(medical,isLimping), false, true];
_patient setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true];
// Update wound bleeding
[_patient] call EFUNC(medical_status,updateWoundBloodLoss);
// Vitals
_patient setVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE, true];
_patient setVariable [VAR_BLOOD_PRESS, [80, 120], true];
_patient setVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES, true];
// IVs
_patient setVariable [QEGVAR(medical,ivBags), nil, true];
// Damage storage
_patient setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true];
#ifdef DEBUG_TESTRESULTS
_patient setVariable [QEGVAR(medical,bodyPartStatus), [0,0,0,0,0,0], true];
#endif
// Generic medical admin
_patient setVariable [VAR_CRDC_ARRST, false, true];
_patient setVariable [VAR_UNCON, false, true];
_patient setVariable [VAR_HEMORRHAGE, 0, true];
_patient setVariable [VAR_IN_PAIN, false, true];
_patient setVariable [VAR_PAIN_SUPP, 0, true];
// Medication
_patient setVariable [VAR_MEDICATIONS, [], true];
// Reset triage card since medication is reset
_patient setVariable [QEGVAR(medical,triageCard), [], true];
[_patient] call EFUNC(medical_engine,updateDamageEffects);
// Reset damage
_patient setDamage 0;
[QEGVAR(medical,FullHeal), _patient] call CBA_fnc_localEvent;

View File

@ -4,13 +4,16 @@
* Calculates the time to bandage a wound based on it's size, the patient and the medic.
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 2: Body part <STRING>
* 3: Treatment class name <STRING>
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
* 3: Treatment <STRING>
*
* Return Value:
* Time in seconds <NUMBER>
* Treatment Time <NUMBER>
*
* Example:
* [player, cursorTarget, "Head", "FieldDressing"] call ace_medical_treatment_fnc_getBandageTime
*
* Public: No
*/
@ -48,4 +51,4 @@ if (_medic == _patient) then {
};
// Nobody can bandage instantly
_bandageTime max 1
_bandageTime max 2

View File

@ -0,0 +1,29 @@
#include "script_component.hpp"
/*
* Author: Ruthberg
* Calculates the PAK treatment time based on the amount of damage to heal.
*
* Arguments:
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* Treatment Time <NUMBER>
*
* Example:
* [player] call ace_medical_treatment_fnc_getHealTime
*
* Public: No
*/
#define DAMAGE_SCALING_FACTOR 5
params ["", "_patient"];
private _bodyPartDamage = 0;
{
_bodyPartDamage = _bodyPartDamage + _x;
} forEach (_patient getVariable [QEGVAR(medical,bodyPartDamage), []]);
10 max (((_bodyPartDamage * DAMAGE_SCALING_FACTOR) min 180) * GVAR(timeCoefficientPAK))

View File

@ -0,0 +1,23 @@
#include "script_component.hpp"
/*
* Author: mharis001
* Calculates the Surgical Kit treatment time based on the amount of bandaged wounds.
*
* Arguments:
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* Treatment Time <NUMBER>
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_getStitchTime
*
* Public: No
*/
#define TIME_PER_WOUND 5
params ["", "_patient"];
count (_patient getVariable [QEGVAR(medical,bandagedWounds), []]) * TIME_PER_WOUND

View File

@ -7,11 +7,11 @@
* 0: Unit <OBJECT>
*
* Return Value:
* Triage info <ARRAY>
* 0: Status ID <NUMBER>
* 1: Name <STRING>
* 2: Color <ARRAY>
* 3: Text color <ARRAY>
* Triage Info <ARRAY>
* 0: Status ID <NUMBER>
* 1: Name <STRING>
* 2: Color <ARRAY>
* 3: Text Color <ARRAY>
*
* Example:
* [player] call ace_medical_treatment_fnc_getTriageStatus

View File

@ -1,44 +1,31 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Check if the item is present between the patient and the medic
* Author: Glowbal, mharis001
* Checks if one of the given items are present between the medic and patient.
* Does not respect the priority defined by the allowSharedEquipment setting.
* Will check medic first and then patient if shared equipment is allowed.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Item <STRING>
* 2: Items <ARRAY>
*
* Return Value:
* Has the items <BOOL>
* Has Item <BOOL>
*
* Example:
* [bob, patient, "bandage"] call ace_medical_treatment_fnc_hasItem
* [player, cursorObject, ["ACE_fieldDressing"]] call ace_medical_treatment_fnc_hasItems
*
* Public: No
*/
params ["_medic", "_patient", "_item"];
params ["_medic", "_patient", "_items"];
if (isNil QEGVAR(medical,setting_allowSharedEquipment)) then {
EGVAR(medical,setting_allowSharedEquipment) = true;
private _fnc_checkItems = {
params ["_unit"];
private _unitItems = _unit call EFUNC(common,uniqueItems);
_items findIf {_x in _unitItems} != -1
};
if (EGVAR(medical,setting_allowSharedEquipment) && {[_patient, _item] call EFUNC(common,hasItem)}) exitWith {
true
};
if ([_medic, _item] call EFUNC(common,hasItem)) exitWith {
true
};
private _hasItem = false;
if (vehicle _medic != _medic && {vehicle _medic call FUNC(isMedicalVehicle)}) then {
{
if ([_medic, _x] call FUNC(canAccessMedicalEquipment) && {[_x, _item] call EFUNC(common,hasItem)}) exitWith {
_hasItem = true;
};
} forEach crew vehicle _medic;
};
_hasItem
_medic call _fnc_checkItems || {GVAR(allowSharedEquipment) != 2 && {_patient call _fnc_checkItems}}

View File

@ -1,36 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Check if all items are present between the patient and the medic.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Items <ARRAY<STRING>>
*
* Return Value:
* Has the items <BOOL>
*
* Example:
* [bob, patient, ["bandage", "morphine"]] call ace_medical_treatment_fnc_hasItems
*
* Public: No
*/
params ["_medic", "_patient", "_items"];
private _return = true;
{
// handle a one of type use item
if (_x isEqualType [] && {{[_medic, _patient, _x] call FUNC(hasItem)} count _x == 0}) exitWith {
_return = false;
};
// handle required item
if (_x isEqualType "" && {!([_medic, _patient, _x] call FUNC(hasItem))}) exitWith {
_return = false;
};
} forEach _items;
_return

View File

@ -1,14 +1,14 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Check if unit has a tourniquet applied to the specified bodypart
* Checks if the unit has a tourniquet applied on the specified body part.
*
* Arguments:
* 0: The Unit <OBJECT>
* 0: Unit <OBJECT>
* 1: Body Part <STRING>
*
* Return Value:
* Has tourniquet applied <BOOL>
* Has Tourniquet Been Applied <BOOL>
*
* Example:
* [player, "leftleg"] call ace_medical_treatment_fnc_hasTourniquetAppliedTo
@ -16,8 +16,8 @@
* Public: No
*/
params ["_target", "_bodyPart"];
params ["_unit", "_bodyPart"];
private _index = ALL_BODY_PARTS find toLower _bodyPart;
_index >= 0 && {HAS_TOURNIQUET_APPLIED_ON(_target,_index)}
_index >= 0 && {HAS_TOURNIQUET_APPLIED_ON(_unit,_index)}

View File

@ -1,32 +0,0 @@
#include "script_component.hpp"
/*
* Author: Ruthberg
* Calculates the personal aid kit treatment time based on amount of damage to heal
*
* Arguments:
* unit <OBJECT>
*
* Return Value:
* treatment time <NUMBER>
*
* Example:
* [_target] call ace_medical_treatment_fnc_healTime
*
* Public: No
*/
params ["_unit"];
private _totalDamage = 0;
private _treatTime = 0;
{
_totalDamage = _totalDamage + _x;
} forEach (_unit getVariable [QEGVAR(medical,bodyPartDamage), []]);
if (EGVAR(medical,PAKTime) > 0) then {
_treatTime = EGVAR(medical,PAKTime);
} else {
_treatTime = 10 max (_totalDamage * 5) min 180;
};
_treatTime

View File

@ -1,13 +1,13 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Checks if a unit is in a designated medical facility
* Author: Glowbal, mharis001
* Checks if the unit is in a medical facility.
*
* Arguments:
* 0: The Unit <OBJECT>
* 0: Unit <OBJECT>
*
* Return Value:
* Is in medical facility <BOOL>
* In Medical Facility <BOOL>
*
* Example:
* [player] call ace_medical_treatment_fnc_isInMedicalFacility
@ -15,49 +15,13 @@
* Public: No
*/
#define CHECK_OBJECTS(var) ((var) findIf {typeOf _x in GVAR(facilityClasses) || {_x getVariable [QEGVAR(medical,isMedicalFacility), false]}} != -1)
params ["_unit"];
//Cache the results as this function could be called rapidly
(_unit getVariable [QGVAR(cacheInFacility), [-9, false]]) params ["_expireTime", "_lastResult"];
if (CBA_missionTime < _expireTime) exitWith {_lastResult};
private _eyePos = eyePos _unit;
private _isInBuilding = false;
private _medicalFacility =
[
"TK_GUE_WarfareBFieldhHospital_Base_EP1",
"TK_GUE_WarfareBFieldhHospital_EP1",
"TK_WarfareBFieldhHospital_Base_EP1",
"TK_WarfareBFieldhHospital_EP1",
"US_WarfareBFieldhHospital_Base_EP1",
"US_WarfareBFieldhHospital_EP1",
"MASH_EP1",
"MASH",
"Land_A_Hospital",
"CDF_WarfareBFieldhHospital",
"GUE_WarfareBFieldhHospital",
"INS_WarfareBFieldhHospital",
"RU_WarfareBFieldhHospital",
"USMC_WarfareBFieldhHospital"
];
private _objects = (lineIntersectsWith [_unit modelToWorldVisual [0, 0, (_eyePos select 2)], _unit modelToWorldVisual [0, 0, (_eyePos select 2) +10], _unit]);
{
if (((typeOf _x) in _medicalFacility) || {_x getVariable [QEGVAR(medical,isMedicalFacility),false]}) exitWith {
_isInBuilding = true;
};
} forEach _objects;
if (!_isInBuilding) then {
_objects = _unit nearObjects 7.5;
{
if (((typeOf _x) in _medicalFacility) || {_x getVariable [QEGVAR(medical,isMedicalFacility),false]}) exitWith {
_isInBuilding = true;
};
} forEach _objects;
private _fnc_check = {
private _position = _unit modelToWorldVisual [0, 0, eyePos _unit select 2];
CHECK_OBJECTS(ARR_5(lineIntersectsWith [_position, _position vectorAdd [0, 0, 10], _unit])) || {CHECK_OBJECTS(_unit nearObjects 7.5)}
};
_unit setVariable [QGVAR(cacheInFacility), [CBA_missionTime + IN_MEDICAL_FACILITY_CACHE_EXPIRY, _isInBuilding]];
_isInBuilding;
[[], _fnc_check, _unit, QGVAR(inMedicalFacilityCache), IN_MEDICAL_FACILITY_CACHE_EXPIRY] call EFUNC(common,cachedCall);

View File

@ -1,13 +1,13 @@
#include "script_component.hpp"
/*
* Author: KoffeinFlummi
* Checks if a unit is in a medical vehicle.
* Checks if the unit is in a medical vehicle.
*
* Arguments:
* 0: unit to be checked <OBJECT>
* 0: Unit <OBJECT>
*
* Return Value:
* Is unit in medical vehicle? <BOOL>
* In Medical Vehicle <BOOL>
*
* Example:
* [player] call ace_medical_treatment_fnc_isInMedicalVehicle
@ -19,7 +19,4 @@ params ["_unit"];
private _vehicle = vehicle _unit;
if (_unit == _vehicle) exitWith {false};
if (_unit in [driver _vehicle, gunner _vehicle, commander _vehicle]) exitWith {false};
[_vehicle] call FUNC(isMedicalVehicle);
_unit != _vehicle && {!(_unit in [driver _vehicle, gunner _vehicle, commander _vehicle])} && {[_vehicle] call FUNC(isMedicalVehicle)}

View File

@ -1,14 +1,15 @@
#include "script_component.hpp"
/*
* Author: Glowbal, KoffeinFlummi
* Check if a unit is any medical class
* Checks if the unit is a medic of the given level.
* Medic Levels: 0 - None, 1 - Medic, 2 - Doctor
*
* Arguments:
* 0: The Unit <OBJECT>
* 1: Class <NUMBER> (default: 1)
* 0: Unit <OBJECT>
* 1: Medic Level <NUMBER> (default: 1)
*
* Return Value:
* Is in of medic class <BOOL>
* Is Medic <BOOL>
*
* Example:
* [player] call ace_medical_treatment_fnc_isMedic
@ -18,13 +19,13 @@
params ["_unit", ["_medicN", 1]];
private _class = _unit getVariable [QEGVAR(medical,medicClass), [0, 1] select (_unit getUnitTrait "medic")];
private _class = _unit getVariable [QEGVAR(medical,medicClass), parseNumber (_unit getUnitTrait "medic")];
if (_class >= _medicN) exitWith {true};
if (!EGVAR(medical,increaseTrainingInLocations)) exitWith {false};
if (!GVAR(locationsBoostTraining)) exitWith {false};
if (([_unit] call FUNC(isInMedicalVehicle)) || {[_unit] call FUNC(isInMedicalFacility)}) then {
_class = _class + 1; //boost by one: untrained becomes medic, medic becomes doctor
if (IN_MED_VEHICLE(_unit) || {IN_MED_FACILITY(_unit)}) then {
_class = _class + 1; // Boost medical training by one: untrained becomes medic, medic becomes doctor
};
_class >= _medicN

View File

@ -1,13 +1,13 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Check if vehicle is a medical vehicle
* Checks if the vehicle is a medical vehicle.
*
* Arguments:
* 0: The Vehicle <OBJECT>
* 0: Vehicle <OBJECT>
*
* Return Value:
* Is in of medic class <BOOL>
* Is Medical Vehicle <BOOL>
*
* Example:
* [cursorObject] call ace_medical_treatment_fnc_isMedicalVehicle
@ -17,4 +17,4 @@
params ["_vehicle"];
(_vehicle getVariable [QEGVAR(medical,medicClass), getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "attendant")]) > 0
_vehicle getVariable [QEGVAR(medical,isMedicalVehicle), getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "attendant") > 0]

View File

@ -0,0 +1,28 @@
#include "script_component.hpp"
/*
* Author: Glowbal, mharis001
* Administers an IV bag treatment to the patient.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
* 3: Treatment <STRING>
* 4: Item User (not used) <OBJECT>
* 5: Used Item <STRING>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject, "RightArm", "BloodIV", objNull, "ACE_bloodIV"] call ace_medical_treatment_fnc_ivBag
*
* Public: No
*/
params ["_medic", "_patient", "_bodyPart", "_classname", "", "_usedItem"];
[_patient, _usedItem] call FUNC(addToTriageCard);
[_patient, "activity", LSTRING(Activity_gaveIV), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog);
[QGVAR(ivBagLocal), [_patient, _bodyPart, _classname], _patient] call CBA_fnc_targetEvent;

View File

@ -0,0 +1,38 @@
#include "script_component.hpp"
/*
* Author: Glowbal, mharis001
* Local callback for administering an IV bag to a patient.
*
* Arguments:
* 0: Patient <OBJECT>
* 1: Body Part <STRING>
* 2: Treatment <STRING>
*
* Return Value:
* None
*
* Example:
* [player, "RightArm", "BloodIV"] call ace_medical_treatment_fnc_ivBagLocal
*
* Public: No
*/
params ["_patient", "_bodyPart", "_classname"];
// Exit if patient has max blood volume
private _bloodVolume = GET_BLOOD_VOLUME(_patient);
if (_bloodVolume >= DEFAULT_BLOOD_VOLUME) exitWith {};
private _partIndex = ALL_BODY_PARTS find toLower _bodyPart;
// Get attributes for the used IV
private _defaultConfig = configFile >> QUOTE(ADDON) >> "IV";
private _ivConfig = _defaultConfig >> _classname;
private _volume = GET_NUMBER(_ivConfig >> "volume",getNumber (_defaultConfig >> "volume"));
private _type = GET_STRING(_ivConfig >> "type",getText (_defaultConfig >> "type"));
// Add IV bag to patient's ivBags array
private _ivBags = _patient getVariable [QEGVAR(medical,ivBags), []];
_ivBags pushBack [_volume, _type, _partIndex];
_ivBags setVariable [QEGVAR(medical,ivBags), _ivBags, true];

View File

@ -1,7 +1,7 @@
#include "script_component.hpp"
/*
* Author: Glowbal, esteldunedain
* Loop that cleans up litter
* Author: Glowbal, esteldunedain, mharis001
* Handles cleaning up litter objects that have reached the end of their lifetime.
*
* Arguments:
* None
@ -10,31 +10,28 @@
* None
*
* Example:
* call ace_medical_treatment_fnc_litterCleanupLoop
* [] call ace_medical_treatment_fnc_litterCleanupLoop
*
* Public: No
*/
{
_x params ["_time", "_objects"];
_x params ["_object", "_timeCreated"];
// Older elements are always at the begining of the array
if (CBA_missionTime - _time < GVAR(litterCleanUpDelay)) exitWith {};
// Litter array has older objects at the beginning
// Can exit on first element that still has lifetime remaining
if (CBA_missionTime - _timeCreated < GVAR(litterCleanupDelay)) exitWith {};
TRACE_2("deleting",_time,_objects);
{
deleteVehicle _x;
} forEach _objects;
deleteVehicle _object;
GVAR(litterObjects) set [_forEachIndex, objNull];
} forEach GVAR(litterObjects);
GVAR(allCreatedLitter) set [_forEachIndex, objNull];
} forEach GVAR(allCreatedLitter);
GVAR(litterObjects) = GVAR(litterObjects) - [objNull];
GVAR(allCreatedLitter) = GVAR(allCreatedLitter) - [objNull];
// If no more litter remain, exit the loop
if (GVAR(allCreatedLitter) isEqualTo []) exitWith {
GVAR(litterPFHRunning) = false;
// Exit the loop if no litter objects left
if (GVAR(litterObjects) isEqualTo []) exitWith {
GVAR(litterCleanup) = false;
};
// Schedule the loop to be executed again 30 sec later
[FUNC(litterCleanupLoop), [], 30] call CBA_fnc_waitAndExecute;
// Schedule cleanup loop to executed again
[FUNC(litterCleanupLoop), [], LITTER_CLEANUP_CHECK_DELAY] call CBA_fnc_waitAndExecute;

View File

@ -1,98 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Spawns litter for the treatment action on the ground around the target
*
* Arguments:
* 0: The Caller <OBJECT>
* 1: The target <OBJECT>
* 2: The treatment Selection Name <STRING>
* 3: The treatment classname <STRING>
* 4: ?
* 5: Users of Items <?>
* 6: Blood Loss on selection (previously called _previousDamage) <NUMBER>
*
* Return Value:
* None
*
* Public: No
*/
#define MIN_ENTRIES_LITTER_CONFIG 3
params ["_caller", "_target", "_selectionName", "_className", "", "_usersOfItems", "_bloodLossOnSelection"];
TRACE_6("params",_caller,_target,_selectionName,_className,_usersOfItems,_bloodLossOnSelection);
// Ensures comptibilty with other possible medical treatment configs
private _previousDamage = _bloodLossOnSelection;
// Exit if litter is disabled by setting
if !(EGVAR(medical,allowLitterCreation)) exitWith {};
// Don't create litter if medic or patient are inside a vehicle
if (vehicle _caller != _caller || {vehicle _target != _target}) exitWith {};
private _config = configFile >> QGVAR(Actions) >> _className;
if !(isClass _config) exitWith {TRACE_1("No action config",_className);};
if !(isArray (_config >> "litter")) exitWith {TRACE_1("No litter config",_className);};
private _litter = getArray (_config >> "litter");
private _createLitter = {
params ["_unit", "_litterClass"];
private _position = getPosASL _unit;
// @TODO: handle carriers over water
// For now, don't spawn litter if we are over water to avoid floating litter
if (surfaceIsWater _position) exitWith {false};
_position = _position vectorAdd [
random 2 - 1,
random 2 - 1,
0
];
private _direction = random 360;
// Create the litter, and timeout the event based on the cleanup delay
// The cleanup delay for events in MP is handled by the server side
TRACE_3("Creating Litter on server",_litterClass,_position,_direction);
[QGVAR(createLitterServer), [_litterClass, _position, _direction]] call CBA_fnc_serverEvent;
true
};
{
if (count _x < MIN_ENTRIES_LITTER_CONFIG) then {
WARNING_1("Wrong litter array: %1",_x);
} else {
_x params [
["_selection", "", [""]],
["_litterCondition", "", [""]],
["_litterOptions", [], [[]]]
];
if (toLower _selection in [toLower _selectionName, "all"]) then {
if (_litterCondition isEqualTo "") then {
_litterCondition = {true};
} else {
_litterCondition = compile _litterCondition;
};
// existing configs seem to use carried over magic variables. we pass them as arguments (_this) anyway
if !([_caller, _target, _selectionName, _className, _usersOfItems, _bloodLossOnSelection] call _litterCondition) exitWith {};
// Loop through through the litter options and place the litter
{
if (_x isEqualType "") then {
[_target, _x] call _createLitter;
};
if (_x isEqualType [] && {count _x > 0}) then {
[_target, selectRandom _x] call _createLitter;
};
} foreach _litterOptions;
};
};
} foreach _litter;

View File

@ -1,68 +0,0 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* handle Litter Create
*
* Arguments:
* 0: Litter Class <STRING>
* 1: Position <ARRAY>
* 2: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* ["litter", [2, 5, 6], bob] call ace_medical_treatment_fnc_handleCreateLitter
*
* Public: No
*/
params ["_litterClass", "_position", "_direction"];
TRACE_3("params",_litterClass,_position,_direction);
//IGNORE_PRIVATE_WARNING ["_values"];
if (isNil QGVAR(allCreatedLitter)) then {
GVAR(allCreatedLitter) = [];
GVAR(litterPFHRunning) = false;
};
private _model = getText (configFile >> "CfgVehicles" >> _litterClass >> "model");
if (_model == "") exitWith {TRACE_2("no model",_litterClass,_model)};
// createSimpleObject expects a path without the leading slash
if (_model select [0,1] == "\") then {
_model = _model select [1];
};
private _litterObject = createSimpleObject [_model, [0,0,0]];
TRACE_2("created",_litterClass,_litterObject);
_litterObject setDir _direction;
_litterObject setPosASL _position;
// Move the litter next frame to get rid of HORRIBLE spacing, fixes #1112
[{
params ["_object", "_position"];
_object setPosASL _position;
}, [_litterObject, _position]] call CBA_fnc_execNextFrame;
private _maxLitterCount = getArray (configFile >> "ACE_Settings" >> QEGVAR(medical,litterSimulationDetail) >> "_values") select EGVAR(medical,litterSimulationDetail);
if (count GVAR(allCreatedLitter) > _maxLitterCount) then {
// gank the first litter object, and spawn ours.
private _oldLitter = GVAR(allCreatedLitter) deleteAt 0;
{
deleteVehicle _x;
} forEach (_oldLitter select 1);
};
GVAR(allCreatedLitter) pushBack [CBA_missionTime, [_litterObject]];
if (!GVAR(litterPFHRunning) && {GVAR(litterCleanUpDelay) > 0}) then {
// Start the litter cleanup loop
GVAR(litterPFHRunning) = true;
call FUNC(litterCleanupLoop);
};

View File

@ -0,0 +1,40 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Loads an unconscious or dead patient in the given or nearest vehicle.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Vehicle <OBJECT> (default: objNull)
*
* Return Value:
* None
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_loadUnit
*
* Public: No
*/
params ["_medic", "_patient", ["_vehicle", objNull]];
if (_patient call EFUNC(common,isAwake)) exitWith {
[[LSTRING(CanNotLoad), _patient call EFUNC(common,getName)]] call EFUNC(common,displayTextStructured);
};
if (_patient call EFUNC(medical_status,isBeingCarried)) then {
[_medic, _patient] call EFUNC(dragging,dropObject_carry);
};
if (_patient call EFUNC(medical_status,isBeingDragged)) then {
[_medic, _patient] call EFUNC(dragging,dropObject);
};
private _vehicle = [_medic, _patient, _vehicle] call EFUNC(common,loadPerson);
if (!isNull _vehicle) then {
private _patientName = [_patient, false, true] call EFUNC(common,getName);
private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName");
[[LSTRING(LoadedInto), _patientName, _vehicleName], 3] call EFUNC(common,displayTextStructured);
};

View File

@ -0,0 +1,28 @@
#include "script_component.hpp"
/*
* Author: Glowbal, mharis001
* Administers medication to the patient on the given body bodypart.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
* 3: Treatment <STRING>
* 4: Item User (not used) <OBJECT>
* 5: Used Item <STRING>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject, "RightArm", "Morphine", objNull, "ACE_morphine"] call ace_medical_treatment_fnc_medication
*
* Public: No
*/
params ["_medic", "_patient", "_bodyPart", "_classname", "", "_usedItem"];
[_patient, _usedItem] call FUNC(addToTriageCard);
[_patient, "activity", LSTRING(Activity_usedItem), [[_medic, false, true] call EFUNC(common,getName), getText (configFile >> "CfgWeapons" >> _usedItem >> "displayName")]] call FUNC(addToLog);
[QGVAR(medicationLocal), [_patient, _bodyPart, _classname]] call CBA_fnc_targetEvent;

View File

@ -0,0 +1,78 @@
#include "script_component.hpp"
/*
* Author: Glowbal, mharis001
* Local callback for administering medication to a patient.
*
* Arguments:
* 0: Patient <OBJECT>
* 1: Body Part <STRING>
* 2: Treatment <STRING>
*
* Return Value:
* None
*
* Example:
* [player, "RightArm", "Morphine"] call ace_medical_treatment_fnc_medicationLocal
*
* Public: No
*/
// todo: move this macro to script_macros_medical.hpp?
#define MORPHINE_PAIN_SUPPRESSION 0.6
params ["_patient", "_bodyPart", "_classname"];
TRACE_3("medicationLocal",_patient,_bodyPart,_classname);
// Medication has no effects on dead units
if (!alive _patient) exitWith {};
// Exit with basic medication handling if advanced medication not enabled
if (!GVAR(advancedMedication)) exitWith {
switch (_classname) do {
case "Morphine": {
private _painSuppress = GET_PAIN_SUPPRESS(_patient);
_patient setVariable [VAR_PAIN_SUPP, (_painSuppress + MORPHINE_PAIN_SUPPRESSION) min 1, true];
};
case "Epinephrine": {
[QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent;
};
};
};
TRACE_1("Running treatmentMedicationLocal with Advanced configuration for", _target);
// Handle tourniquet on body part blocking blood flow at injection site
private _partIndex = ALL_BODY_PARTS find toLower _bodyPart;
if (HAS_TOURNIQUET_APPLIED_ON(_patient,_partIndex)) exitWith {
TRACE_1("unit has tourniquets blocking blood flow on injection site",_tourniquets);
private _occludedMedications = _patient getVariable [QEGVAR(medical,occludedMedications), []];
_occludedMedications pushBack [_partIndex, _classname];
_patient setVariable [QEGVAR(medical,occludedMedications), _occludedMedications, true];
};
// Get adjustment attributes for used medication
private _defaultConfig = configFile >> QUOTE(ADDON) >> "Medication";
private _medicationConfig = _defaultConfig >> _classname;
private _painReduce = GET_NUMBER(_medicationConfig >> "painReduce",getNumber (_defaultConfig >> "painReduce"));
private _timeInSystem = GET_NUMBER(_medicationConfig >> "timeInSystem",getNumber (_defaultConfig >> "timeInSystem"));
private _timeTillMaxEffect = GET_NUMBER(_medicationConfig >> "timeTillMaxEffect",getNumber (_defaultConfig >> "timeTillMaxEffect"));
private _maxDose = GET_NUMBER(_medicationConfig >> "maxDose",getNumber (_defaultConfig >> "maxDose"));
private _viscosityChange = GET_NUMBER(_medicationConfig >> "viscosityChange",getNumber (_defaultConfig >> "viscosityChange"));
private _hrIncreaseLow = GET_ARRAY(_medicationConfig >> "hrIncreaseLow",getArray (_defaultConfig >> "hrIncreaseLow"));
private _hrIncreaseNormal = GET_ARRAY(_medicationConfig >> "hrIncreaseNormal",getArray (_defaultConfig >> "hrIncreaseNormal"));
private _hrIncreaseHigh = GET_ARRAY(_medicationConfig >> "hrIncreaseHigh",getArray (_defaultConfig >> "hrIncreaseHigh"));
private _incompatibleMedication = GET_ARRAY(_medicationConfig >> "incompatibleMedication",getArray (_defaultConfig >> "incompatibleMedication"));
private _heartRate = GET_HEART_RATE(_patient);
private _hrIncrease = [_hrIncreaseLow, _hrIncreaseNormal, _hrIncreaseHigh] select (floor ((0 max _heartRate min 110) / 55));
_hrIncrease params ["_minIncrease", "_maxIncrease"];
private _heartRateChange = _minIncrease + random (_maxIncrease - _minIncrease);
// Adjust the medication effects and add the medication to the list
TRACE_3("adjustments",_heartRateChange,_painReduce,_viscosityChange);
[_patient, _className, _timeTillMaxEffect, _timeInSystem, _heartRateChange, _painReduce, _viscosityChange] call EFUNC(medical_status,addMedicationAdjustment);
// Check for medication compatiblity
[_patient, _className, _maxDose, _incompatibleMedication] call FUNC(onMedicationUsage);

View File

@ -18,8 +18,8 @@
* Public: No
*/
params ["_target", "_className", "_maxDosage", "_incompatabileMeds"];
TRACE_4("onMedicationUsage",_target,_className,_maxDosage,_incompatabileMeds);
params ["_target", "_className", "_maxDosage", "_incompatibleMedication"];
TRACE_4("onMedicationUsage",_target,_className,_maxDosage,_incompatibleMedication);
private _fnc_getMedicationCount = {
params ["_target", "_medication"];
@ -51,7 +51,7 @@ if (_currentDose >= floor (_maxDosage + round(random(2))) && {_maxDosage >= 1})
if (_inSystem> _xLimit) then {
_overdosedMedications pushBackUnique _xMed;
};
} forEach _incompatabileMeds;
} forEach _incompatibleMedication;
if !(_overdosedMedications isEqualTo []) then {
private _medicationConfig = (configFile >> "ace_medical_treatment" >> "Medication");

View File

@ -0,0 +1,48 @@
#include "script_component.hpp"
/*
* Author: Glowbal
* Places a dead body inside a body bag.
*
* Arguments:
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* None
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_placeInBodyBag
*
* Public: No
*/
params ["", "_patient"];
TRACE_1("placeInBodyBag",_patient);
if (!local _patient) exitWith {
TRACE_1("Calling where local",local _patient);
[QGVAR(placeInBodyBag), [nil, _patient], _patient] call CBA_fnc_targetEvent;
};
if (alive _patient) then {
TRACE_1("Manually killing with setDead",_patient);
[_patient, "buried_alive"] call EFUNC(medical_status,setDead);
};
private _position = (getPosASL _patient) vectorAdd [0, 0, 0.2];
private _headPos = _patient modelToWorldVisual (_patient selectionPosition "head");
private _spinePos = _patient modelToWorldVisual (_patient selectionPosition "Spine3");
private _direction = (_headPos vectorFromTo _spinePos) call CBA_fnc_vectDir;
// Move the body away so it won't collide with the body bag object
// This setPosASL seems to need to be called where the unit is local
_patient setPosASL [-5000, -5000, 0];
// Create the body bag object, set its position to prevent it from flipping
private _bodyBag = createVehicle ["ACE_bodyBagObject", [0, 0, 0], [], 0, "NONE"];
_bodyBag setPosASL _position;
_bodyBag setDir _direction;
// Server will handle hiding and deleting the body
["ace_placedInBodyBag", [_patient, _bodyBag]] call CBA_fnc_globalEvent;

View File

@ -0,0 +1,35 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Removes a body. Ideally it is deleted the next frame.
* However, player bodies cannot be deleted until they respawn, so it is hidden and deleted later.
*
* Arguments:
* 0: Body <OBJECT>
*
* Return Value:
* None
*
* Example:
* [cursorObject] call ace_medical_treatment_fnc_removeBody
*
* Public: No
*/
params ["_body"];
TRACE_2("removeBody",_body,isPlayer _body);
// Hide the body globally
[QEGVAR(common,hideObjectGlobal), [_body, true]] call CBA_fnc_serverEvent;
// Add body to array of those waiting for deletion
if (isNil QGVAR(bodiesToDelete)) then {
GVAR(bodiesToDelete) = [];
};
GVAR(bodiesToDelete) pushBack _body;
// Start up the body cleanup loop to delete bodies once they are free
if (count GVAR(bodiesToDelete) == 1) then {
[] call FUNC(bodyCleanupLoop);
};

View File

@ -1,33 +0,0 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Removes corpse. Idealy it is just deleted the next frame,
* but player bodies cannot be deleted until they respawn, so it is hidden and deleted later.
*
* Arguments:
* 0: Mr Body <OBJECT>
*
* Return Value:
* None
*
* Example:
* [cursorTarget] call ace_medical_treatment_fnc_serverRemoveBody
*
* Public: No
*/
params ["_target"];
TRACE_2("",_target,isPlayer _target);
// Hide the body globaly
[QEGVAR(common,hideObjectGlobal), [_target, true]] call CBA_fnc_serverEvent;
if (isNil QGVAR(bodiesToDelete)) then {GVAR(bodiesToDelete) = [];};
GVAR(bodiesToDelete) pushBack _target;
// Start up a loop to wait for bodies to be free to delete
if ((count GVAR(bodiesToDelete)) == 1) then {
[] call FUNC(bodyCleanupLoop);
};
nil

View File

@ -1,12 +1,12 @@
#include "script_component.hpp"
/*
* Author: PabstMirror
* Apply a splint to the patient
* Applies a splint to the patient on the given body part.
*
* Arguments:
* 0: The medic <OBJECT>
* 1: The patient <OBJECT>
* 2: Body part <STRING>
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
*
* Return Value:
* Nothing
@ -17,9 +17,7 @@
* Public: No
*/
params ["_caller", "_target", "_bodyPart"];
TRACE_3("splint",_caller,_target,_bodyPart);
params ["_medic", "_patient", "_bodyPart"];
TRACE_3("splint",_medic,_patient,_bodyPart);
private _partIndex = ALL_BODY_PARTS find toLower _bodyPart;
[QGVAR(treatmentSplintLocal), [_caller, _target, _partIndex], _target] call CBA_fnc_targetEvent;
[QGVAR(splintLocal), [_medic, _patient, _bodyPart], _patient] call CBA_fnc_targetEvent;

Some files were not shown because too many files have changed in this diff Show More