From 94f3b301e083bf20464f62bc01a91c90632ca4cf Mon Sep 17 00:00:00 2001 From: Drofseh Date: Sun, 24 Sep 2023 12:57:08 -0700 Subject: [PATCH] Medical Treatment - Add Grave Digging for Corpse Disposal (#9276) * Add grave digging * Update fnc_placeInBodyBagOrGrave.sqf * Update fnc_placeInBodyBagOrGrave.sqf * Update fnc_placeInBodyBagOrGrave.sqf * Update addons/medical_treatment/functions/fnc_placeInBodyBag.sqf Co-authored-by: BrettMayson * Add setting to enable/disable * improvements - fix flipped bool in fnc_canDigGrave - improve fnc_placeInBodyBagOrGrave.sqf by splitting out some checks and item assignment into separate bodybag and grave functions * fix typo in variable * Apply suggestions from code review Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> * add to XEH_PREP and fix event for non-local patient * Add interaction to check name on headstone * Update addons/medical_treatment/XEH_postInit.sqf Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> * Simplify Setting * Apply suggestions from code review Co-authored-by: jonpas * Update addons/medical_treatment/stringtable.xml Co-authored-by: jonpas * Make placeInBodyBagOrGrave more generic and use any grave class * Update addons/medical_treatment/functions/fnc_placeInGrave.sqf Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> * Update medical-treatment-framework.md * Update docs/wiki/framework/medical-treatment-framework.md Co-authored-by: jonpas * update docs * Update addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf * Update addons/medical_treatment/functions/fnc_placeInGrave.sqf * fix includes --------- Co-authored-by: BrettMayson Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com> Co-authored-by: PabstMirror Co-authored-by: jonpas Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com> --- addons/medical_gui/ui/cross_grave.paa | Bin 0 -> 5625 bytes .../ACE_Medical_Treatment_Actions.hpp | 10 +++ addons/medical_treatment/XEH_PREP.hpp | 3 + addons/medical_treatment/XEH_postInit.sqf | 34 ++++++++++- .../functions/fnc_canDigGrave.sqf | 23 +++++++ .../functions/fnc_placeInBodyBag.sqf | 31 +--------- .../functions/fnc_placeInBodyBagOrGrave.sqf | 57 ++++++++++++++++++ .../functions/fnc_placeInGrave.sqf | 31 ++++++++++ addons/medical_treatment/initSettings.sqf | 18 ++++++ addons/medical_treatment/stringtable.xml | 24 ++++++++ .../framework/medical-treatment-framework.md | 14 +++++ 11 files changed, 216 insertions(+), 29 deletions(-) create mode 100644 addons/medical_gui/ui/cross_grave.paa create mode 100644 addons/medical_treatment/functions/fnc_canDigGrave.sqf create mode 100644 addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf create mode 100644 addons/medical_treatment/functions/fnc_placeInGrave.sqf diff --git a/addons/medical_gui/ui/cross_grave.paa b/addons/medical_gui/ui/cross_grave.paa new file mode 100644 index 0000000000000000000000000000000000000000..f3b7f1570c165312a10f5432fe28130ee26f3217 GIT binary patch literal 5625 zcmeI0KX21O7{*^K4f2BUKqiEm#RFd;3n1A=N)`}E&%wnhxPh>5BwbafkX7_Dp9XO^a1<%!Xu9ecPMAF6})Ij;m7iR zoE)P05-DX_(%!gr3**-8Z;q#%`nu<>fBS@Zqu)YMS;UHdF*eT-ul0L~wa}ldKR&_r z&Gjqdg`plSiG}~HpVJUQJaSwp3hhoW<)&R8kT0OR=!>6b5$c^vm09Oqs(=xp=fCF>jd&9WBy z#eZJ2^0F2BSL6S@=zQ>RJpbu9N%kGcSKW}sZwo{I+I8Cwe+tC%Jku=Nanu>t9v>x% zZ!2}|3cr|*G`E9n`Yd-R-VfbyozUfKn_Mxkg%bu`kD2FXIUd$_KVeIfD!GVwc(6CZ z#vCBB>9gF9pY85I0+-i4R;nEz-X0ka+WFDdCYwKt_P> QEGVAR(medical,replacementItems), "isArray _x"]); }] call CBA_fnc_addEventHandler; + +if (["ace_trenches"] call EFUNC(common,isModLoaded)) then { + if (hasInterface) then { + private _checkHeadstoneAction = [ + QGVAR(checkHeadstone), + LLSTRING(checkHeadstoneName), + QPATHTOEF(medical_gui,ui\cross_grave.paa), + { + [ + [_target getVariable QGVAR(headstoneData)], + true + ] call CBA_fnc_notify; + }, + {!isNil {_target getVariable QGVAR(headstoneData)}}, + {}, + [], + [1.05, 0.02, 0.3] //position in centre of cross + ] call EFUNC(interact_menu,createAction); + + ["Land_Grave_dirt_F", 0, [], _checkHeadstoneAction] call EFUNC(interact_menu,addActionToClass); + }; + + if (isServer) then { + ["ace_placedInBodyBag", { + params ["_target", "_restingPlace"]; + TRACE_2("ace_placedInBodyBag eh",_target,_restingPlace); + + private _targetName = [_target, false, true] call EFUNC(common,getName); + _restingPlace setVariable [QGVAR(headstoneData), _targetName, true]; + }] call CBA_fnc_addEventHandler; + }; +}; diff --git a/addons/medical_treatment/functions/fnc_canDigGrave.sqf b/addons/medical_treatment/functions/fnc_canDigGrave.sqf new file mode 100644 index 0000000000..85c76382ec --- /dev/null +++ b/addons/medical_treatment/functions/fnc_canDigGrave.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Ruthberg, commy2, esteldunedain, drofseh + * Checks if a unit can dig a grave at the position of the patient. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * Can dig + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_canDigGrave + * + * Public: No + */ + +params ["_medic", "_patient"]; + +if !(["ace_trenches"] call EFUNC(common,isModLoaded)) exitWith {false}; + +(GVAR(allowGraveDigging) > 0) && {_patient call EFUNC(common,canDig)} && {_medic call EFUNC(trenches,hasEntrenchingTool)} diff --git a/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf b/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf index fd4a62a10b..df73a16952 100644 --- a/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf +++ b/addons/medical_treatment/functions/fnc_placeInBodyBag.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Glowbal + * Author: Glowbal, drofseh * Places a dead body inside a body bag. * * Arguments: @@ -24,30 +24,5 @@ if ((alive _patient) && {!GVAR(allowBodyBagUnconscious)}) exitWith { [LSTRING(bodybagWhileStillAlive)] call EFUNC(common,displayTextStructured); }; -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", _medic] 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; +// Body bag needs to be a little higher to prevent it from flipping +[_this, "ACE_bodyBagObject", [0, 0, 0.2]] call FUNC(placeInBodyBagOrGrave); diff --git a/addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf b/addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf new file mode 100644 index 0000000000..33a577da81 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf @@ -0,0 +1,57 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, drofseh + * Places a dead body inside a body bag or grave. + * + * Arguments: + * 0: Arguments + * - 0: Medic + * - 1: Patient + * 1: Resting Place Classname + * 2: Offset (default: [0,0,0]) + * 3: Rotation (default: 0) + * + * Return Value: + * None + * + * Example: + * [[player, cursorObject], "ACE_bodyBagObject"] call ace_medical_treatment_fnc_placeInBodyBagOrGrave + * + * Public: No + */ + +params ["_args", "_restingPlaceClass", ["_offset", [0,0,0]], ["_rotation", 0]]; +_args params ["_medic", "_patient"]; +TRACE_1("placeInBodyBagOrGrave",_patient); + +if (!local _patient) exitWith { + TRACE_1("Calling where local",local _patient); + [QGVAR(placeInBodyBagOrGrave), _this, _patient] call CBA_fnc_targetEvent; +}; + +if (alive _patient) then { + TRACE_1("Manually killing with setDead",_patient); + [_patient, "buried_alive", _medic] call EFUNC(medical_status,setDead); +}; + +private _headPos = _patient modelToWorldVisual (_patient selectionPosition "head"); +private _spinePos = _patient modelToWorldVisual (_patient selectionPosition "Spine3"); +private _direction = (_headPos vectorFromTo _spinePos) call CBA_fnc_vectDir; +private _position = getPosASL _patient; +// apply adjustments +_position = _position vectorAdd _offset; +_direction = _direction + _rotation; + + +// 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 _restingPlace = createVehicle [_restingPlaceClass, [0, 0, 0], [], 0, "NONE"]; +_restingPlace setPosASL _position; +_restingPlace setDir _direction; + +// Server will handle hiding and deleting the body +// Keep event name as body bag only to avoid breaking things for others +["ace_placedInBodyBag", [_patient, _restingPlace]] call CBA_fnc_globalEvent; diff --git a/addons/medical_treatment/functions/fnc_placeInGrave.sqf b/addons/medical_treatment/functions/fnc_placeInGrave.sqf new file mode 100644 index 0000000000..f9ebf582f3 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_placeInGrave.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, drofseh + * Places a dead body inside a grave. + * + * Arguments: + * 0: Medic + * 1: Patient + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_medical_treatment_fnc_placeInGrave + * + * Public: No + */ + +params ["_medic", "_patient"]; +TRACE_1("placeInGrave",_patient); + +if ((alive _patient) && {GVAR(allowGraveDigging) < 2}) exitWith { + [LSTRING(bodybagWhileStillAlive)] call EFUNC(common,displayTextStructured); +}; + +private _graveClassname = missionNameSpace getVariable [QGVAR(graveClassname), "Land_Grave_dirt_F"]; +// Land_Grave_dirt_F needs to be rotated 90 degrees to line up with the body +private _graveRotation = missionNameSpace getVariable [QGVAR(graveRotation), 90]; + +[_this, _graveClassname, [0,0,0], _graveRotation] call FUNC(placeInBodyBagOrGrave); + diff --git a/addons/medical_treatment/initSettings.sqf b/addons/medical_treatment/initSettings.sqf index fd83a9995f..18e28608a8 100644 --- a/addons/medical_treatment/initSettings.sqf +++ b/addons/medical_treatment/initSettings.sqf @@ -125,6 +125,15 @@ true ] call CBA_fnc_addSetting; +[ + QGVAR(treatmentTimeGrave), + "SLIDER", + [LSTRING(TreatmentTimeGrave_DisplayName), LSTRING(TreatmentTimeGrave_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0.1, 120, 30, 1], + true +] call CBA_fnc_addSetting; + [ QGVAR(medicEpinephrine), "LIST", @@ -305,6 +314,15 @@ true ] call CBA_fnc_addSetting; +[ + QGVAR(allowGraveDigging), + "LIST", + [LSTRING(AllowGaveDigging_DisplayName), LSTRING(AllowGaveDigging_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(AllowGaveDigging_graveOnlyDead), ELSTRING(common,Yes)], 1], + true +] call CBA_fnc_addSetting; + [ QGVAR(holsterRequired), "LIST", diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index e597980f9e..8f91fefc7c 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -412,6 +412,12 @@ 装入裹尸袋时间 초 단위로 시체 운반용 부대를 사용하는데 걸리는 시간을 정합니다. + + Grave Digging Time + + + Time, in seconds, required to dig a grave for a body. + Allow Epinephrine Erlaube Epiniphrin @@ -825,6 +831,15 @@ 能够将昏迷的伤员装入尸袋中。 기절상태의 인원을 시체운반용부대에 옮겨 담을 수 있는지를 정합니다. + + Allow Grave Digging + + + Enables digging graves to dispose of corpses. + + + Only if dead + Allow IV Transfusion Erlaube Bluttransfusionen @@ -4445,6 +4460,12 @@ 將屍體放入屍袋中... Vücut, ceset torbasına yerleştiriliyor... + + Dig grave for body + + + Digging grave for body... + %1 has bandaged patient %1 has vendado al paciente @@ -4686,6 +4707,9 @@ 身体抽搐了一下,可能还没死! 꿈틀대는걸 보니 죽은 것 같지는 않습니다! + + Check name on headstone + Bandage Rollover Bandażowanie Wielu Ran diff --git a/docs/wiki/framework/medical-treatment-framework.md b/docs/wiki/framework/medical-treatment-framework.md index adb9cd485d..ca10a9878a 100644 --- a/docs/wiki/framework/medical-treatment-framework.md +++ b/docs/wiki/framework/medical-treatment-framework.md @@ -56,3 +56,17 @@ class ACE_Medical_Treatment_Actions { }; }; ``` + +## 2. Mission Variables + +### 2.1 Grave Digging Object Configuration + +The object created when digging a grave can be modified by setting the `ace_medical_treatment_graveClassname` variable. +```sqf +ace_medical_treatment_graveClassname = "Land_Grave_11_F"; // classname, e.g. unmarked gravel (no headstone OR check actions) +``` + +The object's rotation can also be modified, if necessary. +```sqf +ace_medical_treatment_graveRotation = 0; // rotation angle (will depend on model classname) +```