Medical Treatment - Change stitching action to be per-body-part (#9005)

* Make stitching action per-body-part

* Apply suggestions from code review

Co-authored-by: mharis001 <34453221+mharis001@users.noreply.github.com>

---------

Co-authored-by: mharis001 <34453221+mharis001@users.noreply.github.com>
Co-authored-by: Salluci <salluci.lovi@gmail.com>
This commit is contained in:
pterolatypus 2023-06-27 23:43:45 +01:00 committed by GitHub
parent 4f0577ce5f
commit f434549faf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 74 deletions

View File

@ -30,7 +30,6 @@ PREP(fullHeal);
PREP(fullHealLocal);
PREP(getBandageTime);
PREP(getHealTime);
PREP(getStitchableWounds);
PREP(getStitchTime);
PREP(getTriageStatus);
PREP(handleBandageOpening);

View File

@ -1,23 +1,31 @@
#include "script_component.hpp"
/*
* Author: Katalam, mharis001, Brett Mayson
* Checks if the patient can be stitched.
* Checks if the patient's body part can be stitched.
*
* Arguments:
* 0: Medic <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
*
* ReturnValue:
* Can Stitch <BOOL>
*
* Example:
* [player, cursorTarget] call ace_medical_treatment_fnc_canStitch
* [player, cursorTarget, "head"] call ace_medical_treatment_fnc_canStitch
*
* Public: No
*/
params ["_medic", "_patient"];
params ["_medic", "_patient", "_bodyPart"];
if ((GVAR(consumeSurgicalKit) == 2) && {!([_medic, _patient, ["ACE_suture"]] call FUNC(hasItem))}) exitWith {false};
count (_patient call FUNC(getStitchableWounds)) > 0
private _isBleeding = false;
{
_x params ["", "_amountOf", "_bleedingRate"];
_isBleeding = _amountOf > 0 && {_bleedingRate > 0};
if (_isBleeding) then {break};
} forEach (GET_OPEN_WOUNDS(_patient) get _bodyPart);
(!_isBleeding && {(GET_BANDAGED_WOUNDS(_patient) getOrDefault [_bodyPart, []]) isNotEqualTo []}) // return

View File

@ -6,23 +6,17 @@
* Arguments:
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
*
* Return Value:
* Treatment Time <NUMBER>
*
* Example:
* [player, cursorObject] call ace_medical_treatment_fnc_getStitchTime
* [player, cursorObject, "head"] call ace_medical_treatment_fnc_getStitchTime
*
* Public: No
*/
params ["", "_patient"];
params ["", "_patient", "_bodyPart"];
private _stitchableTotal = 0;
{
_stitchableTotal = _stitchableTotal + count _y;
} forEach (_patient call FUNC(getStitchableWounds));
_stitchableTotal * GVAR(woundStitchTime)
count (GET_BANDAGED_WOUNDS(_patient) getOrDefault [_bodyPart, []]) * GVAR(woundStitchTime)

View File

@ -1,42 +0,0 @@
#include "script_component.hpp"
/*
* Author: kymckay
* Returns a hashmap of the stitchable wounds that the given unit has on each body part.
* A stitchable wound is a bandaged wound on a body part that does not have any bleeding wounds.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* Stitchable Wounds <HASHMAP>
*
* Example:
* [player] call ace_medical_treatment_fnc_getStitchableWounds
*
* Public: No
*/
params ["_unit"];
// First determine which body parts have a bleeding wound
private _bleedingBodyParts = createHashMap;
{
private _isBleeding = _y findIf {
_x params ["", "_amountOf", "_bleedingRate"];
_amountOf > 0 && {_bleedingRate > 0}
} != -1;
if (_isBleeding) then {
_bleedingBodyParts set [_x, true];
};
} forEach GET_OPEN_WOUNDS(_unit);
// Any bandaged wound on a body part not bleeding is stitchable
private _stitchableWounds = createHashMap;
{
if (!(_x in _bleedingBodyParts) && {_y isNotEqualTo []}) then {
_stitchableWounds set [_x, _y];
};
} forEach GET_BANDAGED_WOUNDS(_unit);
_stitchableWounds

View File

@ -7,6 +7,7 @@
* 0: Arguments <ARRAY>
* 0: Medic (not used) <OBJECT>
* 1: Patient <OBJECT>
* 2: Body Part <STRING>
* 1: Elapsed Time <NUMBER>
* 2: Total Time <NUMBER>
*
@ -20,35 +21,34 @@
*/
params ["_args", "_elapsedTime", "_totalTime"];
_args params ["_medic", "_patient"];
private _stitchableWounds = _patient call FUNC(getStitchableWounds);
// Stop treatment if there are no wounds that can be stitched remaining
if (_stitchableWounds isEqualTo createHashMap) exitWith {false};
// Not enough time has elapsed to stitch a wound
if (_totalTime - _elapsedTime > ([_patient, _patient] call FUNC(getStitchTime)) - GVAR(woundStitchTime)) exitWith {true};
_args params ["_medic", "_patient", "_bodyPart"];
private _bandagedWounds = GET_BANDAGED_WOUNDS(_patient);
private _stitchedWounds = GET_STITCHED_WOUNDS(_patient);
private _bandagedWoundsOnPart = _bandagedWounds get _bodyPart;
// Stop treatment if there are no wounds that can be stitched remaining
if (_bandagedWoundsOnPart isEqualTo []) exitWith {false};
// Not enough time has elapsed to stitch a wound
if (_totalTime - _elapsedTime > ([_patient, _patient, _bodyPart] call FUNC(getStitchTime)) - GVAR(woundStitchTime)) exitWith {true};
// Remove the first stitchable wound from the bandaged wounds
private _bodyPart = (keys _stitchableWounds) select 0;
private _bandagedWoundsOnPart = _bandagedWounds get _bodyPart;
private _treatedWound = _bandagedWoundsOnPart deleteAt (count _bandagedWoundsOnPart - 1);
_treatedWound params ["_treatedID", "_treatedAmountOf", "", "_treatedDamageOf"];
// Check if we need to add a new stitched wound or increase the amount of an existing one
private _woundIndex = (_stitchedWounds getOrDefault [_bodyPart, []]) findIf {
private _stitchedWounds = GET_STITCHED_WOUNDS(_patient);
private _stitchedWoundsOnPart = _stitchedWounds getOrDefault [_bodyPart, [], true];
private _woundIndex = _stitchedWoundsOnPart findIf {
_x params ["_classID"];
_classID == _treatedID
};
if (_woundIndex == -1) then {
(_stitchedWounds getOrDefault [_bodyPart, [], true]) pushBack _treatedWound;
_stitchedWoundsOnPart pushBack _treatedWound;
} else {
private _wound = (_stitchedWounds get _bodyPart) select _woundIndex;
private _wound = _stitchedWoundsOnPart select _woundIndex;
_wound set [1, (_wound select 1) + _treatedAmountOf];
};
@ -76,7 +76,7 @@ _patient setVariable [VAR_STITCHED_WOUNDS, _stitchedWounds, true];
if (
EGVAR(medical,limping) == 2
&& {_patient getVariable [QEGVAR(medical,isLimping), false]}
&& {_bodyPart isEqualTo "leftleg" || _bodyPart isEqualTo "rightleg"}
&& {_bodyPart in ["leftleg", "rightleg"]}
) then {
TRACE_3("Updating damage effects",_patient,_bodyPart,local _patient);
[QEGVAR(medical_engine,updateDamageEffects), _patient, _patient] call CBA_fnc_targetEvent;
@ -85,7 +85,7 @@ if (
// Consume a suture for the next wound if one exists, stop stitching if none are left
if (GVAR(consumeSurgicalKit) == 2) then {
// Don't consume a suture if there are no more wounds to stitch
if (count (values _stitchableWounds) isEqualTo 1) exitWith {false};
if (_bandagedWoundsOnPart isEqualTo []) exitWith {false};
([_medic, _patient, ["ACE_suture"]] call FUNC(useItem)) params ["_user"];
!isNull _user
} else {