mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Initial draft of the range card implementation.
This commit is contained in:
parent
b2330ae641
commit
697710d40d
1
addons/rangecard/$PBOPREFIX$
Normal file
1
addons/rangecard/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
z\ace\addons\rangecard
|
11
addons/rangecard/CfgEventHandlers.hpp
Normal file
11
addons/rangecard/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
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) );
|
||||
};
|
||||
};
|
60
addons/rangecard/CfgVehicles.hpp
Normal file
60
addons/rangecard/CfgVehicles.hpp
Normal file
@ -0,0 +1,60 @@
|
||||
class CfgVehicles {
|
||||
class Man;
|
||||
class CAManBase: Man {
|
||||
class ACE_Actions {
|
||||
class ACE_Weapon {
|
||||
class GVAR(copyRangeCard) {
|
||||
displayName = "$STR_ACE_RangeCard_CopyRangeCard";
|
||||
distance = 2.0;
|
||||
condition = QUOTE(_target call FUNC(canCopy));
|
||||
statement = QUOTE(_target call FUNC(updateClassNames));
|
||||
icon = QUOTE(PATHTOF(UI\RangeCard_Icon.paa));
|
||||
};
|
||||
};
|
||||
};
|
||||
class ACE_SelfActions {
|
||||
class ACE_Equipment {
|
||||
class GVAR(open) {
|
||||
displayName = "$STR_ACE_RangeCard_OpenRangeCard";
|
||||
condition = QUOTE(call FUNC(canShow) && !GVAR(RangeCardOpened));
|
||||
statement = QUOTE(false call FUNC(openRangeCard));
|
||||
showDisabled = 0;
|
||||
priority = 0.1;
|
||||
icon = QUOTE(PATHTOF(UI\RangeCard_Icon.paa));
|
||||
exceptions[] = {"notOnMap"};
|
||||
};
|
||||
class GVAR(openCopy) {
|
||||
displayName = "$STR_ACE_RangeCard_OpenRangeCardCopy";
|
||||
condition = QUOTE(call FUNC(canShowCopy) && !GVAR(RangeCardOpened));
|
||||
statement = QUOTE(true call FUNC(openRangeCard));
|
||||
showDisabled = 0;
|
||||
priority = 0.1;
|
||||
icon = QUOTE(PATHTOF(UI\RangeCard_Icon.paa));
|
||||
exceptions[] = {"notOnMap"};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class Item_Base_F;
|
||||
class ACE_Item_RangeCard: Item_Base_F {
|
||||
author = "Ruthberg";
|
||||
scope = 2;
|
||||
scopeCurator = 2;
|
||||
displayName = "Range Card";
|
||||
vehicleClass = "Items";
|
||||
class TransportItems {
|
||||
class ACE_RangeCard {
|
||||
name = "ACE_RangeCard";
|
||||
count = 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class Box_NATO_Support_F;
|
||||
class ACE_Box_Misc: Box_NATO_Support_F {
|
||||
class TransportItems {
|
||||
MACRO_ADDITEM(ACE_RangeCard,6);
|
||||
};
|
||||
};
|
||||
};
|
19
addons/rangecard/CfgWeapons.hpp
Normal file
19
addons/rangecard/CfgWeapons.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
|
||||
class CfgWeapons {
|
||||
class ACE_ItemCore;
|
||||
class InventoryItem_Base_F;
|
||||
|
||||
class ACE_RangeCard: ACE_ItemCore {
|
||||
author[] = {"Ruthberg"};
|
||||
scope = 2;
|
||||
displayName = "$STR_ACE_RangeCard_Name";
|
||||
descriptionShort = "$STR_ACE_RangeCard_Description";
|
||||
picture = PATHTOF(UI\RangeCard_Icon.paa);
|
||||
icon = "iconObject_circle";
|
||||
mapSize = 0.034;
|
||||
|
||||
class ItemInfo: InventoryItem_Base_F {
|
||||
mass = 1;
|
||||
};
|
||||
};
|
||||
};
|
10
addons/rangecard/README.md
Normal file
10
addons/rangecard/README.md
Normal file
@ -0,0 +1,10 @@
|
||||
ace_rangecards
|
||||
===============
|
||||
|
||||
Adds range cards
|
||||
|
||||
## Maintainers
|
||||
|
||||
The people responsible for merging changes to this component or answering potential questions.
|
||||
|
||||
- [Ruthberg] (http://github.com/Ulteq)
|
198
addons/rangecard/RscTitles.hpp
Normal file
198
addons/rangecard/RscTitles.hpp
Normal file
@ -0,0 +1,198 @@
|
||||
#define ST_LEFT 0
|
||||
#define ST_RIGHT 1
|
||||
#define ST_CENTER 2
|
||||
|
||||
class RscListNBox;
|
||||
class ScrollBar;
|
||||
|
||||
class RangeCard_RscText {
|
||||
idc=-1;
|
||||
type=0;
|
||||
style=ST_CENTER;
|
||||
colorDisabled[]={0,0,0,0.0};
|
||||
colorBackground[]={0,0,0,0};
|
||||
colorText[]={0,0,0,1};
|
||||
text="";
|
||||
x=0;
|
||||
y=0;
|
||||
h=0.028;
|
||||
w=0.06;
|
||||
font="TahomaB";
|
||||
SizeEx=0.025;
|
||||
shadow=0;
|
||||
};
|
||||
|
||||
class RangeCard_RscListNBox: RscListNBox {
|
||||
idc=-1;
|
||||
type=102;
|
||||
style=0;
|
||||
font="TahomaB";
|
||||
sizeEx=0.026;
|
||||
rowHeight=0.027;
|
||||
colorDisabled[]={0,0,0,0.0};
|
||||
colorBackground[]={1,1,1,1};
|
||||
colorText[]={0,0,0,1};
|
||||
colorScrollbar[]={0.95,0.95,0.95,1};
|
||||
colorSelect[]={0,0,0,1};
|
||||
colorSelect2[]={0,0,0,1};
|
||||
colorSelectBackground[]={1,1,1,0};
|
||||
colorSelectBackground2[]={1,1,1,0};
|
||||
period=0;
|
||||
LineSpacing=0;
|
||||
maxHistoryDelay=1.0;
|
||||
autoScrollSpeed=-1;
|
||||
autoScrollDelay=5;
|
||||
autoScrollRewind=0;
|
||||
soundSelect[]={"",0.09,1};
|
||||
drawSideArrows=0;
|
||||
idcLeft=-1;
|
||||
idcRight=-1;
|
||||
|
||||
class ScrollBar {
|
||||
color[]={1,1,1,0.6};
|
||||
colorActive[]={1,1,1,1};
|
||||
colorDisabled[]={1,1,1,0.3};
|
||||
};
|
||||
|
||||
class ListScrollBar : ScrollBar {
|
||||
};
|
||||
};
|
||||
|
||||
class ACE_RangeCard_Dialog {
|
||||
idd = -1;
|
||||
movingEnable = 1;
|
||||
onLoad = "uiNamespace setVariable ['RangleCard_Display', (_this select 0)]";
|
||||
onUnload = QUOTE(_this call FUNC(onCloseDialog));
|
||||
objects[] = {};
|
||||
|
||||
class controls {
|
||||
class BACKGROUND {
|
||||
moving=1;
|
||||
type=0;
|
||||
font="TahomaB";
|
||||
SizeEX=0.025;
|
||||
idc=-1;
|
||||
style=48;
|
||||
x="safezoneX";
|
||||
y="safezoneY+0.181889";
|
||||
w="1.62727*3/4";
|
||||
h="1.62727";
|
||||
colorBackground[]={1,1,1,1};
|
||||
colorText[]={1,1,1,1};
|
||||
text=QUOTE(PATHTOF(UI\RangeCard.paa));
|
||||
};
|
||||
class CAPTION_TEXT_1: RangeCard_RscText {
|
||||
idc=770000;
|
||||
style=ST_LEFT;
|
||||
x="safezoneX+0.18";
|
||||
y="safezoneY+0.181889+0.0";
|
||||
w="0.56*1.62727*3/4";
|
||||
text=".408 CheyTac - 410 gr Predator Projectiles";
|
||||
};
|
||||
class CAPTION_TEXT_2: CAPTION_TEXT_1 {
|
||||
idc=770001;
|
||||
SizeEx=0.022;
|
||||
y="safezoneY+0.181889+0.03";
|
||||
text="Drop Tables for B.P.: 1013.25mb; Corrected for MVV at Air/Ammo Temperatures -15-35 °C";
|
||||
};
|
||||
class CAPTION_TEXT_3: CAPTION_TEXT_2 {
|
||||
idc=770002;
|
||||
y="safezoneY+0.181889+0.06";
|
||||
text="CheyTac Intervention - 29'' 1:13'' twist (M-200)";
|
||||
};
|
||||
class ZERO_RANGE_TEXT: RangeCard_RscText {
|
||||
idc=77003;
|
||||
style=ST_LEFT;
|
||||
SizeEx=0.028;
|
||||
x="safezoneX+0.885";
|
||||
y="safezoneY+0.181889+0.01";
|
||||
w="0.125*1.62727*3/4";
|
||||
text="100m ZERO";
|
||||
};
|
||||
class BAROMETRIC_PRESSURE_TEXT: ZERO_RANGE_TEXT {
|
||||
idc=77004;
|
||||
colorText[]={1,0,0,0.8};
|
||||
y="safezoneY+0.181889+0.05";
|
||||
text="B.P.: 1013.25mb";
|
||||
};
|
||||
class TARGET_RANGE_TEXT_1: RangeCard_RscText {
|
||||
idc=770010;
|
||||
colorText[]={1,1,1,1};
|
||||
x="safezoneX+0.185";
|
||||
y="safezoneY+0.181889+0.098";
|
||||
text="Target";
|
||||
};
|
||||
class TARGET_RANGE_TEXT_2: TARGET_RANGE_TEXT_1 {
|
||||
idc=770011;
|
||||
SizeEx=0.03;
|
||||
y="safezoneY+0.181889+0.125";
|
||||
text="Range";
|
||||
};
|
||||
class TARGET_RANGE_TEXT_3: TARGET_RANGE_TEXT_1 {
|
||||
idc=770012;
|
||||
y="safezoneY+0.181889+0.152";
|
||||
text="(m)";
|
||||
};
|
||||
class BULLET_DROP_TEXT_1: RangeCard_RscText {
|
||||
idc=770013;
|
||||
x="safezoneX+0.25";
|
||||
y="safezoneY+0.181889+0.095";
|
||||
w="0.405*1.62727*3/4";
|
||||
text="Bullet Drop (MRADs)";
|
||||
};
|
||||
class WIND_LEAD_CAPTION_LIST: RangeCard_RscListNBox {
|
||||
idc=770100;
|
||||
sizeEx=0.021;
|
||||
x="safezoneX+0.728";
|
||||
y="safezoneY+0.181889+0.091";
|
||||
w="0.25*1.62727*3/4";
|
||||
h="0.0909445";
|
||||
columns[]={(0.03/2), (0.985/2)};
|
||||
idcLeft=770101;
|
||||
idcRight=770102;
|
||||
};
|
||||
class TEMPERATURE_CAPTION_LIST_1: RangeCard_RscListNBox {
|
||||
idc=770200;
|
||||
x="safezoneX+0.24";
|
||||
y="safezoneY+0.181889+0.125";
|
||||
w="0.405*1.62727*3/4";
|
||||
h="0.0909445";
|
||||
columns[]={(0/9), (1/9), (2/9), (3/9), (4/9), (5/9), (5.9/9), (6.9/9), (7.8/9)};
|
||||
idcLeft=770201;
|
||||
idcRight=770202;
|
||||
};
|
||||
class TEMPERATURE_CAPTION_LIST_2: RangeCard_RscListNBox {
|
||||
idc=770300;
|
||||
x="safezoneX+0.728";
|
||||
y="safezoneY+0.181889+0.15";
|
||||
w="0.25*1.62727*3/4";
|
||||
h="0.0909445";
|
||||
columns[]={(0/6), (0.9/6), (1.8/6), (2.9/6), (3.8/6), (4.8/6)};
|
||||
idcLeft=770301;
|
||||
idcRight=770302;
|
||||
};
|
||||
class RANGE_CARD_DATA: RangeCard_RscListNBox {
|
||||
idc=770400;
|
||||
x="safezoneX+0.182";
|
||||
y="safezoneY+0.181889+0.194";
|
||||
w="0.72*1.62727*3/4";
|
||||
h="1.62727";
|
||||
columns[]={(0/16), (1.2/16), (2.2/16), (3.2/16), (4.2/16), (5.1/16), (6.1/16), (7.1/16), (8.1/16),
|
||||
(9/16), (10.2/16), (11/16), (11.9/16), (12.8/16), (13.7/16), (14.6/16)};
|
||||
idcLeft=770401;
|
||||
idcRight=770402;
|
||||
};
|
||||
class FOOTNOTE_TEXT_1: CAPTION_TEXT_1 {
|
||||
idc=770020;
|
||||
SizeEx=0.022;
|
||||
y="safezoneY+1.72431";
|
||||
w="0.705*1.62727*3/4";
|
||||
text="For best results keep ammunition at ambient air temperature. Tables calculated for the above listed barrel";
|
||||
};
|
||||
class FOOTNOTE_TEXT_2: FOOTNOTE_TEXT_1 {
|
||||
idc=770021;
|
||||
y="safezoneY+1.72431+0.024";
|
||||
text="and load with optic mounted 1.5'' above line of bore.";
|
||||
};
|
||||
};
|
||||
};
|
BIN
addons/rangecard/UI/RangeCard.paa
Normal file
BIN
addons/rangecard/UI/RangeCard.paa
Normal file
Binary file not shown.
BIN
addons/rangecard/UI/RangeCard_Icon.paa
Normal file
BIN
addons/rangecard/UI/RangeCard_Icon.paa
Normal file
Binary file not shown.
11
addons/rangecard/XEH_postInit.sqf
Normal file
11
addons/rangecard/XEH_postInit.sqf
Normal file
@ -0,0 +1,11 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
#include "initKeybinds.sqf"
|
||||
|
||||
GVAR(RangeCardOpened) = false;
|
||||
|
||||
GVAR(ammoClass) = "B_65x39_Caseless";
|
||||
GVAR(weaponClass) = "arifle_MXM_F";
|
||||
|
||||
GVAR(ammoClassCopy) = "";//"ACE_762x51_Ball_M118LR";
|
||||
GVAR(weaponClassCopy) = "";//srifle_DMR_06_olive_F";
|
14
addons/rangecard/XEH_preInit.sqf
Normal file
14
addons/rangecard/XEH_preInit.sqf
Normal file
@ -0,0 +1,14 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
ADDON = false;
|
||||
|
||||
PREP(calculateSolution);
|
||||
PREP(canCopy);
|
||||
PREP(canShow);
|
||||
PREP(canShowCopy);
|
||||
PREP(onCloseDialog);
|
||||
PREP(openRangeCard);
|
||||
PREP(updateClassNames);
|
||||
PREP(updateRangeCard);
|
||||
|
||||
ADDON = true;
|
17
addons/rangecard/config.cpp
Normal file
17
addons/rangecard/config.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
units[] = {"ACE_Item_RangeCard"};
|
||||
weapons[] = {"ACE_RangeCard"};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ACE_Advanced_Ballistics"};
|
||||
author = "Ruthberg";
|
||||
VERSION_CONFIG;
|
||||
};
|
||||
};
|
||||
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "CfgVehicles.hpp"
|
||||
#include "CfgWeapons.hpp"
|
||||
#include "RscTitles.hpp"
|
218
addons/rangecard/functions/fnc_calculateSolution.sqf
Normal file
218
addons/rangecard/functions/fnc_calculateSolution.sqf
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Author: Ruthberg
|
||||
* Calculates the range card data
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Scope base angle <NUMBER>
|
||||
* 1: Bullet mass <NUMBER>
|
||||
* 2: Bore height <NUMBER>
|
||||
* 3: air friction <NUMBER>
|
||||
* 4: muzzle velocity <NUMBER>
|
||||
* 5: temperature <NUMBER>
|
||||
* 6: barometric pressure <NUMBER>
|
||||
* 7: relative humidity <NUMBER>
|
||||
* 8: simulation steps <NUMBER>
|
||||
* 9: wind speed <ARRAY>
|
||||
* 10: wind direction <NUMBER>
|
||||
* 11: inclination angle <NUMBER>
|
||||
* 12: target speed <NUMBER>
|
||||
* 13: target range <NUMBER>
|
||||
* 14: ballistic coefficient <NUMBER>
|
||||
* 15: drag model <NUMBER>
|
||||
* 16: atmosphere model <STRING>
|
||||
* 17: Store range card data? <BOOL>
|
||||
* 18: Stability factor <NUMBER>
|
||||
* 19: Twist Direction <NUMBER>
|
||||
* 20: Latitude <NUMBER>
|
||||
* 21: Range Card Slot <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* 0: Elevation (MOA) <NUMBER>
|
||||
* 1: Windage (MOA) <ARRAY>
|
||||
* 2: Lead (MOA) <NUMBER>
|
||||
* 3: Time of fligth (SECONDS) <NUMBER>
|
||||
* 4: Remaining velocity (m/s) <NUMBER>
|
||||
* 5: Remaining kinetic energy (ft·lb) <NUMBER>
|
||||
* 6: Vertical coriolis drift (MOA) <NUMBER>
|
||||
* 7: Horizontal coriolis drift (MOA) <NUMBER>
|
||||
* 8: Spin drift (MOA) <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* call ace_rangecard_calculate_range_card_data
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_scopeBaseAngle", "_bulletMass", "_boreHeight", "_airFriction", "_muzzleVelocity", "_temperature", "_barometricPressure", "_relativeHumidity", "_simSteps", "_windSpeed1", "_windSpeed2", "_windDirection", "_inclinationAngle", "_targetSpeed", "_targetRange", "_drag", "_bc", "_dragModel", "_atmosphereModel", "_storeRangeCardData", "_stabilityFactor", "_twistDirection", "_latitude", "_directionOfFire", "_rangeCardSlot"];
|
||||
_scopeBaseAngle = _this select 0;
|
||||
_bulletMass = _this select 1;
|
||||
_boreHeight = _this select 2;
|
||||
_airFriction = _this select 3;
|
||||
_muzzleVelocity = _this select 4;
|
||||
_temperature = _this select 5;
|
||||
_barometricPressure = _this select 6;
|
||||
_relativeHumidity = _this select 7;
|
||||
_simSteps = _this select 8;
|
||||
_windSpeed1 = (_this select 9) select 0;
|
||||
_windSpeed2 = (_this select 9) select 1;
|
||||
_windDirection = _this select 10;
|
||||
_inclinationAngle = _this select 11;
|
||||
_targetSpeed = _this select 12;
|
||||
_targetRange = _this select 13;
|
||||
_bc = _this select 14;
|
||||
_dragModel = _this select 15;
|
||||
_atmosphereModel = _this select 16;
|
||||
_storeRangeCardData = _this select 17;
|
||||
_stabilityFactor = _this select 18;
|
||||
_twistDirection = _this select 19;
|
||||
_latitude = _this select 20;
|
||||
_directionOfFire = _this select 21;
|
||||
_rangeCardSlot = _this select 22;
|
||||
|
||||
if (_storeRangeCardData) then {
|
||||
GVAR(rangeCardDataMVs) pushBack format[" %1", round(_muzzleVelocity)];
|
||||
};
|
||||
|
||||
private ["_bulletPos", "_bulletVelocity", "_bulletAccel", "_bulletSpeed", "_gravity", "_deltaT"];
|
||||
_bulletPos = [0, 0, 0];
|
||||
_bulletVelocity = [0, 0, 0];
|
||||
_bulletAccel = [0, 0, 0];
|
||||
_bulletSpeed = 0;
|
||||
_gravity = [0, sin(_scopeBaseAngle + _inclinationAngle) * -9.80665, cos(_scopeBaseAngle + _inclinationAngle) * -9.80665];
|
||||
_deltaT = 1 / _simSteps;
|
||||
|
||||
private ["_elevation", "_windage1", "_windage2", "_lead", "_TOF", "_trueVelocity", "_trueSpeed", "_kineticEnergy", "_verticalCoriolis", "_verticalDeflection", "_horizontalCoriolis", "_horizontalDeflection", "_spinDrift", "_spinDeflection"];
|
||||
_elevation = 0;
|
||||
_windage1 = 0;
|
||||
_windage2 = 0;
|
||||
_lead = 0;
|
||||
_TOF = 0;
|
||||
_trueVelocity = [0, 0, 0];
|
||||
_trueSpeed = 0;
|
||||
_verticalCoriolis = 0;
|
||||
_verticalDeflection = 0;
|
||||
_horizontalCoriolis = 0;
|
||||
_horizontalDeflection = 0;
|
||||
_spinDrift = 0;
|
||||
_spinDeflection = 0;
|
||||
|
||||
private ["_n", "_range", "_rangeFactor"];
|
||||
_n = 0;
|
||||
_range = 0;
|
||||
_rangeFactor = 1;
|
||||
if (_storeRangeCardData) then {
|
||||
if (GVAR(currentUnit) == 1) then {
|
||||
_rangeFactor = 1.0936133;
|
||||
};
|
||||
};
|
||||
|
||||
private ["_wind1", "_wind2", "_windDrift"];
|
||||
_wind1 = [cos(270 - _windDirection * 30) * _windSpeed1, sin(270 - _windDirection * 30) * _windSpeed1, 0];
|
||||
_wind2 = [cos(270 - _windDirection * 30) * _windSpeed2, sin(270 - _windDirection * 30) * _windSpeed2, 0];
|
||||
_windDrift = 0;
|
||||
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
|
||||
_bc = [_bc, _temperature, _barometricPressure, _relativeHumidity, _atmosphereModel] call EFUNC(advanced_ballistics,calculateAtmosphericCorrection);
|
||||
};
|
||||
|
||||
private ["_speedTotal", "_stepsTotal", "_speedAverage"];
|
||||
_speedTotal = 0;
|
||||
_stepsTotal = 0;
|
||||
_speedAverage = 0;
|
||||
|
||||
private ["_eoetvoesMultiplier"];
|
||||
_eoetvoesMultiplier = 0;
|
||||
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
|
||||
_eoetvoesMultiplier = 2 * (0.0000729 * _muzzleVelocity / -9.80665) * cos(_latitude) * sin(_directionOfFire);
|
||||
};
|
||||
|
||||
_TOF = 0;
|
||||
|
||||
_bulletPos set [0, 0];
|
||||
_bulletPos set [1, 0];
|
||||
_bulletPos set [2, -(_boreHeight / 100)];
|
||||
|
||||
_bulletVelocity set [0, 0];
|
||||
_bulletVelocity set [1, Cos(_scopeBaseAngle) * _muzzleVelocity];
|
||||
_bulletVelocity set [2, Sin(_scopeBaseAngle) * _muzzleVelocity];
|
||||
|
||||
while {_TOF < 6 && (_bulletPos select 1) < _targetRange} do {
|
||||
_bulletSpeed = vectorMagnitude _bulletVelocity;
|
||||
|
||||
_speedTotal = _speedTotal + _bulletSpeed;
|
||||
_stepsTotal = _stepsTotal + 1;
|
||||
_speedAverage = (_speedTotal / _stepsTotal);
|
||||
|
||||
if (_speedAverage > 400 && _bulletSpeed < 340) exitWith {};
|
||||
if (atan((_bulletPos select 2) / (abs(_bulletPos select 1) + 1)) < -2.25) exitWith {};
|
||||
|
||||
_trueVelocity = _bulletVelocity vectorDiff _wind1;
|
||||
_trueSpeed = vectorMagnitude _trueVelocity;
|
||||
|
||||
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
|
||||
_drag = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,extensionAvailable), false]) then {
|
||||
parseNumber(("ace_advanced_ballistics" callExtension format["retard:%1:%2:%3", _dragModel, _bc, _trueSpeed]))
|
||||
} else {
|
||||
([_dragModel, _bc, _trueSpeed] call EFUNC(advanced_ballistics,calculateRetardation))
|
||||
};
|
||||
_bulletAccel = (vectorNormalized _trueVelocity) vectorMultiply (-1 * _drag);
|
||||
} else {
|
||||
_bulletAccel = _trueVelocity vectorMultiply (_trueSpeed * _airFriction);
|
||||
};
|
||||
|
||||
_bulletAccel = _bulletAccel vectorAdd _gravity;
|
||||
|
||||
_bulletVelocity = _bulletVelocity vectorAdd (_bulletAccel vectorMultiply _deltaT);
|
||||
_bulletPos = _bulletPos vectorAdd (_bulletVelocity vectorMultiply _deltaT);
|
||||
|
||||
_TOF = _TOF + _deltaT;
|
||||
|
||||
if (_storeRangeCardData) then {
|
||||
_range = GVAR(rangeCardStartRange) + _n * GVAR(rangeCardIncrement);
|
||||
if ((_bulletPos select 1) * _rangeFactor >= _range && _range <= GVAR(rangeCardEndRange)) then {
|
||||
if ((_bulletPos select 1) > 0) then {
|
||||
_elevation = - atan((_bulletPos select 2) / (_bulletPos select 1));
|
||||
_windage1 = - atan((_bulletPos select 0) / (_bulletPos select 1));
|
||||
};
|
||||
if (_range != 0) then {
|
||||
_lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _range);
|
||||
};
|
||||
private ["_elevationString", "_windageString", "_leadString"];
|
||||
_elevationString = Str(round(-_elevation * 60 / 3.38 * 10) / 10);
|
||||
if (_elevationString == "0") then {
|
||||
_elevationString = "-0.0";
|
||||
};
|
||||
if (_elevationString find "." == -1) then {
|
||||
_elevationString = _elevationString + ".0";
|
||||
};
|
||||
_windageString = Str(round(_windage1 * 60 / 3.38 * 10) / 10);
|
||||
if (_windageString find "." == -1) then {
|
||||
_windageString = _windageString + ".0";
|
||||
};
|
||||
_leadString = Str(round(_lead * 10) / 10);
|
||||
if (_leadString find "." == -1) then {
|
||||
_leadString = _leadString + ".0";
|
||||
};
|
||||
(GVAR(rangeCardDataElevation) select _rangeCardSlot) set [_n, _elevationString];
|
||||
(GVAR(rangeCardDataWindage) select _rangeCardSlot) set [_n, _windageString];
|
||||
(GVAR(rangeCardDataLead) select _rangeCardSlot) set [_n, _leadString];
|
||||
_n = _n + 1;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if ((_bulletPos select 1) > 0) then {
|
||||
_elevation = - atan((_bulletPos select 2) / (_bulletPos select 1));
|
||||
_windage1 = - atan((_bulletPos select 0) / (_bulletPos select 1));
|
||||
_windDrift = (_wind2 select 0) * (_TOF - _targetRange / _muzzleVelocity);
|
||||
_windage2 = - atan(_windDrift / (_bulletPos select 1));
|
||||
};
|
||||
|
||||
if (_targetRange != 0) then {
|
||||
_lead = (_targetSpeed * _TOF) / (Tan(3.38 / 60) * _targetRange);
|
||||
};
|
||||
|
||||
_kineticEnergy = 0.5 * (_bulletMass / 1000 * (_bulletSpeed ^ 2));
|
||||
_kineticEnergy = _kineticEnergy * 0.737562149;
|
||||
|
||||
[_elevation * 60, [_windage1 * 60, _windage2 * 60], _lead, _TOF, _bulletSpeed, _kineticEnergy, _verticalCoriolis * 60, _horizontalCoriolis * 60, _spinDrift * 60]
|
18
addons/rangecard/functions/fnc_canCopy.sqf
Normal file
18
addons/rangecard/functions/fnc_canCopy.sqf
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Authors: Ruthberg
|
||||
* Checks if the target has a copyable range card
|
||||
*
|
||||
* Arguments:
|
||||
* unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* canShow (bool)
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_rangecard_fnc_canCopy
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
((primaryWeapon _this) != "" && [_this] call EFUNC(common,isPlayer) && [_this, "ACE_RangeCard"] call EFUNC(common,hasItem))
|
18
addons/rangecard/functions/fnc_canShow.sqf
Normal file
18
addons/rangecard/functions/fnc_canShow.sqf
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Authors: Ruthberg
|
||||
* Tests if the Range Card can be shown
|
||||
*
|
||||
* Arguments:
|
||||
* Nothing
|
||||
*
|
||||
* Return Value:
|
||||
* canShow (bool)
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_rangecard_fnc_canShow
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
(GVAR(ammoClass) != "" && GVAR(weaponClass) != "" && !GVAR(RangeCardOpened) && !(underwater ACE_player) && ("ACE_RangeCard" in (uniformItems ACE_player)) || ("ACE_RangeCard" in (vestItems ACE_player)))
|
18
addons/rangecard/functions/fnc_canShowCopy.sqf
Normal file
18
addons/rangecard/functions/fnc_canShowCopy.sqf
Normal file
@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Authors: Ruthberg
|
||||
* Tests if the Range Card copy can be shown
|
||||
*
|
||||
* Arguments:
|
||||
* Nothing
|
||||
*
|
||||
* Return Value:
|
||||
* canShow (bool)
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_rangecard_fnc_canShowCopy
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
(GVAR(ammoClassCopy) != "" && GVAR(weaponClassCopy) != "" && !GVAR(RangeCardOpened) && !(underwater ACE_player) && ("ACE_RangeCard" in (uniformItems ACE_player)) || ("ACE_RangeCard" in (vestItems ACE_player)))
|
4
addons/rangecard/functions/fnc_onCloseDialog.sqf
Normal file
4
addons/rangecard/functions/fnc_onCloseDialog.sqf
Normal file
@ -0,0 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
uiNamespace setVariable ['RangleCard_Display', nil];
|
||||
GVAR(RangeCardOpened) = false;
|
36
addons/rangecard/functions/fnc_openRangeCard.sqf
Normal file
36
addons/rangecard/functions/fnc_openRangeCard.sqf
Normal file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Authors: Ruthberg
|
||||
* Opens the range card dialog
|
||||
*
|
||||
* Arguments:
|
||||
* Open copy? <BOOLEAN>
|
||||
*
|
||||
* Return Value:
|
||||
* Nothing
|
||||
*
|
||||
* Example:
|
||||
* call ace_rangecard_fnc_openRangeCard
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (GVAR(RangeCardOpened)) exitWith {};
|
||||
|
||||
if (_this) then {
|
||||
if (GVAR(ammoClassCopy) != "" && GVAR(weaponClassCopy) != "") then {
|
||||
GVAR(RangeCardOpened) = true;
|
||||
|
||||
createDialog "ACE_RangeCard_Dialog";
|
||||
|
||||
[GVAR(ammoClassCopy), GVAR(weaponClassCopy)] call FUNC(updateRangeCard);
|
||||
};
|
||||
} else {
|
||||
if (ACE_player call FUNC(updateClassNames)) then {
|
||||
GVAR(RangeCardOpened) = true;
|
||||
|
||||
createDialog "ACE_RangeCard_Dialog";
|
||||
|
||||
[GVAR(ammoClass), GVAR(weaponClass)] call FUNC(updateRangeCard);
|
||||
};
|
||||
};
|
43
addons/rangecard/functions/fnc_updateClassNames.sqf
Normal file
43
addons/rangecard/functions/fnc_updateClassNames.sqf
Normal file
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Authors: Ruthberg
|
||||
* Updates the ammo and weapon class names
|
||||
*
|
||||
* Arguments:
|
||||
* unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Update successful? <BOOLEAN>
|
||||
*
|
||||
* Example:
|
||||
* unit call ace_rangecard_fnc_updateClassNames
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_unit", "_ammoClass", "_weaponClass", "_ammo", "_ammoConfig", "_parentClasses"];
|
||||
_unit = _this;
|
||||
|
||||
_ammoClass = "";
|
||||
_weaponClass = primaryWeapon _unit;
|
||||
|
||||
if (_weaponClass == "") exitWith { (GVAR(ammoClass) != "" && GVAR(weaponClass) != "") };
|
||||
|
||||
{
|
||||
_ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
|
||||
_ammoConfig = (configFile >> "CfgAmmo" >> _ammo);
|
||||
_parentClasses = [_ammoConfig, true] call BIS_fnc_returnParents;
|
||||
if ("BulletBase" in _parentClasses) exitWith { _ammoClass = _ammo; };
|
||||
} forEach (primaryWeaponMagazine _unit);
|
||||
|
||||
if (_ammoClass == "") exitWith { (GVAR(ammoClass) != "" && GVAR(weaponClass) != "") };
|
||||
|
||||
if (_unit == ACE_player) then {
|
||||
GVAR(ammoClass) = _ammoClass;
|
||||
GVAR(weaponClass) = _weaponClass;
|
||||
} else {
|
||||
GVAR(ammoClassCopy) = _ammoClass;
|
||||
GVAR(weaponClassCopy) = _weaponClass;
|
||||
};
|
||||
|
||||
true
|
118
addons/rangecard/functions/fnc_updateRangeCard.sqf
Normal file
118
addons/rangecard/functions/fnc_updateRangeCard.sqf
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Authors: Ruthberg
|
||||
* Updates the range card data
|
||||
*
|
||||
* Arguments:
|
||||
* 0: ammo class <STRING>
|
||||
* 1: weapon class <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* Nothing
|
||||
*
|
||||
* Example:
|
||||
* [mode] call ace_rangecard_fnc_openRangeCard
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
PARAMS_2(_ammoClass,_weaponClass);
|
||||
|
||||
if (_ammoClass == "" || _weaponClass == "") exitWith {};
|
||||
|
||||
lnbClear 770100;
|
||||
lnbClear 770200;
|
||||
lnbClear 770300;
|
||||
lnbClear 770400;
|
||||
|
||||
lnbAddRow [770100, ["4mps Wind(MRADs)", "1mps LEAD(MRADs)"]];
|
||||
lnbAddRow [770100, ["Air/Ammo Temp", "Air/Ammo Temp"]];
|
||||
|
||||
lnbAddRow [770200, ["-15°C", " -5°C", " 5°C", " 10°C", " 15°C", " 20°C", " 25°C", " 30°C", " 35°C"]];
|
||||
lnbAddRow [770300, ["-15°C", " 10°C", " 35°C", "-15°C", " 10°C", " 35°C"]];
|
||||
|
||||
GVAR(rangeCardDataElevation) = [[], [], [], [], [], [], [], [], []];
|
||||
GVAR(rangeCardDataWindage) = [[], [], [], [], [], [], [], [], []];
|
||||
GVAR(rangeCardDataLead) = [[], [], [], [], [], [], [], [], []];
|
||||
GVAR(rangeCardDataMVs) = [];
|
||||
GVAR(lastValidRow) = [];
|
||||
|
||||
GVAR(currentUnit) = 2;
|
||||
GVAR(rangeCardStartRange) = 100;
|
||||
GVAR(rangeCardIncrement) = 50;
|
||||
GVAR(rangeCardEndRange) = GVAR(rangeCardStartRange) + 49 * GVAR(rangeCardIncrement);
|
||||
|
||||
_ammoConfig = _ammoClass call EFUNC(advanced_ballistics,readAmmoDataFromConfig);
|
||||
_weaponConfig = _weaponClass call EFUNC(advanced_ballistics,readWeaponDataFromConfig);
|
||||
_airFriction = _ammoConfig select 0;
|
||||
_barrelTwist = _weaponConfig select 0;
|
||||
_barrelLength = _weaponConfig select 2;
|
||||
_muzzleVelocity = [_barrelLength, _ammoConfig select 10, _ammoConfig select 11, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift);
|
||||
|
||||
ctrlSetText [770000, format["%1'' - %2 gr (%3)", round((_ammoConfig select 1) * 39.3700787) / 1000, round((_ammoConfig select 3) * 15.4323584), _ammoClass]];
|
||||
ctrlSetText [770002, format["Barrel: %1'' 1:%2'' twist", round(_barrelLength * 0.0393700787), round(_barrelTwist * 0.0393700787)]];
|
||||
|
||||
_bc = (_ammoConfig select 6) select 0;
|
||||
_dragModel = _ammoConfig select 5;
|
||||
_atmosphereModel = _ammoConfig select 8;
|
||||
_boreHeight = 3.81;
|
||||
_zeroRange = 100;
|
||||
|
||||
_barometricPressure = EGVAR(weather,altitude) call EFUNC(weather,calculateBarometricPressure);
|
||||
_relativeHumidity = 0.5;
|
||||
|
||||
ctrlSetText [770001, format["Drop Tables for B.P.: %1mb; Corrected for MVV at Air/Ammo Temperatures -15-35 °C", round(_barometricPressure * 100) / 100]];
|
||||
ctrlSetText [77004 , format["B.P.: %1mb", round(_barometricPressure * 100) / 100]];
|
||||
|
||||
_cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2), _ammoClass, _weaponClass];
|
||||
if (isNil {_cacheEntry}) then {
|
||||
{
|
||||
_mvShift = [_ammoConfig select 9, _x] call EFUNC(advanced_ballistics,calculateAmmoTemperatureVelocityShift);
|
||||
_mv = _muzzleVelocity + _mvShift;
|
||||
|
||||
_result = [0, 0, _boreHeight, _airFriction, _mv, _x, 1013.25, 0.5, 1000, [0, 0], 0, 0, 0, _zeroRange, _bc, _dragModel, _atmosphereModel, false, 1.5, 0, 0, 0] call FUNC(calculateSolution);
|
||||
_scopeBaseAngle = (_result select 0) / 60;
|
||||
|
||||
[_scopeBaseAngle,27,_boreHeight,_airFriction,_mv,_x,_barometricPressure,_relativeHumidity,1000,[4,0],3,0,4,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,true,1.5,1,46,23,_forEachIndex] call FUNC(calculateSolution);
|
||||
} forEach [-15, -5, 5, 10, 15, 20, 25, 30, 35];
|
||||
|
||||
for "_i" from 0 to 9 do {
|
||||
GVAR(lastValidRow) pushBack count (GVAR(rangeCardDataElevation) select _i);
|
||||
while {count (GVAR(rangeCardDataElevation) select _i) < 50} do {
|
||||
(GVAR(rangeCardDataElevation) select _i) pushBack "###";
|
||||
(GVAR(rangeCardDataWindage) select _i) pushBack "##";
|
||||
(GVAR(rangeCardDataLead) select _i) pushBack "##";
|
||||
};
|
||||
};
|
||||
|
||||
missionNamespace setVariable [format[QGVAR(%1_%2), _ammoClass, _weaponClass], [GVAR(rangeCardDataElevation), GVAR(rangeCardDataWindage), GVAR(rangeCardDataLead), GVAR(rangeCardDataMVs), GVAR(lastValidRow)]];
|
||||
} else {
|
||||
GVAR(rangeCardDataElevation) = _cacheEntry select 0;
|
||||
GVAR(rangeCardDataWindage) = _cacheEntry select 1;
|
||||
GVAR(rangeCardDataLead) = _cacheEntry select 2;
|
||||
GVAR(rangeCardDataMVs) = _cacheEntry select 3;
|
||||
GVAR(lastValidRow) = _cacheEntry select 4;
|
||||
};
|
||||
|
||||
lnbAddRow [770200, GVAR(rangeCardDataMVs)];
|
||||
|
||||
for "_i" from 0 to 49 do {
|
||||
lnbAddRow [770400, [Str(GVAR(rangeCardStartRange) + GVAR(rangeCardIncrement) * _i), (GVAR(rangeCardDataElevation) select 0) select _i, (GVAR(rangeCardDataElevation) select 1) select _i, (GVAR(rangeCardDataElevation) select 2) select _i,
|
||||
(GVAR(rangeCardDataElevation) select 3) select _i, (GVAR(rangeCardDataElevation) select 4) select _i, (GVAR(rangeCardDataElevation) select 5) select _i,
|
||||
(GVAR(rangeCardDataElevation) select 6) select _i, (GVAR(rangeCardDataElevation) select 7) select _i, (GVAR(rangeCardDataElevation) select 8) select _i,
|
||||
(GVAR(rangeCardDataWindage) select 0) select _i, (GVAR(rangeCardDataWindage) select 3) select _i, (GVAR(rangeCardDataWindage) select 8) select _i,
|
||||
(GVAR(rangeCardDataLead) select 0) select _i, (GVAR(rangeCardDataLead) select 3) select _i, (GVAR(rangeCardDataLead) select 8) select _i]];
|
||||
};
|
||||
|
||||
#define __dsp (uiNamespace getVariable "RangleCard_Display")
|
||||
#define __ctrlListNBox (__dsp displayCtrl 770400)
|
||||
|
||||
{
|
||||
__ctrlListNBox lnbSetColor [[_x, 0], [1, 1, 1, 1]];
|
||||
} forEach [0, 8, 18, 28, 38, 48];
|
||||
|
||||
{
|
||||
for "_i" from (GVAR(lastValidRow) select _x) to 49 do {
|
||||
__ctrlListNBox lnbSetColor [[_i, _forEachIndex + 1], [0, 0, 0, 0.6]];
|
||||
};
|
||||
} forEach [0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 3, 8, 0, 3, 8];
|
1
addons/rangecard/functions/script_component.hpp
Normal file
1
addons/rangecard/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "\z\ace\addons\rangecard\script_component.hpp"
|
31
addons/rangecard/initKeybinds.sqf
Normal file
31
addons/rangecard/initKeybinds.sqf
Normal file
@ -0,0 +1,31 @@
|
||||
["ACE3 Equipment", QGVAR(RangeCardDialogKey), localize "STR_ACE_RangeCard_RangeCardDialogKey",
|
||||
{
|
||||
// Conditions: canInteract, canShow
|
||||
if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false};
|
||||
if (GVAR(RangeCardOpened)) exitWith {
|
||||
closeDialog 0;
|
||||
false
|
||||
};
|
||||
if !(call FUNC(canShow)) exitWith {false};
|
||||
// Statement
|
||||
false call FUNC(openRangeCard);
|
||||
true
|
||||
},
|
||||
{false},
|
||||
[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key)
|
||||
|
||||
["ACE3 Equipment", QGVAR(RangeCardCopyDialogKey), localize "STR_ACE_RangeCard_RangeCardCopyDialogKey",
|
||||
{
|
||||
// Conditions: canInteract, canShowCopy
|
||||
if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false};
|
||||
if (GVAR(RangeCardOpened)) exitWith {
|
||||
closeDialog 0;
|
||||
false
|
||||
};
|
||||
if !(call FUNC(canShowCopy)) exitWith {false};
|
||||
// Statement
|
||||
true call FUNC(openRangeCard);
|
||||
true
|
||||
},
|
||||
{false},
|
||||
[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key)
|
12
addons/rangecard/script_component.hpp
Normal file
12
addons/rangecard/script_component.hpp
Normal file
@ -0,0 +1,12 @@
|
||||
#define COMPONENT rangecard
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
#ifdef DEBUG_ENABLED_RANGECARD
|
||||
#define DEBUG_MODE_FULL
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SETTINGS_RANGECARD
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_RANGECARD
|
||||
#endif
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
26
addons/rangecard/stringtable.xml
Normal file
26
addons/rangecard/stringtable.xml
Normal file
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project name="ACE">
|
||||
<Package name="RangeCard">
|
||||
<Key ID="STR_ACE_RangeCard_Name">
|
||||
<English>Range Card</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_RangeCard_Description">
|
||||
<English>50 METER increments -- MRAD/MRAD (reticle/turrets)</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_RangeCard_OpenRangeCard">
|
||||
<English>Open Range Card</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_RangeCard_OpenRangeCardCopy">
|
||||
<English>Open Range Card Copy</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_RangeCard_RangeCardDialogKey">
|
||||
<English>Open Range Card</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_RangeCard_RangeCardCopyDialogKey">
|
||||
<English>Open Range Card Copy</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_RangeCard_CopyRangeCard">
|
||||
<English>Copy Range Card</English>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
Loading…
Reference in New Issue
Block a user