ACE3/addons/frag/functions/fnc_doSpallMomentum.sqf

125 lines
3.4 KiB
Plaintext
Raw Normal View History

#include "script_component.hpp"
/*
* Author: Lambda.Tiger
* This function creates spalling if the hit slowed the speed down enough.
*
* Arguments:
* Arguments are the same as BI's "HitPart" EH:
* https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#HitPart
*
* Return Value:
* None
*
* Example:
* [BIS_HITPART_EH_ARGS] call ace_frag_fnc_doSpallMomentum;
*
* Public: No
*/
TRACE_1("",_this);
2024-01-09 06:26:43 +00:00
params [
"_projectile",
["_hitObj", objNull],
// "",
2024-01-09 06:26:43 +00:00
["_lPosASL", [0, 0, 0]],
["_lVel", [0, 0, 0]],
// "",
// "",
// "",
["_surfaceType", ""],
["_ammo", "", [""]],
["_shotParents", [objNull, objNull], [[]]],
["_vUp", [0,0,1]]
2024-01-09 06:26:43 +00:00
];
if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF) exitWith {
TRACE_2("timeExit",CBA_missionTime,GVAR(lastSpallTime));
};
if (isNull _hitObj || {_hitObj isKindOf "man"}) exitWith {
TRACE_1("invalidHit",_hitObj);
2024-01-09 06:26:43 +00:00
};
2024-01-09 06:26:43 +00:00
if (_lPosASL isEqualTo [0,0,0]) exitWith {
TRACE_1("Problem with hitPart data - bad pos",_lPosASL);
};
private _vel = if (alive _projectile) then {
2024-01-09 00:07:15 +00:00
velocity _projectile;
} else {
[0, 0, 0]
};
private _lVelUnit = vectorNormalized _lVel;
// Find spall speed / fragment
private _dV = vectorMagnitude _lVel - vectorMagnitude _vel;
private _caliber = getNumber (configFile >> "cfgAmmo" >> _ammo >> "caliber"); // !*! optimize this later?
// scaled momentum change made on caliber-mass assumption ~sqrt(2)/20 * caliber ~= mass
private _deltaMomentum = 0.07071 * _caliber * sqrt( _dV );
TRACE_3("found speed",_dV,_caliber,_deltaMomentum);
if (_deltaMomentum < 2) exitWith {
TRACE_1("lowImpulse",_ammo);
};
private _material = [_surfaceType] call FUNC(getMaterialInfo);
TRACE_1("materialCacheRetrieved",_material);
//** start calculating where the spalling should come !*! could be better **//
private _unitStep = _lVelUnit vectorMultiply 0.05;
private _spallPos = +_lPosASL;
if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith {
TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL);
};
// step through
for "_i" from 1 to 20 do
{
2024-01-09 06:26:43 +00:00
private _nPos = _spallPos vectorAdd _unitStep;
if (!lineIntersects [_spallPos, _nPos]) then {
_spallPos = _nPos vectorAdd _unitStep;
break
};
_spallPos = _nPos;
};
#ifdef DEBUG_MODE_FULL
if GVAR(dbgSphere) then {
[_spallPos, "green"] call FUNC(dev_sphereDraw);
[_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw);
[_lPosASL, "orange"] call FUNC(dev_sphereDraw);
};
#endif
2024-01-09 06:26:43 +00:00
//***** Passed all other exit withs, performance o'clock */
2024-01-09 06:26:43 +00:00
GVAR(lastSpallTime) = CBA_missionTime;
2024-01-09 06:26:43 +00:00
//***** Select spalled fragment spawner **//
private _fragSpawnType = switch (true) do
{
case (_deltaMomentum < 3): { QGVAR(spall_tiny) };
case (_deltaMomentum < 5): { QGVAR(spall_small) };
case (_deltaMomentum < 8): { QGVAR(spall_medium) };
case (_deltaMomentum < 11): { QGVAR(spall_large) };
default { QGVAR(spall_huge) };
};
//***** Spawn spalled fragments
2024-01-08 21:38:26 +00:00
private _spallSpawner = createVehicleLocal [_fragSpawnType, ASLToATL _spallPos, [], 0, "CAN_COLLIDE"];
_spallSpawner setVectorDirandUp [_lVelUnit, _vUp];
2024-01-09 06:26:43 +00:00
_spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2));
_spallSpawner setShotParents _shotParents;
#ifdef DEBUG_MODE_FULL
2024-01-08 21:38:26 +00:00
systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _deltaMomentum);
_spallSpawner addEventHandler [
"SubmunitionCreated",
{
params ["", "_subProj"];
[_subProj] call FUNC(dev_addRound);
}
];
#endif