diff --git a/addons/frag/functions/fnc_doFrag.sqf b/addons/frag/functions/fnc_doFrag.sqf index 5476533b9c..4898c75113 100644 --- a/addons/frag/functions/fnc_doFrag.sqf +++ b/addons/frag/functions/fnc_doFrag.sqf @@ -19,6 +19,7 @@ */ #define ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM 3 +#define ACE_FRAG_NEGATIVE_AGL_OFFSET 0.1 params ["_posASL", "_projectileVelocity", "_ammo", "_shotParents"]; TRACE_4("doFrag",_posASL,_projectileVelocity,_ammo,_shotParents); @@ -47,11 +48,18 @@ if (_modFragCount < ACE_FRAG_LOW_FRAG_MOD_COUNT) then { GVAR(lastFragTime) = CBA_missionTime; }; +// Double check if round is below, or too close to terrain for +private _posAGL = ASLToAGL _posASL; +if (_posAGL#2 < ACE_FRAG_NEGATIVE_AGL_OFFSET) then { + TRACE_1("below 0 AGL",_posAGL); + _posAGL set [2, ACE_FRAG_NEGATIVE_AGL_OFFSET]; +}; + TRACE_3("doFrag choices",_maxFragCount,_fragRange,GVAR(fragSimComplexity)); if (GVAR(fragSimComplexity) != 1 && _fragRange > 3) then { - _maxFragCount = _maxFragCount - ([_posASL, _fragVelocity, _fragRange, _maxFragCount, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); + _maxFragCount = _maxFragCount - ([_posAGL, _fragVelocity, _fragRange, _maxFragCount, _fragTypes, _modFragCount, _shotParents] call FUNC(doFragTargeted)); }; if (GVAR(fragSimComplexity) > 0 && _maxFragCount >= ACE_FRAG_MIN_FRAG_BUDGET_FOR_RANDOM) then { - [_posASL, _fragVelocity, _projectileVelocity, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); + [_posAGL, _fragVelocity, _projectileVelocity, _fragTypes, _maxFragCount, _shotParents] call FUNC(doFragRandom); }; diff --git a/addons/frag/functions/fnc_doFragRandom.sqf b/addons/frag/functions/fnc_doFragRandom.sqf index 41d4dde814..c0f2c355af 100644 --- a/addons/frag/functions/fnc_doFragRandom.sqf +++ b/addons/frag/functions/fnc_doFragRandom.sqf @@ -5,7 +5,7 @@ * This function will spawn 5, 10, or 15 fragments. * * Arguments: - * 0: Position (posASL) of fragmenting projectile + * 0: Position (posAGL) of fragmenting projectile * 1: Initial fragment velocity from Gurney equation * 2: Velocity of the fragmenting projectile * 3: Type of fragments to generate @@ -16,19 +16,19 @@ * None * * Example: - * [getPosASL _projectile, 800, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom + * [ASLtoAGL (getPosASL _projectile), 800, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragRandom * * Public: No */ -params ["_posASL", "_fragVelocity", "_projectileVelocity", "_fragType", "_maxFragCount", "_shotParents"]; -TRACE_6("doFragRandom",_posASL,_fragVelocity,_projectileVelocity,_fragType,_maxFragCount,_shotParents); +params ["_posAGL", "_fragVelocity", "_projectileVelocity", "_fragType", "_maxFragCount", "_shotParents"]; +TRACE_6("doFragRandom",_posAGL,_fragVelocity,_projectileVelocity,_fragType,_maxFragCount,_shotParents); // See CfgAmmoFragSpawner for different frag types -private _heightATL = (ASLToATL _posASL)#2; +private _heightAGL = _posAGL#2; private _hMode = switch (true) do { - case (_heightATL > 10): {"_top"}; - case (_heightATL > 4): {"_high"}; + case (_heightAGL > 10): {"_top"}; + case (_heightAGL > 4): {"_high"}; default {"_mid"}; }; @@ -41,10 +41,10 @@ _maxFragCount = switch (true) do { }; // Spawn the fragment spawner -private _fragSpawner = createVehicle [_type + _maxFragCount + _hMode, ASLToAGL _posASL, [], 0, "CAN_COLLIDE"]; +private _fragSpawner = createVehicle [_type + _maxFragCount + _hMode, _posAGL, [], 0, "CAN_COLLIDE"]; private _randDir = random 360; -_fragSpawner setVectorDirandUp [[0,0,-1], [cos _randDir, sin _randDir,0]]; -_fragSpawner setVelocity (_projectileVelocity vectorAdd [0, 0, -0.5*_fragVelocity]); +_fragSpawner setVectorDirandUp [[0,0,-1], [cos _randDir, sin _randDir, 0]]; +_fragSpawner setVelocity (_projectileVelocity vectorAdd [0, 0, -_fragVelocity]); _fragSpawner setShotParents _shotParents; TRACE_2("spawnedRandomFragmenter",typeOf _fragSpawner,getObjectID _fragSpawner); @@ -57,6 +57,6 @@ _fragSpawner addEventHandler [ } ]; if (GVAR(dbgSphere)) then { - [_posASL] call FUNC(dev_sphereDraw); + [AGLtoASL _posAGL] call FUNC(dev_sphereDraw); }; #endif diff --git a/addons/frag/functions/fnc_doFragTargeted.sqf b/addons/frag/functions/fnc_doFragTargeted.sqf index e148e38936..83b4cfbe2a 100644 --- a/addons/frag/functions/fnc_doFragTargeted.sqf +++ b/addons/frag/functions/fnc_doFragTargeted.sqf @@ -4,7 +4,7 @@ * This function creates fragments targeted at specific entities, up to _maxFrags. * * Arguments: - * 0: Position of fragmenting projectile ASL + * 0: Position of fragmenting projectile AGL * 1: Velocity of the fragmenting projectile * 2: Maximum range of fragments to calculate * 3: Maximum number of fragments to produce @@ -16,7 +16,7 @@ * Number of fragments created * * Example: - * [getPosASL _projectile, velocity _projectile, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragTargeted + * [ASLtoAGL (getPosASL _projectile), velocity _projectile, 50, 50, [], 1, [player, player]] call ace_frag_fnc_doFragTargeted * * Public: No */ @@ -25,8 +25,8 @@ #define ACE_FRAG_DEFAULT_CROSS_AREA 0.75 #define ACE_FRAG_MIN_TARGET_AREA 0.5 -params [ "_posASL", "_fragVelocity", "_fragRange", "_maxFrags", "_fragTypes", "_modFragCount", "_shotParents"]; -TRACE_5("fnc_doFragTargeted",_posASL,_fragRange,_maxFrags,_fragTypes,_modFragCount); +params [ "_posAGL", "_fragVelocity", "_fragRange", "_maxFrags", "_fragTypes", "_modFragCount", "_shotParents"]; +TRACE_5("fnc_doFragTargeted",_posAGL,_fragRange,_maxFrags,_fragTypes,_modFragCount); if (_fragTypes isEqualTo []) then { _fragTypes = [ @@ -38,12 +38,11 @@ if (_fragTypes isEqualTo []) then { ]; }; -private _posAGL = ASLToAGL _posASL; // Post 2.18 change - uncomment line 41, and remove lines 43, 50-55, 64-66 -// private _targets = [ASLToAGL _posASL, _fragRange, _fragRange, 0, false, _fragRange] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; +// private _targets = [_posAGL, _fragRange, _fragRange, 0, false, _fragRange] nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], false, true, true]; private _objects = _posAGL 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",_posAGL,_fragRange); 0 }; @@ -55,7 +54,7 @@ private _targets = []; _targets append _crew; } forEach _objects; -TRACE_3("Targets found",_posASL,_fragRange,count _targets); +TRACE_3("Targets found",_posAGL,_fragRange,count _targets); // limit number of fragments per direction (2D) to _fragsPerFragArc using _fragArcs private _fragArcs = createHashMap; @@ -99,7 +98,7 @@ private _totalFragCount = 0; _height = _dims#2; }; - private _distance = _target distance _posASL; + private _distance = _target distance _posAGL; // calculate chance to be hit by a fragment private _fragChance = _crossSectionArea * _modFragCount / _distance^2; @@ -114,7 +113,7 @@ private _totalFragCount = 0; }; // handle limiting fragments per degree arc - private _dir = floor (_posASL getDir _target); + private _dir = floor (_posAGL getDir _target); private _fragPerArc = _fragArcs getOrDefault [_dir, 0]; if (_fragPerArc > _fragsPerFragArc) then { continue; @@ -131,13 +130,13 @@ private _totalFragCount = 0; _targetPos = if (_isPerson) then { private _hitPoint = selectRandom ACE_FRAG_HITPOINTS; private _hitPointPos = _target selectionPosition [_hitPoint, "HitPoints", "AveragePoint"]; - _target modelToWorldWorld _hitPointPos vectorAdd _targetPos; + _target modelToWorld _hitPointPos vectorAdd _targetPos; } else { - _targetPos vectorAdd getPosASL _target vectorAdd [ + ASLtoAGL (_targetPos vectorAdd getPosASL _target vectorAdd [ -0.5 + random 1, -0.5 + random 1, (0.1 + random 0.4) * _height - ]; + ]); }; // select a fragment / submunition frag spawner @@ -152,15 +151,22 @@ private _totalFragCount = 0; TRACE_4("fragments",_fragSpawner,_fragChance,_distance,_locFragVel); // Create fragment - private _vectorDir = _posASL vectorFromTo _targetPos; + private _vectorDir = _posAGL vectorFromTo _targetPos; private _fragObj = createVehicle [_fragSpawner, _posAGL, [], 0, "CAN_COLLIDE"]; - _fragObj setVectorDir _vectorDir; + _fragObj setVectorDirAndUp [_vectorDir, _vectorDir vectorAdd [0, -1, 0]] ; _fragObj setVelocity (_vectorDir vectorMultiply _locFragVel); _fragObj setShotParents _shotParents; #ifdef DEBUG_MODE_DRAW [_fragObj, "purple", true] call FUNC(dev_trackObj); + _fragObj addEventHandler [ + "SubmunitionCreated", + { + params ["","_subProj"]; + [_subProj, "purple", true] call FUNC(dev_trackObj); + } + ]; if (GVAR(dbgSphere)) then { - [_targetPos, "orange"] call FUNC(dev_sphereDraw); + [AGLtoASL _targetPos, "orange"] call FUNC(dev_sphereDraw); }; #endif