Added new advanced_ballistics module

This commit is contained in:
ulteq 2015-04-05 21:08:55 +02:00
parent 26fb06f774
commit 93eaaeb8e2
45 changed files with 1999 additions and 1 deletions

View File

@ -0,0 +1,441 @@
class CfgAmmo
{
class BulletBase;
class B_556x45_Ball_Tracer_Red;
class B_762x51_Tracer_Red;
class B_556x45_Ball : BulletBase
{
airFriction=-0.001265;
hit=8;
typicalSpeed=750;
ACE_caliber=0.224;
ACE_bulletLength=0.906;
ACE_bulletMass=62;
ACE_ammoTempMuzzleVelocityShifts[]={-27.20, -26.44, -23.76, -21.00, -17.54, -13.10, -7.95, -1.62, 6.24, 15.48, 27.75};
ACE_ballisticCoefficients[]={0.151};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=7;
ACE_muzzleVelocities[]={723, 764, 796, 825, 843, 866, 878, 892, 906, 915, 922, 900};
ACE_barrelLengths[]={8.3, 9.4, 10.6, 11.8, 13.0, 14.2, 15.4, 16.5, 17.7, 18.9, 20.0, 24.0};
};
class ACE_556x45_Ball_Mk262 : B_556x45_Ball
{
airFriction=-0.001125;
caliber=0.6;
deflecting=18;
hit=11;
typicalSpeed=836;
ACE_caliber=0.224;
ACE_bulletLength=0.906;
ACE_bulletMass=77;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.361};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={624, 816, 832, 838};
ACE_barrelLengths[]={7.5, 14.5, 18, 20};
};
class ACE_556x45_Ball_Mk318 : B_556x45_Ball
{
airFriction=-0.001120;
caliber=0.6;
deflecting=18;
hit=9;
typicalSpeed=886;
ACE_caliber=0.224;
ACE_bulletLength=0.906;
ACE_bulletMass=62;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.307};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={780, 886, 950};
ACE_barrelLengths[]={10, 15.5, 20};
};
class ACE_545x39_Ball_7N6M : B_556x45_Ball
{
airFriction=-0.001162;
caliber=0.5;
deflecting=18;
hit=7;
typicalSpeed=880;
ACE_caliber=0.220;
ACE_bulletLength=0.85;
ACE_bulletMass=52.9;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.168};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=7;
ACE_muzzleVelocities[]={780, 880, 920};
ACE_barrelLengths[]={10, 16.3, 20};
};
class ACE_545x39_Ball_7T3M : B_556x45_Ball_Tracer_Red
{
airFriction=-0.001162;
caliber=0.5;
deflecting=18;
hit=7;
typicalSpeed=883;
ACE_caliber=0.220;
ACE_bulletLength=0.85;
ACE_bulletMass=49.8;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.168};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=7;
ACE_muzzleVelocities[]={785, 883, 925};
ACE_barrelLengths[]={10, 16.3, 20};
};
class B_65x39_Caseless : BulletBase
{
airFriction=-0.000772;
typicalSpeed=800;
ACE_caliber=0.264;
ACE_bulletLength=1.295;
ACE_bulletMass=123;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.263};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ICAO";
ACE_dragModel=7;
ACE_muzzleVelocities[]={760, 788, 800, 805};
ACE_barrelLengths[]={16, 20, 24, 26};
};
class B_762x51_Ball : BulletBase
{
airFriction=-0.001035;
typicalSpeed=833;
hit=14;
ACE_caliber=0.308;
ACE_bulletLength=1.14;
ACE_bulletMass=146;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.2};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ICAO";
ACE_dragModel=7;
ACE_muzzleVelocities[]={700, 800, 820, 833, 845};
ACE_barrelLengths[]={10, 16, 20, 24, 26};
};
class ACE_762x51_Ball_M118LR : B_762x51_Ball
{
airFriction=-0.0008525;
caliber=1.05;
hit=16;
typicalSpeed=790;
ACE_caliber=0.308;
ACE_bulletLength=1.24;
ACE_bulletMass=175;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.505, 0.496, 0.485, 0.485, 0.485};
ACE_velocityBoundaries[]={853, 549, 549, 549};
ACE_standardAtmosphere="ICAO";
ACE_dragModel=1;
ACE_muzzleVelocities[]={750, 780, 790, 794};
ACE_barrelLengths[]={16, 20, 24, 26};
};
class ACE_762x51_Ball_Subsonic : B_762x51_Ball
{
airFriction=-0.000535;
caliber=0.5;
hit=16;
typicalSpeed=790;
ACE_caliber=0.308;
ACE_bulletLength=1.340;
ACE_bulletMass=200;
ACE_ammoTempMuzzleVelocityShifts[]={-2.655, -2.547, -2.285, -2.012, -1.698, -1.280, -0.764, -0.153, 0.596, 1.517, 2.619};
ACE_ballisticCoefficients[]={0.235};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ICAO";
ACE_dragModel=7;
ACE_muzzleVelocities[]={305, 325, 335, 340};
ACE_barrelLengths[]={16, 20, 24, 26};
};
class ACE_762x54_Ball_7N14 : B_762x51_Ball
{
airFriction=-0.001023;
caliber=0.95;
hit=15;
typicalSpeed=820;
ACE_caliber=0.312;
ACE_bulletLength=1.14;
ACE_bulletMass=152;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.4};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ICAO";
ACE_dragModel=1;
ACE_muzzleVelocities[]={700, 800, 820, 833};
ACE_barrelLengths[]={16, 20, 24, 26};
};
class ACE_762x54_Ball_7T2 : B_762x51_Tracer_Red
{
airFriction=-0.001023;
caliber=0.9;
hit=15;
typicalSpeed=800;
ACE_caliber=0.312;
ACE_bulletLength=1.14;
ACE_bulletMass=149;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.395};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ICAO";
ACE_dragModel=1;
ACE_muzzleVelocities[]={680, 750, 798, 800};
ACE_barrelLengths[]={16, 20, 24, 26};
};
class ACE_762x35_Ball : B_762x51_Ball
{
airFriction=-0.000821;
caliber=0.9;
hit=11;
typicalSpeed=790;
ACE_caliber=0.308;
ACE_bulletLength=1.153;
ACE_bulletMass=125;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.349, 0.338, 0.330, 0.310};
ACE_velocityBoundaries[]={792, 610, 488};
ACE_standardAtmosphere="ICAO";
ACE_dragModel=1;
ACE_muzzleVelocities[]={620, 655, 675};
ACE_barrelLengths[]={9, 16, 20};
};
class ACE_762x39_Ball : B_762x51_Ball
{
airFriction=-0.0015168;
hit=12;
typicalSpeed=716;
ACE_caliber=0.308;
ACE_bulletLength=1.14;
ACE_bulletMass=123;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.275};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ICAO";
ACE_dragModel=1;
ACE_muzzleVelocities[]={650, 716, 750};
ACE_barrelLengths[]={10, 16.3, 20};
};
class ACE_762x39_Ball_57N231P : B_762x51_Tracer_Red
{
airFriction=-0.0015168;
hit=12;
typicalSpeed=716;
ACE_caliber=0.308;
ACE_bulletLength=1.14;
ACE_bulletMass=117;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.275};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ICAO";
ACE_dragModel=1;
ACE_muzzleVelocities[]={650, 716, 750};
ACE_barrelLengths[]={10, 16.3, 20};
};
class B_9x21_Ball : BulletBase
{
airFriction=-0.00125;
typicalSpeed=390;
hit=6;
ACE_caliber=0.356;
ACE_bulletLength=0.610;
ACE_bulletMass=115;
ACE_ammoTempMuzzleVelocityShifts[]={-2.655, -2.547, -2.285, -2.012, -1.698, -1.280, -0.764, -0.153, 0.596, 1.517, 2.619};
ACE_ballisticCoefficients[]={0.17};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={350, 390, 420};
ACE_barrelLengths[]={4, 5, 9};
};
class ACE_9x18_Ball_57N181S : B_9x21_Ball
{
hit=5;
airFriction=-0.001234;
typicalSpeed=298;
ACE_caliber=0.365;
ACE_bulletLength=0.610;
ACE_bulletMass=92.6;
ACE_ammoTempMuzzleVelocityShifts[]={-2.655, -2.547, -2.285, -2.012, -1.698, -1.280, -0.764, -0.153, 0.596, 1.517, 2.619};
ACE_ballisticCoefficients[]={0.125};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={298, 330, 350};
ACE_barrelLengths[]={3.8, 5, 9};
};
class ACE_9x19_Ball : B_9x21_Ball
{
airFriction=-0.001234;
typicalSpeed=370;
hit=6;
ACE_caliber=0.355;
ACE_bulletLength=0.610;
ACE_bulletMass=124;
ACE_ammoTempMuzzleVelocityShifts[]={-2.655, -2.547, -2.285, -2.012, -1.698, -1.280, -0.764, -0.153, 0.596, 1.517, 2.619};
ACE_ballisticCoefficients[]={0.165};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={340, 370, 400};
ACE_barrelLengths[]={4, 5, 9};
};
class ACE_10x25_Ball : B_9x21_Ball
{
airFriction=-0.00168;
typicalSpeed=425;
hit=7;
ACE_caliber=0.5;
ACE_bulletLength=0.764;
ACE_bulletMass=165;
ACE_ammoTempMuzzleVelocityShifts[]={-2.655, -2.547, -2.285, -2.012, -1.698, -1.280, -0.764, -0.153, 0.596, 1.517, 2.619};
ACE_ballisticCoefficients[]={0.189};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={360, 400, 430};
ACE_barrelLengths[]={4, 4.61, 9};
};
class ACE_765x17_Ball: B_9x21_Ball
{
airFriction=-0.001213;
typicalSpeed=282;
hit=7;
ACE_caliber=0.3125;
ACE_bulletLength=0.610;
ACE_bulletMass=65;
ACE_ammoTempMuzzleVelocityShifts[]={-2.655, -2.547, -2.285, -2.012, -1.698, -1.280, -0.764, -0.153, 0.596, 1.517, 2.619};
ACE_ballisticCoefficients[]={0.118};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={282, 300, 320};
ACE_barrelLengths[]={4, 5, 9};
};
class ACE_303_Ball : ACE_762x51_Ball_M118LR
{
airFriction=-0.00083;
typicalSpeed=761;
ACE_caliber=0.311;
ACE_bulletLength=1.227;
ACE_bulletMass=174;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.499, 0.493, 0.48};
ACE_velocityBoundaries[]={671, 549};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={748, 761, 765};
ACE_barrelLengths[]={20, 24, 26};
};
class B_408_Ball : BulletBase
{
airFriction=-0.000395;
typicalSpeed=910;
ACE_caliber=0.408;
ACE_bulletLength=2.126;
ACE_bulletMass=410;
ACE_transonicStabilityCoef=1;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.97};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={910};
ACE_barrelLengths[]={29};
};
class ACE_106x83mm_Ball : B_408_Ball
{
ACE_caliber=0.416;
ACE_bulletLength=2.089;
ACE_bulletMass=398;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.72};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={960};
ACE_barrelLengths[]={29};
};
class ACE_338_Ball : B_408_Ball
{
airFriction=-0.000526;
caliber=1.55;
deflecting=12;
hit=20;
typicalSpeed=826;
ACE_caliber=0.338;
ACE_bulletLength=1.70;
ACE_bulletMass=300;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.381};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ICAO";
ACE_dragModel=7;
ACE_muzzleVelocities[]={820, 826, 830};
ACE_barrelLengths[]={24, 26.5, 28};
};
class B_127x99_Ball : BulletBase
{
airFriction=-0.0006;
typicalSpeed=853;
ACE_caliber=0.510;
ACE_bulletLength=2.310;
ACE_bulletMass=647;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.670};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={853};
ACE_barrelLengths[]={29};
};
class ACE_127x99_Ball_AMAX : B_127x99_Ball
{
ACE_caliber=0.510;
ACE_bulletLength=2.540;
ACE_bulletMass=750;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={1.050};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={860};
ACE_barrelLengths[]={29};
};
class B_127x108_Ball : BulletBase
{
typicalSpeed=820;
ACE_caliber=0.511;
ACE_bulletLength=2.520;
ACE_bulletMass=745;
ACE_ammoTempMuzzleVelocityShifts[]={-26.55, -25.47, -22.85, -20.12, -16.98, -12.80, -7.64, -1.53, 5.96, 15.17, 26.19};
ACE_ballisticCoefficients[]={0.63};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={820};
ACE_barrelLengths[]={28.7};
};
class B_45ACP_Ball : BulletBase
{
airFriction=-0.0007182;
typicalSpeed=250;
ACE_caliber=0.452;
ACE_bulletLength=0.68;
ACE_bulletMass=230;
ACE_ammoTempMuzzleVelocityShifts[]={-2.655, -2.547, -2.285, -2.012, -1.698, -1.280, -0.764, -0.153, 0.596, 1.517, 2.619};
ACE_ballisticCoefficients[]={0.195};
ACE_velocityBoundaries[]={};
ACE_standardAtmosphere="ASM";
ACE_dragModel=1;
ACE_muzzleVelocities[]={230, 250, 285};
ACE_barrelLengths[]={4, 5, 9};
};
};

View File

@ -0,0 +1,19 @@
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE( call COMPILE_FILE(XEH_preInit) );
};
};
class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE( call COMPILE_FILE(XEH_postInit) );
};
};
class Extended_FiredBIS_EventHandlers {
class CAManBase {
class ADDON {
firedBIS = QUOTE(_this call FUNC(handleFired));
};
};
};

View File

@ -0,0 +1,11 @@
class CfgVehicles {
class Module_F;
class GVAR(Module): Module_F {
author = "Ruthberg";
category = "ACE";
displayName = "Advanced Ballistics";
scope = 2;
isGlobal = 1;
icon = QUOTE(PATHTOF(UI\Icon_Module_Wind_ca.paa));
};
};

View File

@ -0,0 +1,174 @@
class CfgWeapons
{
class arifle_katiba_Base_F;
class arifle_MX_Base_F;
class DMR_01_base_F;
class EBR_base_F;
class GM6_base_F;
class LMG_RCWS;
class LRR_base_F;
class MGun;
class MGunCore;
class mk20_base_F;
class pdw2000_base_F;
class Pistol_Base_F;
class Rifle_Base_F;
class Rifle_Long_Base_F;
class SDAR_base_F;
class SMG_01_Base;
class SMG_02_base_F;
class Tavor_base_F;
class hgun_P07_F: Pistol_Base_F
{
ACE_barrelTwist=10;
ACE_barrelLength=4;
};
class hgun_Rook40_F: Pistol_Base_F
{
ACE_barrelTwist=10;
ACE_barrelLength=4.4;
};
class hgun_Pistol_heavy_01_F: Pistol_Base_F
{
ACE_barrelTwist=16;
ACE_barrelLength=4.5;
};
class hgun_Pistol_heavy_02_F: Pistol_Base_F
{
ACE_barrelTwist=16;
ACE_barrelLength=3;
};
class hgun_ACPC2_F: Pistol_Base_F
{
ACE_barrelTwist=16;
ACE_barrelLength=5;
};
class hgun_PDW2000_F: pdw2000_base_F
{
ACE_barrelTwist=9;
ACE_barrelLength=7;
};
class arifle_Katiba_F: arifle_katiba_Base_F
{
ACE_barrelTwist=8;
ACE_barrelLength=228.7;
};
class arifle_Katiba_C_F: arifle_katiba_Base_F
{
ACE_barrelTwist=8;
ACE_barrelLength=26.8;
};
class arifle_Katiba_GL_F: arifle_katiba_Base_F
{
ACE_barrelTwist=8;
ACE_barrelLength=28.7;
};
class arifle_MX_F: arifle_MX_Base_F
{
ACE_barrelTwist=9;
ACE_barrelLength=14.5;
};
class arifle_MX_GL_F: arifle_MX_Base_F
{
ACE_barrelTwist=9;
ACE_barrelLength=14.5;
};
class arifle_MX_SW_F: arifle_MX_Base_F
{
ACE_barrelTwist=9;
ACE_barrelLength=16.0;
};
class arifle_MXC_F: arifle_MX_Base_F
{
ACE_barrelTwist=8;
ACE_barrelLength=10.5;
};
class arifle_MXM_F: arifle_MX_Base_F
{
ACE_barrelTwist=9;
ACE_barrelLength=18;
};
class arifle_SDAR_F: SDAR_base_F
{
ACE_barrelTwist=11.25;
ACE_barrelLength=18;
};
class SMG_02_F: SMG_02_base_F
{
ACE_barrelTwist=10;
ACE_barrelLength=7.7;
};
class arifle_TRG20_F: Tavor_base_F
{
ACE_barrelTwist=7;
ACE_barrelLength=15;
};
class arifle_TRG21_F: Tavor_base_F
{
ACE_barrelTwist=7;
ACE_barrelLength=18.1;
};
class LMG_Zafir_F: Rifle_Long_Base_F
{
ACE_barrelTwist=12;
ACE_barrelLength=18.1;
};
class arifle_Mk20_F: mk20_base_F
{
ACE_barrelTwist=7;
ACE_barrelLength=17.4;
};
class arifle_Mk20C_F: mk20_base_F
{
ACE_barrelTwist=7;
ACE_barrelLength=16;
};
class arifle_Mk20_GL_F: mk20_base_F
{
ACE_barrelTwist=7;
ACE_barrelLength=16;
};
class SMG_01_F: SMG_01_Base
{
ACE_barrelTwist=16;
ACE_barrelLength=5.5;
};
class srifle_DMR_01_F: DMR_01_base_F
{
ACE_barrelTwist=9.5;
ACE_barrelLength=24;
};
class srifle_EBR_F: EBR_base_F
{
ACE_barrelTwist=12;
ACE_barrelLength=24;
};
class LMG_Mk200_F: Rifle_Long_Base_F
{
ACE_barrelTwist=7;
ACE_barrelLength=12.5;
};
class srifle_LRR_F: LRR_base_F
{
ACE_barrelTwist=13;
ACE_barrelLength=29;
};
class srifle_GM6_F: GM6_base_F
{
ACE_barrelTwist=15;
ACE_barrelLength=43.3;
};
class HMG_127 : LMG_RCWS
{
};
class HMG_01: HMG_127
{
};
class HMG_M2: HMG_01
{
ACE_barrelTwist=12;
ACE_barrelLength=45;
};
};

View File

@ -0,0 +1,11 @@
ace_winddeflection
===============
Wind deflection for projectiles/bullets.
## Maintainers
The people responsible for merging changes to this component or answering potential questions.
- [Glowbal](https://github.com/Glowbal)
- [Ruthberg] (http://github.com/Ulteq)

View File

@ -0,0 +1,92 @@
class RscTitles
{
class RscWindIntuitive
{
idd=-1;
onLoad="with uiNameSpace do { RscWindIntuitive = _this select 0 };";
movingEnable=0;
duration=60;
fadeIn="false";
fadeOut="false";
class controls
{
class RscWindIntuitive
{
idc=132948;
type=0;
style=48;
font="TahomaB";
colorBackground[]={0,0,0,0};
colorText[]={0,0,0,0};
x="SafeZoneX + 0.001";
y="SafeZoneY + 0.001";
w=0.2;
h=0.2*4/3;
size=0.034;
sizeEx=0.027;
text="";
};
};
};
class RscTurretDial
{
idd=-1;
onLoad="with uiNameSpace do { RscTurretDial = _this select 0 };";
movingEnable=0;
duration=5;
fadeIn="false";
fadeOut="false";
class controls
{
class RscTurretDial
{
idc=132949;
type=0;
style=128;
font="TahomaB";
colorBackground[]={0,0,0,0.8};
colorText[]={1,1,1,1};
x="SafeZoneX + 0.0025";
y="SafeZoneY + 0.0025";
w=0.10;
h=0.05;
sizeEx=0.03;
text="";
};
};
};
class RscProtractor
{
idd=-1;
onLoad="with uiNameSpace do { RscProtractor = _this select 0 };";
movingEnable=0;
duration=60;
fadeIn="false";
fadeOut="false";
class controls
{
class RscProtractorBase
{
idc=132950;
type=0;
style=48;
font="TahomaB";
colorBackground[]={0,0,0,0};
colorText[]={1,1,1,1};
x="SafeZoneX + 0.001";
y="SafeZoneY + 0.001";
w=0.2;
h=0.2*4/3;
size=0.034;
sizeEx=0.027;
text="";
};
class RscProtractorMarker : RscProtractorBase
{
idc=132951;
};
};
};
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,66 @@
#include "script_component.hpp"
#include "initKeybinds.sqf"
GVAR(bulletDatabase) = [];
GVAR(bulletDatabaseStartTime) = [];
GVAR(bulletDatabaseSpeed) = [];
GVAR(bulletDatabaseFrames) = [];
GVAR(bulletDatabaseLastFrame) = [];
GVAR(bulletDatabaseHDeflect) = [];
GVAR(bulletDatabaseSpinDrift) = [];
GVAR(bulletDatabaseOccupiedIndices) = [];
GVAR(bulletDatabaseFreeIndices) = [];
GVAR(WindInfo) = false;
GVAR(WindInfoStart) = time;
GVAR(Protractor) = false;
GVAR(ProtractorStart) = time;
GVAR(Altitude) = 0;
GVAR(Latitude) = 50;
if (worldName in ["Chernarus", "Bootcamp_ACR", "Woodland_ACR", "utes"]) then { GVAR(Latitude) = 50; GVAR(Altitude) = 0; };
if (worldName in ["Altis", "Stratis"]) then { GVAR(Latitude) = 40; GVAR(Altitude) = 0; };
if (worldName in ["Takistan", "Zargabad", "Mountains_ACR"]) then { GVAR(Latitude) = 35; GVAR(Altitude) = 2000; };
if (worldName in ["Shapur_BAF", "ProvingGrounds_PMC"]) then { GVAR(Latitude) = 35; GVAR(Altitude) = 100; };
if (worldName in ["fallujah"]) then { GVAR(Latitude) = 33; GVAR(Altitude) = 0; };
if (worldName in ["fata", "Abbottabad"]) then { GVAR(Latitude) = 30; GVAR(Altitude) = 1000; };
if (worldName in ["sfp_wamako"]) then { GVAR(Latitude) = 14; GVAR(Altitude) = 0; };
if (worldName in ["sfp_sturko"]) then { GVAR(Latitude) = 56; GVAR(Altitude) = 0; };
if (worldName in ["Bornholm"]) then { GVAR(Latitude) = 55; GVAR(Altitude) = 0; };
if (worldName in ["Imrali"]) then { GVAR(Latitude) = 40; GVAR(Altitude) = 0; };
if (worldName in ["Caribou"]) then { GVAR(Latitude) = 68; GVAR(Altitude) = 0; };
if (worldName in ["Namalsk"]) then { GVAR(Latitude) = 65; GVAR(Altitude) = 0; };
if (worldName in ["MCN_Aliabad"]) then { GVAR(Latitude) = 36; GVAR(Altitude) = 0; };
if (worldName in ["Clafghan"]) then { GVAR(Latitude) = 34; GVAR(Altitude) = 640; };
if (worldName in ["Sangin", "hellskitchen"]) then { GVAR(Latitude) = 32; GVAR(Altitude) = 0; };
if (worldName in ["Sara"]) then { GVAR(Latitude) = 40; GVAR(Altitude) = 0; };
if (worldName in ["reshmaan"]) then { GVAR(Latitude) = 35; GVAR(Altitude) = 2000; };
if (worldName in ["Thirsk"]) then { GVAR(Latitude) = 65; GVAR(Altitude) = 0; };
if (worldName in ["lingor"]) then { GVAR(Latitude) = -4; GVAR(Altitude) = 0; };
if (worldName in ["Panthera3"]) then { GVAR(Latitude) = 46; GVAR(Altitude) = 0; };
// TODO: Remove this hack once the weather engine is up and running
if (isNil QUOTE(EGVAR(weather,currentTemperature))) then { EGVAR(weather,currentTemperature) = 24; };
if (isNil QUOTE(EGVAR(weather,currentHumidity))) then { EGVAR(weather,currentHumidity) = 50; };
GVAR(SimulationPrecision) = 1;
GVAR(INIT_MESSAGE_ENABLED) = true;
GVAR(WindEnabled) = true;
GVAR(SpinDriftEnabled) = true;
GVAR(CoriolisEnabled) = true;
GVAR(EoetvoesEnabled) = true;
GVAR(AdvancedAirDragEnabled) = true;
GVAR(TransonicRegionEnabled) = true;
GVAR(AmmoTemperatureEnabled) = true;
GVAR(BulletTraceEnabled) = true;
GVAR(AtmosphericDensitySimulationEnabled) = true;
GVAR(BarrelLengthInfluenceEnabled) = true;
GVAR(VehicleGunnerEnabled) = true;
GVAR(ExtensionsEnabled) = false;
[] call FUNC(initializeTerrainExtension);

View File

@ -0,0 +1,19 @@
#include "script_component.hpp"
ADDON = false;
PREP(calculateAirDensity);
PREP(calculateAmmoTemperatureVelocityShift);
PREP(calculateAtmosphericCorrection);
PREP(calculateBarrelLengthVelocityShift);
PREP(calculateRetardation);
PREP(calculateRoughnessLength);
PREP(calculateStabilityFactor);
PREP(calculateWindSpeed);
PREP(displayProtractor);
PREP(displayWindInfo);
PREP(handleFired);
PREP(handleFiredExtension);
PREP(initializeTerrainExtension);
ADDON = true;

View File

@ -0,0 +1,27 @@
#include "script_component.hpp"
class CfgPatches {
class ADDON {
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ACE_common", "ACE_weather"};
versionDesc = "ACE Advanced Ballistics";
version = VERSION;
author[] = {$STR_ACE_Common_ACETeam, "Glowbal", "Ruthberg"};
};
};
class CfgAddons {
class PreloadAddons {
class ADDON {
list[] = {QUOTE(ADDON)};
};
};
};
#include "CfgEventHandlers.hpp"
#include "CfgAmmo.hpp"
#include "CfgWeapons.hpp"
#include "CfgVehicles.hpp"
#include "RscTitles.hpp"

View File

@ -0,0 +1,11 @@
#define GRAVITY 9.80665
#define ABSOLUTE_ZERO_IN_CELSIUS -273.15
#define KELVIN(t) (t - ABSOLUTE_ZERO_IN_CELSIUS)
#define CELSIUS(t) (t + ABSOLUTE_ZERO_IN_CELSIUS)
#define UNIVERSAL_GAS_CONSTANT 8.314
#define WATER_VAPOR_MOLAR_MASS 0.018016
#define DRY_AIR_MOLAR_MASS 0.028964
#define SPECIFIC_GAS_CONSTANT_DRY_AIR 287.058
#define STD_AIR_DENSITY_ICAO 1.22498
#define STD_AIR_DENSITY_ASM 1.20885
#define GET_TEMPERATURE_AT_HEIGHT(h) (EGVAR(weather,currentTemperature) - 0.0065 * (h))

View File

@ -0,0 +1,21 @@
#include "script_component.hpp"
#include "defines.h"
private ["_temperature", "_pressure", "_relativeHumidity"];
_temperature = _this select 0; // in C
_pressure = _this select 1; // in hPa
_relativeHumidity = _this select 2; // as ratio 0-1
_pressure = _pressure * 100;
if (_relativeHumidity > 0) then {
private ["_pSat", "_vaporPressure", "_partialPressure"];
// Saturation vapor pressure calculated according to: http://wahiduddin.net/calc/density_algorithms.htm
_pSat = 6.1078 * 10 ^ ((7.5 * _temperature) / (_temperature + 237.3));
_vaporPressure = _relativeHumidity * _pSat;
_partialPressure = _pressure - _vaporPressure;
(_partialPressure * DRY_AIR_MOLAR_MASS + _vaporPressure * WATER_VAPOR_MOLAR_MASS) / (UNIVERSAL_GAS_CONSTANT * KELVIN(_temperature))
} else {
_pressure / (SPECIFIC_GAS_CONSTANT_DRY_AIR * KELVIN(_temperature))
};

View File

@ -0,0 +1,27 @@
#include "script_component.hpp"
private ["_ammo", "_temperature", "_muzzleVelocityTable", "_muzzleVelocityShift", "_temperatureIndexA", "_temperatureIndexB", "_temperatureRatio"];
_ammo = _this select 0;
_temperature = _this select 1;
_muzzleVelocityTable = [];
if (isArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_ammoTempMuzzleVelocityShifts")) then {
_muzzleVelocityTable = getArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_ammoTempMuzzleVelocityShifts");
};
if (count _muzzleVelocityTable != 11) exitWith { 0 };
_temperatureIndexA = floor((_temperature + 15) / 5);
_temperatureIndexA = 0 max _temperatureIndexA;
_temperatureIndexA = _temperatureIndexA min 10;
_temperatureIndexB = ceil((_temperature + 15) / 5);
_temperatureIndexB = 0 max _temperatureIndexB;
_temperatureIndexB = _temperatureIndexB min 10;
_temperatureRatio = ((_temperature + 15) / 5) - floor((_temperature + 15) / 5);
_muzzleVelocityShift = (_muzzleVelocityTable select _temperatureIndexA) * (1 - _temperatureRatio) + (_muzzleVelocityTable select _temperatureIndexB) * _temperatureRatio;
_muzzleVelocityShift

View File

@ -0,0 +1,17 @@
#include "script_component.hpp"
#include "defines.h"
private ["_ballisticCoefficient", "_temperature", "_pressure", "_relativeHumidity", "_atmosphereModel", "_airDensity"];
_ballisticCoefficient = _this select 0;
_temperature = _this select 1; // in C
_pressure = _this select 2; // in hPa
_relativeHumidity = _this select 3; // as ratio 0-1
_atmosphereModel = _this select 4; // "ICAO" or "ASM"
_airDensity = [_temperature, _pressure, _relativeHumidity] call FUNC(calculateAirDensity);
if (_atmosphereModel == "ICAO") then {
(STD_AIR_DENSITY_ICAO / _airDensity) * _ballisticCoefficient
} else {
(STD_AIR_DENSITY_ASM / _airDensity) * _ballisticCoefficient
};

View File

@ -0,0 +1,50 @@
#include "script_component.hpp"
private ["_ammo", "_weapon", "_barrelLength", "_muzzleVelocityTable", "_barrelLengthTable", "_muzzleVelocity", "_lowerIndex", "_upperIndex", "_barrelLengthRatio", "_muzzleVelocityNew"];
_ammo = _this select 0;
_weapon = _this select 1;
_muzzleVelocity = _this select 2;
_barrelLength = getNumber(configFile >> "cfgWeapons" >> _weapon >> "ACE_barrelLength");
if (_barrelLength == 0) exitWith { 0 };
_muzzleVelocityTable = [];
_barrelLengthTable = [];
if (isArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_muzzleVelocities")) then {
_muzzleVelocityTable = getArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_muzzleVelocities");
};
if (isArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_barrelLengths")) then {
_barrelLengthTable = getArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_barrelLengths");
};
if (count _muzzleVelocityTable != count _barrelLengthTable) exitWith { 0 };
if (count _muzzleVelocityTable == 0 || count _barrelLengthTable == 0) exitWith { 0 };
if (count _muzzleVelocityTable == 1) exitWith { (_muzzleVelocityTable select 0) - _muzzleVelocity };
_lowerIndex = 0;
_upperIndex = (count _barrelLengthTable) - 1;
if (_barrelLength <= (_barrelLengthTable select _lowerIndex)) exitWith { (_muzzleVelocityTable select _lowerIndex) - _muzzleVelocity };
if (_barrelLength >= (_barrelLengthTable select _upperIndex)) exitWith { (_muzzleVelocityTable select _upperIndex) - _muzzleVelocity };
for "_i" from 0 to (count _barrelLengthTable) - 1 do {
if (_barrelLength >= _barrelLengthTable select _i) then {
_lowerIndex = _i;
};
};
for "_i" from (count _barrelLengthTable) - 1 to 0 step -1 do {
if (_barrelLength <= _barrelLengthTable select _i) then {
_upperIndex = _i;
};
};
_barrelLengthRatio = 0;
if ((_barrelLengthTable select _upperIndex) - (_barrelLengthTable select _lowerIndex) > 0) then {
_barrelLengthRatio = ((_barrelLengthTable select _upperIndex) - _barrelLength) / ((_barrelLengthTable select _upperIndex) - (_barrelLengthTable select _lowerIndex));
};
_muzzleVelocityNew = (_muzzleVelocityTable select _lowerIndex) + ((_muzzleVelocityTable select _upperIndex) - (_muzzleVelocityTable select _lowerIndex)) * (1 - _barrelLengthRatio);
_muzzleVelocityNew - _muzzleVelocity

View File

@ -0,0 +1,28 @@
#include "script_component.hpp"
private ["_hellmann_exponents", "_hellmann_index", "_windSource", "_nearObjects", "_isWater"];
// Source: https://en.wikipedia.org/wiki/Wind_gradient
// Entries 0-2 -> open water surface; Entries 3-5 -> flat open coast; Entries 6-8 -> human inhabited areas
// Sorting: open water surface/flat open coast/human inhabited areas & stable air/neutral air/unstable air
_hellmann_exponents = [0.27, 0.10, 0.06, 0.40, 0.16, 0.11, 0.60, 0.34, 0.27];
_hellmann_exponent = 0.14;
_windSource = _this vectorDiff ((vectorNormalized wind) vectorMultiply 25);
_nearObjects = count (_windSource nearObjects ["Building", 50]);
_isWater = surfaceIsWater _this;
_hellmann_index = 0 max floor(overcast * 3) min 2;
if (_nearObjects >= 5) then {
_hellmann_exponent = _hellmann_exponents select (_hellmann_index + 6);
};
if (_nearObjects < 5) then {
_hellmann_exponent = _hellmann_exponents select (_hellmann_index + 3);
};
if (_nearObjects == 0 && _isWater) then {
_hellmann_exponent = _hellmann_exponents select (_hellmann_index + 0);
};
_hellmann_exponent

View File

@ -0,0 +1,129 @@
#include "script_component.hpp"
// Source: GNU Exterior Ballistics
private ["_dragModel", "_dragCoefficient", "_velocity", "_A", "_M", "_result"];
_dragModel = _this select 0;
_dragCoefficient = _this select 1;
_velocity = (_this select 2) * 3.2808399;
_A = -1;
_M = -1;
_result = 0;
switch _dragModel do {
case 1:
{
switch true do {
case (_velocity > 4230) : { _A = 0.0001477404177730177; _M = 1.9565; };
case (_velocity > 3680) : { _A = 0.0001920339268755614; _M = 1.925 ; };
case (_velocity > 3450) : { _A = 0.0002894751026819746; _M = 1.875 ; };
case (_velocity > 3295) : { _A = 0.0004349905111115636; _M = 1.825 ; };
case (_velocity > 3130) : { _A = 0.0006520421871892662; _M = 1.775 ; };
case (_velocity > 2960) : { _A = 0.0009748073694078696; _M = 1.725 ; };
case (_velocity > 2830) : { _A = 0.001453721560187286; _M = 1.675 ; };
case (_velocity > 2680) : { _A = 0.002162887202930376; _M = 1.625 ; };
case (_velocity > 2460) : { _A = 0.003209559783129881; _M = 1.575 ; };
case (_velocity > 2225) : { _A = 0.003904368218691249; _M = 1.55 ; };
case (_velocity > 2015) : { _A = 0.003222942271262336; _M = 1.575 ; };
case (_velocity > 1890) : { _A = 0.002203329542297809; _M = 1.625 ; };
case (_velocity > 1810) : { _A = 0.001511001028891904; _M = 1.675 ; };
case (_velocity > 1730) : { _A = 0.0008609957592468259; _M = 1.75 ; };
case (_velocity > 1595) : { _A = 0.0004086146797305117; _M = 1.85 ; };
case (_velocity > 1520) : { _A = 0.0001954473210037398; _M = 1.95 ; };
case (_velocity > 1420) : { _A = 0.00005431896266462351; _M = 2.125 ; };
case (_velocity > 1360) : { _A = 0.000008847742581674416; _M = 2.375 ; };
case (_velocity > 1315) : { _A = 0.000001456922328720298; _M = 2.625 ; };
case (_velocity > 1280) : { _A = 0.0000002419485191895565; _M = 2.875 ; };
case (_velocity > 1220) : { _A = 0.00000001657956321067612; _M = 3.25 ; };
case (_velocity > 1185) : { _A = 0.0000000004745469537157371; _M = 3.75 ; };
case (_velocity > 1150) : { _A = 0.00000000001379746590025088; _M = 4.25 ; };
case (_velocity > 1100) : { _A = 0.0000000000004070157961147882; _M = 4.75 ; };
case (_velocity > 1060) : { _A = 0.00000000000002938236954847331; _M = 5.125 ; };
case (_velocity > 1025) : { _A = 0.00000000000001228597370774746; _M = 5.25 ; };
case (_velocity > 980) : { _A = 0.00000000000002916938264100495; _M = 5.125 ; };
case (_velocity > 945) : { _A = 0.0000000000003855099424807451; _M = 4.75 ; };
case (_velocity > 905) : { _A = 0.00000000001185097045689854; _M = 4.25 ; };
case (_velocity > 860) : { _A = 0.0000000003566129470974951; _M = 3.75 ; };
case (_velocity > 810) : { _A = 0.00000001045513263966272; _M = 3.25 ; };
case (_velocity > 780) : { _A = 0.0000001291159200846216; _M = 2.875 ; };
case (_velocity > 750) : { _A = 0.0000006824429329105383; _M = 2.625 ; };
case (_velocity > 700) : { _A = 0.000003569169672385163; _M = 2.375 ; };
case (_velocity > 640) : { _A = 0.00001839015095899579; _M = 2.125 ; };
case (_velocity > 600) : { _A = 0.00005711174688734240; _M = 1.950 ; };
case (_velocity > 550) : { _A = 0.00009226557091973427; _M = 1.875 ; };
case (_velocity > 250) : { _A = 0.00009337991957131389; _M = 1.875 ; };
case (_velocity > 100) : { _A = 0.00007225247327590413; _M = 1.925 ; };
case (_velocity > 65) : { _A = 0.00005792684957074546; _M = 1.975 ; };
case (_velocity > 0) : { _A = 0.00005206214107320588; _M = 2.000 ; };
};
};
case 2:
{
switch true do {
case (_velocity > 1674) : { _A = 0.0079470052136733; _M = 1.36999902851493; };
case (_velocity > 1172) : { _A = 0.00100419763721974; _M = 1.65392237010294; };
case (_velocity > 1060) : { _A = 0.0000000000000000000000715571228255369; _M = 7.91913562392361; };
case (_velocity > 949) : { _A = 0.000000000139589807205091; _M = 3.81439537623717; };
case (_velocity > 670) : { _A = 0.000234364342818625; _M = 1.71869536324748; };
case (_velocity > 335) : { _A = 0.000177962438921838; _M = 1.76877550388679; };
case (_velocity > 0) : { _A = 0.0000518033561289704; _M = 1.98160270524632; };
};
};
case 5:
{
switch true do {
case (_velocity > 1730) : { _A = 0.00724854775171929; _M = 1.41538574492812; };
case (_velocity > 1228) : { _A = 0.0000350563361516117; _M = 2.13077307854948; };
case (_velocity > 1116) : { _A = 0.000000000000184029481181151; _M = 4.81927320350395; };
case (_velocity > 1004) : { _A = 0.000000000000000000000134713064017409; _M = 7.8100555281422 ; };
case (_velocity > 837) : { _A = 0.000000103965974081168; _M = 2.84204791809926; };
case (_velocity > 335) : { _A = 0.0001093015938698234; _M = 1.81096361579504; };
case (_velocity > 0) : { _A = 0.0000351963178524273; _M = 2.00477856801111; };
};
};
case 6:
{
switch true do {
case (_velocity > 3236) : { _A = 0.0455384883480781; _M = 1.15997674041274; };
case (_velocity > 2065) : { _A = 0.07167261849653769; _M = 1.10704436538885; };
case (_velocity > 1311) : { _A = 0.00166676386084348; _M = 1.60085100195952; };
case (_velocity > 1144) : { _A = 0.000000101482730119215; _M = 2.9569674731838 ; };
case (_velocity > 1004) : { _A = 0.00000000000000000431542773103552; _M = 6.34106317069757; };
case (_velocity > 670) : { _A = 0.0000204835650496866; _M = 2.11688446325998; };
case (_velocity > 0) : { _A = 0.0000750912466084823; _M = 1.92031057847052; };
};
};
case 7:
{
switch true do {
case (_velocity > 4200) : { _A = 0.00000000129081656775919; _M = 3.24121295355962; };
case (_velocity > 3000) : { _A = 0.0171422231434847; _M = 1.27907168025204; };
case (_velocity > 1470) : { _A = 0.00233355948302505; _M = 1.52693913274526; };
case (_velocity > 1260) : { _A = 0.000797592111627665; _M = 1.67688974440324; };
case (_velocity > 1110) : { _A = 0.00000000000571086414289273; _M = 4.3212826264889 ; };
case (_velocity > 960) : { _A = 0.0000000000000000302865108244904; _M = 5.99074203776707; };
case (_velocity > 670) : { _A = 0.00000752285155782535; _M = 2.1738019851075 ; };
case (_velocity > 540) : { _A = 0.0000131766281225189; _M = 2.08774690257991; };
case (_velocity > 0) : { _A = 0.0000134504843776525; _M = 2.08702306738884; };
};
};
case 8:
{
switch true do {
case (_velocity > 3571) : { _A = 0.0112263766252305; _M = 1.33207346655961; };
case (_velocity > 1841) : { _A = 0.0167252613732636; _M = 1.28662041261785; };
case (_velocity > 1120) : { _A = 0.00220172456619625; _M = 1.55636358091189; };
case (_velocity > 1088) : { _A = 0.00000000000000020538037167098; _M = 5.80410776994789; };
case (_velocity > 976) : { _A = 0.00000000000592182174254121; _M = 4.29275576134191; };
case (_velocity > 0) : { _A = 0.000043917343795117; _M = 1.99978116283334; };
};
};
};
if (_A != -1 && _M != -1 && _velocity > 0 && _velocity < 10000) then {
_result = _A * (_velocity ^ _M) / _dragCoefficient;
_result = _result / 3.2808399;
};
_result

View File

@ -0,0 +1,21 @@
#include "script_component.hpp"
private ["_roughness_lengths", "_windSource", "_nearBuildings", "_isWater"];
// Source: http://es.ucsc.edu/~jnoble/wind/extrap/index.html
_roughness_lengths = [0.0002, 0.0005, 0.0024, 0.03, 0.055, 0.1, 0.2, 0.4, 0.8, 1.6];
_windSource = _this vectorDiff ((vectorNormalized wind) vectorMultiply 25);
_nearBuildings = count (_windSource nearObjects ["Building", 50]);
_isWater = surfaceIsWater _windSource;
if (_nearBuildings == 0 && _isWater) exitWith {
0.0005
};
if (_nearBuildings >= 10) exitWith {
1.6
};
_roughness_lengths select (2 + (_nearBuildings min 6))

View File

@ -0,0 +1,25 @@
private ["_caliber", "_bulletLength", "_bulletMass", "_barrelTwist", "_muzzleVelocity", "_temperature", "_barometricPressure", "_l", "_t", "_stabilityFactor"];
_caliber = _this select 0;
_bulletLength = _this select 1;
_bulletMass = _this select 2;
_barrelTwist = _this select 3;
_muzzleVelocity = _this select 4;
_temperature = _this select 5;
_barometricPressure = _this select 6;
// Source: http://www.jbmballistics.com/ballistics/bibliography/articles/miller_stability_1.pdf
_t = _barrelTwist / _caliber;
_l = _bulletLength / _caliber;
_stabilityFactor = 30 * _bulletMass / (_t^2 * _caliber^3 * _l * (1 + _l^2));
_muzzleVelocity = _muzzleVelocity * 3.2808399;
if (_muzzleVelocity > 1120) then {
_stabilityFactor = _stabilityFactor * (_muzzleVelocity / 2800) ^ (1/3);
} else {
_stabilityFactor = _stabilityFactor * (_muzzleVelocity / 1120) ^ (1/3);
};
_stabilityFactor = _stabilityFactor * (_temperature + 273) / (15 + 273) * 1013.25 / _barometricPressure;
_stabilityFactor

View File

@ -0,0 +1,65 @@
#include "script_component.hpp"
private ["_windSpeed", "_windDir", "_height", "_newWindSpeed", "_windSource", "_roughnessLength"];
fnc_polar2vect = {
private ["_mag2D"];
_mag2D = (_this select 0) * cos((_this select 2));
[_mag2D * sin((_this select 1)), _mag2D * cos((_this select 1)), (_this select 0) * sin((_this select 2))];
};
_windSpeed = vectorMagnitude ACE_wind;
_windDir = (ACE_wind select 0) atan2 (ACE_wind select 1);
// Wind gradient
if (_windSpeed > 0.05) then {
_height = (ASLToATL _this) select 2;
_height = 0 max _height min 20;
if (_height < 20) then {
_roughnessLength = _this call FUNC(calculateRoughnessLength);
_windSpeed = _windSpeed * ln(_height / _roughnessLength) / ln(20 / _roughnessLength);
};
};
// Terrain effect on wind
if (_windSpeed > 0.05) then {
_newWindSpeed = 0;
{
_windSource = [100, _windDir + 180, _x] call fnc_polar2vect;
if (!(terrainIntersectASL [_this, _this vectorAdd _windSource])) exitWith {
_newWindSpeed = cos(_x * 9) * _windSpeed;
};
_windSource = [100, _windDir + 180 + _x, 0] call fnc_polar2vect;
if (!(terrainIntersectASL [_this, _this vectorAdd _windSource])) exitWith {
_newWindSpeed = cos(_x * 9) * _windSpeed;
};
_windSource = [100, _windDir + 180 - _x, 0] call fnc_polar2vect;
if (!(terrainIntersectASL [_this, _this vectorAdd _windSource])) exitWith {
_newWindSpeed = cos(_x * 9) * _windSpeed;
};
} forEach [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
_windSpeed = _newWindSpeed;
};
// Obstacle effect on wind
if (_windSpeed > 0.05) then {
_newWindSpeed = 0;
{
_windSource = [20, _windDir + 180, _x] call fnc_polar2vect;
if (!(lineIntersects [_this, _this vectorAdd _windSource])) exitWith {
_newWindSpeed = cos(_x * 2) * _windSpeed;
};
_windSource = [20, _windDir + 180 + _x, 0] call fnc_polar2vect;
if (!(lineIntersects [_this, _this vectorAdd _windSource])) exitWith {
_newWindSpeed = cos(_x * 2) * _windSpeed;
};
_windSource = [20, _windDir + 180 - _x, 0] call fnc_polar2vect;
if (!(lineIntersects [_this, _this vectorAdd _windSource])) exitWith {
_newWindSpeed = cos(_x * 2) * _windSpeed;
};
} forEach [0, 5, 10, 15, 20, 25, 30, 35, 40, 45];
_windSpeed = _newWindSpeed;
};
_windSpeed = 0 max _windSpeed;
_windSpeed

View File

@ -0,0 +1,50 @@
#include "script_component.hpp"
#define __dsp (uiNamespace getVariable "RscProtractor")
#define __ctrl1 (__dsp displayCtrl 132950)
#define __ctrl2 (__dsp displayCtrl 132951)
private ["_inclinationAngle", "_refPosition"];
if (GVAR(Protractor)) exitWith {
GVAR(Protractor) = false;
1 cutText ["", "PLAIN"];
true
};
if (weaponLowered ACE_player) exitWith { true };
if (vehicle ACE_player != ACE_player) exitWith { true };
if (currentWeapon ACE_player != primaryWeapon ACE_player) exitWith { true };
[] spawn {
2 cutText ["", "PLAIN"];
GVAR(WindInfo) = false;
0 cutText ["", "PLAIN"];
GVAR(Protractor) = true;
while {GVAR(Protractor) && !(weaponLowered ACE_player) && currentWeapon ACE_player == primaryWeapon ACE_player} do {
_refPosition = [SafeZoneX + 0.001, SafeZoneY + 0.001, 0.2, 0.2 * 4/3];
_inclinationAngle = asin((ACE_player weaponDirection currentWeapon ACE_player) select 2);
_inclinationAngle = -58 max _inclinationAngle min 58;
1 cutRsc ["RscProtractor", "PLAIN", 1, false];
__ctrl1 ctrlSetScale 0.75;
__ctrl1 ctrlCommit 0;
__ctrl1 ctrlSetText QUOTE(PATHTOF(UI\protractor.paa));
__ctrl1 ctrlSetTextColor [1, 1, 1, 1];
__ctrl2 ctrlSetScale 0.75;
__ctrl2 ctrlSetPosition [(_refPosition select 0), (_refPosition select 1) - 0.0012 * _inclinationAngle, (_refPosition select 2), (_refPosition select 3)];
__ctrl2 ctrlCommit 0;
__ctrl2 ctrlSetText QUOTE(PATHTOF(UI\protractor_marker.paa));
__ctrl2 ctrlSetTextColor [1, 1, 1, 1];
sleep 0.1;
};
GVAR(Protractor) = false;
1 cutText ["", "PLAIN"];
};
true

View File

@ -0,0 +1,64 @@
#include "script_component.hpp"
#define __dsp (uiNamespace getVariable "RscWindIntuitive")
#define __ctrl (__dsp displayCtrl 132948)
private ["_windSpeed", "_windDir", "_playerDir", "_windIndex", "_windColor", "_newWindSpeed", "_windSource", "_height"];
if (GVAR(WindInfo)) exitWith {
GVAR(WindInfo) = false;
0 cutText ["", "PLAIN"];
true
};
if (underwater ACE_player) exitWith { true };
if (vehicle ACE_player != ACE_player) exitWith { true };
[] spawn {
2 cutText ["", "PLAIN"];
GVAR(Protractor) = false;
1 cutText ["", "PLAIN"];
GVAR(WindInfo) = true;
while {GVAR(WindInfo) && !(underwater ACE_player) && vehicle ACE_player == ACE_player} do {
_windIndex = 12;
_windColor = [1, 1, 1, 1];
_windSpeed = (eyePos ACE_player) call FUNC(calculateWindSpeed);
if (_windSpeed > 0.2) then {
_playerDir = getDir ACE_player;
_windDir = (wind select 0) atan2 (wind select 1);
_windIndex = round(((_playerDir - _windDir + 360) % 360) / 30);
_windIndex = _windIndex % 12;
};
// Color Codes from https://en.wikipedia.org/wiki/Beaufort_scale#Modern_scale
if (_windSpeed > 0.3) then { _windColor = [0.796, 1, 1, 1]; };
if (_windSpeed > 1.5) then { _windColor = [0.596, 0.996, 0.796, 1]; };
if (_windSpeed > 3.3) then { _windColor = [0.596, 0.996, 0.596, 1]; };
if (_windSpeed > 5.4) then { _windColor = [0.6, 0.996, 0.4, 1]; };
if (_windSpeed > 7.9) then { _windColor = [0.6, 0.996, 0.047, 1]; };
if (_windSpeed > 10.7) then { _windColor = [0.8, 0.996, 0.059, 1]; };
if (_windSpeed > 13.8) then { _windColor = [1, 0.996, 0.067, 1]; };
if (_windSpeed > 17.1) then { _windColor = [1, 0.796, 0.051, 1]; };
if (_windSpeed > 20.7) then { _windColor = [1, 0.596, 0.039, 1]; };
if (_windSpeed > 24.4) then { _windColor = [1, 0.404, 0.031, 1]; };
if (_windSpeed > 28.4) then { _windColor = [1, 0.22, 0.027, 1]; };
if (_windSpeed > 32.6) then { _windColor = [1, 0.078, 0.027, 1]; };
0 cutRsc ["RscWindIntuitive", "PLAIN", 1, false];
__ctrl ctrlSetScale 0.75;
__ctrl ctrlCommit 0;
__ctrl ctrlSetText format[QUOTE(PATHTOF(UI\wind%1.paa)), _windIndex];
__ctrl ctrlSetTextColor _windColor;
sleep 0.5;
};
GVAR(WindInfo) = false;
0 cutText ["", "PLAIN"];
};
true

View File

@ -0,0 +1,346 @@
/*
* Author: Glowbal, Ruthberg
* Handles wind deflection for projectiles.
*
* Arguments:
* 0: unit - Object the event handler is assigned to <OBJECT>
* 1: weapon - Fired weapon <STRING>
* 2: muzzle - Muzzle that was used <STRING>
* 3: mode - Current mode of the fired weapon <STRING>
* 4: ammo - Ammo used <STRING>
* 5: magazine - magazine name which was used <STRING>
* 6: projectile - Object of the projectile that was shot <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [clientFiredBIS-XEH] call ace_winddeflection_fnc_handleFired
*
* Public: No
*/
#include "script_component.hpp"
#include "defines.h"
private ["_unit", "_weapon", "_mode", "_ammo", "_magazine", "_caliber", "_bullet", "_index", "_opticsName", "_opticType", "_bulletTraceVisible", "_temperature", "_barometricPressure", "_atmosphereModel", "_bulletMass", "_bulletLength", "_bulletTranslation", "_airFriction", "_dragModel", "_velocityBoundaryData", "_muzzleVelocity", "_muzzleVelocityCoef", "_muzzleVelocityShift", "_bulletVelocity", "_bulletSpeed", "_bulletLength", "_bulletWeight", "_barrelTwist", "_twistDirection", "_stabilityFactor", "_transonicStabilityCoef", "_ACE_Elevation", "_ACE_Windage", "_ID"];
_unit = _this select 0;
_weapon = _this select 1;
_mode = _this select 3;
_ammo = _this select 4;
_magazine = _this select 5;
_bullet = _this select 6;
if (isDedicated) exitWith {};
if (!alive _bullet) exitWith {};
if (!([_unit] call EFUNC(common,isPlayer))) exitWith {};
if (underwater _unit) exitWith {};
if (!(_ammo isKindOf "BulletBase")) exitWith {};
if (_unit distanceSqr ACE_player > 9000000) exitWith {};
if (GVAR(ONLY_ACTIVE_FOR_LOCAL_PLAYER) && _unit != ACE_player) exitWith {};
if (!GVAR(VehicleGunnerEnabled) && !(_unit isKindOf "Man")) exitWith {};
if (GVAR(DISABLED_IN_FULL_AUTO_MODE) && getNumber(configFile >> "cfgWeapons" >> _weapon >> _mode >> "autoFire") == 1) exitWith {};
_airFriction = getNumber(configFile >> "cfgAmmo" >> _ammo >> "airFriction");
_muzzleVelocity = getNumber(configFile >> "cfgMagazines" >> _magazine >> "initSpeed");
_muzzleVelocityCoef = getNumber(configFile >> "cfgWeapons" >> _weapon >> "initSpeed");
if (_muzzleVelocityCoef > 0) then {
_muzzleVelocity = _muzzleVelocityCoef;
};
if (_muzzleVelocityCoef < 0) then {
_muzzleVelocity = _muzzleVelocity * (-1 * _muzzleVelocityCoef);
};
_muzzleAccessory = "";
switch (currentWeapon _unit) do {
case primaryWeapon _unit: { _muzzleAccessory = (primaryWeaponItems _unit) select 0; };
case handgunWeapon _unit: { _muzzleAccessory = (handgunItems _unit) select 0; };
};
if (_muzzleAccessory != "" && isNumber(configFile >> "cfgWeapons" >> _muzzleAccessory >> "ItemInfo" >> "MagazineCoef" >> "initSpeed")) then {
_initSpeedCoef = getNumber(configFile >> "cfgWeapons" >> _muzzleAccessory >> "ItemInfo" >> "MagazineCoef" >> "initSpeed");
_muzzleVelocity = _muzzleVelocity * _initSpeedCoef;
};
if (GVAR(BarrelLengthInfluenceEnabled)) then {
_muzzleVelocityShift = [_ammo, _weapon, _muzzleVelocity] call FUNC(calculateBarrelLengthVelocityShift);
if (_muzzleVelocityShift != 0) then {
_bulletVelocity = velocity _bullet;
_bulletSpeed = vectorMagnitude _bulletVelocity;
_bulletVelocity = _bulletVelocity vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply (_muzzleVelocityShift * (_bulletSpeed / _muzzleVelocity)));
_bullet setVelocity _bulletVelocity;
_muzzleVelocity = _muzzleVelocity + _muzzleVelocityShift;
};
};
if (GVAR(AmmoTemperatureEnabled)) then {
_temperature = GET_TEMPERATURE_AT_HEIGHT((getPosASL _unit) select 2);
_muzzleVelocityShift = [_ammo, _temperature] call FUNC(calculateAmmoTemperatureVelocityShift);
if (_muzzleVelocityShift != 0) then {
_bulletVelocity = velocity _bullet;
_bulletSpeed = vectorMagnitude _bulletVelocity;
_bulletVelocity = _bulletVelocity vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply (_muzzleVelocityShift * (_bulletSpeed / _muzzleVelocity)));
_bullet setVelocity _bulletVelocity;
_muzzleVelocity = _muzzleVelocity + _muzzleVelocityShift;
};
};
// TODO: Make _bulletTraceVisible global and toggle it with events
_bulletTraceVisible = false;
if (GVAR(BulletTraceEnabled) && currentWeapon ACE_player == primaryWeapon ACE_player && count primaryWeaponItems ACE_player > 2) then {
_opticsName = (primaryWeaponItems ACE_player) select 2;
_opticType = getNumber(configFile >> "cfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType");
_bulletTraceVisible = (_opticType == 2 || currentWeapon ACE_player in ["ACE_Vector", "Binocular", "Rangefinder", "Laserdesignator"]) && cameraView == "GUNNER";
};
_caliber = getNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_caliber");
_bulletLength = getNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_bulletLength");
_bulletMass = getNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_bulletMass");
_barrelTwist = getNumber(configFile >> "cfgWeapons" >> _weapon >> "ACE_barrelTwist");
_stabilityFactor = 1.5;
if (_caliber > 0 && _bulletLength > 0 && _bulletMass > 0 && _barrelTwist > 0) then {
_temperature = GET_TEMPERATURE_AT_HEIGHT((getPosASL _unit) select 2);
_barometricPressure = 1013.25 * exp(-(GVAR(Altitude) + ((getPosASL _bullet) select 2)) / 7990) - 10 * overcast;
_stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor);
};
_twistDirection = 1;
if (isNumber(configFile >> "cfgWeapons" >> _weapon >> "ACE_twistDirection")) then {
_twistDirection = getNumber(configFile >> "cfgWeapons" >> _weapon >> "ACE_twistDirection");
if (_twistDirection != -1 && _twistDirection != 0 && _twistDirection != 1) then {
_twistDirection = 1;
};
};
_transonicStabilityCoef = 0.5;
if (isNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_transonicStabilityCoef")) then {
_transonicStabilityCoef = getNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_transonicStabilityCoef");
};
_dragModel = 1;
_ballisticCoefficients = [];
_velocityBoundaries = [];
_atmosphereModel = "ICAO";
if (GVAR(AdvancedAirDragEnabled)) then {
if (isNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_dragModel")) then {
_dragModel = getNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_dragModel");
if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then {
_dragModel = 1;
};
};
if (isArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_ballisticCoefficients")) then {
_ballisticCoefficients = getArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_ballisticCoefficients");
};
if (isArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_velocityBoundaries")) then {
_velocityBoundaries = getArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_velocityBoundaries");
};
if (isText(configFile >> "cfgAmmo" >> _ammo >> "ACE_standardAtmosphere")) then {
_atmosphereModel = getText(configFile >> "cfgAmmo" >> _ammo >> "ACE_standardAtmosphere");
};
};
_index = count GVAR(bulletDatabase);
if (count GVAR(bulletDatabaseFreeIndices) > 0) then {
_index = GVAR(bulletDatabaseFreeIndices) select 0;
GVAR(bulletDatabaseFreeIndices) = GVAR(bulletDatabaseFreeIndices) - [_index];
};
GVAR(bulletDatabase) set[_index, [_bullet, _caliber, _airFriction, _muzzleVelocity, _stabilityFactor, _transonicStabilityCoef, _twistDirection, _unit, _bulletTraceVisible, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _dragModel, _index]];
GVAR(bulletDatabaseStartTime) set[_index, time];
GVAR(bulletDatabaseSpeed) set[_index, 0];
GVAR(bulletDatabaseFrames) set[_index, 1];
GVAR(bulletDatabaseLastFrame) set[_index, time];
GVAR(bulletDatabaseHDeflect) set[_index, 0];
GVAR(bulletDatabaseSpinDrift) set[_index, 0];
if ((GVAR(bulletDatabaseOccupiedIndices) pushBack _index) == 0) then {
[{
private ["_bulletDatabaseEntry", "_bullet", "_caliber", "_muzzleVelocity", "_frames", "_speed", "_airFriction", "_airFrictionRef", "_dragModel", "_atmosphereModel", "_ballisticCoefficient", "_ballisticCoefficients", "_velocityBoundaries", "_airDensity", "_stabilityFactor", "_transonicStabilityCoef", "_twistDirection", "_unit", "_bulletTraceVisible", "_index", "_temperature", "_humidity", "_deltaT", "_TOF", "_bulletPosition", "_bulletVelocity", "_bulletSpeed", "_trueVelocity", "_trueSpeed", "_bulletSpeedAvg", "_wind", "_drag", "_dragRef", "_vect", "_accel", "_accelRef", "_centripetalAccel", "_pressure", "_pressureDeviation", "_windSourceObstacle", "_windSourceTerrain", "_height", "_roughnessLength"];
{
_bullet = (GVAR(bulletDatabase) select _x) select 0;
_index = (GVAR(bulletDatabase) select _x) select 13;
if (!alive _bullet) then {
GVAR(bulletDatabaseOccupiedIndices) = GVAR(bulletDatabaseOccupiedIndices) - [_index];
GVAR(bulletDatabaseFreeIndices) pushBack _index;
};
true
} count GVAR(bulletDatabaseOccupiedIndices);
if (count GVAR(bulletDatabaseOccupiedIndices) == 0) exitWith {
GVAR(bulletDatabase) = [];
GVAR(bulletDatabaseStartTime) = [];
GVAR(bulletDatabaseSpeed) = [];
GVAR(bulletDatabaseFrames) = [];
GVAR(bulletDatabaseLastFrame) = [];
GVAR(bulletDatabaseHDeflect) = [];
GVAR(bulletDatabaseSpinDrift) = [];
GVAR(bulletDatabaseOccupiedIndices) = [];
GVAR(bulletDatabaseFreeIndices) = [];
[_this select 1] call cba_fnc_removePerFrameHandler;
};
{
_bulletDatabaseEntry = GVAR(bulletDatabase) select _x;
_bullet = _bulletDatabaseEntry select 0;
_caliber = _bulletDatabaseEntry select 1;
_airFriction = _bulletDatabaseEntry select 2;
_muzzleVelocity = _bulletDatabaseEntry select 3;
_stabilityFactor = _bulletDatabaseEntry select 4;
_transonicStabilityCoef = _bulletDatabaseEntry select 5;
_twistDirection = _bulletDatabaseEntry select 6;
_unit = _bulletDatabaseEntry select 7;
_bulletTraceVisible = _bulletDatabaseEntry select 8;
_ballisticCoefficients = _bulletDatabaseEntry select 9;
_velocityBoundaries = _bulletDatabaseEntry select 10;
_atmosphereModel = _bulletDatabaseEntry select 11;
_dragModel = _bulletDatabaseEntry select 12;
_index = _bulletDatabaseEntry select 13;
_TOF = time - (GVAR(bulletDatabaseStartTime) select _index);
_bulletVelocity = velocity _bullet;
_bulletPosition = getPosASL _bullet;
_bulletSpeed = vectorMagnitude _bulletVelocity;
_bulletDir = (_bulletVelocity select 0) atan2 (_bulletVelocity select 1);
_speed = (GVAR(bulletDatabaseSpeed) select _index);
GVAR(bulletDatabaseSpeed) set[_index, _speed + _bulletSpeed];
_frames = (GVAR(bulletDatabaseFrames) select _index);
GVAR(bulletDatabaseFrames) set[_index, _frames + 1];
_bulletSpeedAvg = (_speed / _frames);
if ((GVAR(SimulationPrecision) < 2) || {_frames % GVAR(SimulationPrecision) == _index % GVAR(SimulationPrecision)}) then {
_deltaT = time - (GVAR(bulletDatabaseLastFrame) select _index);
GVAR(bulletDatabaseLastFrame) set[_index, time];
_trueVelocity = _bulletVelocity;
_trueSpeed = _bulletSpeed;
_wind = [0, 0, 0];
if (GVAR(WindEnabled) && (vectorMagnitude ACE_wind) > 0) then {
_windSourceObstacle = _bulletPosition vectorDiff ((vectorNormalized ACE_wind) vectorMultiply 10);
_windSourceTerrain = _bulletPosition vectorDiff ((vectorNormalized ACE_wind) vectorMultiply 100);
if (!(lineIntersects [_bulletPosition, _windSourceObstacle]) && !(terrainIntersectASL [_bulletPosition, _windSourceTerrain])) then {
_wind = ACE_wind;
_height = ASLToATL(_bulletPosition) select 2;
_height = 0 max _height min 20;
if (_height < 20) then {
_roughnessLength = _bulletPosition call FUNC(calculateRoughnessLength);
_wind = _wind vectorMultiply (ln(_height / _roughnessLength) / ln(20 / _roughnessLength));
};
_trueVelocity = _bulletVelocity vectorDiff _wind;
_trueSpeed = vectorMagnitude _trueVelocity;
};
};
_airFrictionRef = _airFriction;
if (GVAR(AdvancedAirDragEnabled) && (count _ballisticCoefficients) == (count _velocityBoundaries) + 1) then {
_dragRef = _deltaT * _airFrictionRef * _bulletSpeed * _bulletSpeed;
_accelRef = (vectorNormalized _bulletVelocity) vectorMultiply (_dragRef);
_bulletVelocity = _bulletVelocity vectorDiff _accelRef;
_ballisticCoefficient = (_ballisticCoefficients select 0);
for "_i" from (count _velocityBoundaries) - 1 to 0 step -1 do {
if (_bulletSpeed < (_velocityBoundaries select _i)) exitWith {
_ballisticCoefficient = (_ballisticCoefficients select (_i + 1));
};
};
if (GVAR(AtmosphericDensitySimulationEnabled)) then {
_pressure = 1013.25 * exp(-(GVAR(Altitude) + (_bulletPosition select 2)) / 7990) - 10 * overcast;
_temperature = GET_TEMPERATURE_AT_HEIGHT(_bulletPosition select 2);
_humidity = EGVAR(weather,currentHumidity);
_airDensity = STD_AIR_DENSITY_ICAO;
if (_humidity > 0) then {
private ["_pSat", "_vaporPressure", "_partialPressure"];
// Saturation vapor pressure calculated according to: http://wahiduddin.net/calc/density_algorithms.htm
_pSat = 6.1078 * 10 ^ ((7.5 * _temperature) / (_temperature + 237.3));
_vaporPressure = _humidity * _pSat;
_partialPressure = (_pressure * 100)- _vaporPressure;
_airDensity = (_partialPressure * DRY_AIR_MOLAR_MASS + _vaporPressure * WATER_VAPOR_MOLAR_MASS) / (UNIVERSAL_GAS_CONSTANT * KELVIN(_temperature));
} else {
_airDensity = (_pressure * 100) / (SPECIFIC_GAS_CONSTANT_DRY_AIR * KELVIN(_temperature));
};
if (_atmosphereModel == "ICAO") then {
_ballisticCoefficient = (STD_AIR_DENSITY_ICAO / _airDensity) * _ballisticCoefficient;
} else {
_ballisticCoefficient = (STD_AIR_DENSITY_ASM / _airDensity) * _ballisticCoefficient;
};
};
_drag = _deltaT * ([_dragModel, _ballisticCoefficient, _trueSpeed] call FUNC(calculateRetardation));
_accel = (vectorNormalized _trueVelocity) vectorMultiply (_drag);
_bulletVelocity = _bulletVelocity vectorDiff _accel;
} else {
if (GVAR(AtmosphericDensitySimulationEnabled)) then {
_pressureDeviation = 1013.25 * exp(-(GVAR(Altitude) + (_bulletPosition select 2)) / 7990) - 1013.25 - 10 * overcast;
_temperature = GET_TEMPERATURE_AT_HEIGHT(_bulletPosition select 2);
_humidity = EGVAR(weather,currentHumidity);
_airFriction = _airFriction + ((_temperature - 15) * 0.0000015 + _humidity * 0.0000040 + _pressureDeviation * -0.0000009);
};
if (_airFriction != _airFrictionRef || vectorMagnitude _wind > 0) then {
_dragRef = _deltaT * _airFrictionRef * _bulletSpeed * _bulletSpeed;
_accelRef = (vectorNormalized _bulletVelocity) vectorMultiply (_dragRef);
_bulletVelocity = _bulletVelocity vectorDiff _accelRef;
_drag = _deltaT * _airFriction * _trueSpeed * _trueSpeed;
_accel = (vectorNormalized _trueVelocity) vectorMultiply (_drag);
_bulletVelocity = _bulletVelocity vectorAdd _accel;
};
};
if (GVAR(CoriolisEnabled) && _bulletSpeedAvg > 0) then {
_horizontalDeflection = 0.0000729 * (_unit distanceSqr _bullet) * sin(GVAR(Latitude)) / _bulletSpeedAvg;
_horizontalDeflectionPartial = _horizontalDeflection - (GVAR(bulletDatabaseHDeflect) select _index);
GVAR(bulletDatabaseHDeflect) set[_index, _horizontalDeflection];
_vect = [sin(_bulletDir + 90) * _horizontalDeflectionPartial, cos(_bulletDir + 90) * _horizontalDeflectionPartial, 0];
_bulletPosition = _bulletPosition vectorAdd _vect;
};
/*
// Negligible effect on the trajectory
if (GVAR(EoetvoesEnabled)) then {
_centripetalAccel = 2 * 0.0000729 * (_muzzleVelocity / -32.2) * cos(GVAR(Latitude)) * sin(_bulletDir);
_accel = [0, 0, -(_centripetalAccel * _deltaT)];
_bulletVelocity = _bulletVelocity vectorAdd _accel;
};
//*/
if (GVAR(SpinDriftEnabled)) then {
_spinDrift = _twistDirection * 0.0254 * 1.25 * (_stabilityFactor + 1.2) * _TOF ^ 1.83;
_spinDriftPartial = _spinDrift - (GVAR(bulletDatabaseSpinDrift) select _index);
GVAR(bulletDatabaseSpinDrift) set[_index, _spinDrift];
_vect = [sin(_bulletDir + 90) * _spinDriftPartial, cos(_bulletDir + 90) * _spinDriftPartial, 0];
_bulletPosition = _bulletPosition vectorAdd _vect;
};
};
if (GVAR(TransonicRegionEnabled) && _transonicStabilityCoef < 1) then {
if (_bulletSpeed < 345 && _bulletSpeedAvg > 340 && _bulletSpeed > 335) then {
_accel = [(random 0.8) - 0.4, (random 0.8) - 0.4, (random 0.8) - 0.4];
_accel = _accel vectorMultiply (1 - _transonicStabilityCoef);
_bulletVelocity = _bulletVelocity vectorAdd _accel;
};
};
if (_bulletTraceVisible && _bulletSpeed > 600 && _bullet distanceSqr _unit > 400) then {
drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.4*_caliber,0.2*_caliber],[[0,0,0,0.6],[0,0,0,0.4]],[1,0],0,0,"","",""];
};
_bullet setVelocity _bulletVelocity;
_bullet setPosASL _bulletPosition;
true
} count GVAR(bulletDatabaseOccupiedIndices);
}, 0, []] call CBA_fnc_addPerFrameHandler;
};

View File

@ -0,0 +1,191 @@
/*
* Author: Glowbal, Ruthberg
* Handles wind deflection for projectiles using the advanced ballistics dll extension.
*
* Arguments:
* 0: unit - Object the event handler is assigned to <OBJECT>
* 1: weapon - Fired weapon <STRING>
* 2: muzzle - Muzzle that was used <STRING>
* 3: mode - Current mode of the fired weapon <STRING>
* 4: ammo - Ammo used <STRING>
* 5: magazine - magazine name which was used <STRING>
* 6: projectile - Object of the projectile that was shot <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [clientFiredBIS-XEH] call ace_advanced_ballistics_fnc_handleFired
*
* Public: No
*/
#include "script_component.hpp"
#include "defines.h"
private ["_unit", "_weapon", "_mode", "_ammo", "_magazine", "_caliber", "_bullet", "_index", "_opticsName", "_opticType", "_bulletTraceVisible", "_temperature", "_barometricPressure", "_atmosphereModel", "_bulletMass", "_bulletLength", "_bulletTranslation", "_airFriction", "_dragModel", "_velocityBoundaryData", "_muzzleVelocity", "_muzzleVelocityCoef", "_muzzleVelocityShift", "_bulletVelocity", "_bulletSpeed", "_bulletLength", "_bulletWeight", "_barrelTwist", "_twistDirection", "_stabilityFactor", "_transonicStabilityCoef", "_ACE_Elevation", "_ACE_Windage", "_ID"];
_unit = _this select 0;
_weapon = _this select 1;
_mode = _this select 3;
_ammo = _this select 4;
_magazine = _this select 5;
_bullet = _this select 6;
if (isDedicated) exitWith {};
if (!alive _bullet) exitWith {};
if (!([_unit] call EFUNC(common,isPlayer))) exitWith {};
if (underwater _unit) exitWith {};
if (!(_ammo isKindOf "BulletBase")) exitWith {};
if (_unit distanceSqr ACE_player > 9000000) exitWith {};
if (GVAR(ONLY_ACTIVE_FOR_LOCAL_PLAYER) && _unit != ACE_player) exitWith {};
if (!GVAR(VehicleGunnerEnabled) && !(_unit isKindOf "Man")) exitWith {};
if (GVAR(DISABLED_IN_FULL_AUTO_MODE) && getNumber(configFile >> "cfgWeapons" >> _weapon >> _mode >> "autoFire") == 1) exitWith {};
_airFriction = getNumber(configFile >> "cfgAmmo" >> _ammo >> "airFriction");
_muzzleVelocity = getNumber(configFile >> "cfgMagazines" >> _magazine >> "initSpeed");
_muzzleVelocityCoef = getNumber(configFile >> "cfgWeapons" >> _weapon >> "initSpeed");
if (_muzzleVelocityCoef > 0) then {
_muzzleVelocity = _muzzleVelocityCoef;
};
if (_muzzleVelocityCoef < 0) then {
_muzzleVelocity = _muzzleVelocity * (-1 * _muzzleVelocityCoef);
};
switch (currentWeapon _unit) do {
case primaryWeapon _unit: { _muzzleAccessory = (primaryWeaponItems _unit) select 0; };
case handgunWeapon _unit: { _muzzleAccessory = (handgunItems _unit) select 0; };
default { _muzzleAccessory = ""; };
};
if (_muzzleAccessory != "" && isNumber(configFile >> "cfgWeapons" >> _muzzleAccessory >> "ItemInfo" >> "MagazineCoef" >> "initSpeed")) then {
_initSpeedCoef = getNumber(configFile >> "cfgWeapons" >> _muzzleAccessory >> "ItemInfo" >> "MagazineCoef" >> "initSpeed");
_muzzleVelocity = _muzzleVelocity * _initSpeedCoef;
};
if (GVAR(BarrelLengthInfluenceEnabled)) then {
_muzzleVelocityShift = [_ammo, _weapon, _muzzleVelocity] call FUNC(calculateBarrelLengthVelocityShift);
if (_muzzleVelocityShift != 0) then {
_bulletVelocity = velocity _bullet;
_bulletSpeed = vectorMagnitude _bulletVelocity;
_bulletVelocity = _bulletVelocity vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply (_muzzleVelocityShift * (_bulletSpeed / _muzzleVelocity)));
_bullet setVelocity _bulletVelocity;
_muzzleVelocity = _muzzleVelocity + _muzzleVelocityShift;
};
};
if (GVAR(AmmoTemperatureEnabled)) then {
_temperature = GET_TEMPERATURE_AT_HEIGHT((getPosASL _unit) select 2);
_muzzleVelocityShift = [_ammo, _temperature] call FUNC(calculateAmmoTemperatureVelocityShift);
if (_muzzleVelocityShift != 0) then {
_bulletVelocity = velocity _bullet;
_bulletSpeed = vectorMagnitude _bulletVelocity;
_bulletVelocity = _bulletVelocity vectorAdd ((vectorNormalized _bulletVelocity) vectorMultiply (_muzzleVelocityShift * (_bulletSpeed / _muzzleVelocity)));
_bullet setVelocity _bulletVelocity;
_muzzleVelocity = _muzzleVelocity + _muzzleVelocityShift;
};
};
_bulletTraceVisible = false;
if (GVAR(BulletTraceEnabled) && currentWeapon ACE_player == primaryWeapon ACE_player && count primaryWeaponItems ACE_player > 2) then {
_opticsName = (primaryWeaponItems ACE_player) select 2;
_opticType = getNumber(configFile >> "cfgWeapons" >> _opticsName >> "ItemInfo" >> "opticType");
_bulletTraceVisible = (_opticType == 2 || currentWeapon ACE_player in ["ACE_Vector", "Binocular", "Rangefinder", "Laserdesignator"]) && cameraView == "GUNNER";
};
_caliber = getNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_caliber");
_bulletLength = getNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_bulletLength");
_bulletMass = getNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_bulletMass");
_barrelTwist = getNumber(configFile >> "cfgWeapons" >> _weapon >> "ACE_barrelTwist");
_stabilityFactor = 1.5;
if (_caliber > 0 && _bulletLength > 0 && _bulletMass > 0 && _barrelTwist > 0) then {
_temperature = GET_TEMPERATURE_AT_HEIGHT((getPosASL _unit) select 2);
_barometricPressure = 1013.25 * exp(-(GVAR(Altitude) + ((getPosASL _bullet) select 2)) / 7990) - 10 * overcast;
_stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor);
};
_twistDirection = 1;
if (isNumber(configFile >> "cfgWeapons" >> _weapon >> "ACE_twistDirection")) then {
_twistDirection = getNumber(configFile >> "cfgWeapons" >> _weapon >> "ACE_twistDirection");
if (_twistDirection != -1 && _twistDirection != 0 && _twistDirection != 1) then {
_twistDirection = 1;
};
};
_transonicStabilityCoef = 0.5;
if (isNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_transonicStabilityCoef")) then {
_transonicStabilityCoef = getNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_transonicStabilityCoef");
};
_dragModel = 1;
_ballisticCoefficients = [];
_velocityBoundaries = [];
_atmosphereModel = "ICAO";
if (GVAR(AdvancedAirDragEnabled)) then {
if (isNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_dragModel")) then {
_dragModel = getNumber(configFile >> "cfgAmmo" >> _ammo >> "ACE_dragModel");
if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then {
_dragModel = 1;
};
};
if (isArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_ballisticCoefficients")) then {
_ballisticCoefficients = getArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_ballisticCoefficients");
};
if (isArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_velocityBoundaries")) then {
_velocityBoundaries = getArray(configFile >> "cfgAmmo" >> _ammo >> "ACE_velocityBoundaries");
};
if (isText(configFile >> "cfgAmmo" >> _ammo >> "ACE_standardAtmosphere")) then {
_atmosphereModel = getText(configFile >> "cfgAmmo" >> _ammo >> "ACE_standardAtmosphere");
};
};
_index = count GVAR(bulletDatabase);
if (count GVAR(bulletDatabaseFreeIndices) > 0) then {
_index = GVAR(bulletDatabaseFreeIndices) select 0;
GVAR(bulletDatabaseFreeIndices) = GVAR(bulletDatabaseFreeIndices) - [_index];
};
"AdvancedBallistics" callExtension format["new:%1:%2:%3:%4:%5:%6:%7:%8:%9:%10:%11:%12:%13:%14:%15:%16:%17:%18", _index, _airFriction, _ballisticCoefficients, _velocityBoundaries, _atmosphereModel, _dragModel, _stabilityFactor, _twistDirection, _muzzleVelocity, _transonicStabilityCoef, getPosASL _bullet, GVAR(Latitude), EGVAR(weather,currentTemperature), GVAR(Altitude), EGVAR(weather,currentHumidity), overcast, floor(time), time - floor(time)];
GVAR(bulletDatabase) set[_index, [_bullet, _caliber, _bulletTraceVisible, _index]];
if ((GVAR(bulletDatabaseOccupiedIndices) pushBack _index) == 0) then {
[{
private ["_bulletDatabaseEntry", "_index", "_bullet", "_caliber", "_bulletTraceVisible", "_bulletVelocity", "_bulletPosition"];
{
_bulletDatabaseEntry = (GVAR(bulletDatabase) select _x);
_bullet = _bulletDatabaseEntry select 0;
_index = _bulletDatabaseEntry select 3;
if (!alive _bullet) then {
GVAR(bulletDatabaseOccupiedIndices) = GVAR(bulletDatabaseOccupiedIndices) - [_index];
GVAR(bulletDatabaseFreeIndices) pushBack _index;
};
true
} count GVAR(bulletDatabaseOccupiedIndices);
if (count GVAR(bulletDatabaseOccupiedIndices) == 0) exitWith {
GVAR(bulletDatabase) = [];
GVAR(bulletDatabaseOccupiedIndices) = [];
GVAR(bulletDatabaseFreeIndices) = [];
[_this select 1] call cba_fnc_removePerFrameHandler;
};
{
_bulletDatabaseEntry = (GVAR(bulletDatabase) select _x);
_bullet = _bulletDatabaseEntry select 0;
_caliber = _bulletDatabaseEntry select 1;
_bulletTraceVisible = _bulletDatabaseEntry select 2;
_index = _bulletDatabaseEntry select 3;
_bulletVelocity = velocity _bullet;
_bulletPosition = getPosASL _bullet;
if (_bulletTraceVisible && vectorMagnitude _bulletVelocity > 600) then {
drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.4*_caliber,0.2*_caliber],[[0,0,0,0.6],[0,0,0,0.4]],[1,0],0,0,"","",""];
};
call compile ("AdvancedBallistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6:%7", _index, _bulletVelocity, _bulletPosition, ACE_wind, ASLToATL(_bulletPosition) select 2, floor(time), time - floor(time)]);
true
} count GVAR(bulletDatabaseOccupiedIndices);
}, 0, []] call CBA_fnc_addPerFrameHandler;
};

View File

@ -0,0 +1,43 @@
/*
* Author: Ruthberg
* Initializes the advanced ballistics dll extension with terrain data
*
* Arguments:
* Nothing
*
* Return Value:
* Nothing
*
* Public: No
*/
#include "script_component.hpp"
[] spawn {
private ["_initStartTime", "_mapSize", "_mapGrids", "_gridCenter", "_gridHeight", "_gridNumObjects", "_gridSurfaceIsWater"];
_initStartTime = time;
_mapSize = getNumber (configFile >> "CfgWorlds" >> worldName >> "MapSize");
if (("AdvancedBallistics" callExtension format["init:%1:%2", worldName, _mapSize]) == "Terrain already initialized") exitWith {
if (GVAR(INIT_MESSAGE_ENABLED)) then {
systemChat "AdvancedBallistics: Terrain already initialized";
};
};
_mapGrids = ceil(_mapSize / 50);
for "_x" from 0 to _mapGrids * 50 step 50 do {
for "_y" from 0 to _mapGrids * 50 step 50 do {
_gridCenter = [_x + 25, _y + 25];
_gridHeight = round(getTerrainHeightASL _gridCenter);
_gridNumObjects = count (_gridCenter nearObjects ["Building", 50]);
_gridSurfaceIsWater = if (surfaceIsWater _gridCenter) then {1} else {0};
"AdvancedBallistics" callExtension format["set:%1:%2:%3", _gridHeight, _gridNumObjects, _gridSurfaceIsWater];
};
sleep 0.001;
};
if (GVAR(INIT_MESSAGE_ENABLED)) then {
systemChat format["AdvancedBallistics: Finished terrain initialization in %1 seconds", ceil(time - _initStartTime)];
};
};

View File

@ -0,0 +1 @@
#include "\z\ace\addons\advanced_ballistics\script_component.hpp"

View File

@ -0,0 +1,23 @@
["ACE3", QGVAR(WindInfoKey), localize "STR_ACE_AdvancedBallistics_WindInfoKey",
{
// Conditions: canInteract
if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false};
// Statement
[] call FUNC(displayWindInfo);
false
},
{false},
[37, [true, false, false]], false, 0] call CBA_fnc_addKeybind; // (SHIFT + K)
["ACE3", QGVAR(ProtractorKey), localize "STR_ACE_AdvancedBallistics_ProtractorKey",
{
// Conditions: canInteract
if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false};
// Statement
[] call FUNC(displayProtractor);
false
},
{false},
[37, [true, true, false]], false, 0] call CBA_fnc_addKeybind; // (CTRL + SHIFT + K)

View File

@ -0,0 +1,12 @@
#define COMPONENT advanced_ballistics
#include "\z\ace\addons\main\script_mod.hpp"
#ifdef DEBUG_ENABLED_ADVANCEDBALLISTICS
#define DEBUG_MODE_FULL
#endif
#ifdef DEBUG_SETTINGS_ADVANCEDBALLISTICS
#define DEBUG_SETTINGS DEBUG_SETTINGS_ADVANCEDBALLISTICS
#endif
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<Project name="ACE">
<Package name="AdvancedBallistics">
<Key ID="STR_ACE_AdvancedBallistics_WindInfoKey">
<English>Show Wind Info</English>
</Key>
<Key ID="STR_ACE_AdvancedBallistics_ProtractorKey">
<English>Show Protractor</English>
</Key>
</Package>
</Project>

View File

@ -15,7 +15,7 @@
* Nothing
*
* Example:
* [clientFiredBIS-XEH] call ace_winddeflection_fnc_handleFired
* [clientFiredBIS-XEH] call ace_advanced_ballistics_fnc_handleFired
*
* Public: No
*/
@ -24,6 +24,9 @@
private ["_unit", "_weapon", "_ammo", "_bullet", "_airFriction", "_index"];
_unit = _this select 0;
// TODO: Add some way to decide whether to use basic wind deflection or advanced ballistics
if (true) exitWith {false};
if (_unit distance ACE_player > 3000) exitWith {false}; // Large enough distance to not simulate any wind deflection.
if (!GVAR(EnableForAI) && !([_unit] call EFUNC(common,isPlayer))) exitWith {false};
_bullet = _this select 6;