2016-07-30 12:00:42 +00:00
|
|
|
/*
|
|
|
|
* Author: commy2
|
|
|
|
* Main HandleDamage EH function for soldiers.
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* Handle damage EH
|
|
|
|
*
|
|
|
|
* Return Value:
|
|
|
|
* Damage to be inflicted <NUMBER>
|
|
|
|
*
|
|
|
|
* Public: No
|
|
|
|
*/
|
|
|
|
#include "script_component.hpp"
|
|
|
|
|
2016-09-26 18:52:08 +00:00
|
|
|
// for travis
|
|
|
|
#define HIT_STRUCTURAL QGVAR($#structural)
|
2016-10-20 13:02:24 +00:00
|
|
|
#define HIT_CRASH QGVAR($#crash)
|
2016-09-26 18:45:29 +00:00
|
|
|
|
2016-10-12 21:20:22 +00:00
|
|
|
params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator"];
|
2016-10-20 13:02:24 +00:00
|
|
|
//diag_log text str _this;
|
2016-07-30 12:00:42 +00:00
|
|
|
|
|
|
|
// HD sometimes triggers for remote units - ignore.
|
|
|
|
if (!local _unit) exitWith {nil};
|
|
|
|
|
|
|
|
// Get missing meta info
|
|
|
|
private ["_hitPoint", "_oldDamage"];
|
2016-10-20 13:02:24 +00:00
|
|
|
private _isCrash = false;
|
2016-07-30 12:00:42 +00:00
|
|
|
|
2016-10-20 13:02:24 +00:00
|
|
|
// Store
|
2016-07-30 12:00:42 +00:00
|
|
|
if (_hitPointIndex < 0) then {
|
|
|
|
_hitPoint = "#structural";
|
|
|
|
_oldDamage = damage _unit;
|
2016-10-20 13:02:24 +00:00
|
|
|
|
|
|
|
// Handle vehicle crashes
|
|
|
|
if (_damage == _unit getVariable [HIT_CRASH, -1]) then {
|
2016-12-07 15:39:22 +00:00
|
|
|
_isCrash = (_ammo == "");
|
2016-10-20 13:02:24 +00:00
|
|
|
_unit setVariable [HIT_CRASH, -1];
|
|
|
|
} else {
|
|
|
|
_unit setVariable [HIT_CRASH, _damage];
|
|
|
|
};
|
2016-07-30 12:00:42 +00:00
|
|
|
} else {
|
|
|
|
_hitPoint = toLower (getAllHitPointsDamage _unit select 0 select _hitPointIndex);
|
|
|
|
_oldDamage = _unit getHitIndex _hitPointIndex;
|
2016-10-20 13:02:24 +00:00
|
|
|
|
|
|
|
// No crash, reset
|
|
|
|
_unit setVariable [HIT_CRASH, -1];
|
2016-07-30 12:00:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
private _newDamage = _damage - _oldDamage;
|
2016-09-26 16:30:39 +00:00
|
|
|
_unit setVariable [format [QGVAR($%1), _hitPoint], _newDamage];
|
2016-07-30 12:00:42 +00:00
|
|
|
|
|
|
|
// These control blood material visuals.
|
|
|
|
// If damage is in dummy hitpoints, "hands" and "legs", don't change anything
|
2016-09-26 17:59:00 +00:00
|
|
|
if (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) exitWith {_oldDamage};
|
2016-07-30 12:00:42 +00:00
|
|
|
|
|
|
|
// Add injury
|
|
|
|
if (_hitPoint isEqualTo "ace_hdbracket") exitWith {
|
2016-10-12 21:20:22 +00:00
|
|
|
_unit setVariable [QGVAR(lastShooter), _shooter];
|
|
|
|
_unit setVariable [QGVAR(lastInstigator), _instigator];
|
|
|
|
|
2016-09-26 18:52:08 +00:00
|
|
|
private _damageStructural = _unit getVariable [HIT_STRUCTURAL, 0];
|
2016-09-26 16:30:39 +00:00
|
|
|
|
2016-07-30 12:00:42 +00:00
|
|
|
// --- Head
|
2016-09-26 16:30:39 +00:00
|
|
|
private _damageFace = _unit getVariable [QGVAR($HitFace), 0];
|
|
|
|
private _damageNeck = _unit getVariable [QGVAR($HitNeck), 0];
|
|
|
|
private _damageHead = (_unit getVariable [QGVAR($HitHead), 0]) max _damageFace max _damageNeck;
|
2016-07-30 12:00:42 +00:00
|
|
|
|
|
|
|
// --- Body
|
2016-09-26 16:30:39 +00:00
|
|
|
private _damagePelvis = _unit getVariable [QGVAR($HitPelvis), 0];
|
|
|
|
private _damageAbdomen = _unit getVariable [QGVAR($HitAbdomen), 0];
|
|
|
|
private _damageDiaphragm = _unit getVariable [QGVAR($HitDiaphragm), 0];
|
|
|
|
private _damageChest = _unit getVariable [QGVAR($HitChest), 0];
|
|
|
|
private _damageBody = (_unit getVariable [QGVAR($HitBody), 0]) max _damagePelvis max _damageAbdomen max _damageDiaphragm max _damageChest;
|
2016-07-30 12:00:42 +00:00
|
|
|
|
|
|
|
// --- Arms and Legs
|
2016-09-26 16:30:39 +00:00
|
|
|
private _damageLeftArm = _unit getVariable [QGVAR($HitLeftArm), 0];
|
|
|
|
private _damageRightArm = _unit getVariable [QGVAR($HitRightArm), 0];
|
|
|
|
private _damageLeftLeg = _unit getVariable [QGVAR($HitLeftLeg), 0];
|
|
|
|
private _damageRightLeg = _unit getVariable [QGVAR($HitRightLeg), 0];
|
2016-07-30 12:00:42 +00:00
|
|
|
|
|
|
|
// Find hit point that received the maxium damage.
|
2016-09-26 16:30:39 +00:00
|
|
|
// second param is a priority. should multiple hitpoints receive the same
|
|
|
|
// amount of damage (e.g. max which is 4), we don't want them to be sorted
|
|
|
|
// alphabetically (which would mean that RightLeg is always chosen)
|
2016-07-30 12:00:42 +00:00
|
|
|
private _allDamages = [
|
2016-09-26 16:30:39 +00:00
|
|
|
[_damageHead, PRIORITY_HEAD, "Head"],
|
|
|
|
[_damageBody, PRIORITY_BODY, "Body"],
|
|
|
|
[_damageLeftArm, PRIORITY_LEFT_ARM, "LeftArm"],
|
|
|
|
[_damageRightArm, PRIORITY_RIGHT_ARM, "RightArm"],
|
|
|
|
[_damageLeftLeg, PRIORITY_LEFT_LEG, "LeftLeg"],
|
|
|
|
[_damageRightLeg, PRIORITY_RIGHT_LEG, "RightLeg"]
|
2016-07-30 12:00:42 +00:00
|
|
|
];
|
2016-09-26 16:30:39 +00:00
|
|
|
TRACE_2("incoming",_allDamages,_damageStructural);
|
2016-07-30 12:00:42 +00:00
|
|
|
|
|
|
|
_allDamages sort false;
|
2016-09-26 16:30:39 +00:00
|
|
|
(_allDamages select 0) params ["_receivedDamage", "", "_woundedHitPoint"];
|
|
|
|
|
|
|
|
if (_receivedDamage == 0) then {
|
|
|
|
_receivedDamage = _damageStructural;
|
|
|
|
_woundedHitPoint = "Body";
|
|
|
|
};
|
|
|
|
TRACE_2("received",_receivedDamage,_woundedHitPoint);
|
2016-07-30 12:00:42 +00:00
|
|
|
|
|
|
|
// Check for falling damage.
|
|
|
|
if (_ammo isEqualTo "") then {
|
|
|
|
if (velocity _unit select 2 < -2) then {
|
2016-12-05 20:34:20 +00:00
|
|
|
if (_receivedDamage < 0.35) then {
|
|
|
|
// Less than ~ 5 m
|
|
|
|
_woundedHitPoint = selectRandom ["LeftLeg", "RightLeg"];
|
|
|
|
} else {
|
|
|
|
// More than ~ 5 m
|
|
|
|
_woundedHitPoint = selectRandom ["LeftLeg", "RightLeg", "Body", "Head"];
|
|
|
|
};
|
2016-07-30 12:00:42 +00:00
|
|
|
_ammo = "#falling";
|
|
|
|
} else {
|
2017-06-05 16:42:00 +00:00
|
|
|
if (_receivedDamage > 0.1) then {
|
|
|
|
// Assume collision damage.
|
|
|
|
_woundedHitPoint = "Body";
|
|
|
|
_ammo = "#vehiclecrash";
|
|
|
|
} else {
|
|
|
|
// Probably fire damage:
|
|
|
|
_woundedHitPoint = selectRandom ["LeftLeg", "RightLeg", "Body"];
|
|
|
|
_ammo = "#unknown";
|
|
|
|
private _combinedDamage = _receivedDamage + (_unit getVariable [QGVAR(trivialDamage), 0]);
|
|
|
|
if (_combinedDamage > 0.1) then {
|
|
|
|
// if the new sum is large enough, reset variable and continue with it added in
|
|
|
|
_unit setVariable [QGVAR(trivialDamage), 0];
|
|
|
|
TRACE_2("Using sum of trivialDamage",_receivedDamage,_combinedDamage);
|
|
|
|
_receivedDamage = _combinedDamage;
|
|
|
|
} else {
|
|
|
|
// otherwise just save the new sum into the variable and exit
|
|
|
|
_unit setVariable [QGVAR(trivialDamage), _combinedDamage];
|
|
|
|
_receivedDamage = 0;
|
|
|
|
};
|
|
|
|
};
|
2016-07-30 12:00:42 +00:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
// Don't trigger for minor damage.
|
|
|
|
if (_receivedDamage > 1E-3) then {
|
|
|
|
[QGVAR(woundReceived), [_unit, _woundedHitPoint, _receivedDamage, _shooter, _ammo]] call CBA_fnc_localEvent;
|
|
|
|
};
|
|
|
|
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
|
|
|
// Check for drowning damage.
|
|
|
|
// Don't change the third expression. Safe method for FLOATs.
|
2016-10-20 13:02:24 +00:00
|
|
|
if (_hitPoint isEqualTo "#structural" && {getOxygenRemaining _unit <= 0.5} && {_damage isEqualTo (_oldDamage + 0.005)}) exitWith {
|
2016-07-30 12:00:42 +00:00
|
|
|
[QGVAR(woundReceived), [_unit, "Body", _newDamage, _unit, "#drowning"]] call CBA_fnc_localEvent;
|
2016-10-20 13:02:24 +00:00
|
|
|
|
|
|
|
0
|
|
|
|
};
|
|
|
|
|
|
|
|
// Handle vehicle crashes
|
|
|
|
if (_isCrash) exitWith {
|
|
|
|
[QGVAR(woundReceived), [_unit, "Body", _newDamage, _unit, "#vehiclecrash"]] call CBA_fnc_localEvent;
|
|
|
|
|
|
|
|
0
|
2016-07-30 12:00:42 +00:00
|
|
|
};
|
|
|
|
|
2016-09-26 17:59:00 +00:00
|
|
|
0
|