Compare commits

..

2 Commits

23 changed files with 55 additions and 1000 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-57
View File
@@ -1,57 +0,0 @@
class CfgSkeletons
{
class braf_A29_Flir
{
isDiscrete=0;
skeletonInherit="";
skeletonBones[]={};
};
};
class CfgModels
{
class braf_a29_gunner_n
{
htMin=0;
htMax=0;
afMax=0;
mfMax=0;
mFact=0;
tBody=0;
skeletonName="braf_A29_Flir";
sectionsInherit="";
sections[]={};
class Animations
{
};
};
class braf_a29_gunner_m
{
htMin=0;
htMax=0;
afMax=0;
mfMax=0;
mFact=0;
tBody=0;
skeletonName="braf_A29_Flir";
sectionsInherit="";
sections[]={};
class Animations
{
};
};
class braf_a29_gunner_w
{
htMin=0;
htMax=0;
afMax=0;
mfMax=0;
mFact=0;
tBody=0;
skeletonName="braf_A29_Flir";
sectionsInherit="";
sections[]={};
class Animations
{
};
};
};
@@ -1,468 +0,0 @@
/*
Author: Brazilian Armed Forces
File: BRAF_AirOptics.hpp
Purpose:
Define a UI (InGame Optics) do A-29 com elementos vanilla + elementos custom (IDCs 9901..9905)
e instala um EventHandler para atualizar os controles em tempo real enquanto a optics estiver ativa.
Correções lógicas aplicadas (padrão Arma 3):
1) onLoad usa _this (minúsculo), não _This
2) EH 'Draw' entrega CONTROL; chamamos a função passando DISPLAY via ctrlParent
3) onUnload remove o EH, evitando acumular handlers após abrir/fechar optics
4) Caminhos usam barra simples '\' (padrão Arma 3), sem inventar '\\'
=======================================================================
BRAF A-29 STARSAPHIRE - DICIONÁRIO DE IDCs (REFERÊNCIA)
=======================================================================
IDDs
300 - Display do optics A-29 (BRAF_RscOptics_A29)
Grupos (ControlsGroup)
170 - CA_IGUI_elements_group (grupo principal do optics)
CUSTOM (BRAF)
9901 - Seta: indicador de elevação (trilho vertical)
9902 - Texto: valor numérico da elevação (ex: -12.3°)
9903 - Seta: indicador de direção (trilho horizontal)
9904 - Texto: valor numérico da direção (ex: -45°)
9905 - Seta: bússola (norte geográfico relativo ao apontamento)
*/
class ScrollBar;
class RscUnitInfo;
class RscControlsGroup;
class RscControlsGroupNoScrollbars;
class CA_HUDRscControlsGroup;
class RscText;
class RangeText: RscText{};
class RscPicture;
class RscOpticsText;
class RscOpticsValue;
class RscIGProgress;
class RscInGameUI
{
class BRAF_RscOptics_A29: RscUnitInfo
{
idd = 300;
controls[] = {"CA_Zeroing","CA_IGUI_elements_group","CA_VehicleToggles"};
class VScrollbar;
class HScrollbar;
onLoad = "[""onLoad"",_this,""RscUnitInfo"",'IGUI'] call (uiNamespace getVariable 'BIS_fnc_initDisplay'); _this call BRAF_fnc_initRSC;";
onUnload = "[""onUnload"",_this,""RscUnitInfo"",'IGUI'] call (uiNamespace getVariable 'BIS_fnc_initDisplay')";
class CA_IGUI_elements_group: RscControlsGroup
{
idc = 170;
class VScrollbar: VScrollbar { width = 0; };
class HScrollbar: HScrollbar { height = 0; };
x = "-4 * (0.01875 * SafezoneH) + (SafezoneX + ((SafezoneW - SafezoneH)/2))";
y = "000 * (0.02500 * SafezoneH) + (SafezoneY)";
w = "100 * (0.01875 * SafezoneH)";
h = "080 * (0.02500 * SafezoneH)";
class controls
{
class ValueDistance: RscText
{
style=1;
sizeEx="0.038*SafezoneH";
shadow=0;
font="EtelkaMonospacePro";
idc=198;
text="245678";
colorText[] = {0,0,0,1};
colorBackground[] = {0,0,0,0};
x="45.5 * (0.01875 * SafezoneH)";
y="35.75 * (0.025 * SafezoneH)";
w="8 * (0.01875 * SafezoneH)";
h="1.2 * (0.025 * SafezoneH)";
};
class TextDistance: ValueDistance
{
style=0;
idc=1800;
text="Laser dist:";
x="42 * (0.01875 * SafezoneH)";
y="35.75 * (0.025 * SafezoneH)";
};
class ValueGrid: ValueDistance
{
idc=171;
text="245678";
x="10 * (0.01875 * SafezoneH)";
y="34 * (0.025 * SafezoneH)";
};
class TextGrid: ValueGrid
{
style=0;
idc=1801;
text="GPS grid:";
x="4.45 * (0.01875 * SafezoneH)";
y="34 * (0.025 * SafezoneH)";
};
class ValueWeapon: ValueDistance
{
idc=172;
text="245678";
x="10 * (0.01875 * SafezoneH)";
y="35.75 * (0.025 * SafezoneH)";
};
class TextTarget: ValueGrid
{
style=0;
idc=1802;
text="Target grid:";
x="4.45 * (0.01875 * SafezoneH)";
y="35.75 * (0.025 * SafezoneH)";
};
class TextElev: ValueGrid
{
style=0;
idc=1803;
text="Elev:";
x="32 * (0.01875 * SafezoneH)";
y="35.75 * (0.025 * SafezoneH)";
};
class ValueElev: ValueDistance
{
idc=175;
text="245";
x="32 * (0.01875 * SafezoneH)";
y="35.75 * (0.025 * SafezoneH)";
};
class TextAz: ValueGrid
{
style=0;
idc=1804;
text="Az:";
x="24.5 * (0.01875 * SafezoneH)";
y="35.75 * (0.025 * SafezoneH)";
};
class ValueAz: ValueDistance
{
idc=156;
text="245";
x="23 * (0.01875 * SafezoneH)";
y="35.75 * (0.025 * SafezoneH)";
};
class TextAlt: ValueGrid
{
style=0;
idc=1805;
text="Alt:";
x="24.5 * (0.01875 * SafezoneH)";
y="34 * (0.025 * SafezoneH)";
};
class ValueAlt: ValueDistance
{
idc=189;
text="245678";
x="24 * (0.01875 * SafezoneH)";
y="34 * (0.025 * SafezoneH)";
};
class CA_Time: ValueGrid
{
idc=190;
style=0;
shadow=0;
text="XX:XX:xx";
x="54 * (0.01875 * SafezoneH)";
y="35.75 * (0.025 * SafezoneH)";
w="6.5 * (0.01875 * SafezoneH)";
};
class braf_fov_mode: RscText
{
idc = 154;
text = "WFOV";
sizeEx="0.03*SafezoneH";
style=0;
shadow=0;
font="EtelkaMonospacePro";
x = "0 * (0.01875 * SafezoneH)";
y="3 * (0.025 * SafezoneH)";
w="5 * (0.01875 * SafezoneH)";
h="1.2 * (0.025 * SafezoneH)";
colorText[] = {0,0,0,1};
};
class CA_VisionMode: RscText
{
idc=152;
sizeEx="0.03*SafezoneH";
style=0;
shadow=0;
font="EtelkaMonospacePro";
text="DTV";
x="4.5 * (0.01875 * SafezoneH)";
y="3 * (0.025 * SafezoneH)";
w="5 * (0.01875 * SafezoneH)";
h="1.2 * (0.025 * SafezoneH)";
colorText[] = {0,0,0,1};
};
class CA_FlirMode: CA_VisionMode
{
idc=153;
text="BHOT";
x="7 * (0.01875 * SafezoneH)";
};
class CA_Laser: RscText
{
idc=158;
style="0x30 + 0x800";
sizeEx="0.038*SafezoneH";
colorText[]={0.70599997,0.074500002,0.0196,1};
shadow=0;
font="EtelkaMonospacePro";
text="\A3\ui_f\data\igui\rscingameui\rscoptics\laser_designator_iconLaserOn.paa";
x="33 * (0.01875 * SafezoneH)";
y="8 * (0.025 * SafezoneH)";
w="3.5 * (0.01875 * SafezoneH)";
h="1.5 * (0.025 * SafezoneH)";
};
class braf_arrow_vert: RscPicture
{
idc = 1901;
text = "\braf\braf_air2\braf_optics_air2\A29\data\braf_arrow_vert_ca.paa";
shadow = 0;
sizeEx = "0.03*SafezoneH";
x = "-0.5 * (0.01875 * SafezoneH)";
y = "16.6 * (0.025 * SafezoneH)";
w = "2.1 * (0.01875 * SafezoneH)";
h = "2.1 * (0.025 * SafezoneH)";
color[] = {1,1,1,1};
colorBackground[] = {0,0,0,0};
};
class braf_elev_value: RscText
{
idc = 1902;
style = 0;
shadow = 0;
sizeEx = "0.03*SafezoneH";
colorText[] = {1,1,1,1};
colorBackground[] = {0,0,0,0};
x = "1 * (0.01875 * SafezoneH)";
y = "16.6 * (0.025 * SafezoneH)";
w = "4 * (0.01875 * SafezoneH)";
h = "2.1 * (0.025 * SafezoneH)";
text = "-120";
};
class braf_arrow_horiz: braf_arrow_vert
{
idc = 1903;
text = "\braf\braf_air2\braf_optics_air2\A29\data\braf_arrow_hor_ca.paa";
x = "-12 * (0.01875 * SafezoneH)";
y = "30 * (0.025 * SafezoneH)";
};
class braf_dir_value: braf_elev_value
{
idc = 1904;
style = 2;
x = "-12.95 * (0.01875 * SafezoneH)";
y = "20 * (0.025 * SafezoneH)";
w = "4.0 * (0.01875 * SafezoneH)";
h = "2.1 * (0.025 * SafezoneH)";
text = "-180";
};
class braf_compass_arrow: RscPicture
{
idc = 1905;
style = 144;
shadow = 0;
text = "\braf\braf_air2\braf_optics_air2\A29\data\braf_arrow_north_ca.paa";
x = "57.5 * (0.01875 * SafezoneH)";
y = "25.5 * (0.02500 * SafezoneH)";
w = "10 * (0.01875 * SafezoneH)";
h = "10 * (0.02500 * SafezoneH)";
};
class braf_compass_n: braf_elev_value
{
idc = -1;
style = 2;
sizeEx = "0.03*SafezoneH";
x = "60 * (0.01875 * SafezoneH)";
y = "28 * (0.02500 * SafezoneH)";
w = "05 * (0.01875 * SafezoneH)";
h = "05 * (0.02500 * SafezoneH)";
text = "N";
};
class BRAF_AirData_Label_HDG: RscText
{
idc = 1906;
style = 2;
shadow = 0;
font = "EtelkaMonospacePro";
sizeEx = "0.02*SafezoneH";
colorText[] = {1,1,1,1};
colorBackground[] = {0,0,0,0};
text = "HDG:";
x="60 * (0.01875 * SafezoneH)";
y = "4.4 * (0.025 * SafezoneH)";
w = "4 * (0.01875 * SafezoneH)";
h = "1.2 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Value_HDG: BRAF_AirData_Label_HDG
{
idc = 1907;
style = 1;
text = "000";
x = "60 * (0.01875 * SafezoneH)";
w = "5 * (0.01875 * SafezoneH)";
};
class BRAF_AirData_Label_IAS: BRAF_AirData_Label_HDG
{
idc = 1908;
text = "IAS:";
y = "5 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Value_IAS: BRAF_AirData_Value_HDG
{
idc = 1909;
text = "000";
y = "5 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Label_GS: BRAF_AirData_Label_HDG
{
idc = 1910;
text = "GS:";
y = "5.6 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Value_GS: BRAF_AirData_Value_HDG
{
idc = 1911;
text = "000";
y = "5.6 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Label_RALT: BRAF_AirData_Label_HDG
{
idc = 1912;
text = "RALT:";
y = "6.2 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Value_RALT: BRAF_AirData_Value_HDG
{
idc = 1913;
text = "0000";
y = "6.2 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Label_BARO: BRAF_AirData_Label_HDG
{
idc = 1914;
text = "BARO:";
y = "6.8 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Value_BARO: BRAF_AirData_Value_HDG
{
idc = 1915;
text = "0000";
y = "6.8 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Label_ROLL: BRAF_AirData_Label_HDG
{
idc = 1916;
text = "ROLL:";
y = "7.4 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Value_ROLL: BRAF_AirData_Value_HDG
{
idc = 1917;
text = "0";
y = "7.4 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Label_PTCH: BRAF_AirData_Label_HDG
{
idc = 1918;
text = "PTCH:";
y = "8 * (0.025 * SafezoneH)";
};
class BRAF_AirData_Value_PTCH: BRAF_AirData_Value_HDG
{
idc = 1919;
text = "0";
y = "8 * (0.025 * SafezoneH)";
};
};
};
};
class BRAF_RscOptics_Fennec: BRAF_RscOptics_A29
{
};
};
class BRAF_A29_Gunner_Optics: Optics_Armored
{
class Wide: RCWSOptics
{
initFov = 0.5236;
minFov = 0.5236;
maxFov = 0.5236;
opticsDisplayName = "WFOV";
visionMode[] = { "Normal", "TI" };
thermalMode[] = { 0, 1 };
thermalNoise[] = { 0.5, 1.25, 2.5, 0.75, 1, 0, 0, 0.95 };
gunnerOpticsModel = "\braf\braf_air2\braf_optics_air2\A29\braf_a29_gunner_w.p3d";
gunnerOpticsEffect[] = {};
directionStabilized = 1;
};
class Medium: Wide
{
opticsDisplayName = "MFOV";
gunnerOpticsModel = "\braf\braf_air2\braf_optics_air2\A29\braf_a29_gunner_m.p3d";
initFov = 0.0593;
minFov = 0.0593;
maxFov = 0.0593;
};
class Narrow: Wide
{
opticsDisplayName = "NFOV";
gunnerOpticsModel = "\braf\braf_air2\braf_optics_air2\A29\braf_a29_gunner_n.p3d";
initFov = 0.0140;
minFov = 0.0140;
maxFov = 0.0140;
};
class Narrower: Narrow
{
opticsDisplayName = "NFOV 2X";
initFov = 0.0070;
minFov = 0.0070;
maxFov = 0.0070;
};
class UltraNarrow: Narrow
{
opticsDisplayName = "NFOV 4X";
initFov = 0.0035;
minFov = 0.0035;
maxFov = 0.0035;
};
};
class BRAF_Fennec_Gunner_Optics: BRAF_A29_Gunner_Optics
{
class Wide;
class Medium;
class Narrow;
class Narrower;
class UltraNarrow;
};
@@ -1580,7 +1580,7 @@ class braf_A29B: BRAF_A29_base
maxTurn=180;
initTurn=0;
gunnerName="$STR_A3_COPILOT";
turretInfoType="BRAF_RscOptics_A29";
turretInfoType="BRAF_RscOptics_Air_FLIR";
isCopilot=1;
weapons[]=
{
@@ -1622,22 +1622,56 @@ class braf_A29B: BRAF_A29_base
class ViewOptics: RCWSOptics
{
};
class OpticsIn: BRAF_A29_Gunner_Optics
class OpticsIn
{
class Wide: Wide
class Wide
{
initAngleX = 0;
minAngleX = -120;
maxAngleX = 30;
initAngleY = 0;
minAngleY = -180;
maxAngleY = 180;
initFov = 0.5236;
minFov = 0.5236;
maxFov = 0.5236;
opticsDisplayName = "WFOV";
visionMode[] = {"Normal","TI"};
thermalMode[] = {0,1};
thermalNoise[] = {0.5,1.25,2.5,0.75,1,0,0,0.95};
gunnerOpticsModel = "\braf\braf_optics_air\StarSaphire\braf_StarSaphire_w.p3d";
gunnerOpticsEffect[] = {};
directionStabilized = 1;
};
class Medium: Medium
class Medium: Wide
{
opticsDisplayName = "MFOV";
gunnerOpticsModel = "\braf\braf_optics_air\StarSaphire\braf_StarSaphire_m.p3d";
initFov = 0.0593;
minFov = 0.0593;
maxFov = 0.0593;
};
class Narrow: Narrow
class Narrow: Wide
{
opticsDisplayName = "NFOV";
gunnerOpticsModel = "\braf\braf_optics_air\StarSaphire\braf_StarSaphire_n.p3d";
initFov = 0.0140;
minFov = 0.0140;
maxFov = 0.0140;
};
class Narrower: Narrower
class Narrower: Narrow
{
opticsDisplayName = "NFOV 2X";
initFov = 0.0070;
minFov = 0.0070;
maxFov = 0.0070;
};
class UltraNarrow: UltraNarrow
class UltraNarrow: Narrow
{
opticsDisplayName = "NFOV 4X";
initFov = 0.0035;
minFov = 0.0035;
maxFov = 0.0035;
};
};
class OpticsOut
@@ -2460,4 +2494,4 @@ class braf_ejection_chute: braf_ejection_chute_base
"\braf\braf_air2\braf_airplanes\braf_super_tucano\Dataa\ejection_chute_co.paa"
};
};
*/
*/
-28
View File
@@ -1,28 +0,0 @@
#define IGUI_GROUP 170
// IDCs (seus)
#define BRAF_ELEV_ARROW 1901
#define BRAF_ELEV_TXT 1902
#define BRAF_AZ_ARROW 1903
#define BRAF_AZ_TXT 1904
#define BRAF_NORTH_ARROW 1905
// RANGES da régua (fixos do seu pod)
#define BRAF_MIN_TURN -180
#define BRAF_MAX_TURN 180
#define BRAF_MIN_ELEV -120
#define BRAF_MAX_ELEV 30
// ====== CONSTANTES DO TAPE (mesmo conceito do USAF) ======
// Azimute (horizontal): X do ponto onde está -180 (início da régua)
// e distância total até +180 (largura da régua)
#define BRAF_AZ_BEG (0.035 * safeZoneW)
#define BRAF_AZ_DIS (0.5375 * safeZoneW)
#define BRAF_AZ_NUM_OFFSET (-0.009 * safeZoneW)
#define BRAF_AZ_TXT_Y_OFFSET (-0.5 * 0.025 * safeZoneH)
// Elevação (vertical): Y do ponto onde está +30 (topo) e distância total até -120 (base)
// (no USAF eles mapeiam para Y)
#define BRAF_EZ_BEG (0.196289 * safeZoneH)
#define BRAF_EZ_DIS (0.684570 * safeZoneH)
#define BRAF_EZ_NUM_OFFSET (0 * safeZoneH)
-290
View File
@@ -1,290 +0,0 @@
/*
Author: Brazilian Armed Forces
File: fn_flirControls.sqf
Objetivo:
- Atualizar indicadores de AZ (direção) e EZ (elevação) do POD FLIR em relação ao corpo da aeronave
- Atualizar indicação de Norte geográfico relativa ao centro do apontamento (compasso)
Padrão adotado:
- Mesmo padrão (carrot/tape):
* ler ctrlPosition
* calcular posição com BEG/DIS/OFFSET
* ctrlSetPosition + ctrlCommit 0
Observação:
- Este script assume que:
* os controles estão acessíveis via _display displayCtrl <IDC>
* existem constantes BEG/DIS/OFFSET para a régua horizontal (AZ) e vertical (EZ)
*/
#define IGUI_GROUP 170
#define BRAF_ELEV_ARROW 1901
#define BRAF_ELEV_TXT 1902
#define BRAF_AZ_ARROW 1903
#define BRAF_AZ_TXT 1904
#define BRAF_NORTH_ARROW 1905
#define BRAF_HDG_VALUE 1907
#define BRAF_IAS_VALUE 1909
#define BRAF_GS_VALUE 1911
#define BRAF_RALT_VALUE 1913
#define BRAF_BARO_VALUE 1915
#define BRAF_ROLL_VALUE 1917
#define BRAF_PTCH_VALUE 1919
#define BRAF_MIN_TURN -180
#define BRAF_MAX_TURN 180
#define BRAF_MIN_ELEV -120
#define BRAF_MAX_ELEV 30
#define BRAF_AZ_BEG (0.04 * safeZoneW)
#define BRAF_AZ_DIS (0.5375 * safeZoneW)
#define BRAF_AZ_NUM_OFFSET (0.5 * safeZoneW)
#define BRAF_AZ_TXT_Y_OFFSET (-1 * 0.025 * safeZoneH)
#define BRAF_EZ_BEG (0.215 * safeZoneH)
#define BRAF_EZ_DIS (0.52 * safeZoneH)
#define BRAF_EZ_NUM_OFFSET (0 * safeZoneH)
disableSerialization;
params ["_display"];
// Segurança: display inválido
if (isNull _display) exitWith {};
// Segurança: só atualiza quando estiver em optics
if (cameraView != "GUNNER") exitWith {};
// Veículo base (corpo)
private _veh = vehicle player;
if (isNull _veh) exitWith {};
// CORREÇÃO: Validar que os controles customizados existem antes de acessá-los
// Previne crashes se os IDCs não foram criados corretamente na config
if (isNull (_display displayCtrl BRAF_ELEV_ARROW)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle de seta de elevação (IDC 1901) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_AZ_ARROW)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle de seta de azimute (IDC 1903) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_ELEV_TXT)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle de texto de elevação (IDC 1902) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_AZ_TXT)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle de texto de azimute (IDC 1904) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_NORTH_ARROW)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle da bússola norte (IDC 1905) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_HDG_VALUE)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle HDG (IDC 1907) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_IAS_VALUE)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle IAS (IDC 1909) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_GS_VALUE)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle GS (IDC 1911) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_RALT_VALUE)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle RALT (IDC 1913) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_BARO_VALUE)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle BARO (IDC 1915) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_ROLL_VALUE)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle ROLL (IDC 1917) não encontrado!";
};
if (isNull (_display displayCtrl BRAF_PTCH_VALUE)) exitWith {
systemChat "[BRAF A-29] ERRO: Controle PTCH (IDC 1919) não encontrado!";
};
// ======================================================================
// 1) Captura da direção REAL da câmera (mundo) e conversão para o corpo
// ======================================================================
// Vetor forward real da câmera ativa (mundo)
private _p0 = positionCameraToWorld [0, 0, 0];
private _p1 = positionCameraToWorld [0, 0, 1];
private _vW = _p1 vectorDiff _p0;
private _lenW = vectorMagnitude _vW;
if (_lenW < 0.0001) exitWith {};
_vW = _vW vectorMultiply (1/_lenW);
// Direção absoluta (mundo) em RADIANOS para o compasso
// atan2 retorna radianos: 0 = norte, π/2 = leste, π ou -π = sul, -π/2 = oeste
private _absDir_rad = (_vW select 0) atan2 (_vW select 1);
// Normalizar para [0, 2π) para ficar positivo
if (_absDir_rad < 0) then {
_absDir_rad = _absDir_rad + (2 * pi);
};
// Converte vetor para o referencial do veículo (corpo)
private _vM = _veh vectorWorldToModel _vW;
private _lenM = vectorMagnitude _vM;
if (_lenM < 0.0001) exitWith {};
_vM = _vM vectorMultiply (1/_lenM);
private _x = _vM select 0;
private _y = _vM select 1;
private _z = _vM select 2;
// AZIMUTH (yaw) relativo ao corpo: [-180..+180] em GRAUS
private _azimuth = (_x atan2 _y);
if (_azimuth > 180) then {
_azimuth = _azimuth - 360;
};
if (_azimuth < -180) then {
_azimuth = _azimuth + 360;
};
// ELEVATION (pitch) relativo ao corpo, permitindo < -90 em GRAUS
private _h = sqrt (_x*_x + _y*_y);
private _signY = if (_y < 0) then {
-1
} else {
1
};
private _yPrime = _h * _signY;
private _elevation = (_z atan2 _yPrime);
// Clamp nos limites do POD
_azimuth = _azimuth max BRAF_MIN_TURN min BRAF_MAX_TURN; // -180..+180
_elevation = _elevation max BRAF_MIN_ELEV min BRAF_MAX_ELEV; // -120..+30
// ======================================================================
// 2) TURRET AZ (Azimute/Direção Horizontal)
// ======================================================================
private _turretAZcarrotCtrlPos = ctrlPosition (_display displayCtrl BRAF_AZ_ARROW);
private _turretAZtextCtrlPos = ctrlPosition (_display displayCtrl BRAF_AZ_TXT);
// X do carrot na régua de -180..+180
// CORREÇÃO: Referências de constantes alteradas para BRAF_AZ_BEG e BRAF_AZ_DIS
private _azPosX = BRAF_AZ_BEG + (((_azimuth + 180) / 360) * BRAF_AZ_DIS);
// Atualizar posição da seta horizontal (carrot) - IDC 1903
(_display displayCtrl BRAF_AZ_ARROW) ctrlSetPosition [
_azPosX,
_turretAZcarrotCtrlPos select 1,
_turretAZcarrotCtrlPos select 2,
_turretAZcarrotCtrlPos select 3
];
(_display displayCtrl BRAF_AZ_ARROW) ctrlCommit 0;
// Atualizar valor numérico do azimute - IDC 1904
// O texto usa o mesmo centro X da seta e fica acima dela.
(_display displayCtrl BRAF_AZ_TXT) ctrlSetText str (round _azimuth);
private _azArrowW = _turretAZcarrotCtrlPos select 2;
private _azTextW = _turretAZtextCtrlPos select 2;
(_display displayCtrl BRAF_AZ_TXT) ctrlSetPosition [
_azPosX + ((_azArrowW - _azTextW) / 2),
(_turretAZcarrotCtrlPos select 1) + BRAF_AZ_TXT_Y_OFFSET,
_azTextW,
_turretAZtextCtrlPos select 3
];
(_display displayCtrl BRAF_AZ_TXT) ctrlCommit 0;
// ======================================================================
// 3) TURRET EZ (Elevação/pitch Vertical)
// Régua: +30 (topo) -> -120 (base)
// ======================================================================
private _turretEZcarrotCtrlPos = ctrlPosition (_display displayCtrl BRAF_ELEV_ARROW);
private _turretEZtextCtrlPos = ctrlPosition (_display displayCtrl BRAF_ELEV_TXT);
// tEl: 0 no topo (+30), 1 na base (-120)
private _tEl = (BRAF_MAX_ELEV - _elevation) / (BRAF_MAX_ELEV - BRAF_MIN_ELEV);
if (_tEl < 0) then {
_tEl = 0;
};
if (_tEl > 1) then {
_tEl = 1;
};
// Y da régua
// CORREÇÃO: Referências de constantes alteradas para BRAF_EZ_BEG e BRAF_EZ_DIS
private _elevPos = BRAF_EZ_BEG + (_tEl * BRAF_EZ_DIS);
// Atualizar posição da seta vertical (carrot) - IDC 1901
(_display displayCtrl BRAF_ELEV_ARROW) ctrlSetPosition [
_turretEZcarrotCtrlPos select 0,
_elevPos,
_turretEZcarrotCtrlPos select 2,
_turretEZcarrotCtrlPos select 3
];
(_display displayCtrl BRAF_ELEV_ARROW) ctrlCommit 0;
// Atualizar valor numérico da elevação - IDC 1902
(_display displayCtrl BRAF_ELEV_TXT) ctrlSetText str (round _elevation);
(_display displayCtrl BRAF_ELEV_TXT) ctrlSetPosition [
_turretEZtextCtrlPos select 0,
_elevPos + BRAF_EZ_NUM_OFFSET,
_turretEZtextCtrlPos select 2,
_turretEZtextCtrlPos select 3
];
// CORREÇÃO: Referência de constante alterada para BRAF_EZ_NUM_OFFSET
(_display displayCtrl BRAF_ELEV_TXT) ctrlCommit 0;
// ======================================================================
// 4) AIRCRAFT DATA - HDG / IAS / GS / RALT / BARO / ROLL / PTCH
// ======================================================================
private _hdg = round (getDir _veh);
private _ias = round (speed _veh);
private _gs = round ((vectorMagnitude (velocity _veh)) * 3.6);
private _ralt = round ((getPosATL _veh) select 2);
private _baro = round ((getPosASL _veh) select 2);
private _pitchBank = _veh call BIS_fnc_getPitchBank;
private _ptch = round (_pitchBank select 0);
private _roll = round (_pitchBank select 1);
private _ctrlHDG = _display displayCtrl BRAF_HDG_VALUE;
private _ctrlIAS = _display displayCtrl BRAF_IAS_VALUE;
private _ctrlGS = _display displayCtrl BRAF_GS_VALUE;
private _ctrlRALT = _display displayCtrl BRAF_RALT_VALUE;
private _ctrlBARO = _display displayCtrl BRAF_BARO_VALUE;
private _ctrlROLL = _display displayCtrl BRAF_ROLL_VALUE;
private _ctrlPTCH = _display displayCtrl BRAF_PTCH_VALUE;
if (!isNull _ctrlHDG) then {
_ctrlHDG ctrlSetText format ["%1", _hdg];
};
if (!isNull _ctrlIAS) then {
_ctrlIAS ctrlSetText format ["%1", _ias];
};
if (!isNull _ctrlGS) then {
_ctrlGS ctrlSetText format ["%1", _gs];
};
if (!isNull _ctrlRALT) then {
_ctrlRALT ctrlSetText format ["%1", _ralt];
};
if (!isNull _ctrlBARO) then {
_ctrlBARO ctrlSetText format ["%1", _baro];
};
if (!isNull _ctrlROLL) then {
_ctrlROLL ctrlSetText format ["%1", _roll];
};
if (!isNull _ctrlPTCH) then {
_ctrlPTCH ctrlSetText format ["%1", _ptch];
};
// ======================================================================
// 5) COMPASS N (Bússola Norte Geográfico)
// ======================================================================
// CORREÇÃO: Referência de IDC alterada:
// COMPASS_N_ARROW → BRAF_NORTH_ARROW (IDC 1905)
// Motivo: Alinhar com nomenclatura definida em braf_constants.h
//
// A fórmula: rotação_seta = -_absDir_rad
// Isso faz a seta apontar para o NORTE true em relação ao que a câmera vê:
// - Se câmera aponta NORTE: -0° → seta aponta PARA CIMA (norte)
// - Se câmera aponta LESTE: -π/2 → seta aponta PARA A ESQUERDA (norte relativo)
// - Se câmera aponta SUL: -π → seta aponta PARA BAIXO (norte relativo)
// - Se câmera aponta OESTE: -(-π/2) = +π/2 → seta aponta PARA A DIREITA (norte relativo)
(_display displayCtrl BRAF_NORTH_ARROW) ctrlSetAngle [ -_absDir_rad, 0.5, 0.5 ];
-48
View File
@@ -1,48 +0,0 @@
/*
Author: Brazilian Armed Forces
File: fn_initRSC.sqf
Objetivo:
- Cria e gerencia o loop EachFrame que chama uma função de atualização BRAF_fnc_flirControls
*/
disableSerialization;
params ["_display"];
// Diagnóstico: Verificar se a função está definida
if (isNil "BRAF_fnc_flirControls") then {
systemChat "[BRAF A-29] AVISO: BRAF_fnc_flirControls não foi carregada!";
};
uiNamespace setVariable ["BRAF_A29_UI_Display", _display];
if ((uiNamespace getVariable ["BRAF_A29_PFH_eachFrame", -1]) > -1) then {
removeMissionEventHandler ["EachFrame", (uiNamespace getVariable "BRAF_A29_PFH_eachFrame")];
uiNamespace setVariable ["BRAF_A29_PFH_eachFrame", nil];
};
private _pfh = addMissionEventHandler ["EachFrame", {
if (cameraView != "GUNNER") exitWith {};
private _display = uiNamespace getVariable ["BRAF_A29_UI_Display", displayNull];
if (isNull _display) exitWith {
removeMissionEventHandler ["EachFrame", (uiNamespace getVariable "BRAF_A29_PFH_eachFrame")];
uiNamespace setVariable ["BRAF_A29_PFH_eachFrame", nil];
uiNamespace setVariable ["BRAF_A29_UI_Display", nil];
};
private _veh = vehicle player;
if (isNull _veh) exitWith {
removeMissionEventHandler ["EachFrame", (uiNamespace getVariable "BRAF_A29_PFH_eachFrame")];
uiNamespace setVariable ["BRAF_A29_PFH_eachFrame", nil];
uiNamespace setVariable ["BRAF_A29_UI_Display", nil];
};
[_display] call BRAF_fnc_flirControls;
}];
uiNamespace setVariable ["BRAF_A29_PFH_eachFrame", _pfh];
//systemChat "[BRAF A-29] Sistema FLIR iniciado com sucesso";
+1 -7
View File
@@ -13,6 +13,7 @@ class CfgPatches {
"BRAF_Insignia",
"BRAF_Soft",
"BRAF_Air",
"BRAF_Optics_Air",
};
requiredVersion = 0.1;
units[] = {
@@ -79,11 +80,6 @@ class CfgFunctions {
file = "braf\braf_air2\braf_fnc\fn_remove_before_flight.sqf";
};*/
};
class UI {
file = "braf\braf_air2\braf_fnc";
class initRSC {};
class flirControls {};
};
};
};
@@ -147,9 +143,7 @@ class VehicleSystemsTemplateRightGunner
class components;
};
class RCWSOptics;
class Optics_Armored;
#include "braf_air_anim\CfgMovesBasic.hpp"
#include "braf_optics_air2\BRAF_AirOptics.hpp"
class CfgVehicles {
class Air;
class ParachuteBase;
-3
View File
@@ -1,4 +1 @@
braf_air2\braf_airplanes\braf_super_tucano\data\a29_sms_co.png
braf_air2\braf_optics_air2\a29\data\braf_a29_reticulo_m_white_ca.png
braf_air2\braf_optics_air2\a29\data\braf_a29_reticulo_n_white_ca.png
braf_air2\braf_optics_air2\a29\data\braf_a29_reticulo_w_white_ca.png
+10 -3
View File
@@ -8,16 +8,23 @@
disableSerialization;
params ["_display"];
private _display = _this;
if (_display isEqualType []) then {
_display = _display param [0, displayNull];
};
if (isNull _display) exitWith {
systemChat "[BRAF FLIR] ERROR: initRSC received an invalid display.";
};
if (isNil "BRAF_fnc_flirControls") then {
systemChat "[BRAF FLIR] WARNING: BRAF_fnc_flirControls is not loaded.";
};
uiNamespace setVariable ["BRAF_FLIR_UI_Display", _display];
[] call BRAF_fnc_shutdownRSC;
uiNamespace setVariable ["BRAF_FLIR_UI_Display", _display];
private _pfh = addMissionEventHandler ["EachFrame", {
if (cameraView != "GUNNER") exitWith {};
+2 -49
View File
@@ -25,8 +25,6 @@ class RscPicture;
class RscOpticsText;
class RscOpticsValue;
class RscIGProgress;
class RCWSOptics;
class Optics_Armored;
class CfgFunctions {
class BRAF {
@@ -46,8 +44,8 @@ class RscInGameUI {
controls[] = {"CA_Zeroing","CA_IGUI_elements_group","CA_VehicleToggles"};
class VScrollbar;
class HScrollbar;
onLoad = "[\"onLoad\",_this,\"RscUnitInfo\",'IGUI'] call (uiNamespace getVariable 'BIS_fnc_initDisplay'); _this call BRAF_fnc_initRSC;";
onUnload = "[\"onUnload\",_this,\"RscUnitInfo\",'IGUI'] call (uiNamespace getVariable 'BIS_fnc_initDisplay'); _this call BRAF_fnc_shutdownRSC;";
onLoad = "[""onLoad"",_this,""RscUnitInfo"",""IGUI""] call (uiNamespace getVariable ""BIS_fnc_initDisplay""); [_this select 0] call BRAF_fnc_initRSC;";
onUnload = "[""onUnload"",_this,""RscUnitInfo"",""IGUI""] call (uiNamespace getVariable ""BIS_fnc_initDisplay""); [_this select 0] call BRAF_fnc_shutdownRSC;";
class CA_IGUI_elements_group: RscControlsGroup {
idc = 170;
@@ -380,48 +378,3 @@ class RscInGameUI {
};
};
};
class BRAF_Air_FLIR_Gunner_Optics: Optics_Armored {
class Wide: RCWSOptics {
initFov = 0.5236;
minFov = 0.5236;
maxFov = 0.5236;
opticsDisplayName = "WFOV";
visionMode[] = {"Normal","TI"};
thermalMode[] = {0,1};
thermalNoise[] = {0.5,1.25,2.5,0.75,1,0,0,0.95};
gunnerOpticsModel = "\braf\braf_optics_air\StarSaphire\braf_StarSaphire_w.p3d";
gunnerOpticsEffect[] = {};
directionStabilized = 1;
};
class Medium: Wide {
opticsDisplayName = "MFOV";
gunnerOpticsModel = "\braf\braf_optics_air\StarSaphire\braf_StarSaphire_m.p3d";
initFov = 0.0593;
minFov = 0.0593;
maxFov = 0.0593;
};
class Narrow: Wide {
opticsDisplayName = "NFOV";
gunnerOpticsModel = "\braf\braf_optics_air\StarSaphire\braf_StarSaphire_n.p3d";
initFov = 0.0140;
minFov = 0.0140;
maxFov = 0.0140;
};
class Narrower: Narrow {
opticsDisplayName = "NFOV 2X";
initFov = 0.0070;
minFov = 0.0070;
maxFov = 0.0070;
};
class UltraNarrow: Narrow {
opticsDisplayName = "NFOV 4X";
initFov = 0.0035;
minFov = 0.0035;
maxFov = 0.0035;
};
};