mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Vary time taken to bandage based on circumstances (#6467)
This commit is contained in:
parent
78ee7d4677
commit
39b1d144e1
@ -61,6 +61,16 @@
|
||||
// Minimum body part damage required for blood effect on uniform
|
||||
#define VISUAL_BODY_DAMAGE_THRESHOLD 0.35
|
||||
|
||||
// Empty wound data, used for some default return values
|
||||
// [ID, classID, bodypartIndex, amountOf, bloodloss, damage, category]
|
||||
#define EMPTY_WOUND [-1, -1, -1, 0, 0, 0, 0]
|
||||
|
||||
// Base time to bandage each wound category
|
||||
#define BANDAGE_TIME_S 4
|
||||
#define BANDAGE_TIME_M 6
|
||||
#define BANDAGE_TIME_L 8
|
||||
#define BANDAGE_TIME_MOD_MEDIC -2
|
||||
#define BANDAGE_TIME_MOD_SELF 4
|
||||
|
||||
|
||||
// - Unit Variables ----------------------------------------------------
|
||||
|
@ -9,7 +9,7 @@ class GVAR(Actions) {
|
||||
allowedSelections[] = {"All"};
|
||||
allowSelfTreatment = 1;
|
||||
requiredMedic = 0;
|
||||
treatmentTime = 8;
|
||||
treatmentTime = QFUNC(getBandageTime);
|
||||
treatmentTimeSelfCoef = 1;
|
||||
items[] = {{"ACE_fieldDressing", "ACE_packingBandage", "ACE_elasticBandage", "ACE_quikclot"}};
|
||||
condition = QUOTE(!EGVAR(medical,advancedBandages));
|
||||
|
@ -45,6 +45,8 @@ PREP(bodyCleanupLoop);
|
||||
PREP(calculateBlood);
|
||||
PREP(canAccessMedicalEquipment);
|
||||
PREP(dropDownTriageCard);
|
||||
PREP(findMostEffectiveWound);
|
||||
PREP(getBandageTime);
|
||||
PREP(getTriageStatus);
|
||||
PREP(handleBandageOpening);
|
||||
PREP(hasTourniquetAppliedTo);
|
||||
|
@ -0,0 +1,73 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: SilentSpike
|
||||
* 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>
|
||||
* 2: Body part index <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* [Wound, Index, Effectiveness] <ARRAY, NUMBER, NUMBER>
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_patient", "_bandage", "_partIndex"];
|
||||
|
||||
// Get the default effectiveness for the used bandage
|
||||
private _config = configFile >> QUOTE(ADDON) >> "Bandaging";
|
||||
private _effectiveness = getNumber (_config >> "effectiveness");
|
||||
|
||||
if (isClass (_config >> _bandage)) then {
|
||||
_config = (_config >> _bandage);
|
||||
|
||||
if (isNumber (_config >> "effectiveness")) then {
|
||||
_effectiveness = getNumber (_config >> "effectiveness");
|
||||
};
|
||||
};
|
||||
|
||||
// Iterate over open wounds to find the most effective target
|
||||
private _openWounds = _patient getVariable [QEGVAR(medical,openWounds), []];
|
||||
if (_openWounds isEqualTo []) exitWith { [EMPTY_WOUND, -1, -1] };
|
||||
|
||||
private _wound = EMPTY_WOUND;
|
||||
private _woundIndex = -1;
|
||||
private _effectivenessFound = -1;
|
||||
|
||||
{
|
||||
_x params ["", "_classID", "_partIndexN", "_amountOf", "_bleeding", "_damage", "_category"];
|
||||
|
||||
// Ignore wounds on other bodyparts
|
||||
if (_partIndexN == _partIndex) then {
|
||||
private _woundEffectiveness = _effectiveness;
|
||||
|
||||
// Select the classname from the wound classname storage
|
||||
private _suffix = ["Minor", "Medium", "Large"] select _category;
|
||||
private _className = format ["%1%2", EGVAR(medical_damage,woundClassNames) select _classID, _suffix];
|
||||
|
||||
// Get the effectiveness of the bandage on this wound type
|
||||
if (isClass (_config >> _className)) then {
|
||||
private _woundTreatmentConfig = _config >> _className;
|
||||
|
||||
if (isNumber (_woundTreatmentConfig >> "effectiveness")) then {
|
||||
_woundEffectiveness = getNumber (_woundTreatmentConfig >> "effectiveness");
|
||||
};
|
||||
} else {
|
||||
// Basic medical bandage just has a base level config (same effectivenes for all wound types)
|
||||
if (_bandage != "BasicBandage") then {
|
||||
WARNING_2("No config for wound type [%1] config base [%2]",_className,_config);
|
||||
};
|
||||
};
|
||||
|
||||
// Track most effective found so far
|
||||
if (_woundEffectiveness * _amountOf * _bleeding > _effectivenessFound * (_wound select 3) * (_wound select 4)) then {
|
||||
_effectivenessFound = _woundEffectiveness;
|
||||
_woundIndex = _forEachIndex;
|
||||
_wound = _x;
|
||||
};
|
||||
};
|
||||
} forEach _openWounds;
|
||||
|
||||
[_wound, _woundIndex, _effectivenessFound]
|
49
addons/medical_treatment/functions/fnc_getBandageTime.sqf
Normal file
49
addons/medical_treatment/functions/fnc_getBandageTime.sqf
Normal file
@ -0,0 +1,49 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: SilentSpike
|
||||
* 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>
|
||||
*
|
||||
* Return Value:
|
||||
* Time in seconds <NUMBER>
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_medic", "_patient", "_bodypart", "_bandage"];
|
||||
|
||||
private _partIndex = ALL_BODY_PARTS find toLower _bodyPart;
|
||||
if (_partIndex < 0) exitWith { 0 };
|
||||
|
||||
private _targetWound = [_patient, _bandage, _partIndex] call FUNC(findMostEffectiveWound);
|
||||
_targetWound params ["_wound", "_woundIndex", "_effectiveness"];
|
||||
|
||||
// Everything is patched up on this body part already
|
||||
if (_wound isEqualTo EMPTY_WOUND) exitWith { 0 };
|
||||
|
||||
_wound params ["", "", "", "_amountOf", "_bloodloss", "_damage", "_category"];
|
||||
|
||||
// Base bandage time is based on wound size and remaining percentage
|
||||
private _bandageTime = ([
|
||||
BANDAGE_TIME_S,
|
||||
BANDAGE_TIME_M,
|
||||
BANDAGE_TIME_L
|
||||
] select _category) * _amountOf;
|
||||
|
||||
// Medics are more practised at applying bandages
|
||||
if ([_medic] call FUNC(isMedic)) then {
|
||||
_bandageTime = _bandageTime + BANDAGE_TIME_MOD_MEDIC;
|
||||
};
|
||||
|
||||
// Bandaging yourself requires more work
|
||||
if (_medic == _patient) then {
|
||||
_bandageTime = _bandageTime + BANDAGE_TIME_MOD_SELF;
|
||||
};
|
||||
|
||||
// Nobody can bandage instantly
|
||||
_bandageTime max 1
|
@ -11,7 +11,7 @@
|
||||
* Return Value:
|
||||
* Succesful treatment started <BOOL>
|
||||
*
|
||||
* Public: Yes
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
@ -133,10 +133,9 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then {
|
||||
_caller setVariable [QGVAR(endInAnim), _endInAnim];
|
||||
};
|
||||
|
||||
// get treatment time
|
||||
// get treatment time from config - also supports variables and code expressions
|
||||
private _treatmentTime = 0;
|
||||
|
||||
// reads number from config. supports variables and code expressions
|
||||
if (isNumber (_config >> "treatmentTime")) then {
|
||||
_treatmentTime = getNumber (_config >> "treatmentTime");
|
||||
} else {
|
||||
|
@ -8,21 +8,20 @@
|
||||
* 2: Body part <STRING>
|
||||
* 3: Treatment class name <STRING>
|
||||
* 4: Item <STRING>
|
||||
* 5: specific Spot <NUMBER> (default: -1)
|
||||
*
|
||||
* Return Value:
|
||||
* Succesful treatment started <BOOL>
|
||||
*
|
||||
* Public: Yes
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_caller", "_target", "_bodyPart", "_className", "_items", "", ["_specificSpot", -1]];
|
||||
params ["_caller", "_target", "_bodyPart", "_className", "_items"];
|
||||
|
||||
[_target, "activity", ELSTRING(medical_treatment,Activity_bandagedPatient), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog);
|
||||
[_target, "activity_view", ELSTRING(medical_treatment,Activity_bandagedPatient), [[_caller, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); // TODO expand message
|
||||
|
||||
[QGVAR(treatmentBandageLocal), [_target, _className, _bodyPart, _specificSpot], _target] call CBA_fnc_targetEvent;
|
||||
[QGVAR(treatmentBandageLocal), [_target, _className, _bodyPart], _target] call CBA_fnc_targetEvent;
|
||||
|
||||
/*{
|
||||
if (_x != "") then {
|
||||
|
@ -14,7 +14,7 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_target", "_bandage", "_bodyPart", ["_specificClass", -1]];
|
||||
params ["_target", "_bandage", "_bodyPart"];
|
||||
|
||||
private _partIndex = ALL_BODY_PARTS find toLower _bodyPart;
|
||||
if (_partIndex < 0) exitWith { false };
|
||||
@ -22,84 +22,25 @@ if (_partIndex < 0) exitWith { false };
|
||||
private _openWounds = _target getVariable [QEGVAR(medical,openWounds), []];
|
||||
if (_openWounds isEqualTo []) exitWith { false };
|
||||
|
||||
// Get the default effectiveness for the used bandage
|
||||
private _config = configFile >> QUOTE(ADDON) >> "Bandaging";
|
||||
private _effectiveness = getNumber (_config >> "effectiveness");
|
||||
|
||||
if (isClass (_config >> _bandage)) then {
|
||||
_config = (_config >> _bandage);
|
||||
|
||||
if (isNumber (_config >> "effectiveness")) then {
|
||||
_effectiveness = getNumber (_config >> "effectiveness");
|
||||
};
|
||||
};
|
||||
|
||||
// Figure out which injury for this bodypart is the best choice to bandage
|
||||
// TODO also use up the remainder on left over injuries
|
||||
private _mostEffectiveSpot = 0;
|
||||
private _effectivenessFound = -1;
|
||||
private _mostEffectiveInjury = _openWounds select 0;
|
||||
private _exit = false;
|
||||
private _targetWound = [_target, _bandage, _partIndex] call FUNC(findMostEffectiveWound);
|
||||
_targetWound params ["_wound", "_woundIndex", "_effectiveness"];
|
||||
|
||||
{
|
||||
_x params ["", "_classID", "_partIndexN", "_amountOf", "_bleeding", "_damage", "_category"];
|
||||
TRACE_2("OPENWOUND: ", _target, _x);
|
||||
|
||||
// Only parse injuries that are for the selected bodypart.
|
||||
if (_partIndexN == _partIndex) then {
|
||||
private _woundEffectiveness = _effectiveness;
|
||||
|
||||
// Select the classname from the wound classname storage
|
||||
private _postfix = ["Minor", "Medium", "Large"] select _category;
|
||||
private _className = format ["%1%2", EGVAR(medical_damage,woundClassNames) select _classID, _postfix];
|
||||
|
||||
// Check if this wound type has attributes specified for the used bandage
|
||||
if (isClass (_config >> _className)) then {
|
||||
// Collect the effectiveness from the used bandage for this wound type
|
||||
private _woundTreatmentConfig = _config >> _className;
|
||||
|
||||
if (isNumber (_woundTreatmentConfig >> "effectiveness")) then {
|
||||
_woundEffectiveness = getNumber (_woundTreatmentConfig >> "effectiveness");
|
||||
};
|
||||
} else {
|
||||
//Basic medical bandage just has a base level config (same effectivenes for all wound types)
|
||||
if (_bandage != "BasicBandage") then {
|
||||
WARNING_2("No config for wound type [%1] config base [%2]", _className, _config);
|
||||
};
|
||||
};
|
||||
|
||||
TRACE_2("Wound classes: ", _specificClass, _classID);
|
||||
if (_specificClass == _classID) exitWith {
|
||||
_effectivenessFound = _woundEffectiveness;
|
||||
_mostEffectiveSpot = _forEachIndex;
|
||||
_mostEffectiveInjury = _x;
|
||||
_exit = true;
|
||||
};
|
||||
|
||||
// Check if this is the currently most effective found.
|
||||
if (_woundEffectiveness * _amountOf * _bleeding > _effectivenessFound * (_mostEffectiveInjury select 3) * (_mostEffectiveInjury select 4)) then {
|
||||
_effectivenessFound = _woundEffectiveness;
|
||||
_mostEffectiveSpot = _forEachIndex;
|
||||
_mostEffectiveInjury = _x;
|
||||
};
|
||||
};
|
||||
|
||||
if (_exit) exitWith {};
|
||||
} forEach _openWounds;
|
||||
|
||||
if (_effectivenessFound == -1) exitWith {}; // Seems everything is patched up on this body part already..
|
||||
// Everything is patched up on this body part already
|
||||
if (_effectiveness == -1) exitWith {};
|
||||
|
||||
// Find the impact this bandage has and reduce the amount this injury is present
|
||||
private _amountOf = _mostEffectiveInjury select 3;
|
||||
private _impact = _effectivenessFound min _amountOf;
|
||||
_mostEffectiveInjury set [3, _amountOf - _impact];
|
||||
_openWounds set [_mostEffectiveSpot, _mostEffectiveInjury];
|
||||
private _amountOf = _wound select 3;
|
||||
private _impact = _effectiveness min _amountOf;
|
||||
_wound set [3, _amountOf - _impact];
|
||||
_openWounds set [_woundIndex, _wound];
|
||||
|
||||
_target setVariable [QEGVAR(medical,openWounds), _openWounds, true];
|
||||
|
||||
// Handle the reopening of bandaged wounds
|
||||
if (_impact > 0 && {EGVAR(medical,advancedBandages) && {EGVAR(medical,woundReopening)}}) then {
|
||||
[_target, _impact, _partIndex, _mostEffectiveSpot, _mostEffectiveInjury, _bandage] call FUNC(handleBandageOpening);
|
||||
[_target, _impact, _partIndex, _woundIndex, _wound, _bandage] call FUNC(handleBandageOpening);
|
||||
};
|
||||
|
||||
true
|
||||
|
Loading…
Reference in New Issue
Block a user