ACE3/addons/medical/functions/fnc_handleDamage_caching.sqf
PabstMirror 988a5c76bb Medical - 1.54 Changes
1.54 Armor
Translate selectiosn to hitpoints
Calc newDamage using hitIndex (because sel is translated)
Fix isFalling never being reset

Cache hitpointIndex to reset damage

Normalize Limb Armor to 1.54

Cleanup

Cleanup
2015-11-25 11:49:20 -06:00

158 lines
6.5 KiB
Plaintext

/*
* Author: KoffeinFlummi, Glowbal
* Cache a handleDamage call to execute it 3 frames later
*
* Arguments:
* 0: Unit That Was Hit <OBJECT>
* 1: Name Of Hit Selection <STRING>
* 2: Amount Of Damage <NUMBER>
* 3: Shooter <OBJECT>
* 4: Projectile <STRING>
* 5: HitPointIndex (-1 for structural) <NUMBER>
*
* Return Value:
* <nil>
*
* Public: No
*/
#include "script_component.hpp"
private ["_hitSelections", "_hitPoints", "_impactVelocity", "_newDamage", "_cache_hitpoints", "_cache_projectiles", "_cache_params", "_cache_damages"];
params ["_unit", "_selectionName", "_damage", "_source", "_projectile", "_hitPointIndex"];
_hitSelections = GVAR(SELECTIONS);
// Calculate change in damage - use getHitIndex because selection is translated (hitdiaphragm->body)
_newDamage = _damage - (damage _unit);
if (_hitPointIndex >= 0) then {_newDamage = _damage - (_unit getHitIndex _hitPointIndex)};
TRACE_7("ACE_DEBUG: HandleDamage_Caching Called",_unit, _selectionName, _damage, _source, _projectile,_hitPointIndex,_newDamage);
// Check for vehicle crash
if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")} && {isNull _source} && {_projectile == ""} && {_selectionName == ""}) then {
if (GVAR(enableVehicleCrashes)) then {
_selectionName = _hitSelections select (floor(random(count _hitSelections)));
_projectile = "vehiclecrash";
_this set [1, _selectionName];
_this set [4, _projectile];
};
};
// Handle falling damage
_impactVelocity = (velocity _unit) select 2;
if (_impactVelocity < -5 && {vehicle _unit == _unit}) then {
TRACE_1("Starting isFalling", time);
_unit setVariable [QGVAR(isFalling), true];
_unit setVariable [QGVAR(impactVelocity), _impactVelocity];
} else {
if ((_unit getVariable [QGVAR(isFalling), false]) && {diag_frameno > (_unit getVariable [QGVAR(frameNo_damageCaching), -3]) + 2}) then {
TRACE_1("Ending isFalling", time);
_unit setVariable [QGVAR(isFalling), false];
};
};
if (_unit getVariable [QGVAR(isFalling), false]) then {
if !(_selectionName in ["", "leg_l", "leg_r"]) then {
if (_selectionName == "body") then {
_newDamage = _newDamage * abs(_unit getVariable [QGVAR(impactVelocity), _impactVelocity]) / 50;
} else {
_newDamage = _newDamage * 0.5;
};
} else {
if (_selectionName == "") then {
_selectionName = ["leg_l", "leg_r"] select (floor(random 2));
_this set [1, _selectionName];
};
_newDamage = _newDamage * 0.7;
};
_projectile = "falling";
_this set [4, "falling"];
};
// Finished with the current frame, reset variables
// Note: sometimes handleDamage spans over 2 or even 3 frames.
if (diag_frameno > (_unit getVariable [QGVAR(frameNo_damageCaching), -3]) + 2) then {
_unit setVariable [QGVAR(frameNo_damageCaching), diag_frameno];
// handle the cached damages 3 frames later
[{
private ["_args", "_params"];
params ["_args", "_idPFH"];
_args params ["_unit", "_frameno"];
if (diag_frameno >= _frameno + 2) then {
_unit setDamage 0;
if (GVAR(level) < 2 || {!([_unit] call FUNC(hasMedicalEnabled))}) then {
[_unit] call FUNC(handleDamage_basic);
} else {
_cache_params = _unit getVariable [QGVAR(cachedHandleDamageParams), []];
_cache_damages = _unit getVariable QGVAR(cachedDamages);
{
_params = _x + [_cache_damages select _foreachIndex];
_params call FUNC(handleDamage_advanced);
} foreach _cache_params;
[_unit] call FUNC(handleDamage_advancedSetDamage);
};
[_idPFH] call CBA_fnc_removePerFrameHandler;
};
}, 0, [_unit, diag_frameno] ] call CBA_fnc_addPerFrameHandler;
_unit setVariable [QGVAR(cachedProjectiles), []];
_unit setVariable [QGVAR(cachedHitPoints), []];
_unit setVariable [QGVAR(cachedDamages), []];
_unit setVariable [QGVAR(cachedHandleDamageParams), []];
};
// Caching of the damage events
if (_selectionName != "") then {
_cache_projectiles = _unit getVariable QGVAR(cachedProjectiles);
private ["_index","_otherDamage"];
_index = _cache_projectiles find _projectile;
// Check if the current projectile has already been handled once
if (_index >= 0 && {_projectile != "falling"}) exitwith {
_cache_damages = _unit getVariable QGVAR(cachedDamages);
// Find the previous damage this projectile has done
_otherDamage = (_cache_damages select _index);
// Take the highest damage of the two
if (_newDamage > _otherDamage) then {
_cache_params = _unit getVariable QGVAR(cachedHandleDamageParams);
_cache_hitpoints = _unit getVariable QGVAR(cachedHitPoints);
private ["_hitPoint", "_restore"];
// Restore the damage before the previous damage was processed
_hitPoint = _cache_hitpoints select _index;
_restore = ((_unit getHitIndex _hitPoint) - _otherDamage) max 0;
_unit setHitIndex [_hitPoint, _restore];
_cache_hitpoints set [_index, _hitPointIndex];
_cache_damages set [_index, _newDamage];
_cache_params set[_index, _this];
_unit setVariable [QGVAR(cachedProjectiles), _cache_projectiles];
_unit setVariable [QGVAR(cachedHitPoints), _cache_hitpoints];
_unit setVariable [QGVAR(cachedDamages), _cache_damages];
_unit setVariable [QGVAR(cachedHandleDamageParams), _cache_params];
};
};
_cache_hitpoints = _unit getVariable QGVAR(cachedHitPoints);
_cache_damages = _unit getVariable QGVAR(cachedDamages);
_cache_params = _unit getVariable QGVAR(cachedHandleDamageParams);
// This is an unhandled projectile
_cache_projectiles pushBack _projectile;
_cache_hitpoints pushBack _hitPointIndex;
_cache_damages pushBack _newDamage;
_cache_params pushBack _this;
// Store the new cached values
_unit setVariable [QGVAR(cachedProjectiles), _cache_projectiles];
_unit setVariable [QGVAR(cachedHitPoints), _cache_hitpoints];
_unit setVariable [QGVAR(cachedDamages), _cache_damages];
_unit setVariable [QGVAR(cachedHandleDamageParams), _cache_params];
};
TRACE_8("ACE_DEBUG: HandleDamage_Caching",_unit, _newDamage, _cache_params, _cache_damages, _unit getVariable QGVAR(cachedProjectiles), _unit getVariable QGVAR(cachedHitPoints), _unit getVariable QGVAR(cachedDamages), _unit getVariable QGVAR(cachedHandleDamageParams));
_newDamage