mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
231 lines
9.7 KiB
Plaintext
231 lines
9.7 KiB
Plaintext
//fnc_frago.sqf
|
|
// #define DEBUG_MODE_FULL
|
|
#include "script_component.hpp"
|
|
|
|
#define FRAG_VEC_VAR 0.004
|
|
|
|
#define MAX_FRAG_COUNT 50
|
|
|
|
if(!isServer) exitWith { };
|
|
|
|
// _startTime = diag_tickTime;
|
|
private ["_round", "_lastPos", "_lastVel", "_shellType", "_gun", "_fragTypes", "_warn", "_atlPos", "_isArmed",
|
|
"_fuseDist", "_indirectHitRange", "_fragRange", "_c", "_m", "_k", "_gC", "_fragPower", "_fragPowerRandom",
|
|
"_manObjects", "_objects", "_crew", "_fragCount", "_fragArcs", "_doRandom", "_target", "_boundingBox",
|
|
"_targetPos", "_distance", "_add", "_bbX", "_bbY", "_bbZ", "_cubic", "_targetVel", "_baseVec", "_dir",
|
|
"_currentCount", "_count", "_vecVar", "_i", "_vec", "_fp", "_vel", "_fragType", "_fragObj", "_randomCount",
|
|
"_sectorSize", "_sectorOffset", "_randomDir"];
|
|
|
|
|
|
_round = _this select 0;
|
|
_lastPos = _this select 1;
|
|
_lastVel = _this select 2;
|
|
_shellType = _this select 3;
|
|
_gun = nil;
|
|
if((count _this) > 5) then {
|
|
_gun = _this select 5;
|
|
};
|
|
|
|
_fragTypes = [
|
|
"ACE_frag_tiny", "ACE_frag_tiny", "ACE_frag_tiny",
|
|
"ACE_frag_tiny_HD", "ACE_frag_tiny_HD", "ACE_frag_tiny_HD",
|
|
"ACE_frag_small","ACE_frag_small","ACE_frag_small","ACE_frag_small",
|
|
"ACE_frag_small_HD","ACE_frag_small_HD","ACE_frag_small_HD","ACE_frag_small_HD",
|
|
"ACE_frag_medium_HD", "ACE_frag_medium_HD", "ACE_frag_medium_HD", "ACE_frag_medium_HD", "ACE_frag_medium_HD"
|
|
];
|
|
|
|
_warn = false;
|
|
if(isArray (configFile >> "CfgAmmo" >> _shellType >> "ACE_frag_CLASSES")) then {
|
|
_fragTypes = getArray (configFile >> "CfgAmmo" >> _shellType >> "ACE_frag_CLASSES");
|
|
} else {
|
|
_warn = true;
|
|
};
|
|
|
|
_atlPos = ASLtoATL _lastPos;
|
|
|
|
_isArmed = true;
|
|
if(!isNil "_gun") then {
|
|
_fuseDist = getNumber(configFile >> "CfgAmmo" >> _shellType >> "fuseDistance");
|
|
_isArmed = ((getPosASL _gun) distance _lastPos > _fuseDist);
|
|
};
|
|
|
|
_indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _shellType >> "indirecthitrange");
|
|
_fragRange = 20*_indirectHitRange*4;
|
|
// _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
|
|
|
|
// _c = 429; // grams of tritonal
|
|
// _m = 496; // grams of fragmentating metal
|
|
// _k = 1/2; // spherical K factor
|
|
// _gC = 2320; // Gurney constant of tritonal in /ms
|
|
|
|
|
|
_c = getNumber(configFile >> "CfgAmmo" >> _shellType >> "ACE_frag_CHARGE");
|
|
if(_c == 0) then { _c = 1; _warn = true;};
|
|
_m = getNumber(configFile >> "CfgAmmo" >> _shellType >> "ACE_frag_METAL");
|
|
if(_m == 0) then { _m = 2; _warn = true;};
|
|
_k = getNumber(configFile >> "CfgAmmo" >> _shellType >> "ACE_frag_GURNEY_K");
|
|
if(_k == 0) then { _k = 1/2; _warn = true;};
|
|
_gC = getNumber(configFile >> "CfgAmmo" >> _shellType >> "ACE_frag_GURNEY_C");
|
|
if(_gC == 0) then { _gC = 2440; _warn = true;};
|
|
|
|
if(_warn) then {
|
|
diag_log text format["Ammo class %1 lacks proper explosive properties definitions for frag!", _shellType]; //TODO: turn this off when we get closer to release
|
|
};
|
|
|
|
_fragPower = (((_m/_c)+_k)^-(1/2))*_gC;
|
|
_fragPower = _fragPower*0.8; // Gunery equation is for a non-fragmenting metal, imperical value of 80% represents fragmentation
|
|
|
|
_fragPowerRandom = _fragPower*0.5;
|
|
if((_atlPos select 2) < 0.5) then {
|
|
_lastPos set[2, (_lastPos select 2)+0.5];
|
|
};
|
|
|
|
// _manObjects = _atlPos nearEntities ["CaManBase", _fragRange];
|
|
|
|
// setAccTime 0.01;
|
|
|
|
//_objects = nearestObjects [_atlPos, ["AllVehicles"], _fragRange]; // Not sure if tracking "ReammoBox" is required, if so revert this change for _objects
|
|
_objects = _atlPos nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange];
|
|
|
|
// _objects = _manObjects;
|
|
// Target also people inside vehicles or manning weapons
|
|
_crew = [];
|
|
{
|
|
{
|
|
_crew set [count _crew,_x]
|
|
} forEach (crew _x);
|
|
} forEach _objects;
|
|
|
|
_objects = _objects - _crew;
|
|
_objects = _objects + _crew;
|
|
|
|
_fragCount = 0;
|
|
|
|
_fragArcs = [];
|
|
_fragArcs set[360, 0];
|
|
|
|
#ifdef DEBUG_MODE_FULL
|
|
player sideChat format["_fragRange: %1", _fragRange];
|
|
player sideChat format["_objects: %1", _objects];
|
|
#endif
|
|
_doRandom = false;
|
|
if(_isArmed && (count _objects) > 0) then {
|
|
{
|
|
//if(random(1) > 0.5) then {
|
|
_target = _x;
|
|
if(alive _target) then {
|
|
_boundingBox = boundingBox _target;
|
|
_targetPos = (getPosASL _target);
|
|
_distance = _targetPos distance _lastPos;
|
|
_add = (((_boundingBox select 1) select 2)/2)+((((_distance-(_fragpower/8)) max 0)/_fragPower)*10);
|
|
_bbX = (abs((_boundingBox select 0) select 0))+((_boundingBox select 1) select 0);
|
|
_bbY = (abs((_boundingBox select 0) select 1))+((_boundingBox select 1) select 1);
|
|
_bbZ = (abs((_boundingBox select 0) select 2))+((_boundingBox select 1) select 2);
|
|
_cubic = _bbX*_bbY*_bbZ;
|
|
if(_cubic > 1) then {
|
|
_doRandom = true;
|
|
|
|
_targetVel = (velocity _target);
|
|
|
|
|
|
_targetPos set[0, (_targetPos select 0)+((_targetVel select 0)*(_distance/_fragPower))];
|
|
_targetPos set[1, (_targetPos select 1)+((_targetVel select 1)*(_distance/_fragPower))];
|
|
_targetPos set[2, (_targetPos select 2)+_add];
|
|
|
|
_baseVec = _lastPos vectorFromTo _targetPos;
|
|
|
|
_dir = floor(_baseVec call CBA_fnc_vectDir);
|
|
_currentCount = _fragArcs select _dir;
|
|
if(isNil "_currentCount") then {
|
|
_currentCount = 0;
|
|
};
|
|
if(_currentCount < 20) then {
|
|
_count = ceil(random(sqrt(_m/1000)));
|
|
_vecVar = FRAG_VEC_VAR;
|
|
if(!(_target isKindOf "Man")) then {
|
|
_vecVar = ((sqrt _cubic)/2000)+FRAG_VEC_VAR;
|
|
if((count (crew _target)) == 0 && _count > 0) then {
|
|
_count = 0 max (_count/2);
|
|
};
|
|
};
|
|
for "_i" from 1 to _count do {
|
|
_vec = +_baseVec;
|
|
|
|
_vec set[0, (_vec select 0)-(_vecVar/2)+(random _vecVar)];
|
|
_vec set[1, (_vec select 1)-(_vecVar/2)+(random _vecVar)];
|
|
_vec set[2, (_vec select 2)-(_vecVar/2)+(random _vecVar)];
|
|
|
|
_fp = (_fragPower-(random (_fragPowerRandom)));
|
|
_vel = [
|
|
(_vec select 0)*_fp,
|
|
(_vec select 1)*_fp,
|
|
(_vec select 2)*_fp
|
|
];
|
|
|
|
_fragType = round (random ((count _fragTypes)-1));
|
|
_fragObj = (_fragTypes select _fragType) createVehicleLocal [0,0,10000];
|
|
// diag_log text format["fp: %1 %2", _fp, typeOf _fragObj];
|
|
_fragObj setPosASL _lastPos;
|
|
_fragObj setVectorDir _vec;
|
|
_fragObj setVelocity _vel;
|
|
#ifdef DEBUG_MODE_FULL
|
|
GVAR(TOTALFRAGS) = GVAR(TOTALFRAGS) + 1;
|
|
GVAR(traceFrags) = true;
|
|
#endif
|
|
if(GVAR(traceFrags)) then {
|
|
[player, _fragObj, [1,0,0,1]] call FUNC(addTrack);
|
|
};
|
|
_fragCount = _fragCount + 1;
|
|
_currentCount = _currentCount + 1;
|
|
};
|
|
_fragArcs set[_dir, _currentCount];
|
|
};
|
|
};
|
|
};
|
|
//};
|
|
if(_fragCount > MAX_FRAG_COUNT) exitWith {};
|
|
} forEach _objects;
|
|
if(_fragCount > MAX_FRAG_COUNT) exitWith {};
|
|
_randomCount = (ceil((MAX_FRAG_COUNT-_fragCount)*0.1)) max 0;
|
|
_sectorSize = 360 / (_randomCount max 1);
|
|
// _doRandom = false;
|
|
if(_doRandom) then {
|
|
for "_i" from 1 to _randomCount do {
|
|
// Distribute evenly
|
|
_sectorOffset = 360 * (_i - 1) / (_randomCount max 1);
|
|
_randomDir = random(_sectorSize);
|
|
_vec = [cos(_sectorOffset + _randomDir), sin(_sectorOffset + _randomDir), sin(30 - (random 45))];
|
|
|
|
_fp = (_fragPower-(random (_fragPowerRandom)));
|
|
|
|
_vel = [
|
|
(_vec select 0)*_fp,
|
|
(_vec select 1)*_fp,
|
|
(_vec select 2)*_fp
|
|
];
|
|
|
|
_fragType = round (random ((count _fragTypes)-1));
|
|
_fragObj = (_fragTypes select _fragType) createVehicleLocal [0,0,10000];
|
|
_fragObj setPosASL _lastPos;
|
|
_fragObj setVectorDir _vec;
|
|
_fragObj setVelocity _vel;
|
|
#ifdef DEBUG_MODE_FULL
|
|
GVAR(TOTALFRAGS) = GVAR(TOTALFRAGS) + 1;
|
|
GVAR(traceFrags) = true;
|
|
#endif
|
|
if(GVAR(traceFrags)) then {
|
|
[player, _fragObj, [1,0.5,0,1]] call FUNC(addTrack);
|
|
};
|
|
_fragCount = _fragCount + 1;
|
|
};
|
|
};
|
|
};
|
|
// #ifdef DEBUG_MODE_FULL
|
|
// player sideChat format["total frags: %1", GVAR(TOTALFRAGS)];
|
|
// player sideChat format["tracks: %1", (count GVAR(trackedObjects))];
|
|
// #endif
|
|
// _endTime = diag_tickTime;
|