Made variable names more verbose and added trailing newlines

This commit is contained in:
lambdatiger 2024-01-15 13:42:45 -06:00
parent b2c0f5720d
commit eeb08c3f05
8 changed files with 114 additions and 111 deletions

View File

@ -10,8 +10,8 @@
#ifdef DEBUG_MODE_DRAW
if (hasInterface) then {
private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler;
missionNamespace setVariable [QGVAR(dev_drawPFEH), _h];
private _handle = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler;
missionNamespace setVariable [QGVAR(dev_drawPFEH), _handle];
["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler;
[objNull, ace_player] call FUNC(dev_switchUnitHandle);
};

View File

@ -15,15 +15,15 @@
* Public: No
*/
params ["_proj"];
params ["_projectile"];
TRACE_1("addBlackList",_round);
switch (typeName _proj) do {
switch (typeName _projectile) do {
case "OBJECT": {
GVAR(shouldFragCache) set [typeOf _proj, false];
GVAR(shouldFragCache) set [typeOf _projectile, false];
};
case "STRING": {
GVAR(shouldFragCache) set [_proj, false];
GVAR(shouldFragCache) set [_projectile, false];
};
default { };
};
};

View File

@ -15,15 +15,15 @@
* None
*
* Example:
* [[_proj, getPosASL _proj, velocity _proj]] call ace_frag_fnc_doFrag;
* [_projectile, getPosASL _projectile, velocity _projectile, typeOf _projectile, getShotParents _projectile] call ace_frag_fnc_doFrag;
*
* Public: No
*/
TRACE_1("begin doFrag",_this);
params [
["_proj", objNull, [objNull]],
"",
["_posASL", [0, 0, 0], [[]], [3]],
["_vel", [0, 0, 0] , [[]], [3]],
["_velocity", [0, 0, 0] , [[]], [3]],
["_ammo", "", [""]],
["_shotParents", [objNull, objNull], [[]]]
];
@ -65,5 +65,5 @@ if (_fragRange > 3 && _timeSince > ACE_FRAG_HOLDOFF*1.5 && GVAR(fragSimComplexit
};
if (_timeSince > 0.2 && {GVAR(fragSimComplexity) > 0}) then {
[_posASL, _vel, _heightAGL, _fragTypes, _maxFrags, _shotParents] call FUNC(doFragRandom);
};
[_posASL, _velocity, _heightAGL, _fragTypes, _maxFrags, _shotParents] call FUNC(doFragRandom);
};

View File

@ -8,28 +8,27 @@
* 0: Position of fragmenting projectile ASL <ARRAY>
* 1: Velocity of the fragmenting projectile <ARRAY>
* 2: Height (AGL) of the fragmenting projectile <SCALAR>
* 3: Type of fragments to generate
* 3: Type of fragments to generate <ARRAY>
* 4: Remaining fragment budget <SCALAR>
* 5: Shot parent <ARRAY>
* 5: Shot parents <ARRAY>
*
* Return Value:
* None
*
* Example:
* [getPosASL _proj, velocity _proj, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom;
* [getPosASL _proj, 800, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom;
*
* Public: No
*/
params [
"_posASL",
["_projVel", [0,0,0]],
["_fragVelocity", [0,0,0]],
["_heightAGL", 2, [123]],
["_fragType", [], [[]]],
["_fragCnt", 10, [123]],
["_shotPrnt", [objNull, objNull], [[]], [2]]
["_shotParents", [objNull, objNull], [[]], [2]]
];
TRACE_5("fnc_doFragRandom", _posASL, _projVel, _heightAGL, _fragType, _fragCnt);
TRACE_5("fnc_doFragRandom", _posASL, _fragVelocity, _heightAGL, _fragType, _fragCnt);
// See cfgAmmoFragSpawner for different frag types
private _hMode = switch (true) do {
@ -54,7 +53,7 @@ _fragCnt = switch (true) do {
// Spawn the fragment spawner
private _fragSpawner = createVehicle [_type + _fragCnt + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"];
_fragSpawner setVectorDirandUp [[0,0,1], [1,0,0]];
_fragSpawner setVelocity _projVel;
_fragSpawner setVelocity _fragVelocity;
_fragSpawner setShotParents _shotParents;
#ifdef DEBUG_MODE_FULL
@ -71,4 +70,4 @@ _fragSpawner addEventHandler [
if (GVAR(dbgSphere)) then {
[_posASL] call FUNC(dev_sphereDraw);
};
#endif
#endif

View File

@ -24,14 +24,14 @@
params [
"_posASL",
["_fragVel", 800, [123]],
["_fragVelocity", 800, [123]],
["_fragRange", 50, [123]],
["_maxFrags", 20, [123]],
["_fragTypes", [], [[]]],
["_modFragCount", 1, [123]],
["_shotPrnt", [objNull, objNull], [[]], [2]]
["_shotParents", [objNull, objNull], [[]], [2]]
];
TRACE_5("fnc_doFragTargeted", _posASL, _fragRange, _maxFrags, _fragTypes, _modFragCount);
TRACE_5("fnc_doFragTargeted",_posASL,_fragRange,_maxFrags,_fragTypes,_modFragCount);
if (_fragTypes isEqualTo []) then {
_fragTypes = [
@ -45,14 +45,14 @@ if (_fragTypes isEqualTo []) then {
private _objects = (ASLToATL _posASL) nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange];
if (_objects isEqualTo []) exitWith {
TRACE_2("No nearby targets", _posASL, _fragRange);
TRACE_2("No nearby targets",_posASL,_fragRange);
0;
};
// grab crews and add them in so that targets stay approx. sorted by distance
{
private _crew = (crew _x);
private _crew = crew _x;
if (count _crew > 1) then {
private _arr = [_x];
{
@ -63,11 +63,11 @@ if (_objects isEqualTo []) exitWith {
};
} forEach _objects;
_objects = flatten _objects;
TRACE_3("Targets found", _posASL, _fragRange, count _objects);
TRACE_3("Targets found",_posASL,_fragRange,count _objects);
// limit number of fragments per direction (2D) to 10 using _fragArcs
private _fragArcs = createHashMap;
private _fragCount = 0;
private _totalFragCount = 0;
{ // Begin of forEach iterating on _objects
if (!alive _x) then {continue};
private _target = _x;
@ -103,16 +103,15 @@ private _fragCount = 0;
// calculate chance to be hit by a fragment
private _fragChance = _crossSectionArea * _modFragCount / _distance^2;
private _count = if (_fragChance > 1) then {
private _fragCount = if (_fragChance > 1) then {
3 min (floor _fragChance);
} else {
[0, 1] select (GVAR(atLeastOne) || {random 1 < _fragChance});
};
if (_count == 0) then {TRACE_2("fragments",_fragChance,_count); continue};
// Approximate offset to hit including speed & gravity
private _locFragVel = _fragVel * (1 - random 0.5);
private _tof = _distance / _locFragVel;
if (_fragCount == 0) then {
TRACE_2("fragments",_fragChance,_fragCount);
continue
};
// handle limiting fragments per degree arc
private _dir = floor (_posASL getDir _target);
@ -120,11 +119,15 @@ private _fragCount = 0;
if (_fragPerArc > 10) then {
continue;
} else {
_fragArcs set [_dir, _fragPerArc + _count];
_fragArcs set [_dir, _fragPerArc + _fragCount];
};
// Approximate offset to hit including speed & gravity
private _locFragVel = _fragVelocity * (1 - random 0.5);
private _timeOfFlight = _distance / _locFragVel;
// target pos for fragment to hit
private _targetPos = (velocity _target vectorMultiply _tof) vectorAdd [0, 0, 9.81 / 2 * _tof ^ 2];
private _targetPos = (velocity _target vectorMultiply _timeOfFlight) vectorAdd [0, 0, ACE_FRAG_HALF_GRAVITY_APPROX * _timeOfFlight ^ 2];
if _isPerson then {
private _hitPoint = selectRandom ACE_FRAG_HITPOINTS;
private _hitPointPos = _target selectionPosition [_hitPoint, "HitPoints", "AveragePoint"];
@ -139,8 +142,8 @@ private _fragCount = 0;
// select a fragment / submunition frag spawner
private _fragSpawner = selectRandom _fragTypes;
if (_count > 1) then {
_fragSpawner = _fragSpawner + "_spawner_" + str _count + (switch (true) do {
if (_fragCount > 1) then {
_fragSpawner = _fragSpawner + "_spawner_" + str _fragCount + (switch (true) do {
case (_distance < 10): {"_short"};
case (_distance < 20): {"_mid"};
default {"_far"};
@ -149,11 +152,11 @@ private _fragCount = 0;
TRACE_4("fragments",_fragSpawner,_fragChance,_distance,_locFragVel);
// Create fragment
private _vecDir = _posASL vectorFromTo _targetPos;
private _vectorDir = _posASL vectorFromTo _targetPos;
private _fragObj = createVehicle [_fragSpawner, ASLtoATL _posASL, [], 0, "CAN_COLLIDE"];
_fragObj setVectorDir _vecDir;
_fragObj setVelocity (_vecDir vectorMultiply _locFragVel);
_fragObj setShotParents _shotPrnt;
_fragObj setVectorDir _vectorDir;
_fragObj setVelocity (_vectorDir vectorMultiply _locFragVel);
_fragObj setShotParents _shotParents;
#ifdef DEBUG_MODE_DRAW
[_fragObj, "purple", true] call FUNC(dev_trackObj);
if (GVAR(dbgSphere)) then {
@ -161,15 +164,15 @@ private _fragCount = 0;
};
#endif
_fragCount = _fragCount + _count;
if (_fragCount >= _maxFrags) then {
TRACE_2("maxFrags", _fragCount, _maxFrags);
_totalFragCount = _totalFragCount + _fragCount;
if (_totalFragCount >= _maxFrags) then {
TRACE_2("maxFrags", _totalFragCount, _maxFrags);
break
};
} forEach _objects;
#ifdef DEBUG_MODE_FULL
systemChat ("fragCount cnt: " + str _fragCount);
TRACE_1("fragCount",_fragCount);
systemChat ("fragCount cnt: " + str _totalFragCount);
TRACE_1("fragCount",_totalFragCount);
#endif
_fragCount
_totalFragCount

View File

@ -18,21 +18,21 @@
TRACE_1("doSpall",_this);
params [
"_projectile",
["_hitObj", objNull],
["_lPosASL", [0, 0, 0]],
["_lVel", [0, 0, 0]],
["_sNorm", [0, 0, 0]],
["_objectHit", objNull],
["_lastPosASL", [0, 0, 0]],
["_lastVelocity", [0, 0, 0]],
["_surfaceNorm", [0, 0, 0]],
["_surfaceType", ""],
["_ammo", "", [""]],
["_shotParents", [objNull, objNull], [[]]],
["_vUp", [0,0,1]]
["_vectorUp", [0,0,1]]
];
if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF ||
_lPosASL isEqualTo [0,0,0] ||
{isNull _hitObj || {_hitObj isKindOf "man" ||
_lastPosASL isEqualTo [0,0,0] ||
{isNull _objectHit || {_objectHit isKindOf "man" ||
{_ammo isEqualTo ""}}}) exitWith {
TRACE_4("time/invldHit",CBA_missionTime,GVAR(lastSpallTime),_hitObj,_lPosASL);
TRACE_4("time/invldHit",CBA_missionTime,GVAR(lastSpallTime),_objectHit,_lastPosASL);
};
private _material = [_surfaceType] call FUNC(getMaterialInfo);
@ -45,21 +45,21 @@ if (_material isEqualTo "ground") then {
// Find spall speed / fragment info
[_ammo] call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"];
private _vel = if (alive _projectile) then {
_explosive = 0; // didn't explode
_explosive = 0; // didn't explode since it's alive a frame later
velocity _projectile
} else {
[0, 0, 0];
};
private _dV = vectorMagnitude _lVel - vectorMagnitude _vel;
private _velocityChange = vectorMagnitude _lastVelocity - vectorMagnitude _vel;
/*
* This is all fudge factor since real spalling is too complex for calculation.
* There are two terms. The first is from round impact, taking a quasi scale
* of sqrt(2)/50 * round caliber * srqt(change in speed). The second term is
* explosive * indirect hit, for any explosive contribution
*/
private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _dV + _explosive * _indirectHit) * GVAR(spallIntensity);
TRACE_3("found speed",_dV,_caliber,_spallPower);
private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _velocityChange + _explosive * _indirectHit) * GVAR(spallIntensity);
TRACE_3("found speed",_velocityChange,_caliber,_spallPower);
if (_spallPower < 2) exitWith {
@ -67,49 +67,49 @@ if (_spallPower < 2) exitWith {
};
private _lVelUnit = vectorNormalized _lVel;
private _unitStep = _lVelUnit vectorMultiply 0.05;
private _lastVelocityUnit = vectorNormalized _lastVelocity;
private _deltaStep = _lastVelocityUnit vectorMultiply 0.05;
if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith {
TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL);
if (terrainIntersectASL [_lastPosASL vectorAdd _deltaStep, _lastPosASL]) exitWith {
TRACE_2("terrainIntersect",_lastPosASL,_deltaStep);
};
#ifdef DEBUG_MODE_DRAW
if GVAR(dbgSphere) then {
[_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw);
[_lPosASL, "yellow"] call FUNC(dev_sphereDraw);
[_lastPosASL vectorAdd _lastVelocityUnit, "orange"] call FUNC(dev_sphereDraw);
[_lastPosASL, "yellow"] call FUNC(dev_sphereDraw);
};
#endif
/*
* Improve performance of finding otherside of object on shallow angle
* impacts. 120 degrees due to 90 degree offset with _lVelUnit into object.
* impacts. 120 degrees due to 90 degree offset with _lastVelocityUnit into object.
*/
private _spallPos = _lPosASL vectorAdd _unitStep;
if (120 > acos ( _lVelUnit vectorDotProduct _sNorm)) then {
_spallPos = _spallPos vectorAdd (_unitStep vectorMultiply 5);
private _spallPosASL = _lastPosASL vectorAdd _deltaStep;
if (120 > acos ( _lastVelocityUnit vectorDotProduct _surfaceNorm)) then {
_spallPosASL = _spallPosASL vectorAdd (_deltaStep vectorMultiply 5);
};
private _insideObject = true;
for "_i" from 2 to 21 do
{
private _nPos = _spallPos vectorAdd _unitStep;
if (!lineIntersects [_spallPos, _nPos]) then {
_spallPos = _nPos vectorAdd (_unitStep vectorMultiply 2);
private _nPos = _spallPosASL vectorAdd _deltaStep;
if (!lineIntersects [_spallPosASL, _nPos]) then {
_spallPosASL = _nPos vectorAdd (_deltaStep vectorMultiply 2);
_insideObject = false;
break
};
_spallPos = _nPos;
_spallPosASL = _nPos;
};
if (_insideObject) exitWith {
TRACE_3("insideObj",_lPosASL,_spallPos,alive _projectile);
TRACE_3("insideObj",_lastPosASL,_spallPosASL,alive _projectile);
};
// Passed all exitWiths
GVAR(lastSpallTime) = CBA_missionTime;
#ifdef DEBUG_MODE_DRAW
if GVAR(dbgSphere) then {
[_spallPos, "green"] call FUNC(dev_sphereDraw);
[_spallPosASL, "green"] call FUNC(dev_sphereDraw);
};
#endif
@ -124,17 +124,17 @@ private _spawnSize = switch (true) do
private _spallSpawner = createVehicle [
"ace_frag_" + _material + _spawnSize,
ASLToATL _spallPos,
ASLToATL _spallPosASL,
[],
0,
"CAN_COLLIDE"
];
_spallSpawner setVectorDirandUp [_lVelUnit, _vUp];
_spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2));
_spallSpawner setVectorDirandUp [_lastVelocityUnit, _vectorUp];
_spallSpawner setVelocity (_lastVelocityUnit vectorMultiply (_velocityChange/ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF));
_spallSpawner setShotParents _shotParents;
#ifdef DEBUG_MODE_FULL
systemChat ("bSpd: " + str speed _spallSpawner + ", frag: " + _fragSpawnType + ", dm: " + str _spallPower);
systemChat ("spd: " + str speed _spallSpawner + ", spawner: " + _fragSpawnType + ", spallPow: " + str _spallPower);
#endif
#ifdef DEBUG_MODE_DRAW
_spallSpawner addEventHandler [
@ -144,4 +144,4 @@ _spallSpawner addEventHandler [
[_subProj] call FUNC(dev_addRound);
}
];
#endif
#endif

View File

@ -9,11 +9,11 @@
*
* Return Value:
* _ammoInfo <ARRAY>
* 0: _fragRange - search range for fragments
* 1: _fragVel - gurney equation calculated velocity
* 2: _fragTypes - array of fragment types
* 0: _fragRange - search range for fragments <SCALAR>
* 1: _fragVel - gurney equation calculated velocity <SCALAR>
* 2: _fragTypes - array of fragment types <ARRAY>
* 3: _fragCount - modified frag count used under assumptions
* of spherical fragmentation
* of spherical fragmentation <SCALAR>
*
* Example:
* ["B_556x45_Ball"] call ace_frag_fnc_getFragInfo;
@ -38,31 +38,31 @@ if (isArray (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CLASSES))) then {
/************ Gurney equation notes *****************//*
* see https://en.wikipedia.org/wiki/Gurney_equations
*
* GURNEY_K is the constant added to _m/_c
* GURNEY_K is the geometry constant added to _metalMass/_chargeMass
* GURNEY_C = sqrt(2E)
*
* _c = 185; - grams of comp-b
* _m = 210; - grams of fragmentating metal
* _k = 3/5; - spherical K factor
* _gC = 2843; - Gurney constant of comp-b in /ms
* _chargeMass = 185; - grams of comp-b
* _metalMass = 210; - grams of fragmentating metal
* _geometryCoefficient = 3/5; - spherical K factor
* _gurneyConstant = 2843; - Gurney constant of comp-b in /ms
*
* _c = 429; - grams of tritonal
* _m = 496; - grams of fragmentating metal
* _k = 1/2; - cylindrical K factor
* _gC = 2320; - Gurney constant of tritonal in m/s
* _chargeMass = 429; - grams of tritonal
* _metalMass = 496; - grams of fragmentating metal
* _geometryCoefficient = 1/2; - cylindrical K factor
* _gurneyConstant = 2320; - Gurney constant of tritonal in m/s
* Equation - 0.8 for empirical 80% speed
* 0.8 * (((_m / _c) + _k) ^ - (1 / 2)) * _gC;
* or 0.8 * _gC * sqrt (_c /(_m + _c * _k)); (slightly faster to compute)
* 0.8 * (((_metalMass / _chargeMass) + _geometryCoefficient) ^ - (1 / 2)) * _gurneyConstant;
* or 0.8 * _gurneyConstant * sqrt (_chargeMass /(_metalMass + _chargeMass * _geometryCoefficient)); (slightly faster to compute)
*/
private _c = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE));
if (_c == 0) then {_c = 1; _warn = true;};
private _m = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(METAL));
if (_m == 0) then {_m = 2; _warn = true;};
private _k = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_K));
if (_k == 0) then {_k = 0.8; _warn = true;};
private _gC = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_C));
if (_gC == 0) then {_gC = 2440; _warn = true;};
private _chargeMass = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(CHARGE));
if (_chargeMass == 0) then {_chargeMass = 1; _warn = true;};
private _metalMass = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(METAL));
if (_metalMass == 0) then {_metalMass = 2; _warn = true;};
private _geometryCoefficient = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_K));
if (_geometryCoefficient == 0) then {_geometryCoefficient = 0.8; _warn = true;};
private _gurneyConstant = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(GURNEY_C));
if (_gurneyConstant == 0) then {_gurneyConstant = 2440; _warn = true;};
private _fragCount = getNumber (configFile >> "cfgAmmo" >> _ammo >> QGVAR(fragCount));
if (_fragCount == 0) then {_fragCount = 400; _warn = true;};
@ -79,11 +79,11 @@ if (_warn) then {
* of spherical fragmentation
*/
_ammoInfo = [
sqrt (_fragCount / (4 * pi * 0.005)),
0.8 * _gC * sqrt (_c / (_m + _c * _k)),
sqrt (_fragCount / (4 * pi * ACE_FRAG_MIN_FRAG_HIT_CHANCE)),
0.8 * _gurneyConstant * sqrt (_chargeMass / (_metalMass + _chargeMass * _geometryCoefficient)),
_fragTypes,
_fragCount / 4 / pi
];
GVAR(fragInfoCache) set [_ammo, _ammoInfo];
_ammoInfo
_ammoInfo

View File

@ -27,7 +27,8 @@
#define ACE_FRAG_HITPOINTS_WEIGHTS
// sqrt(2)/50
#define ACE_FRAG_ROUND_COEF 0.02828427
#ifndef GLUE
#define GLUE(g1,g2) g1##g2
#endif
// half of gravity approx 9.81/2
#define ACE_FRAG_HALF_GRAVITY_APPROX 4.905
// stop searching at 0.5% chance to hit
#define ACE_FRAG_MIN_FRAG_HIT_CHANCE 0.005
#define ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF 2