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 #ifdef DEBUG_MODE_DRAW
if (hasInterface) then { if (hasInterface) then {
private _h = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler; private _handle = [LINKFUNC(dev_drawTrace), 0] call CBA_fnc_addPerFrameHandler;
missionNamespace setVariable [QGVAR(dev_drawPFEH), _h]; missionNamespace setVariable [QGVAR(dev_drawPFEH), _handle];
["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler; ["unit", LINKFUNC(dev_switchUnitHandle), true] call CBA_fnc_addPlayerEventHandler;
[objNull, ace_player] call FUNC(dev_switchUnitHandle); [objNull, ace_player] call FUNC(dev_switchUnitHandle);
}; };

View File

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

View File

@ -15,15 +15,15 @@
* None * None
* *
* Example: * 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 * Public: No
*/ */
TRACE_1("begin doFrag",_this); TRACE_1("begin doFrag",_this);
params [ params [
["_proj", objNull, [objNull]], "",
["_posASL", [0, 0, 0], [[]], [3]], ["_posASL", [0, 0, 0], [[]], [3]],
["_vel", [0, 0, 0] , [[]], [3]], ["_velocity", [0, 0, 0] , [[]], [3]],
["_ammo", "", [""]], ["_ammo", "", [""]],
["_shotParents", [objNull, objNull], [[]]] ["_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 { 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> * 0: Position of fragmenting projectile ASL <ARRAY>
* 1: Velocity of the fragmenting projectile <ARRAY> * 1: Velocity of the fragmenting projectile <ARRAY>
* 2: Height (AGL) of the fragmenting projectile <SCALAR> * 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> * 4: Remaining fragment budget <SCALAR>
* 5: Shot parent <ARRAY> * 5: Shot parents <ARRAY>
* *
* Return Value: * Return Value:
* None * None
* *
* Example: * 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 * Public: No
*/ */
params [ params [
"_posASL", "_posASL",
["_projVel", [0,0,0]], ["_fragVelocity", [0,0,0]],
["_heightAGL", 2, [123]], ["_heightAGL", 2, [123]],
["_fragType", [], [[]]], ["_fragType", [], [[]]],
["_fragCnt", 10, [123]], ["_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 // See cfgAmmoFragSpawner for different frag types
private _hMode = switch (true) do { private _hMode = switch (true) do {
@ -54,7 +53,7 @@ _fragCnt = switch (true) do {
// Spawn the fragment spawner // Spawn the fragment spawner
private _fragSpawner = createVehicle [_type + _fragCnt + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"]; private _fragSpawner = createVehicle [_type + _fragCnt + _hMode, ASLToATL _posASL, [], 0, "CAN_COLLIDE"];
_fragSpawner setVectorDirandUp [[0,0,1], [1,0,0]]; _fragSpawner setVectorDirandUp [[0,0,1], [1,0,0]];
_fragSpawner setVelocity _projVel; _fragSpawner setVelocity _fragVelocity;
_fragSpawner setShotParents _shotParents; _fragSpawner setShotParents _shotParents;
#ifdef DEBUG_MODE_FULL #ifdef DEBUG_MODE_FULL
@ -71,4 +70,4 @@ _fragSpawner addEventHandler [
if (GVAR(dbgSphere)) then { if (GVAR(dbgSphere)) then {
[_posASL] call FUNC(dev_sphereDraw); [_posASL] call FUNC(dev_sphereDraw);
}; };
#endif #endif

View File

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

View File

@ -18,21 +18,21 @@
TRACE_1("doSpall",_this); TRACE_1("doSpall",_this);
params [ params [
"_projectile", "_projectile",
["_hitObj", objNull], ["_objectHit", objNull],
["_lPosASL", [0, 0, 0]], ["_lastPosASL", [0, 0, 0]],
["_lVel", [0, 0, 0]], ["_lastVelocity", [0, 0, 0]],
["_sNorm", [0, 0, 0]], ["_surfaceNorm", [0, 0, 0]],
["_surfaceType", ""], ["_surfaceType", ""],
["_ammo", "", [""]], ["_ammo", "", [""]],
["_shotParents", [objNull, objNull], [[]]], ["_shotParents", [objNull, objNull], [[]]],
["_vUp", [0,0,1]] ["_vectorUp", [0,0,1]]
]; ];
if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF || if (CBA_missionTime - GVAR(lastSpallTime) < ACE_FRAG_SPALL_HOLDOFF ||
_lPosASL isEqualTo [0,0,0] || _lastPosASL isEqualTo [0,0,0] ||
{isNull _hitObj || {_hitObj isKindOf "man" || {isNull _objectHit || {_objectHit isKindOf "man" ||
{_ammo isEqualTo ""}}}) exitWith { {_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); private _material = [_surfaceType] call FUNC(getMaterialInfo);
@ -45,21 +45,21 @@ if (_material isEqualTo "ground") then {
// Find spall speed / fragment info // Find spall speed / fragment info
[_ammo] call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"]; [_ammo] call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"];
private _vel = if (alive _projectile) then { 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 velocity _projectile
} else { } else {
[0, 0, 0]; [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. * 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 * 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 * of sqrt(2)/50 * round caliber * srqt(change in speed). The second term is
* explosive * indirect hit, for any explosive contribution * explosive * indirect hit, for any explosive contribution
*/ */
private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _dV + _explosive * _indirectHit) * GVAR(spallIntensity); private _spallPower = (ACE_FRAG_ROUND_COEF * _caliber * sqrt _velocityChange + _explosive * _indirectHit) * GVAR(spallIntensity);
TRACE_3("found speed",_dV,_caliber,_spallPower); TRACE_3("found speed",_velocityChange,_caliber,_spallPower);
if (_spallPower < 2) exitWith { if (_spallPower < 2) exitWith {
@ -67,49 +67,49 @@ if (_spallPower < 2) exitWith {
}; };
private _lVelUnit = vectorNormalized _lVel; private _lastVelocityUnit = vectorNormalized _lastVelocity;
private _unitStep = _lVelUnit vectorMultiply 0.05; private _deltaStep = _lastVelocityUnit vectorMultiply 0.05;
if (terrainIntersectASL [_lPosASL vectorAdd _unitStep, _lPosASL]) exitWith { if (terrainIntersectASL [_lastPosASL vectorAdd _deltaStep, _lastPosASL]) exitWith {
TRACE_3("terrainIntersect",_lPosASL,_unitStep,_lPosASL); TRACE_2("terrainIntersect",_lastPosASL,_deltaStep);
}; };
#ifdef DEBUG_MODE_DRAW #ifdef DEBUG_MODE_DRAW
if GVAR(dbgSphere) then { if GVAR(dbgSphere) then {
[_lPosASL vectorAdd _lVelUnit, "orange"] call FUNC(dev_sphereDraw); [_lastPosASL vectorAdd _lastVelocityUnit, "orange"] call FUNC(dev_sphereDraw);
[_lPosASL, "yellow"] call FUNC(dev_sphereDraw); [_lastPosASL, "yellow"] call FUNC(dev_sphereDraw);
}; };
#endif #endif
/* /*
* Improve performance of finding otherside of object on shallow angle * 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; private _spallPosASL = _lastPosASL vectorAdd _deltaStep;
if (120 > acos ( _lVelUnit vectorDotProduct _sNorm)) then { if (120 > acos ( _lastVelocityUnit vectorDotProduct _surfaceNorm)) then {
_spallPos = _spallPos vectorAdd (_unitStep vectorMultiply 5); _spallPosASL = _spallPosASL vectorAdd (_deltaStep vectorMultiply 5);
}; };
private _insideObject = true; private _insideObject = true;
for "_i" from 2 to 21 do for "_i" from 2 to 21 do
{ {
private _nPos = _spallPos vectorAdd _unitStep; private _nPos = _spallPosASL vectorAdd _deltaStep;
if (!lineIntersects [_spallPos, _nPos]) then { if (!lineIntersects [_spallPosASL, _nPos]) then {
_spallPos = _nPos vectorAdd (_unitStep vectorMultiply 2); _spallPosASL = _nPos vectorAdd (_deltaStep vectorMultiply 2);
_insideObject = false; _insideObject = false;
break break
}; };
_spallPos = _nPos; _spallPosASL = _nPos;
}; };
if (_insideObject) exitWith { if (_insideObject) exitWith {
TRACE_3("insideObj",_lPosASL,_spallPos,alive _projectile); TRACE_3("insideObj",_lastPosASL,_spallPosASL,alive _projectile);
}; };
// Passed all exitWiths // Passed all exitWiths
GVAR(lastSpallTime) = CBA_missionTime; GVAR(lastSpallTime) = CBA_missionTime;
#ifdef DEBUG_MODE_DRAW #ifdef DEBUG_MODE_DRAW
if GVAR(dbgSphere) then { if GVAR(dbgSphere) then {
[_spallPos, "green"] call FUNC(dev_sphereDraw); [_spallPosASL, "green"] call FUNC(dev_sphereDraw);
}; };
#endif #endif
@ -124,17 +124,17 @@ private _spawnSize = switch (true) do
private _spallSpawner = createVehicle [ private _spallSpawner = createVehicle [
"ace_frag_" + _material + _spawnSize, "ace_frag_" + _material + _spawnSize,
ASLToATL _spallPos, ASLToATL _spallPosASL,
[], [],
0, 0,
"CAN_COLLIDE" "CAN_COLLIDE"
]; ];
_spallSpawner setVectorDirandUp [_lVelUnit, _vUp]; _spallSpawner setVectorDirandUp [_lastVelocityUnit, _vectorUp];
_spallSpawner setVelocity (_lVelUnit vectorMultiply (_dV/2)); _spallSpawner setVelocity (_lastVelocityUnit vectorMultiply (_velocityChange/ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF));
_spallSpawner setShotParents _shotParents; _spallSpawner setShotParents _shotParents;
#ifdef DEBUG_MODE_FULL #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 #endif
#ifdef DEBUG_MODE_DRAW #ifdef DEBUG_MODE_DRAW
_spallSpawner addEventHandler [ _spallSpawner addEventHandler [
@ -144,4 +144,4 @@ _spallSpawner addEventHandler [
[_subProj] call FUNC(dev_addRound); [_subProj] call FUNC(dev_addRound);
} }
]; ];
#endif #endif

View File

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

View File

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