mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Initial commit
This commit is contained in:
parent
82d9044a9a
commit
182ebc027b
@ -1,15 +1,158 @@
|
||||
class GVAR(spall_small): GVAR(small) {
|
||||
timeToLive = 0.1;
|
||||
class GVAR(spallBase): B_65x39_Caseless {
|
||||
GVAR(skip) = 1;
|
||||
submunitionAmmo[] = {QGVAR(small),4,QGVAR(medium),3,QGVAR(large),2,QGVAR(huge),1};
|
||||
submunitionConeType[] = {"random", 20};
|
||||
submunitionConeAngle = 40;
|
||||
submunitionDirectionType = "SubmunitionModelDirection";
|
||||
triggerTime = 0;
|
||||
submunitionInitialOffset[] = {0,0,0};
|
||||
submunitionInitSpeed = 0;
|
||||
triggerSpeedCoef[] = {0.75,1.25};
|
||||
deleteParentWhenTriggered = 1;
|
||||
submunitionParentSpeedCoef = 1;
|
||||
};
|
||||
|
||||
class GVAR(spall_medium): GVAR(medium) {
|
||||
timeToLive = 0.15;
|
||||
|
||||
/*
|
||||
* ground
|
||||
*/
|
||||
class GVAR(ground_spall_tiny): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 9, QGVAR(small), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 4};
|
||||
};
|
||||
|
||||
class GVAR(spall_large): GVAR(large) {
|
||||
timeToLive = 0.25;
|
||||
class GVAR(ground_spall_small): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(small), 4,QGVAR(medium), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 6};
|
||||
};
|
||||
|
||||
class GVAR(spall_huge): GVAR(huge) {
|
||||
timeToLive = 0.3;
|
||||
class GVAR(ground_spall_medium): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(small), 2, QGVAR(small_HD), 1,QGVAR(medium), 3, QGVAR(medium_HD), 1, QGVAR(large), 2};
|
||||
submunitionConeType[] = {"poissondisccenter", 15};
|
||||
};
|
||||
|
||||
class GVAR(ground_spall_large): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium_HD), 5, QGVAR(large), 1, QGVAR(large_HD), 2};
|
||||
submunitionConeType[] = {"poissondisccenter", 15};
|
||||
};
|
||||
|
||||
class GVAR(ground_spall_huge): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 3, QGVAR(tiny_HD), 3, QGVAR(small), 4, QGVAR(small_HD), 4, QGVAR(medium), 5, QGVAR(large), 1, QGVAR(large_HD), 2};
|
||||
submunitionConeType[] = {"poissondisccenter", 20};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* rock
|
||||
*/
|
||||
class GVAR(rock_spall_tiny): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium_HD), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 4};
|
||||
};
|
||||
|
||||
class GVAR(rock_spall_small): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 5};
|
||||
};
|
||||
|
||||
class GVAR(rock_spall_medium): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(small), 4, QGVAR(medium), 1, QGVAR(medium_HD), 2, QGVAR(large_HD), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 7};
|
||||
};
|
||||
|
||||
class GVAR(rock_spall_large): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(small), 5, QGVAR(medium), 2, QGVAR(large), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 10};
|
||||
};
|
||||
|
||||
class GVAR(rock_spall_huge): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(small), 5, QGVAR(medium), 2, QGVAR(large), 1, QGVAR(huge_HD), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 13};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* wood
|
||||
*/
|
||||
class GVAR(wood_spall_tiny): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 4};
|
||||
submunitionConeType[] = {"poissondisccenter", 4};
|
||||
};
|
||||
|
||||
class GVAR(wood_spall_small): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 4, QGVAR(medium), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 6};
|
||||
};
|
||||
|
||||
class GVAR(wood_spall_medium): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 2, QGVAR(small), 2, QGVAR(medium), 2, QGVAR(medium_HD), 1, QGVAR(large_HD), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 8};
|
||||
};
|
||||
|
||||
class GVAR(wood_spall_large): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 1, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large_HD), 2, QGVAR(huge_HD), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 10};
|
||||
};
|
||||
|
||||
class GVAR(wood_spall_huge): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 1, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large_HD), 2, QGVAR(huge_HD), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 12};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* concrete
|
||||
*/
|
||||
class GVAR(concrete_spall_tiny): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(tiny_HD), 3, QGVAR(small), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 4};
|
||||
};
|
||||
|
||||
class GVAR(concrete_spall_small): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(tiny_HD), 2, QGVAR(small), 2, QGVAR(medium), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 6};
|
||||
};
|
||||
|
||||
class GVAR(concrete_spall_medium): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(tiny_HD), 1, QGVAR(small), 4, QGVAR(medium), 5, QGVAR(large_HD), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 9};
|
||||
};
|
||||
|
||||
class GVAR(concrete_spall_large): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 6, QGVAR(small), 4, QGVAR(medium), 3, QGVAR(large), 1, QGVAR(large_HD), 2};
|
||||
submunitionConeType[] = {"poissondisccenter", 12};
|
||||
};
|
||||
|
||||
class GVAR(concrete_spall_huge): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 8, QGVAR(small), 4, QGVAR(medium), 3, QGVAR(large), 1, QGVAR(large_HD), 1, QGVAR(huge_HD), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 18};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* metal
|
||||
*/
|
||||
class GVAR(metal_spall_tiny): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 9, QGVAR(small), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 4};
|
||||
};
|
||||
|
||||
class GVAR(metal_spall_small): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(small), 2, QGVAR(medium), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 6};
|
||||
};
|
||||
|
||||
class GVAR(metal_spall_medium): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 5, QGVAR(small), 4, QGVAR(medium), 2, QGVAR(large), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 8};
|
||||
};
|
||||
|
||||
class GVAR(metal_spall_large): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 4, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large), 1, QGVAR(huge), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 12};
|
||||
};
|
||||
|
||||
class GVAR(metal_spall_huge): GVAR(spallBase) {
|
||||
submunitionAmmo[] = {QGVAR(tiny), 8, QGVAR(small), 3, QGVAR(medium), 2, QGVAR(large), 3, QGVAR(huge), 1};
|
||||
submunitionConeType[] = {"poissondisccenter", 18};
|
||||
};
|
||||
|
@ -9,11 +9,15 @@ PREP(dev_trackHitBox);
|
||||
PREP(dev_trackObj);
|
||||
PREP(doExplosions);
|
||||
PREP(doReflections);
|
||||
PREP(doSpall);
|
||||
PREP(doSpallHitPart);
|
||||
PREP(doSpallPenetrate);
|
||||
PREP(findReflections);
|
||||
PREP(fired);
|
||||
PREP(frago);
|
||||
PREP(getFragInfo);
|
||||
PREP(getMaterialInfo);
|
||||
PREP(getSpallInfo);
|
||||
PREP(getSpallInfo);
|
||||
PREP(initMaterialCache);
|
||||
PREP(shouldFrag);
|
||||
PREP(shouldSpall);
|
||||
|
@ -6,8 +6,10 @@ PREP_RECOMPILE_START;
|
||||
#include "XEH_PREP.hpp"
|
||||
PREP_RECOMPILE_END;
|
||||
|
||||
call FUNC(initMaterialCache);
|
||||
GVAR(spallInfoCache) = createHashMap;
|
||||
GVAR(shouldSpallCache) = createHashMap;
|
||||
GVAR(nextSpallAllowTime) = -1;
|
||||
|
||||
GVAR(shouldFragCache) = createHashMap;
|
||||
GVAR(fragInfoCache) = createHashMap;
|
||||
|
@ -19,11 +19,10 @@ params ["_projectile"];
|
||||
TRACE_2("addBlackList",_projectile,typeOf projectile);
|
||||
|
||||
_projectile setVariable [QGVAR(blacklisted), true];
|
||||
_projectile removeEventHandler [
|
||||
"HitPart",
|
||||
_projectile getVariable [QGVAR(hitPartEventHandler), -1]
|
||||
];
|
||||
(_projectile getVariable [QGVAR(spallEH), [-1, -1]]) params ["_hitPartEH", "_penetratedEH"];
|
||||
_projectile removeEventHandler ["HitPart", _hitPartEH];
|
||||
_projectile removeEventHandler ["Penetrated", _penetratedEH];
|
||||
_projectile removeEventHandler [
|
||||
"Explode",
|
||||
_projectile getVariable [QGVAR(explodeEventHandler), -1]
|
||||
_projectile getVariable [QGVAR(fragEH), -1]
|
||||
];
|
||||
|
@ -1,127 +0,0 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Jaynus, NouberNou, Lambda.Tiger,
|
||||
* This function check whether a spall event has occured and generates spall.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The object a projectile hit <OBJECT>
|
||||
* 1: The config name of the projectile <STRING>
|
||||
* 2: The projectile that should cause spalling <OBJECT>
|
||||
* 3: The position (ASL) the projectile hit the object <ARRAY>
|
||||
* 4: The old velocity of the projectile <ARRAY>
|
||||
* 5: The projectile's shotParents <ARRAY>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [editorPlacedHouse_0, typeOf _projectile, _projectile, [1000, 40, 60], [0, 1000, 0], [objNull, ace_player]] call ace_frag_fnc_doSpall
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#define WEIGHTED_SIZE [QGVAR(spall_small), 4, QGVAR(spall_medium), 3, QGVAR(spall_large), 2, QGVAR(spall_huge), 1]
|
||||
params ["_objectHit", "_roundType", "_round", "_oldPosASL", "_oldVelocity", "_shotParents"];
|
||||
|
||||
TRACE_6("",_objectHit,_roundType,_round,_oldPosASL,_oldVelocity,_shotParents);
|
||||
if ((isNil "_objectHit") || {isNull _objectHit}) exitWith {
|
||||
WARNING_1("Problem with hitPart data - bad object [%1]",_objectHit);
|
||||
};
|
||||
|
||||
private _caliber = getNumber (configFile >> "CfgAmmo" >> _roundType >> "caliber");
|
||||
private _explosive = getNumber (configFile >> "CfgAmmo" >> _roundType >> "explosive");
|
||||
private _idh = getNumber (configFile >> "CfgAmmo" >> _roundType >> "indirectHitRange");
|
||||
|
||||
_roundType call FUNC(getSpallInfo) params ["_caliber", "_explosive"];
|
||||
|
||||
private _exit = false;
|
||||
private _velocityModifier = 1;
|
||||
|
||||
private _curVelocity = velocity _round;
|
||||
private _oldSpeed = vectorMagnitude _oldVelocity;
|
||||
private _curSpeed = vectorMagnitude _curVelocity;
|
||||
|
||||
if (alive _round) then {
|
||||
private _diff = _oldVelocity vectorDiff _curVelocity;
|
||||
private _polar = _diff call CBA_fnc_vect2polar;
|
||||
|
||||
if (abs (_polar select 1) > 45 || {abs (_polar select 2) > 45}) then {
|
||||
if (_caliber < 2.5) then {
|
||||
_exit = true;
|
||||
} else {
|
||||
SUB(_velocityModifier,_curSpeed / _oldSpeed);
|
||||
};
|
||||
};
|
||||
};
|
||||
if (_exit) exitWith {
|
||||
TRACE_1("exit alive",_caliber);
|
||||
};
|
||||
|
||||
private _unitDir = vectorNormalized _oldVelocity;
|
||||
|
||||
if ((isNil "_oldPosASL") || {!(_oldPosASL isEqualTypeArray [0,0,0])}) exitWith {WARNING_1("Problem with hitPart data - bad pos [%1]",_oldPosASL);};
|
||||
private _pos1 = _oldPosASL;
|
||||
private _spallPosAGL = _pos1;
|
||||
private _searchStepSize = _unitDir vectorMultiply 0.05;
|
||||
for "_i" from 0 to 20 do {
|
||||
_spallPosAGL = _pos1 vectorAdd _searchStepSize;
|
||||
if (!lineIntersects [_pos1, _spallPosAGL]) exitWith {};
|
||||
_pos1 = _spallPosAGL;
|
||||
};
|
||||
if (_spallPosAGL isEqualTo _pos1) exitWith {
|
||||
TRACE_1("can't find other side",_oldPosASL);
|
||||
};
|
||||
_spallPosAGL = ASLToAGL _spallPosAGL;
|
||||
|
||||
(_shotParents#1) setVariable [QGVAR(nextSpallEvent), CBA_missionTime + ACE_FRAG_SPALL_UNIT_HOLDOFF];
|
||||
private _oldVelocitySpherical = _oldVelocity call CBA_fnc_vect2polar;
|
||||
|
||||
if (_explosive > 0) then {
|
||||
_roundType call FUNC(getFragInfo) params ["", "_fragVelocity"];
|
||||
_oldVelocitySpherical set [0, _fragVelocity * 0.66];
|
||||
};
|
||||
TRACE_2("spallPosandVel",_spallPosAGL,_oldVelocitySpherical);
|
||||
|
||||
private _spread = 15 + (random 25);
|
||||
private _spallCount = 5 + (random 10);
|
||||
TRACE_1("",_spallCount);
|
||||
for "_i" from 1 to _spallCount do {
|
||||
private _fragmentElevation = ((_oldVelocitySpherical select 2) - _spread) + (random (_spread * 2));
|
||||
private _fragmentAzimuth = ((_oldVelocitySpherical select 1) - _spread) + (random (_spread * 2));
|
||||
if (abs _fragmentElevation > 90) then {
|
||||
ADD(_fragmentAzimuth,180);
|
||||
};
|
||||
_fragmentAzimuth = _fragmentAzimuth % 360;
|
||||
private _fragmentSpeed = (_oldVelocitySpherical select 0) * 0.33 * _velocityModifier;
|
||||
_fragmentSpeed = _fragmentSpeed * (0.75 + random 0.5);
|
||||
|
||||
private _spallFragVect = [_fragmentSpeed, _fragmentAzimuth, _fragmentElevation] call CBA_fnc_polar2vect;
|
||||
private _fragment = createVehicleLocal [selectRandomWeighted WEIGHTED_SIZE, _spallPosAGL, [], 0, "CAN_COLLIDE"];
|
||||
_fragment setVelocity _spallFragVect;
|
||||
_fragment setShotParents _shotParents;
|
||||
|
||||
#ifdef DEBUG_MODE_DRAW
|
||||
[_fragment, "orange", true] call FUNC(dev_trackObj);
|
||||
#endif
|
||||
};
|
||||
|
||||
_spread = 5 + (random 5);
|
||||
_spallCount = 3 + (random 5);
|
||||
for "_i" from 1 to _spallCount do {
|
||||
private _fragmentElevation = ((_oldVelocitySpherical select 2) - _spread) + (random (_spread * 2));
|
||||
private _fragmentAzimuth = ((_oldVelocitySpherical select 1) - _spread) + (random (_spread * 2));
|
||||
if (abs _fragmentElevation > 90) then {
|
||||
ADD(_fragmentAzimuth,180);
|
||||
};
|
||||
_fragmentAzimuth = _fragmentAzimuth % 360;
|
||||
private _fragmentSpeed = (_oldVelocitySpherical select 0) * 0.55 * _velocityModifier;
|
||||
_fragmentSpeed = _fragmentSpeed * (0.75 + random 0.5);
|
||||
|
||||
private _spallFragVect = [_fragmentSpeed, _fragmentAzimuth, _fragmentElevation] call CBA_fnc_polar2vect;
|
||||
private _fragment = createVehicleLocal [selectRandomWeighted WEIGHTED_SIZE, _spallPosAGL, [], 0, "CAN_COLLIDE"];
|
||||
_fragment setVelocity _spallFragVect;
|
||||
_fragment setShotParents _shotParents;
|
||||
|
||||
#ifdef DEBUG_MODE_DRAW
|
||||
[_fragment, "purple", true] call FUNC(dev_trackObj);
|
||||
#endif
|
||||
};
|
131
addons/frag/functions/fnc_doSpallHitPart.sqf
Normal file
131
addons/frag/functions/fnc_doSpallHitPart.sqf
Normal file
@ -0,0 +1,131 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Jaynus, NouberNou, Lambda.Tiger,
|
||||
* This function creates spalling when a projectile hits a object and comes to a stop.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The projectile that may generate spalling <OBJECT>
|
||||
* 1: The object the projectile hit <OBJECT>
|
||||
* 2: The position (ASL) of the projectile hit<ARRAY>
|
||||
* 3: The velocity of the projectile before it hit the surface <ARRAY>
|
||||
* 4: The surface normal of the surface hit <ARRAY>
|
||||
* 5: The name of the config name or path to bisurf of the surface hit <STRING>
|
||||
* 6: The projectiles ammo config <STRING>
|
||||
* 7: The projectiles shot parent <ARRAY>
|
||||
* 8: The "up" vector of the projectile when it hit the object <ARRAY>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [BIS_HITPART_EH_ARGS] call ace_frag_fnc_doSpallHitPart;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
TRACE_1("doSpallHitPart",_this);
|
||||
if (CBA_missionTime < GVAR(nextSpallAllowTime)) exitWith {
|
||||
TRACE_2("timeExit",CBA_missionTime,GVAR(nextSpallAllowTime));
|
||||
};
|
||||
params ["_projectile", "_objectHit", "_lastPosASL", "_lastVelocity", "_surfaceNorm", "_surfaceType", "_ammo", "_shotParents", "_vectorUp"];
|
||||
|
||||
// Find spall speed / fragment info
|
||||
_ammo call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"];
|
||||
// Add in v2.18 `getShotInfo`'s `fuseDistanceLeft <= 0` to _explosive
|
||||
if ((alive _projectile && _explosive < 0.5) ||
|
||||
_ammo == "" ||
|
||||
_lastPosASL isEqualTo [0,0,0] ||
|
||||
{_objectHit isKindOf "CAManBase"}) exitWith {
|
||||
TRACE_3("exitEarly",alive _projectile,_lastPosASL,_objectHit);
|
||||
};
|
||||
|
||||
private _material = _surfaceType call FUNC(getMaterialInfo);
|
||||
if (_material == "ground") exitWith {
|
||||
TRACE_1("hitGround",_surfaceType);
|
||||
};
|
||||
|
||||
private _speedChange = vectorMagnitude _lastVelocity;
|
||||
/*
|
||||
* 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 caliber coefficient * round caliber * srqt(change in speed). The second term is
|
||||
* explosive * indirect hit, for any explosive contribution
|
||||
*/
|
||||
private _spallPower = (ACE_FRAG_SPALL_CALIBER_COEF * _caliber * sqrt _speedChange + _explosive * _indirectHit) * GVAR(spallIntensity);
|
||||
TRACE_3("found speed",_speedChange,_caliber,_spallPower);
|
||||
|
||||
if (_spallPower < ACE_FRAG_SPALL_POWER_MIN) exitWith {
|
||||
TRACE_1("lowImpulse",_ammo);
|
||||
};
|
||||
|
||||
private _lastVelocityNorm = vectorNormalized _lastVelocity;
|
||||
private _deltaStep = _lastVelocityNorm vectorMultiply 0.05;
|
||||
|
||||
if (terrainIntersectASL [_lastPosASL vectorAdd _deltaStep, _lastPosASL]) exitWith {
|
||||
TRACE_2("terrainIntersect",_lastPosASL,_deltaStep);
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_DRAW
|
||||
if GVAR(dbgSphere) then {
|
||||
[_lastPosASL vectorAdd _lastVelocityNorm, "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 _lastVelocityNorm into object.
|
||||
*/
|
||||
private _spallPosASL = _lastPosASL vectorAdd _deltaStep;
|
||||
if (120 > acos (_lastVelocityNorm vectorDotProduct _surfaceNorm)) then {
|
||||
_spallPosASL = _spallPosASL vectorAdd (_deltaStep vectorMultiply 5);
|
||||
};
|
||||
private _lastSpallPos = _spallPosASL;
|
||||
for "_i" from 2 to 21 do
|
||||
{
|
||||
_spallPosASL = _lastSpallPos vectorAdd _deltaStep;
|
||||
if (!lineIntersects [_lastSpallPos, _spallPosASL]) exitWith {
|
||||
_spallPosASL = _lastSpallPos vectorAdd _deltaStep;
|
||||
};
|
||||
_lastSpallPos = _spallPosASL;
|
||||
};
|
||||
|
||||
if (_spallPosASL isEqualTo _lastSpallPos) exitWith {
|
||||
TRACE_2("insideObj",_lastPosASL,_spallPosASL);
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_DRAW
|
||||
if GVAR(dbgSphere) then {
|
||||
[_spallPosASL, "green"] call FUNC(dev_sphereDraw);
|
||||
};
|
||||
#endif
|
||||
|
||||
private _spawnSize = switch (true) do {
|
||||
case (_spallPower < ACE_FRAG_SPALL_POWER_TINY_MAX): {"_spall_tiny"};
|
||||
case (_spallPower < ACE_FRAG_SPALL_POWER_SMALL_MAX): {"_spall_small"};
|
||||
case (_spallPower < ACE_FRAG_SPALL_POWER_MEDIUM_MAX): {"_spall_medium"};
|
||||
case (_spallPower < ACE_FRAG_SPALL_POWER_LARGE_MAX): {"_spall_large"};
|
||||
default {"_spall_huge"};
|
||||
};
|
||||
GVAR(nextSpallAllowTime) = CBA_missionTime + ACE_FRAG_SPALL_HOLDOFF;
|
||||
|
||||
private _spallSpawner = createVehicleLocal [
|
||||
QUOTE(GLUE(ADDON,_)) + _material + _spawnSize,
|
||||
ASLToAGL _spallPosASL,
|
||||
[],
|
||||
0,
|
||||
"CAN_COLLIDE"
|
||||
];
|
||||
_spallSpawner setVectorDirandUp [_lastVelocityNorm, _vectorUp];
|
||||
_spallSpawner setVelocityModelSpace [0, _speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF, 0];
|
||||
_spallSpawner setShotParents _shotParents;
|
||||
|
||||
TRACE_3("createSpallSpawner",speed _spallSpawner,_material + _spawnSize,_spallPower);
|
||||
#ifdef DEBUG_MODE_DRAW
|
||||
_spallSpawner addEventHandler [
|
||||
"SubmunitionCreated",
|
||||
{
|
||||
params ["", "_subProj"];
|
||||
[_subProj, "purple", true] call FUNC(dev_trackObj);
|
||||
}
|
||||
];
|
||||
#endif
|
99
addons/frag/functions/fnc_doSpallPenetrate.sqf
Normal file
99
addons/frag/functions/fnc_doSpallPenetrate.sqf
Normal file
@ -0,0 +1,99 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Jaynus, NouberNou, Lambda.Tiger,
|
||||
* This function creates spalling if a projectile penetrated a surface and was slowed down enough proportional to the caliber.
|
||||
* It is dissimilar in function from fnc_doSpall, but leveraging the "Penetrated" projectile EH to process faster.
|
||||
*
|
||||
* Arguments:
|
||||
* Arguments are the same as BI's "Penetratred" EH:
|
||||
* https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#Penetrated
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [BIS_PENETRATED_EH_ARGS] call ace_frag_fnc_doSpallPenetrate;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#define EPSILON 0.1
|
||||
|
||||
TRACE_1("doSpallPenetration",_this);
|
||||
if (CBA_missionTime < GVAR(nextSpallAllowTime)) exitWith {
|
||||
TRACE_1("timeExit",_this);
|
||||
};
|
||||
params ["_projectile", "_hitObject", "_surfaceType", "", "_spallPosASL", "_newVelocity"];
|
||||
|
||||
private _ammo = typeOf _projectile;
|
||||
if (_spallPosASL isEqualTo [0,0,0] ||
|
||||
{_ammo isEqualTo ""} ||
|
||||
{_hitObject isKindOf "CAManBase"}) exitWith {
|
||||
TRACE_4("time/invalidHit",CBA_missionTime,GVAR(nextSpallAllowTime),_hitObject,_spallPosASL);
|
||||
};
|
||||
|
||||
private _material = _surfaceType call FUNC(getMaterialInfo);
|
||||
if (_material == "ground") exitWith {
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
systemChat "ground spall";
|
||||
#endif
|
||||
};
|
||||
|
||||
_ammo call FUNC(getSpallInfo) params ["_caliber", "_explosive", "_indirectHit"];
|
||||
private _velocityChange = velocity _projectile vectorDiff _newVelocity;
|
||||
private _speedChange = vectorMagnitude _velocityChange;
|
||||
/*
|
||||
* This is all fudge factor since real spalling is too complex for calculation.
|
||||
* The equation takes taking a quasi scale of energy using caliber and change in speed.
|
||||
*/
|
||||
private _spallPower = ACE_FRAG_SPALL_CALIBER_COEF * _caliber * sqrt _speedChange * GVAR(spallIntensity);
|
||||
TRACE_5("found speed",_velocityChange,_speedChange,_caliber,_spallPower,_material);
|
||||
|
||||
if (_spallPower < ACE_FRAG_SPALL_POWER_MIN) exitWith {
|
||||
TRACE_1("lowImpulse",_ammo);
|
||||
};
|
||||
private _spallDirection = vectorNormalized _velocityChange;
|
||||
|
||||
#ifdef DEBUG_MODE_DRAW
|
||||
if GVAR(dbgSphere) then {
|
||||
[_spallPosASL, "green"] call FUNC(dev_sphereDraw);
|
||||
};
|
||||
#endif
|
||||
|
||||
private _spawnSize = switch (true) do {
|
||||
case (_spallPower < ACE_FRAG_SPALL_POWER_TINY_MAX): {"_spall_tiny"};
|
||||
case (_spallPower < ACE_FRAG_SPALL_POWER_SMALL_MAX): {"_spall_small"};
|
||||
case (_spallPower < ACE_FRAG_SPALL_POWER_MEDIUM_MAX): {"_spall_medium"};
|
||||
case (_spallPower < ACE_FRAG_SPALL_POWER_LARGE_MAX): {"_spall_large"};
|
||||
default {"_spall_huge"};
|
||||
};
|
||||
GVAR(nextSpallAllowTime) = CBA_missionTime + ACE_FRAG_SPALL_HOLDOFF;
|
||||
|
||||
// Solve for one of the vectors normal to _spallDirection on y = 0 plane
|
||||
private _spallVectorUp = [0, 0, 1];
|
||||
if (_spallDirection#2 > EPSILON) then {
|
||||
private _newZ = _spallDirection#0 / _spallDirection#2;
|
||||
_spallVectorUp = vectorNormalized [1, 0, -_newZ];
|
||||
};
|
||||
|
||||
private _spallSpawner = createVehicleLocal [
|
||||
QUOTE(GLUE(ADDON,_)) + _material + _spawnSize,
|
||||
ASLToAGL _spallPosASL,
|
||||
[],
|
||||
0,
|
||||
"CAN_COLLIDE"
|
||||
];
|
||||
_spallSpawner setVectorDirandUp [_spallDirection, _spallVectorUp];
|
||||
_spallSpawner setVelocityModelSpace [0, _speedChange * ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF, 0];
|
||||
_spallSpawner setShotParents getShotParents _projectile;
|
||||
TRACE_4("dir&up",_spallDirection,vectorDir _spallSpawner,_spallVectorUp,vectorUp _spallSpawner);
|
||||
|
||||
TRACE_3("createSpallSpawner",speed _spallSpawner,_material + _spawnSize,_spallPower);
|
||||
#ifdef DEBUG_MODE_DRAW
|
||||
_spallSpawner addEventHandler [
|
||||
"SubmunitionCreated",
|
||||
{
|
||||
params ["", "_subProj"];
|
||||
[_subProj, "purple", true] call FUNC(dev_trackObj);
|
||||
}
|
||||
];
|
||||
#endif
|
@ -28,29 +28,24 @@ if (GVAR(spallEnabled) && {_ammo call FUNC(shouldSpall)}) then {
|
||||
private _hitPartEventHandler = _projectile addEventHandler [
|
||||
"HitPart",
|
||||
{
|
||||
params ["_projectile", "_hitObject", "", "_posASL", "_velocity"];
|
||||
params ["_projectile", "_objectHit", "", "_posASL", "_velocity", "_surfNorm", "", "", "_surfType"];
|
||||
|
||||
// starting v2.18 it may be faster to use the instigator EH parameter, the same as the second entry shotParents, to recreate _shotParent
|
||||
// The "explode" EH does not get the same parameter
|
||||
private _shotParents = getShotParents _projectile;
|
||||
_shotParents set [0, objNull];
|
||||
private _ammo = typeOf _projectile;
|
||||
private _vectorUp = vectorUp _projectile;
|
||||
|
||||
/*
|
||||
* Wait a frame to see what happens to the round, may result in
|
||||
* multiple hits / slowdowns getting shunted to the first hit
|
||||
*/
|
||||
[
|
||||
// only let a unit make a frag event once per ACE_FRAG_SPALL_UNIT_HOLDOFF
|
||||
{
|
||||
private _shotParents = _this#5;
|
||||
if (CBA_missionTime < _shotParents#1 getVariable [QGVAR(nextSpallEvent), -1]) exitWith {};
|
||||
_this call FUNC(doSpall);
|
||||
},
|
||||
[_hitObject, _ammo, _projectile, _posASL, _velocity, [objNull, _shotParents#1]]
|
||||
] call CBA_fnc_execNextFrame;
|
||||
[LINKFUNC(doSpallHitPart), [_projectile, _objectHit, _posASL, _velocity, _surfNorm, _surfType, _ammo, _shotParents, _vectorUp]] call CBA_fnc_execNextFrame;
|
||||
}
|
||||
];
|
||||
_projectile setVariable [QGVAR(hitPartEventHandler), _hitPartEventHandler];
|
||||
private _penetratedEventHandler = _projectile addEventHandler ["Penetrated",LINKFUNC(doSpallPenetrate)];
|
||||
_projectile setVariable [QGVAR(hitPartEventHandler), [_hitPartEventHandler, _penetratedEventHandler]];
|
||||
};
|
||||
|
||||
if (GVAR(reflectionsEnabled) || (GVAR(enabled) && {_ammo call FUNC(shouldFrag)})) then {
|
||||
|
62
addons/frag/functions/fnc_getMaterialInfo.sqf
Normal file
62
addons/frag/functions/fnc_getMaterialInfo.sqf
Normal file
@ -0,0 +1,62 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Lambda.Tiger
|
||||
* This function returns a classification of material type based on the surface hit.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Surface type given as either a CfgSurfaces path or .bisurf filepath, same format as "HitPart" projectile parameter <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* Material categories as expanded on in line 44 below <STRING>
|
||||
*
|
||||
* Example:
|
||||
* "a3\data_f\penetration\concrete.bisurf" call ace_frag_fnc_getMaterialInfo
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
#define ACE_FRAG_SOUNDENVIRON_STR_LEN 12
|
||||
#define ACE_FRAG_SOUNDHIT_STR_LEN 8
|
||||
#define ACE_FRAG_MATERIAL_SEARCH_LEN 10
|
||||
|
||||
params ["_surfType"];
|
||||
|
||||
private _material = GVAR(spallMaterialCache) get _surfType;
|
||||
|
||||
TRACE_2("materialCache",_surfType,_material);
|
||||
if (!isNil "_material") exitWith {_material};
|
||||
// Use 'soundEnviron' or 'soundHit' to extract approx material
|
||||
private _surfaceConfig = configFile >> "CfgSurfaces" >> _surfType;
|
||||
if (isClass _surfaceConfig) then {
|
||||
_material = getText (_surfaceConfig >> "soundEnviron");
|
||||
if (_material == "" || {_material == "empty"}) then {
|
||||
_material = getText (_surfaceConfig >> "soundhit");
|
||||
};
|
||||
} else { // Messy way when a surface isn't added to CfgSurfaces
|
||||
private _surfFileText = toLowerANSI preprocessFile _surfType;
|
||||
_surfFileText = _surfFileText regexReplace ["[^a-z0-9]", ""];
|
||||
private _idx = ACE_FRAG_SOUNDENVIRON_STR_LEN + (_surfFileText find "soundenviron");
|
||||
if (_surfFileText select [_idx, 5] isEqualTo "empty") then {
|
||||
_idx = ACE_FRAG_SOUNDHIT_STR_LEN + (_surfFileText find "soundhit");
|
||||
};
|
||||
_material = _surfFileText select [_idx, ACE_FRAG_MATERIAL_SEARCH_LEN];
|
||||
};
|
||||
TRACE_1("materialSubString",_material);
|
||||
|
||||
_material = switch (true) do {
|
||||
case ("dirt" in _material);
|
||||
case ("grass" in _material): { "ground" };
|
||||
case ("gravel" in _material);
|
||||
case ("rock" in _material): { "rock" };
|
||||
case ("wood" in _material): { "wood" };
|
||||
case ("lino" in _material);
|
||||
case ("building" in _material);
|
||||
case ("concrete" in _material): { "concrete" };
|
||||
case ("metal" in _material): { "metal" };
|
||||
default { "ground" };
|
||||
};
|
||||
|
||||
GVAR(spallMaterialCache) set [_surfType, _material];
|
||||
TRACE_2("materialCacheSet",_surfType,_material);
|
||||
|
||||
_material
|
96
addons/frag/functions/fnc_initMaterialCache.sqf
Normal file
96
addons/frag/functions/fnc_initMaterialCache.sqf
Normal file
@ -0,0 +1,96 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Lambda.Tiger
|
||||
* For performance, we load a bunch of vanilla materials preemptively into the spall material cache.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* call ace_frag_fnc_initMaterialCache
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
GVAR(spallMaterialCache) = createHashMapFromArray [
|
||||
["a3\data_f\penetration\armour.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_100mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_12mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_16mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_1mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_20mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_23mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_250mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_30mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_3mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_40mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_5mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_60mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_7mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_80mm.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_heavy.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_medium.bisurf","metal"],
|
||||
["a3\data_f\penetration\armour_plate_thin.bisurf","metal"],
|
||||
["a3\data_f\penetration\bell.bisurf","ground"],
|
||||
["a3\data_f\penetration\body.bisurf","ground"],
|
||||
["a3\data_f\penetration\building.bisurf","concrete"],
|
||||
["a3\data_f\penetration\building_dust_particle.bisurf","concrete"],
|
||||
["a3\data_f\penetration\building_dust_soft.bisurf","concrete"],
|
||||
["a3\data_f\penetration\building_plate.bisurf","concrete"],
|
||||
["a3\data_f\penetration\building_wood_particle.bisurf","wood"],
|
||||
["a3\data_f\penetration\cactus.bisurf","ground"],
|
||||
["a3\data_f\penetration\cloth.bisurf","ground"],
|
||||
["a3\data_f\penetration\cloth_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\concrete.bisurf","concrete"],
|
||||
["a3\data_f\penetration\concrete_plate.bisurf","concrete"],
|
||||
["a3\data_f\penetration\default.bisurf","ground"],
|
||||
["a3\data_f\penetration\engine.bisurf","metal"],
|
||||
["a3\data_f\penetration\foliage.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_dead.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_dead_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_green.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_green_big.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_green_big_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_green_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_palm.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_palm_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_pine.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_pine_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\foliage_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\fueltank.bisurf","metal"],
|
||||
["a3\data_f\penetration\glass.bisurf","ground"],
|
||||
["a3\data_f\penetration\glass_armored.bisurf","ground"],
|
||||
["a3\data_f\penetration\glass_armored_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\glass_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\granite.bisurf","ground"],
|
||||
["a3\data_f\penetration\granite_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\hard_ground.bisurf","ground"],
|
||||
["a3\data_f\penetration\hay.bisurf","ground"],
|
||||
["a3\data_f\penetration\iron_cast.bisurf","metal"],
|
||||
["a3\data_f\penetration\iron_cast_plate.bisurf","metal"],
|
||||
["a3\data_f\penetration\leather.bisurf","ground"],
|
||||
["a3\data_f\penetration\meat.bisurf","ground"],
|
||||
["a3\data_f\penetration\meatbones.bisurf","ground"],
|
||||
["a3\data_f\penetration\medium_ground.bisurf","ground"],
|
||||
["a3\data_f\penetration\metal.bisurf","metal"],
|
||||
["a3\data_f\penetration\metal_plate.bisurf","metal"],
|
||||
["a3\data_f\penetration\metal_plate_thin.bisurf","metal"],
|
||||
["a3\data_f\penetration\plastic.bisurf","ground"],
|
||||
["a3\data_f\penetration\plastic_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\plexiglass.bisurf","ground"],
|
||||
["a3\data_f\penetration\plexiglass_plate.bisurf","ground"],
|
||||
["a3\data_f\penetration\rubber.bisurf","ground"],
|
||||
["a3\data_f\penetration\soft_ground.bisurf","ground"],
|
||||
["a3\data_f\penetration\tyre.bisurf","ground"],
|
||||
["a3\data_f\penetration\tyre_armored.bisurf","ground"],
|
||||
["a3\data_f\penetration\vehicle_interior.bisurf","metal"],
|
||||
["a3\data_f\penetration\void.bisurf","ground"],
|
||||
["a3\data_f\penetration\water.bisurf","ground"],
|
||||
["a3\data_f\penetration\weapon_plate.bisurf","metal"],
|
||||
["a3\data_f\penetration\wood.bisurf","wood"],
|
||||
["a3\data_f\penetration\wood_plate.bisurf","wood"]
|
||||
];
|
@ -8,13 +8,6 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)];
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(spallEnabled), "CHECKBOX",
|
||||
[LSTRING(EnableSpall), LSTRING(EnableSpall_Desc)],
|
||||
_category,
|
||||
false,
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
[
|
||||
QGVAR(reflectionsEnabled), "CHECKBOX",
|
||||
[LSTRING(EnableReflections), LSTRING(EnableReflections_Desc)],
|
||||
@ -22,3 +15,22 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)];
|
||||
false,
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(spallEnabled), "CHECKBOX",
|
||||
[LSTRING(EnableSpall), LSTRING(EnableSpall_Desc)],
|
||||
_category,
|
||||
false,
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(spallIntensity), "SLIDER",
|
||||
[LSTRING(SpallIntensity), LSTRING(SpallIntensity_Desc)],
|
||||
_category,
|
||||
[0.1, 2, 1, 1],
|
||||
1,
|
||||
{
|
||||
GVAR(shouldSpallCache) = createHashMap;
|
||||
}
|
||||
] call CBA_fnc_addSetting;
|
@ -3,9 +3,9 @@
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
// #define LOG_FRAG_INFO
|
||||
// #define DEBUG_MODE_FULL
|
||||
// #define DEBUG_MODE_DRAW
|
||||
// #define DISABLE_COMPILE_CACHE
|
||||
#define DEBUG_MODE_FULL
|
||||
#define DEBUG_MODE_DRAW
|
||||
#define DISABLE_COMPILE_CACHE
|
||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||
|
||||
#ifdef DEBUG_ENABLED_FRAG
|
||||
@ -19,6 +19,8 @@
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
#define GLUE(g1,g2) g1##g2
|
||||
|
||||
// Mimimum hold-off time between frag events per unit
|
||||
#define ACE_FRAG_FRAG_UNIT_HOLDOFF 0.5
|
||||
#define ACE_FRAG_SPALL_UNIT_HOLDOFF 0.5
|
||||
@ -28,3 +30,14 @@
|
||||
#define ACE_FRAG_COUNT_MAX_TIME 1.5
|
||||
#define ACE_FRAG_COUNT_MAX 50
|
||||
#define ACE_FRAG_IMPERIC_VELOCITY_CONSTANT 0.8
|
||||
|
||||
// Spall values
|
||||
#define ACE_FRAG_SPALL_HOLDOFF 0.2
|
||||
#define ACE_FRAG_SPALL_VELOCITY_INHERIT_COEFF 0.8
|
||||
// sqrt(2)/50
|
||||
#define ACE_FRAG_SPALL_CALIBER_COEF 0.02828427
|
||||
#define ACE_FRAG_SPALL_POWER_MIN 2
|
||||
#define ACE_FRAG_SPALL_POWER_TINY_MAX 5
|
||||
#define ACE_FRAG_SPALL_POWER_SMALL_MAX 8
|
||||
#define ACE_FRAG_SPALL_POWER_MEDIUM_MAX 11
|
||||
#define ACE_FRAG_SPALL_POWER_LARGE_MAX 15
|
||||
|
@ -114,6 +114,12 @@
|
||||
<Key ID="STR_ACE_Frag_Debug">
|
||||
<English>Debug</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Frag_SpallIntensity">
|
||||
<English>Spalling Intensity</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Frag_SpallIntensity_Desc">
|
||||
<English>Modifier to increase or decrease the number and intensity of spalling events. Increasing this value may cause performance degradation.</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Frag_EnableDebugTrace">
|
||||
<English>Frag/Spall Debug Tracing</English>
|
||||
<German>Splitter-/Explosions-Debug-Verfolgung</German>
|
||||
|
Loading…
Reference in New Issue
Block a user