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 <brett@mayson.io>

* 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 <jonpas33@gmail.com>

* Update addons/medical_treatment/stringtable.xml

Co-authored-by: jonpas <jonpas33@gmail.com>

* 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 <jonpas33@gmail.com>

* update docs

* Update addons/medical_treatment/functions/fnc_placeInBodyBagOrGrave.sqf

* Update addons/medical_treatment/functions/fnc_placeInGrave.sqf

* fix includes

---------

Co-authored-by: BrettMayson <brett@mayson.io>
Co-authored-by: johnb432 <58661205+johnb432@users.noreply.github.com>
Co-authored-by: PabstMirror <pabstmirror@gmail.com>
Co-authored-by: jonpas <jonpas33@gmail.com>
Co-authored-by: Grim <69561145+LinkIsGrim@users.noreply.github.com>
This commit is contained in:
Drofseh 2023-09-24 12:57:08 -07:00 committed by GitHub
parent 6fd24c1455
commit 94f3b301e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 216 additions and 29 deletions

Binary file not shown.

View File

@ -253,6 +253,16 @@ class GVAR(actions) {
consumeItem = 1; consumeItem = 1;
litter[] = {}; litter[] = {};
}; };
class Grave: BodyBag {
displayName = CSTRING(DigGrave);
displayNameProgress = CSTRING(DiggingGrave);
icon = QPATHTOEF(medical_gui,ui\cross_grave.paa);
treatmentTime = QGVAR(treatmentTimeGrave);
condition = QFUNC(canDigGrave);
callbackSuccess = QFUNC(placeInGrave);
items[] = {};
consumeItem = 0;
};
class CPR: BasicBandage { class CPR: BasicBandage {
displayName = CSTRING(Actions_CPR); displayName = CSTRING(Actions_CPR);
displayNameProgress = CSTRING(Actions_PerformingCPR); displayNameProgress = CSTRING(Actions_PerformingCPR);

View File

@ -6,6 +6,7 @@ PREP(bandageLocal);
PREP(bodyCleanupLoop); PREP(bodyCleanupLoop);
PREP(canBandage); PREP(canBandage);
PREP(canCPR); PREP(canCPR);
PREP(canDigGrave);
PREP(canPlaceInBodyBag); PREP(canPlaceInBodyBag);
PREP(canSplint); PREP(canSplint);
PREP(canStitch); PREP(canStitch);
@ -47,6 +48,8 @@ PREP(medication);
PREP(medicationLocal); PREP(medicationLocal);
PREP(onMedicationUsage); PREP(onMedicationUsage);
PREP(placeInBodyBag); PREP(placeInBodyBag);
PREP(placeInBodyBagOrGrave);
PREP(placeInGrave);
PREP(removeBody); PREP(removeBody);
PREP(scanMedicalItems); PREP(scanMedicalItems);
PREP(setTriageStatus); PREP(setTriageStatus);

View File

@ -25,7 +25,7 @@ if (isServer) then {
[QGVAR(fullHealLocal), LINKFUNC(fullHealLocal)] call CBA_fnc_addEventHandler; [QGVAR(fullHealLocal), LINKFUNC(fullHealLocal)] call CBA_fnc_addEventHandler;
[QGVAR(ivBagLocal), LINKFUNC(ivBagLocal)] call CBA_fnc_addEventHandler; [QGVAR(ivBagLocal), LINKFUNC(ivBagLocal)] call CBA_fnc_addEventHandler;
[QGVAR(medicationLocal), LINKFUNC(medicationLocal)] call CBA_fnc_addEventHandler; [QGVAR(medicationLocal), LINKFUNC(medicationLocal)] call CBA_fnc_addEventHandler;
[QGVAR(placeInBodyBag), LINKFUNC(placeInBodyBag)] call CBA_fnc_addEventHandler; [QGVAR(placeInBodyBagOrGrave), LINKFUNC(placeInBodyBagOrGrave)] call CBA_fnc_addEventHandler;
[QGVAR(splintLocal), LINKFUNC(splintLocal)] call CBA_fnc_addEventHandler; [QGVAR(splintLocal), LINKFUNC(splintLocal)] call CBA_fnc_addEventHandler;
[QGVAR(tourniquetLocal), LINKFUNC(tourniquetLocal)] call CBA_fnc_addEventHandler; [QGVAR(tourniquetLocal), LINKFUNC(tourniquetLocal)] call CBA_fnc_addEventHandler;
@ -61,3 +61,35 @@ if (isServer) then {
[_toReplace, _replacements] call EFUNC(common,registerItemReplacement); [_toReplace, _replacements] call EFUNC(common,registerItemReplacement);
} forEach (configProperties [configFile >> QEGVAR(medical,replacementItems), "isArray _x"]); } forEach (configProperties [configFile >> QEGVAR(medical,replacementItems), "isArray _x"]);
}] call CBA_fnc_addEventHandler; }] 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;
};
};

View File

@ -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 <OBJECT>
* 1: Patient <OBJECT>
*
* Return Value:
* Can dig <BOOL>
*
* 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)}

View File

@ -1,6 +1,6 @@
#include "..\script_component.hpp" #include "..\script_component.hpp"
/* /*
* Author: Glowbal * Author: Glowbal, drofseh
* Places a dead body inside a body bag. * Places a dead body inside a body bag.
* *
* Arguments: * Arguments:
@ -24,30 +24,5 @@ if ((alive _patient) && {!GVAR(allowBodyBagUnconscious)}) exitWith {
[LSTRING(bodybagWhileStillAlive)] call EFUNC(common,displayTextStructured); [LSTRING(bodybagWhileStillAlive)] call EFUNC(common,displayTextStructured);
}; };
if (!local _patient) exitWith { // Body bag needs to be a little higher to prevent it from flipping
TRACE_1("Calling where local",local _patient); [_this, "ACE_bodyBagObject", [0, 0, 0.2]] call FUNC(placeInBodyBagOrGrave);
[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;

View File

@ -0,0 +1,57 @@
#include "..\script_component.hpp"
/*
* Author: Glowbal, drofseh
* Places a dead body inside a body bag or grave.
*
* Arguments:
* 0: Arguments <ARRAY>
* - 0: Medic <OBJECT>
* - 1: Patient <OBJECT>
* 1: Resting Place Classname <STRING>
* 2: Offset <ARRAY> (default: [0,0,0])
* 3: Rotation <NUMBER> (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;

View File

@ -0,0 +1,31 @@
#include "..\script_component.hpp"
/*
* Author: Glowbal, drofseh
* Places a dead body inside a grave.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
*
* 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);

View File

@ -125,6 +125,15 @@
true true
] call CBA_fnc_addSetting; ] 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), QGVAR(medicEpinephrine),
"LIST", "LIST",
@ -305,6 +314,15 @@
true true
] call CBA_fnc_addSetting; ] 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), QGVAR(holsterRequired),
"LIST", "LIST",

View File

@ -412,6 +412,12 @@
<Chinesesimp>装入裹尸袋时间</Chinesesimp> <Chinesesimp>装入裹尸袋时间</Chinesesimp>
<Korean>초 단위로 시체 운반용 부대를 사용하는데 걸리는 시간을 정합니다.</Korean> <Korean>초 단위로 시체 운반용 부대를 사용하는데 걸리는 시간을 정합니다.</Korean>
</Key> </Key>
<Key ID="STR_ACE_Medical_Treatment_TreatmentTimeGrave_DisplayName">
<English>Grave Digging Time</English>
</Key>
<Key ID="STR_ACE_Medical_Treatment_TreatmentTimeGrave_Description">
<English>Time, in seconds, required to dig a grave for a body.</English>
</Key>
<Key ID="STR_ACE_Medical_Treatment_MedicEpinephrine_DisplayName"> <Key ID="STR_ACE_Medical_Treatment_MedicEpinephrine_DisplayName">
<English>Allow Epinephrine</English> <English>Allow Epinephrine</English>
<German>Erlaube Epiniphrin</German> <German>Erlaube Epiniphrin</German>
@ -825,6 +831,15 @@
<Chinesesimp>能够将昏迷的伤员装入尸袋中。</Chinesesimp> <Chinesesimp>能够将昏迷的伤员装入尸袋中。</Chinesesimp>
<Korean>기절상태의 인원을 시체운반용부대에 옮겨 담을 수 있는지를 정합니다.</Korean> <Korean>기절상태의 인원을 시체운반용부대에 옮겨 담을 수 있는지를 정합니다.</Korean>
</Key> </Key>
<Key ID="STR_ACE_Medical_Treatment_AllowGaveDigging_DisplayName">
<English>Allow Grave Digging</English>
</Key>
<Key ID="STR_ACE_Medical_Treatment_AllowGaveDigging_Description">
<English>Enables digging graves to dispose of corpses.</English>
</Key>
<Key ID="STR_ACE_Medical_Treatment_AllowGaveDigging_graveOnlyDead">
<English>Only if dead</English>
</Key>
<Key ID="STR_ACE_Medical_Treatment_MedicIV_DisplayName"> <Key ID="STR_ACE_Medical_Treatment_MedicIV_DisplayName">
<English>Allow IV Transfusion</English> <English>Allow IV Transfusion</English>
<German>Erlaube Bluttransfusionen</German> <German>Erlaube Bluttransfusionen</German>
@ -4445,6 +4460,12 @@
<Chinese>將屍體放入屍袋中...</Chinese> <Chinese>將屍體放入屍袋中...</Chinese>
<Turkish>Vücut, ceset torbasına yerleştiriliyor...</Turkish> <Turkish>Vücut, ceset torbasına yerleştiriliyor...</Turkish>
</Key> </Key>
<Key ID="STR_ACE_Medical_Treatment_DigGrave">
<English>Dig grave for body</English>
</Key>
<Key ID="STR_ACE_Medical_Treatment_DiggingGrave">
<English>Digging grave for body...</English>
</Key>
<Key ID="STR_ACE_Medical_Treatment_Activity_bandagedPatient"> <Key ID="STR_ACE_Medical_Treatment_Activity_bandagedPatient">
<English>%1 has bandaged patient</English> <English>%1 has bandaged patient</English>
<Spanish>%1 has vendado al paciente</Spanish> <Spanish>%1 has vendado al paciente</Spanish>
@ -4686,6 +4707,9 @@
<Chinesesimp>身体抽搐了一下,可能还没死!</Chinesesimp> <Chinesesimp>身体抽搐了一下,可能还没死!</Chinesesimp>
<Korean>꿈틀대는걸 보니 죽은 것 같지는 않습니다!</Korean> <Korean>꿈틀대는걸 보니 죽은 것 같지는 않습니다!</Korean>
</Key> </Key>
<Key ID="STR_ACE_Medical_Treatment_checkHeadstoneName">
<English>Check name on headstone</English>
</Key>
<Key ID="STR_ACE_Medical_Treatment_bandageRollover_DisplayName"> <Key ID="STR_ACE_Medical_Treatment_bandageRollover_DisplayName">
<English>Bandage Rollover</English> <English>Bandage Rollover</English>
<Polish>Bandażowanie Wielu Ran</Polish> <Polish>Bandażowanie Wielu Ran</Polish>

View File

@ -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)
```