From e9b4618d6a90a159bfc728aea2944ca459cfd4d9 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Wed, 21 Sep 2016 01:25:11 -0500 Subject: [PATCH 01/23] Pike prototype --- addons/pike/$PBOPREFIX$ | 1 + addons/pike/CfgAmmo.hpp | 58 ++++++++++++++++ addons/pike/CfgEventhandlers.hpp | 18 +++++ addons/pike/CfgMagazines.hpp | 13 ++++ addons/pike/CfgWeapons.hpp | 6 ++ addons/pike/README.md | 11 +++ addons/pike/XEH_PREP.hpp | 1 + addons/pike/XEH_postInit.sqf | 5 ++ addons/pike/XEH_preInit.sqf | 7 ++ addons/pike/XEH_preStart.sqf | 3 + addons/pike/config.cpp | 20 ++++++ addons/pike/functions/fnc_handleFired.sqf | 61 +++++++++++++++++ addons/pike/functions/script_component.hpp | 1 + addons/pike/models/ace_pike_ammo.p3d | Bin 0 -> 20548 bytes addons/pike/models/pike_surface.rvmat | 76 +++++++++++++++++++++ addons/pike/script_component.hpp | 18 +++++ addons/pike/stringtable.xml | 8 +++ 17 files changed, 307 insertions(+) create mode 100644 addons/pike/$PBOPREFIX$ create mode 100644 addons/pike/CfgAmmo.hpp create mode 100644 addons/pike/CfgEventhandlers.hpp create mode 100644 addons/pike/CfgMagazines.hpp create mode 100644 addons/pike/CfgWeapons.hpp create mode 100644 addons/pike/README.md create mode 100644 addons/pike/XEH_PREP.hpp create mode 100644 addons/pike/XEH_postInit.sqf create mode 100644 addons/pike/XEH_preInit.sqf create mode 100644 addons/pike/XEH_preStart.sqf create mode 100644 addons/pike/config.cpp create mode 100644 addons/pike/functions/fnc_handleFired.sqf create mode 100644 addons/pike/functions/script_component.hpp create mode 100644 addons/pike/models/ace_pike_ammo.p3d create mode 100644 addons/pike/models/pike_surface.rvmat create mode 100644 addons/pike/script_component.hpp create mode 100644 addons/pike/stringtable.xml diff --git a/addons/pike/$PBOPREFIX$ b/addons/pike/$PBOPREFIX$ new file mode 100644 index 00000000000..2eefcc6075b --- /dev/null +++ b/addons/pike/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\pike \ No newline at end of file diff --git a/addons/pike/CfgAmmo.hpp b/addons/pike/CfgAmmo.hpp new file mode 100644 index 00000000000..69a712252f2 --- /dev/null +++ b/addons/pike/CfgAmmo.hpp @@ -0,0 +1,58 @@ +class CfgAmmo { + class FlareBase; + class GVAR(ammo_gl): FlareBase { + model = QPATHTOF(models\ace_pike_ammo.p3d); + lightColor[] = {0, 0, 0, 0}; + smokeColor[] = {0, 0, 0, 0}; + timeToLive = 1; + }; + + class M_Titan_AT; + class GVAR(ammo_rocket): M_Titan_AT { + irLock = 0; + laserLock = 0; + airLock = 0; + manualControl = 0; + + timeToLive = 30; + + model = QPATHTOF(models\ace_pike_ammo.p3d); + maxSpeed = 150; + thrust = 30; + thrustTime = 2; + + hit = 100; + indirectHit = 8; + indirectHitRange = 6; + + initTime = 0; + + // Begin ACE guidance Configs + class ace_missileguidance { + enabled = 1; + + minDeflection = 0.0005; // Minium flap deflection for guidance + maxDeflection = 0.0025; // Maximum flap deflection for guidance + incDeflection = 0.0005; // The incrmeent in which deflection adjusts. + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = {"SALH"}; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = {"LOAL"}; + + seekerAngle = 90; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 1; + seekerMaxRange = 1000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "LIN"; + attackProfiles[] = { "LIN", "DIR", "MID", "HI" }; + }; + }; +}; diff --git a/addons/pike/CfgEventhandlers.hpp b/addons/pike/CfgEventhandlers.hpp new file mode 100644 index 00000000000..5da5fd0dc24 --- /dev/null +++ b/addons/pike/CfgEventhandlers.hpp @@ -0,0 +1,18 @@ + +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preStart)); + }; +}; + +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) ); + }; +}; diff --git a/addons/pike/CfgMagazines.hpp b/addons/pike/CfgMagazines.hpp new file mode 100644 index 00000000000..ef69f814941 --- /dev/null +++ b/addons/pike/CfgMagazines.hpp @@ -0,0 +1,13 @@ +class CfgMagazines { + class 1Rnd_HE_Grenade_shell; + class ACE_40mm_Pike: 1Rnd_HE_Grenade_shell { + displayName = CSTRING(magazine_displayName); + displayNameShort = "Pike SALH"; + descriptionShort = ""; + // picture = QPATHTOF(data\inventory_ca.paa); + ammo = QGVAR(ammo_gl); + model = QPATHTOF(models\ace_pike_ammo.p3d); + initSpeed = 40; + mass = 10; + }; +}; diff --git a/addons/pike/CfgWeapons.hpp b/addons/pike/CfgWeapons.hpp new file mode 100644 index 00000000000..61c2fef5a1a --- /dev/null +++ b/addons/pike/CfgWeapons.hpp @@ -0,0 +1,6 @@ +class CfgWeapons { + class GrenadeLauncher; + class UGL_F: GrenadeLauncher { + magazines[] += {"ACE_40mm_Pike"}; + }; +}; diff --git a/addons/pike/README.md b/addons/pike/README.md new file mode 100644 index 00000000000..1e3424afa4e --- /dev/null +++ b/addons/pike/README.md @@ -0,0 +1,11 @@ +ace_pike +=========== + +Adds 40mm Pike semi-active laser seeking rocket, firable from the M320 or EGLM grenade launcher. + + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [PabstMirror](http://github.com/PabstMirror) diff --git a/addons/pike/XEH_PREP.hpp b/addons/pike/XEH_PREP.hpp new file mode 100644 index 00000000000..64eb51ef80f --- /dev/null +++ b/addons/pike/XEH_PREP.hpp @@ -0,0 +1 @@ +PREP(handleFired); diff --git a/addons/pike/XEH_postInit.sqf b/addons/pike/XEH_postInit.sqf new file mode 100644 index 00000000000..7f39382a7e3 --- /dev/null +++ b/addons/pike/XEH_postInit.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +if (!hasInterface) exitWith {}; + +["ace_firedPlayer", FUNC(handleFired)] call CBA_fnc_addEventHandler; diff --git a/addons/pike/XEH_preInit.sqf b/addons/pike/XEH_preInit.sqf new file mode 100644 index 00000000000..a7feade1c39 --- /dev/null +++ b/addons/pike/XEH_preInit.sqf @@ -0,0 +1,7 @@ +#include "script_component.hpp" + +ADDON = false; + +#include "XEH_PREP.hpp" + +ADDON = true; diff --git a/addons/pike/XEH_preStart.sqf b/addons/pike/XEH_preStart.sqf new file mode 100644 index 00000000000..022888575ed --- /dev/null +++ b/addons/pike/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/pike/config.cpp b/addons/pike/config.cpp new file mode 100644 index 00000000000..0fea3337069 --- /dev/null +++ b/addons/pike/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_common", "ace_laser", "ace_missileguidance"}; + author = ECSTRING(common,ACETeam); + authors[] = {"PabstMirror"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgEventhandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/pike/functions/fnc_handleFired.sqf b/addons/pike/functions/fnc_handleFired.sqf new file mode 100644 index 00000000000..34b1ee58167 --- /dev/null +++ b/addons/pike/functions/fnc_handleFired.sqf @@ -0,0 +1,61 @@ +/* + * Author: PabstMirror + * Handlese firing the 40mm pike grenade/rocket + * + * Arguments: + * FiredEH + * + * Return Value: + * Nothing + * + * Example: + * [] call ace_pike_fnc_handleFired + * + * Public: No + */ +#include "script_component.hpp" + +//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; +TRACE_7("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); +if (_ammo != QGVAR(ammo_gl)) exitWith {}; + +[{ + params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; + TRACE_7("rocket stage",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); + + //If null (deleted or hit water) exit: + if (isNull _projectile) exitWith {}; + + private _posASL = getPosASL _projectile; + private _vel = velocity _projectile; + + systemChat format ["gl %1 %2",_vel, round vectorMagnitude _vel]; + + deleteVehicle _projectile; + + private _rocket = QGVAR(ammo_rocket) createVehicle (getPosATL _projectile); + + _rocket setPosASL _posASL; + + // Set correct velocity and direction (must set velocity before changeMissileDirection) + _rocket setVelocity _vel; + [_rocket, vectorNormalized _vel] call EFUNC(missileguidance,changeMissileDirection); + + + private _vel = velocity _rocket; + systemChat format ["rocket %1 %2",_vel, round vectorMagnitude _vel]; + + // Start missile guidance + [_unit, _weapon, _muzzle, _mode, QGVAR(ammo_rocket), _magazine, _rocket] call EFUNC(missileguidance,onFired); + + #ifdef DEBUG_MODE_FULL + [{ + params ["_args", "_pfID"]; + _args params [["_rocket", objNull], "_startTime"]; + if (!alive _rocket) exitWith {systemChat "done"; [_pfID] call CBA_fnc_removePerFrameHandler;}; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,1,1], ASLtoAGL getPosASL _rocket, 0.75, 0.75, 0, "", 1, 0.025, "TahomaB"]; + hintSilent format ["vel %1\n%2 mps\n%3dist %3\ntof %4",velocity _rocket, round vectorMagnitude velocity _rocket, _rocket distance player, time - _startTime]; + }, 0.0, [_rocket, time]] call CBA_fnc_addPerFrameHandler; + #endif + +}, _this, 0.1] call CBA_fnc_waitAndExecute; diff --git a/addons/pike/functions/script_component.hpp b/addons/pike/functions/script_component.hpp new file mode 100644 index 00000000000..85866ed86ba --- /dev/null +++ b/addons/pike/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\pike\script_component.hpp" \ No newline at end of file diff --git a/addons/pike/models/ace_pike_ammo.p3d b/addons/pike/models/ace_pike_ammo.p3d new file mode 100644 index 0000000000000000000000000000000000000000..c98ca0fff56881a68d586650482b91113042f32e GIT binary patch literal 20548 zcmeI4dyG}Z9mnr3AS{nXd8yTwr56zd*|qHABG)_Db{CXFLEewGvdgZ3MZx7!quqGq zVVlsXe`srKq#IMy7p4g}DJ|UIBat>>h-t9V()N$G6jlnDw55R*0{wkw&YYe5y=Ysr zJKLl?n{&_a_nY6$?=y4Gna8=iJ7@OXx{{JaqBN06%$rg-=Vm!4M4u<8COH;D*C|tT z`OKbF)BNpetKamK^63qGXXdp&q%C!+tgSQu{ljqn;(3zC)MxCq1m|n!Sd;^ zzS5kv`3WgsH?S=i=S%tf-aWi8&QD}&hMnEhnJ@Z@z2*Dk{QhmZg7QB-yw5EkoZgcw zh`+mhe?fdHU%)TrUH*i`J16Z=O{S*7Or!{7+j`l2-_QblBzghTWUE;a< z;43IE`ELD)|H9z*)a;6siNB&L)v=^0)`Rl))c4w&vTpverA@h5m-0sjw|DA`nsRP_ zFsMCOP+s!g`Vqh5PqnG9RMeUHVQK38{?bnUWNqrUf2_*7`O9*pxmcI-%Z}G}>OU*Z z73BY+Hdjzy@(b#}u|BnWWPK`kdq&3(9@v@s-Skyit0yG?@W}dHtV_H}4Ldva;q^H; zKUlsqS5RK^mpJw7>%C%U91qv?f?V(F!Q<1o-*LV7RgKA79r^dl^^SFkKSHi|tjqOu z^Krck%1gdmKjL4K`z&r;zc3++zbke0{feyB6OupRz{*^#OZi`)+107% zSLWRO;PkFsL3zn{>qq?EXLiN$P(SjwFRzT_zjJJK*6KEXtVi)VKPW`@d69B!2ti@%-!ewW{-W=f5>_bN(mPulWG z{poYUW9vt~SFSu2;*9jaAj^{!^L!ln?LIXs-=`)V{LHES=SA)idDie_)6u@?EyJ3_i|W@h>KD$?;S4S3t(V5CCoYW*zw@J``WjxCzc$>l`)K<7{I!~MyU6f)QjV7+ zpZ*Khs=JLnw07~=vEV;Z>T8o@hxk9=aUuO!$A$bGC#R{`zxn6twnSCMf3l`kJtMN%m9>k%t_%KBkFxbFJ5;IK4^@UwZ{4K( zXWC1ThX=N8N{>&S?uAr#oo{OYaaMZouOOjf|E~$ zBWImRz4N!~@Sq&Oy7xqCq1aH@!!u5#j)+YTRej%y6l{{Gszip(+F`T)QjfCrz=r$! z^rg&{i+yX<>Ap4L*R~9pBF~=oNA5YX<9K$vnut3ww}J?U4bHT z3Y0A0u!M_Jp!$e}^_@w98Y2R1CIy-!Ili%VbK4#h$F>Ep{AlQ=?`Lvc{PoZOQRODuLd6bI#=W9XQ~ z5xNu#(+5A|49PeCtx^Uyle%F@02Bvd2)>*Z5l**3VMxH^e{CGdwEQ|p#|mMXqsO8n zTUaPKcqDh zX`B-oPZx$$lZwf?W$^PuS}l>r8!Y(@6h@>8j?U!VGPwF7og$HLbI353PIPo8=a#|M z59wzl(jk_VsdU7{QQveD1;Rro-&gH#pK*F`1v8_Q3z|( zT7xN{fnsuQ8C?C4@+gE=^)!UnDNsz#ErXjMQXW5fRAO>&nLkp@q<0~lPJ!YLbVZb7 z^D)y-k8K~mi!a)e#+%fSvp2;`8mkfgC4i1z{ECsuxn(Hk=jvk}b+@L(NAVk4tg`X8 z#H2uR%V76IinXZz;zpwszu?AB1n&w>3KX{tc0Z(8MeDCiG)nRJ1K301wU|kP;+Dbg zhZH-J48rMD{PhZUfBmCe+#TF9WceY*9_k*41UqKD1v06aoLdGzKcqbBR2anQv-o>8 zZW$c?kn%{+LQ0y~$_Mc$ZQ zA^I8lIWm*++a2s&>UxBfBQqJ^r{F0wDNxuS)LYeSpK@d-!VAimS1e4WJ9a0{(n4DYYkMtS|^`Jw_GXaxx%lwh{l~5}kQl4FzoLlCPv{XVhI;6Z}VRCMn zKTg=5@hrw&banC!wwsC z9JqUN#`A_V@?nFH10x2`utUbVB)Mquf|gCm#8~9S$t)!8(zo~A+aKoE=6<-D=hKua#$iMtdU#h)Q9?0ZoaFdj7k6Xe^S8B-ukn_5s3`<*Cd5O0W9OigGB_CltV`Trn8wQg-VTT=Yic$6||$#q&W zHKC92`|P$R)I414)`l}`LP`8JL6kDE;qM?!$wUUyD17Lam>$1g>(+*I@!oMI%#zI2 zvscZ;gbhSEqfbB!9cS=BM&E!1`IZwh?C`-^cB?JxT2^gpX-=9wWJy6v&S~5zyVwfx yl!RygLyvg(c~JYhANB&`?8@-5HhXriOyUe-K%X~o?kRNc5J_H(Z2u=gV-DZ literal 0 HcmV?d00001 diff --git a/addons/pike/models/pike_surface.rvmat b/addons/pike/models/pike_surface.rvmat new file mode 100644 index 00000000000..043d6baa363 --- /dev/null +++ b/addons/pike/models/pike_surface.rvmat @@ -0,0 +1,76 @@ +class StageTI { + texture = "a3\data_f\default_glass_ti_ca.paa"; +}; +ambient[] = {1,1,1,1}; +diffuse[] = {1,1,1,1}; +forcedDiffuse[] = {0,0,0,1}; +emmisive[] = {0,0,0,0}; +specular[] = {0.2,0.2,0.2,1}; +specularPower = 500; +PixelShaderID = "Super"; +VertexShaderID = "Super"; +class Stage1 { + texture="#(argb,8,8,3)color(0.5,0.5,0.5,1)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage2 { + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,0.5,DT)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage3 { + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage4 { + texture = "#(argb,8,8,3)color(1,1,1,1,AS)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage5 { + texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; +class Stage6 { + texture = "#(ai,32,128,1)fresnel(1.6,1.4)"; + uvSource="none"; +}; +class Stage7 { + useWorldEnvMap = "true"; + texture = "a3\data_f\env_interier_car_ca.paa"; + uvSource = "tex"; + class uvTransform { + aside[] = {1,0,0}; + up[] = {0,1,0}; + dir[] = {0,0,1}; + pos[] = {0,0,0}; + }; +}; diff --git a/addons/pike/script_component.hpp b/addons/pike/script_component.hpp new file mode 100644 index 00000000000..4b45e277e37 --- /dev/null +++ b/addons/pike/script_component.hpp @@ -0,0 +1,18 @@ +#define COMPONENT pike +#define COMPONENT_BEAUTIFIED Pike +#include "\z\ace\addons\main\script_mod.hpp" + +#define DEBUG_MODE_FULL +#define DISABLE_COMPILE_CACHE +#define CBA_DEBUG_SYNCHRONOUS +#define ENABLE_PERFORMANCE_COUNTERS + +#ifdef DEBUG_ENABLED_PIKE + #define DEBUG_MODE_FULL +#endif + +#ifdef DEBUG_SETTINGS_PIKE + #define DEBUG_SETTINGS DEBUG_SETTINGS_PIKE +#endif + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/pike/stringtable.xml b/addons/pike/stringtable.xml new file mode 100644 index 00000000000..3ed702fccee --- /dev/null +++ b/addons/pike/stringtable.xml @@ -0,0 +1,8 @@ + + + + + 40mm Pike + + + \ No newline at end of file From 8243d2d433a824102ec97456de9fff4a62bbfefc Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Wed, 12 Dec 2018 23:31:08 -0600 Subject: [PATCH 02/23] Magwells --- addons/pike/CfgMagazineWells.hpp | 5 +++++ addons/pike/CfgWeapons.hpp | 6 ------ addons/pike/XEH_postInit.sqf | 2 +- addons/pike/config.cpp | 4 ++-- addons/pike/script_component.hpp | 1 - 5 files changed, 8 insertions(+), 10 deletions(-) create mode 100644 addons/pike/CfgMagazineWells.hpp delete mode 100644 addons/pike/CfgWeapons.hpp diff --git a/addons/pike/CfgMagazineWells.hpp b/addons/pike/CfgMagazineWells.hpp new file mode 100644 index 00000000000..e5ccc8b0749 --- /dev/null +++ b/addons/pike/CfgMagazineWells.hpp @@ -0,0 +1,5 @@ +class CfgMagazineWells { + class CBA_40mm_EGLM { // for longer grenades that can only fit side breech-loading + ADDON[] = {"ACE_40mm_Pike"}; + }; +}; diff --git a/addons/pike/CfgWeapons.hpp b/addons/pike/CfgWeapons.hpp deleted file mode 100644 index 61c2fef5a1a..00000000000 --- a/addons/pike/CfgWeapons.hpp +++ /dev/null @@ -1,6 +0,0 @@ -class CfgWeapons { - class GrenadeLauncher; - class UGL_F: GrenadeLauncher { - magazines[] += {"ACE_40mm_Pike"}; - }; -}; diff --git a/addons/pike/XEH_postInit.sqf b/addons/pike/XEH_postInit.sqf index 7f39382a7e3..05f38dadaf1 100644 --- a/addons/pike/XEH_postInit.sqf +++ b/addons/pike/XEH_postInit.sqf @@ -2,4 +2,4 @@ if (!hasInterface) exitWith {}; -["ace_firedPlayer", FUNC(handleFired)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; diff --git a/addons/pike/config.cpp b/addons/pike/config.cpp index 0fea3337069..f676a6143b4 100644 --- a/addons/pike/config.cpp +++ b/addons/pike/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_common", "ace_laser", "ace_missileguidance"}; + requiredAddons[] = {"ace_missileguidance"}; author = ECSTRING(common,ACETeam); authors[] = {"PabstMirror"}; url = ECSTRING(main,URL); @@ -17,4 +17,4 @@ class CfgPatches { #include "CfgAmmo.hpp" #include "CfgEventhandlers.hpp" #include "CfgMagazines.hpp" -#include "CfgWeapons.hpp" +#include "CfgMagazineWells.hpp" diff --git a/addons/pike/script_component.hpp b/addons/pike/script_component.hpp index 4b45e277e37..4a826ab71a5 100644 --- a/addons/pike/script_component.hpp +++ b/addons/pike/script_component.hpp @@ -4,7 +4,6 @@ #define DEBUG_MODE_FULL #define DISABLE_COMPILE_CACHE -#define CBA_DEBUG_SYNCHRONOUS #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_PIKE From f11ed762e32b3a39ced60b986f09bf8b337759cc Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 13 Dec 2018 00:30:29 -0600 Subject: [PATCH 03/23] move include --- addons/pike/functions/fnc_handleFired.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/pike/functions/fnc_handleFired.sqf b/addons/pike/functions/fnc_handleFired.sqf index 34b1ee58167..283f6d93dfa 100644 --- a/addons/pike/functions/fnc_handleFired.sqf +++ b/addons/pike/functions/fnc_handleFired.sqf @@ -1,3 +1,4 @@ +#include "script_component.hpp" /* * Author: PabstMirror * Handlese firing the 40mm pike grenade/rocket @@ -13,7 +14,6 @@ * * Public: No */ -#include "script_component.hpp" //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; TRACE_7("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); From 507b0bce58d3abc8dfbad96e1ce1d5424b3fc005 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 13 Dec 2018 13:17:45 -0600 Subject: [PATCH 04/23] Update fnc_handleFired.sqf --- addons/pike/functions/fnc_handleFired.sqf | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/addons/pike/functions/fnc_handleFired.sqf b/addons/pike/functions/fnc_handleFired.sqf index 283f6d93dfa..40d5b07f3d7 100644 --- a/addons/pike/functions/fnc_handleFired.sqf +++ b/addons/pike/functions/fnc_handleFired.sqf @@ -26,28 +26,24 @@ if (_ammo != QGVAR(ammo_gl)) exitWith {}; //If null (deleted or hit water) exit: if (isNull _projectile) exitWith {}; + // Save grenade state private _posASL = getPosASL _projectile; private _vel = velocity _projectile; - - systemChat format ["gl %1 %2",_vel, round vectorMagnitude _vel]; - - deleteVehicle _projectile; + TRACE_2("",_posASL,_vel); + // Swap fired GL to a missile type + deleteVehicle _projectile; private _rocket = QGVAR(ammo_rocket) createVehicle (getPosATL _projectile); - - _rocket setPosASL _posASL; + [QEGVAR(common,setShotParents), [_rocket, _unit, _unit]] call CBA_fnc_serverEvent; - // Set correct velocity and direction (must set velocity before changeMissileDirection) + // Set correct position, velocity and direction (must set velocity before changeMissileDirection) + _rocket setPosASL _posASL; _rocket setVelocity _vel; [_rocket, vectorNormalized _vel] call EFUNC(missileguidance,changeMissileDirection); - - - private _vel = velocity _rocket; - systemChat format ["rocket %1 %2",_vel, round vectorMagnitude _vel]; // Start missile guidance [_unit, _weapon, _muzzle, _mode, QGVAR(ammo_rocket), _magazine, _rocket] call EFUNC(missileguidance,onFired); - + #ifdef DEBUG_MODE_FULL [{ params ["_args", "_pfID"]; @@ -57,5 +53,5 @@ if (_ammo != QGVAR(ammo_gl)) exitWith {}; hintSilent format ["vel %1\n%2 mps\n%3dist %3\ntof %4",velocity _rocket, round vectorMagnitude velocity _rocket, _rocket distance player, time - _startTime]; }, 0.0, [_rocket, time]] call CBA_fnc_addPerFrameHandler; #endif - + }, _this, 0.1] call CBA_fnc_waitAndExecute; From f9f490d2523d01f7c875c0e7fe6d10b02f0dbdd8 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 13 Dec 2018 14:18:27 -0600 Subject: [PATCH 05/23] Update configs --- .../functions/fnc_attackProfile_LIN.sqf | 4 +++- addons/pike/CfgAmmo.hpp | 24 ++++++++++++------- addons/pike/CfgMagazines.hpp | 2 +- addons/pike/functions/fnc_handleFired.sqf | 1 + 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf index 464ee9e36bc..28b5486dfd9 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf @@ -21,7 +21,9 @@ params ["_seekerTargetPos", "_args"]; _args params ["_firedEH"]; _firedEH params ["_shooter","","","","","","_projectile"]; -if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; +if (_seekerTargetPos isEqualTo [0,0,0]) exitWith { + _projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 0]) +}; private _shooterPos = getPosASL _shooter; private _projectilePos = getPosASL _projectile; diff --git a/addons/pike/CfgAmmo.hpp b/addons/pike/CfgAmmo.hpp index 69a712252f2..a82c09db0de 100644 --- a/addons/pike/CfgAmmo.hpp +++ b/addons/pike/CfgAmmo.hpp @@ -7,25 +7,31 @@ class CfgAmmo { timeToLive = 1; }; - class M_Titan_AT; - class GVAR(ammo_rocket): M_Titan_AT { + class MissileBase; + class GVAR(ammo_rocket): MissileBase { irLock = 0; laserLock = 0; airLock = 0; manualControl = 0; - + timeToLive = 30; model = QPATHTOF(models\ace_pike_ammo.p3d); maxSpeed = 150; - thrust = 30; - thrustTime = 2; - + thrust = 15; + thrustTime = 8; + initTime = 0; + airFriction = 0.1; + hit = 100; indirectHit = 8; indirectHitRange = 6; - initTime = 0; + CraterEffects = "AAMissileCrater"; + explosionEffects = "AAMissileExplosion"; + effectsMissileInit = "RocketBackEffectsRPG"; + effectsMissile = "missile3"; + // Begin ACE guidance Configs class ace_missileguidance { @@ -48,11 +54,11 @@ class CfgAmmo { seekerAccuracy = 1; // seeker accuracy multiplier seekerMinRange = 1; - seekerMaxRange = 1000; // Range from the missile which the seeker can visually search + seekerMaxRange = 2000; // Range from the missile which the seeker can visually search // Attack profile type selection defaultAttackProfile = "LIN"; - attackProfiles[] = { "LIN", "DIR", "MID", "HI" }; + attackProfiles[] = { "LIN" }; }; }; }; diff --git a/addons/pike/CfgMagazines.hpp b/addons/pike/CfgMagazines.hpp index ef69f814941..99ea4056759 100644 --- a/addons/pike/CfgMagazines.hpp +++ b/addons/pike/CfgMagazines.hpp @@ -8,6 +8,6 @@ class CfgMagazines { ammo = QGVAR(ammo_gl); model = QPATHTOF(models\ace_pike_ammo.p3d); initSpeed = 40; - mass = 10; + mass = 17; // 1.7 lbs }; }; diff --git a/addons/pike/functions/fnc_handleFired.sqf b/addons/pike/functions/fnc_handleFired.sqf index 40d5b07f3d7..9454b7932e3 100644 --- a/addons/pike/functions/fnc_handleFired.sqf +++ b/addons/pike/functions/fnc_handleFired.sqf @@ -43,6 +43,7 @@ if (_ammo != QGVAR(ammo_gl)) exitWith {}; // Start missile guidance [_unit, _weapon, _muzzle, _mode, QGVAR(ammo_rocket), _magazine, _rocket] call EFUNC(missileguidance,onFired); + TRACE_2("starting missile guidance",_rocket,typeOf _rocket); #ifdef DEBUG_MODE_FULL [{ From 452a041e0cd142dac95f8aba67235077737baa08 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Wed, 3 Mar 2021 12:11:09 -0600 Subject: [PATCH 06/23] initial clgp --- addons/clgp/$PBOPREFIX$ | 1 + addons/clgp/ACE_GuidanceConfig.hpp | 6 + addons/clgp/CfgAmmo.hpp | 103 ++++++++++++++++++ addons/clgp/CfgEventhandlers.hpp | 15 +++ addons/clgp/CfgMagazines.hpp | 11 ++ addons/clgp/CfgWeapons.hpp | 8 ++ addons/clgp/GUI.hpp | 92 ++++++++++++++++ addons/clgp/README.md | 10 ++ addons/clgp/XEH_PREP.hpp | 7 ++ addons/clgp/XEH_postInit.sqf | 25 +++++ addons/clgp/XEH_preInit.sqf | 9 ++ addons/clgp/XEH_preStart.sqf | 3 + addons/clgp/config.cpp | 22 ++++ addons/clgp/data/ace_cuhead.p3d | Bin 0 -> 292069 bytes addons/clgp/data/cu_dial_co.paa | Bin 0 -> 35131 bytes addons/clgp/data/cu_mat.rvmat | 92 ++++++++++++++++ addons/clgp/data/cu_shell_co.paa | Bin 0 -> 28407 bytes addons/clgp/data/model.cfg | 66 +++++++++++ .../fnc_copperhead_attackprofile.sqf | 69 ++++++++++++ .../clgp/functions/fnc_copperhead_onfired.sqf | 41 +++++++ .../fnc_copperhead_submunitionCondition.sqf | 23 ++++ .../functions/fnc_copperhead_uiCanOpen.sqf | 33 ++++++ .../functions/fnc_copperhead_uiCreate.sqf | 87 +++++++++++++++ addons/clgp/functions/script_component.hpp | 1 + addons/clgp/script_component.hpp | 11 ++ addons/clgp/stringtable.xml | 8 ++ addons/common/XEH_PREP.hpp | 1 + .../common/functions/fnc_rscObjectHelper.sqf | 64 +++++++++++ addons/missileguidance/XEH_PREP.hpp | 1 + addons/missileguidance/XEH_post_init.sqf | 6 + .../functions/fnc_deploySubmunition.sqf | 58 ++++++++++ .../functions/fnc_doAttackProfile.sqf | 8 +- .../functions/fnc_guidancePFH.sqf | 63 ++++++----- .../missileguidance/functions/fnc_onFired.sqf | 36 +++--- 34 files changed, 934 insertions(+), 46 deletions(-) create mode 100644 addons/clgp/$PBOPREFIX$ create mode 100644 addons/clgp/ACE_GuidanceConfig.hpp create mode 100644 addons/clgp/CfgAmmo.hpp create mode 100644 addons/clgp/CfgEventhandlers.hpp create mode 100644 addons/clgp/CfgMagazines.hpp create mode 100644 addons/clgp/CfgWeapons.hpp create mode 100644 addons/clgp/GUI.hpp create mode 100644 addons/clgp/README.md create mode 100644 addons/clgp/XEH_PREP.hpp create mode 100644 addons/clgp/XEH_postInit.sqf create mode 100644 addons/clgp/XEH_preInit.sqf create mode 100644 addons/clgp/XEH_preStart.sqf create mode 100644 addons/clgp/config.cpp create mode 100644 addons/clgp/data/ace_cuhead.p3d create mode 100644 addons/clgp/data/cu_dial_co.paa create mode 100644 addons/clgp/data/cu_mat.rvmat create mode 100644 addons/clgp/data/cu_shell_co.paa create mode 100644 addons/clgp/data/model.cfg create mode 100644 addons/clgp/functions/fnc_copperhead_attackprofile.sqf create mode 100644 addons/clgp/functions/fnc_copperhead_onfired.sqf create mode 100644 addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf create mode 100644 addons/clgp/functions/fnc_copperhead_uiCanOpen.sqf create mode 100644 addons/clgp/functions/fnc_copperhead_uiCreate.sqf create mode 100644 addons/clgp/functions/script_component.hpp create mode 100644 addons/clgp/script_component.hpp create mode 100644 addons/clgp/stringtable.xml create mode 100644 addons/common/functions/fnc_rscObjectHelper.sqf create mode 100644 addons/missileguidance/functions/fnc_deploySubmunition.sqf diff --git a/addons/clgp/$PBOPREFIX$ b/addons/clgp/$PBOPREFIX$ new file mode 100644 index 00000000000..87f75410bd5 --- /dev/null +++ b/addons/clgp/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\clgp \ No newline at end of file diff --git a/addons/clgp/ACE_GuidanceConfig.hpp b/addons/clgp/ACE_GuidanceConfig.hpp new file mode 100644 index 00000000000..f32e29af2a1 --- /dev/null +++ b/addons/clgp/ACE_GuidanceConfig.hpp @@ -0,0 +1,6 @@ +class EGVAR(missileguidance,AttackProfiles) { + class copperhead { + onFired = QFUNC(copperhead_onfired); + functionName = QFUNC(copperhead_attackprofile); + }; +}; diff --git a/addons/clgp/CfgAmmo.hpp b/addons/clgp/CfgAmmo.hpp new file mode 100644 index 00000000000..08d0815c0af --- /dev/null +++ b/addons/clgp/CfgAmmo.hpp @@ -0,0 +1,103 @@ +class CfgAmmo { + + class SubmunitionBase; + class ace_155mm_m712_launch: SubmunitionBase { + model = "\A3\weapons_f\ammo\shell"; + hit = 160; + indirectHit = 50; + indirectHitRange = 8; + + submunitionAmmo = "ace_155mm_m712_guidance"; + submunitionCount = 1; + submunitionConeAngle = 0; + triggerDistance = 0; + muzzleEffect = ""; + airFriction = 0; + + EGVAR(frag,skip) = 1; // don't frag because this is a scripted ammo + + class CamShakeFire { + power = 3.00922; + duration = 1.8; + frequency = 20; + distance = 72.4431; + }; + class CamShakePlayerFire { + power = 0.01; + duration = 0.1; + frequency = 20; + distance = 1; + }; + class ace_missileguidance { + enabled = 1; + submunitionCondition = QFUNC(copperhead_submunitionCondition); + }; + }; + + class ammo_Bomb_LaserGuidedBase; + class ace_155mm_m712_guidance: ammo_Bomb_LaserGuidedBase { + model = "\A3\Weapons_F_EPC\Ammo\Bomb_04_fly_F.p3d"; + hit = 160; + indirectHit = 50; + indirectHitRange = 8; + + maneuvrability = 12; + airFriction = 0.04; // note: works differently from shell (v^3...) + sideAirFriction = 0.225; + + artilleryLock = 0; // would keep shell pointed towards velocity, but disables manuverability and airfric + + initTime = 0; + thrustTime = 0; + thrust = 0; // free fall + + flightProfiles[] = { "Direct" }; + class Direct {}; + class Components {}; + + manualControl = 1; + maxControlRange = 100000; + missileManualControlCone = 360; + missileLockCone = 360; + missileKeepLockedCone = 360; + missileLockMaxDistance = 100000; + missileLockMinDistance = 0; + + autoSeekTarget = 0; + weaponLockSystem = 0; + irLock = 0; + laserLock = 0; + airLock = 0; + + timeToLive = 200; + + class ace_missileguidance { + enabled = 1; + + useVanillaDeflection = 1; // use missileTarget for deflection + + canVanillaLock = 0; + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = { "SALH" }; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = { "LOAL" }; + + seekerAngle = 30; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 0; + seekerMaxRange = 1750; // Range from the missile which the seeker can visually search + + seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] + + // Attack profile type selection + defaultAttackProfile = "copperhead"; + attackProfiles[] = {"copperhead"}; + useModeForAttackProfile = 0; + }; + }; + +}; diff --git a/addons/clgp/CfgEventhandlers.hpp b/addons/clgp/CfgEventhandlers.hpp new file mode 100644 index 00000000000..ae3e5ad2c6f --- /dev/null +++ b/addons/clgp/CfgEventhandlers.hpp @@ -0,0 +1,15 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_FILE(XEH_preStart)); + }; +}; +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)); + }; +}; diff --git a/addons/clgp/CfgMagazines.hpp b/addons/clgp/CfgMagazines.hpp new file mode 100644 index 00000000000..304f82d252f --- /dev/null +++ b/addons/clgp/CfgMagazines.hpp @@ -0,0 +1,11 @@ +class CfgMagazines { + class 32Rnd_155mm_Mo_shells; + class ace_1rnd_155mm_m712: 32Rnd_155mm_Mo_shells { + author = ECSTRING(common,ACETeam); + displayNameMFDFormat = "M712"; + displayNameShort = "M712"; + displayName = "Copperhead"; + ammo = "ace_155mm_m712_launch"; + count = 1; + }; +}; diff --git a/addons/clgp/CfgWeapons.hpp b/addons/clgp/CfgWeapons.hpp new file mode 100644 index 00000000000..d77a6ecb8bf --- /dev/null +++ b/addons/clgp/CfgWeapons.hpp @@ -0,0 +1,8 @@ +class CfgWeapons { + class CannonCore; + class mortar_155mm_AMOS: CannonCore { + reloadTime = 1; + magazineReloadTime = 1; + magazines[] += {"ace_1rnd_155mm_m712"}; + }; +}; diff --git a/addons/clgp/GUI.hpp b/addons/clgp/GUI.hpp new file mode 100644 index 00000000000..90dc1362c8c --- /dev/null +++ b/addons/clgp/GUI.hpp @@ -0,0 +1,92 @@ +class RscObject; +class RscButton; + +class GVAR(copperhead_dialButton): RscButton { + style = 2; + x = 0; + y = 0; + w = 99; + h = 99; + soundEnter[] = {"", 0.2, 1}; + soundPush[] = {"", 0.2, 1}; + soundClick[] = {"", 0.2, 1}; + soundEscape[] = {"", 0.2, 1}; + color[] = {0,0,0,0}; + colorBackground[] = {0,0,1,0}; + // colorBackground[] = {0,0,1,0.1}; + colorBackgroundDisabled[] = {0,0,0,0}; + colorBackgroundActive[] = {0,0,0,0}; + colorFocused[] = {0,0,0,0}; + text = ""; +}; + +class GVAR(copperhead_dialog) { + idd = -1; + enableSimulation = 1; + onLoad = QUOTE(with uiNamespace do {GVAR(copperhead_dialog) = _this select 0}); + duration = 1e99; + class ControlsBackground {}; + class Controls {}; + class Objects { + class TheThing: RscObject { + type = 82; + idc = 100; + model = QPATHTOF(data\ace_cuhead.p3d); + direction[] = {0,0,1}; + up[] = {0,1,0}; + position[] = {0,-0.338,0.5}; + positionBack[] = {0,-0.338,0.5}; + enableZoom = 0; + zoomDuration = 1; + scale = 1; + inBack = 0; + class Areas { + class Dial1 { + selection = "dial1"; + class Controls { + class ButtonDial1: GVAR(copperhead_dialButton) { + idc = 111; + tooltip = "Flight Profile"; + }; + }; + }; + class Dial2 { + selection = "dial2"; + class Controls { + class ButtonDial2: GVAR(copperhead_dialButton) { + idc = 112; + tooltip = "Guidance Delay"; + }; + }; + }; + class Dial3 { + selection = "dial3"; + class Controls { + class ButtonDial3: GVAR(copperhead_dialButton) { + idc = 113; + tooltip = "Laser Code"; + }; + }; + }; + class Dial4 { + selection = "dial4"; + class Controls { + class ButtonDial4: GVAR(copperhead_dialButton) { + idc = 114; + tooltip = "Laser Code"; + }; + }; + }; + class Dial5 { + selection = "dial5"; + class Controls { + class ButtonDial5: GVAR(copperhead_dialButton) { + idc = 115; + tooltip = "Laser Code"; + }; + }; + }; + }; + }; + }; +}; diff --git a/addons/clgp/README.md b/addons/clgp/README.md new file mode 100644 index 00000000000..33ba2ed87e6 --- /dev/null +++ b/addons/clgp/README.md @@ -0,0 +1,10 @@ +ace_clgp +=================== + +Cannon Launched Guided Projectiles + +## Maintainers + +The people responsible for merging changes to this component or answering potential questions. + +- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/clgp/XEH_PREP.hpp b/addons/clgp/XEH_PREP.hpp new file mode 100644 index 00000000000..88acc80e428 --- /dev/null +++ b/addons/clgp/XEH_PREP.hpp @@ -0,0 +1,7 @@ +LOG("prep"); + +PREP(copperhead_attackprofile); +PREP(copperhead_onfired); +PREP(copperhead_submunitionCondition); +PREP(copperhead_uiCanOpen); +PREP(copperhead_uiCreate); diff --git a/addons/clgp/XEH_postInit.sqf b/addons/clgp/XEH_postInit.sqf new file mode 100644 index 00000000000..a82d357ab3c --- /dev/null +++ b/addons/clgp/XEH_postInit.sqf @@ -0,0 +1,25 @@ +#include "script_component.hpp" + +// Add shell config action to vehicles that can fire it +if (hasInterface) then { + ["turret", { + params ["_player", "_turret"]; + TRACE_2("turret",_player,_turret); + if (_turret isNotEqualTo [0]) exitWith {}; + private _vehicle = vehicle _player; + if ((!alive _player) || {!alive _vehicle} || {_vehicle getVariable [QGVAR(copperhead_actionHandled), false]}) exitWith { TRACE_1("exit?"); }; + + private _canFireCopperhead = false; + { + if ("ace_1rnd_155mm_m712" in ([_x] call CBA_fnc_compatibleMagazines)) exitWith { _canFireCopperhead = true; }; + } forEach (_vehicle weaponsTurret [0]); + + if (_canFireCopperhead) then { + TRACE_2("adding action to object",_vehicle,typeOf _vehicle); + private _action = [QGVAR(copperhead), LLSTRING(copperhead_action), "", + LINKFUNC(copperhead_uiCreate), LINKFUNC(copperhead_uiCanOpen)] call EFUNC(interact_menu,createAction); + [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + }; + _vehicle setVariable [QGVAR(copperhead_actionHandled), true]; + }, true] call CBA_fnc_addPlayerEventHandler +}; diff --git a/addons/clgp/XEH_preInit.sqf b/addons/clgp/XEH_preInit.sqf new file mode 100644 index 00000000000..b47cf6628db --- /dev/null +++ b/addons/clgp/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/clgp/XEH_preStart.sqf b/addons/clgp/XEH_preStart.sqf new file mode 100644 index 00000000000..022888575ed --- /dev/null +++ b/addons/clgp/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/clgp/config.cpp b/addons/clgp/config.cpp new file mode 100644 index 00000000000..02cd7dec720 --- /dev/null +++ b/addons/clgp/config.cpp @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_missileguidance"}; + author = ECSTRING(common,ACETeam); + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "ACE_GuidanceConfig.hpp" + +#include "CfgEventhandlers.hpp" +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "GUI.hpp" diff --git a/addons/clgp/data/ace_cuhead.p3d b/addons/clgp/data/ace_cuhead.p3d new file mode 100644 index 0000000000000000000000000000000000000000..8f3d2efb62eb93c00453278935c8fc43e3eaeae8 GIT binary patch literal 292069 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 F{{YL{c47bk literal 0 HcmV?d00001 diff --git a/addons/clgp/data/cu_dial_co.paa b/addons/clgp/data/cu_dial_co.paa new file mode 100644 index 0000000000000000000000000000000000000000..62e56819f24adcbb3009b4de0c062ae58cb0470c GIT binary patch literal 35131 zcmeFZe|%Hr**|`tlLiQF=ta)ZzAQt2#{6v?}bG&v4Tfbf#&5O>nw(8@lRDlh1Wp*z5Dx z_pk4tpYwY8lD6l*@9X}3UGMk%Iz;Z~o9mj^-rQW5hY)IM@yz_}sk=@7IR}sY_d9O7 z>2@A|ZioL$s}Xu?BSKqz2;CDxXy-wMIv#^};lJ|7;f4S2=K#vW;~NMyBbv$v8jT_2=~(>(i8yVVAh;u_C&em$C>i=ccI zL5q+dZD0T89Kw%wpB(H%!3k9#%pK}O!ey}!T@8oAh-k3+r6J_@NikGUY~L6{?xyP% zZ;P9ICwl+RMgBRU@LxS>uUzCb<5gzVVC#q>!tQQqzy9X!wRq3j-p?I*g#YhivwJq- zK1tvkW9C{jx?C+V7xqZqLW?+`tX#XHKg zCtlv9?Vr_P7Z#Bu=e}>pOfAnx9(m?)dCK+FF03AN^|HZGBJdYNXl`+1SA=|Om%3C} z|G)QawA6^uP#{h4i3D_}%=s8;=hTE^b*IwGbTGX)1&iwE2#J|GzaQ=+dUOsBYn(>K zHoKHa@c51xNf0Wv5^G{4x%(u~!@C;6V3|786I>g_vs{mj=Ojz=7;(_vEb1=ZxgcRI723(@XF?^z4qDS;=u&8)L~2!ifY_rONnA#Dm%!?)Ee_Q_J3({n`L8 zpjq+Bt#-F3fm(}^jY9JCh*Tc>RINe?>#}CB;f_Jl0S8RsAUV#&>ODERCUamh^N~wU zt=lr|c(piF?$PwNU`&OzS@Sc8)r3ydUo)`}-}H(rd?&XE&3Vpu^Sbq3 zLPa%gKH=v2#1@ZaJfh0Xw6WNTj|)RYa}z9ITdJh$z=Ftg9mt$E!68$8Ebuli8h7b9 zH70|l;{l{hq$ao7`9?Suh?qYx3B#ZamJ@j1)Me2YRDP@>);WZ$0hJOdxY1m0^=aw` z^ynJlX66MOicbdDH_tT6jY(c6>*I8+iJu(AHRC0F&hlfg`^pFTz2!lCB}TyRj6PW0 z)!M-co0y^TXATpXOqxq@8_vaN+t&9j(p|2`g`MLE?Gm4>4H8bqw@%$tQh!1c7$!Z-Op$g_$xuEVef6uJ{+7Ff~7F~h6sB89E@M*P@)~oQ-u97 zL_T8YY(wo88jBy13QWcp2w!QA-+eVak7#mJ3%8uG#V1R6tYIFl#MR?-p4ugHu@lS< z!)U{ynGWibQgVdcW+zn~Zlf`tZ9?yEqU%M@RuSLaoDP((%gf@gVzZkq9*H&GWMwqz zKikbeo>PzbT=9{+-57_sssqLN?!Z;X!!scs4uTt!QlLb;rERM{&iHs$&rD0jPM+=D zO{yKfUp_m4YXlKHOlX_k8u*$*W#V2-azWsq%vT{UTzTyaV& z8^^9O$yYb8rne5dPYA!3>-`Ii)G@2`VYX(qiV=9W)`1lGaTiWaN}S+PG`AQC^(0;xYdPyi79}7U}BeqXBO0D>8U$+q`_V$csK>2k}WZZ?zYZ`a9o> zHVbfiJWhXY?Y+_?G!idwQmJrRa<(!01RH)#bJxrY%O=f+&5}xQPUNi4Ul9qhY+T6d zmtje}xwNuGEai#PXesOM80DP(xFYq&nY!Y-qdPHrc<{qL#TU{JHs>1U6h(}Rz^1^b zCdHzJ=%G;QOg~bYp;AJx4*V4><2u+{!X>Zm<5Wp^9m;1-A3bvzbD6Fp{-_>RM)&H-VE;G7>yqt+$9G8(NtV zsqN7*HqKP`=x<0QU=KC6>(Mf()F${D@8kK{;=5aaxb3^0t$=FZeUTKmqsXH_JVs=aGS*)w!Pw0^Y>MAs%)}=mw>sdG=Mgl5kkKYrj zlXsx}%!-*a$Xc81(HYXsSZywWeXj48ylh{Kf`9`){^8`Hkkg|L=mp({xU1afKWN7b zeEx}jT*PIU>a(wGnyF}R*tM*42yQw3LLQgai*PM{Clk}#`=wLo^vD_&<*n(Rz)J;x zdH5wZ;u3u!`@wN z#o2eFds36KC06g_<7_g{h<@$n3)dX5`GOzUWzDC~Y3p{cF1z4r#$qND`bw$RSBh_y zhNCc@Oh?TE!4K2rP*Dwh`AqY3!YRCb%BB;4*w4!2}T6Zz)LoAe9Nn=~f0 zBZ{VGJ<=vbqj)#t_k;Un@%r@`hPCxozf4yB4(D2_0-dw5tbs>H9j!T6BX>*w%7!M`vUNyzuM{1kynH)O`?`sk^1)bhHT z6f^dmpgA&TqkLj--~)}fn`8$&6u2NxF5Y42DvRrDr80cNgq)Z0DxbgVfHmyWByyza zbAR48Q{|?xtJZ{I1=sM=*{Mk@BeY9s&snNL`jWo*+$h)iL64f$FHU@|Lmh-&^fXal zksXtRY;9E3!bUgljQm4wDIC=?koEF z_`I%bb!Azb-+j`jI$k|Xfe^*;-THzfQAueW*MAX>8j!RQ8o)~gf3cLZhEs$D9%w*4 zV{#R=aWjoN-%_ZQ`i+*A&kl5OUQf#y8Z~x(J%|@a;BYM2(w~4M`@^Yf8m|`oCFncW zND5Xf3?f4Has?*z-ab05D-wIjW{;T5>5n0aGkzpm>5uU5y+h|0c>N7>56{azbo8du zGi7gwvbP&iu@S9|3@X(6XT(HV8{$(;;E&9mzjDJy{T;mq)<9fBxLUNNV@M zOzFL_25v}p&{Dc|%XceB-K_J&)*%mWiJKSi=q=3)qZoI}aJVYi)DO$HbqGp}9up zIix1yNz_aJcnoC)(u<;0N@i-OVulXEf2DIOwl<^N^nQ(z@Zn9#?m3a@_v zukiWTtzQ^UX_>zNgm9Z<<|QTw$h7SK=4QMkoGMGdz``Uq*kFb}2{g=f7eOd!5E}@R zRB(7fZz^KwI(RKKKFcpY3e?oio*VcI+LBNLbk3)N3;pd>~u$22|3e zbd(Rhqj0!&!wN#L>~r_B2y>w~R?Y4wnr08|ux9ge>=qJ}lAED{+ zJZeJQHx_r7fAL};n*02@J_KjrAPSD5Qz_DYvJXYy-9$A+KfhjlC5=q|N5^xKFJ{8j zUbLt;)8Z@GETeqs)ViJf0>UtdW*)cwltlO=7pwY1YB2R@(g+WJIjLCS2~V<7s)vN~&zwZ>IR zh4+63!3RXYR+}$f-pj*@Wka9MnD_@8abrP8F*;`0l1Cj->0cD{Db4Ut`0@ZxdSqus ze;52XygWoX>?-Zrq zfdy;8w_mH|G{m>2fJ4oi22~{9VKNmT+k`sC4Mz_kdc*RuzTa<6;Kl{W+JvUPM+JHw(vuB&H2k6IrqVsYftI#QPIq(+Orp#Bvbb31> zd*N7Vu7yZNK(n{nQC$Ge;0)J+wAHd&RmN~HD#&$q@Ce$aTh^S ze7$-1Nj=&BDoNnEPFVgnaMrHHNa#l~KLHnp0xyW058Cx4{}RcO==`AGNdAv^(o2no z{$^#A8U>!4G{S_761GDitrB_3mk--3KP(ye3W9{&?AjPU0`uYecvR;w^eYIYuTEUC z3_8;dQzt10dM7XkhI^Ym@HH-Q^1d$tfT$G2z+B;LobRo-7ckfAc$DS?e^hX46%3l* z!QU7j)31-_h4R%7))$FSVs$vKI9S~zgAI#ll2FQ5pe>CwB-4ByfB9~$^wh3m);zJ_ zAReF=b@$GxXMW{s)Dm$)f2Z^oL;Gezt^81$NAs~CW12URFX?*NsdS1pvLw#$w0at^ zufp#J(t-Dh9thL1F6IJ%vSt$Blr%5Mn(50{V}6esJM(vSyRl2$^c zl3{=h(OP)@q`Pm*%z3}|Kn!1C-X}CQV}FXwe8QMRx}F}a$r`OTMjwK)2(ivSLakIP zanY0+{O#$dotA>XSL3{l%MuSJ9%Ni&;8W`NtbNh;>Mm`x25X%O(hg8X0-G}gJ9t!y zivf+;W*0^9wq~l>nK64lqzuxX1brENuAM1EaDo{hX#z`BS!2`5)|`Y}v*vdbh6pPWyTnnaCy=yV-675STe-5;*~V2 zsQqRxI~*V{8`?%-F>R)| z&eZc)npbRJPlD4+_2DwD*hK)A)GSv)d=Qorn8}*sla!9-s}7X#Zxu(6vax<`|Is=1 zl!L$Pnklv5m75cdjbd$Ol%PCZ-31X^$-{Y}x)ZotXdWFJ-8-wpdShw&6!%w#v~ zMoaofDo3q8SGt82q&uhF&x9#s^ysx3?=zv)WVuOv{v1|12T9H*ctrdy(+lxQ6U)NY z;gI^t2HP~=g5>A^%oN^5^OUhW7@W|GLBmnp($t8nOt@f+x$B6X?mlugtgpc=Bh)hJ z(zRA{S##!-VkxLM<60|?Sr^~pNt>i3rb5vb$IR#g)9b1%I%2BS*Y|gwsb-uZ%_sGb z*unSKuStm4DtX6<;-y={;ABx1UEal-XwZOzWrWaS?2ftr68@U`WnhdL0!JZ&M)N~? zV8$KjLeWS!Aa-ClJh`N+Qg&DLOVfAa2WZ5k1_8#K{u9c@Ix$%ziADY1tu{S}YO$9_ z^wIG|`8>kv*J?W~*5F^q z5*mCYFky&}lg%P}WmE4}4`yQKqONhc!um?Pj`$3?Q-Q=5_ljfJ`hwu*0l(_Awu-65 z+>#^0+!R9KK)pPMqLnqsKZy1g$T%#>@ub zasVvxx@8w3-he}yxc>9Gta;t~^0Cehj%4Tc-@TnNYo&WjGl%pTeec>Ye+$1$zry&P z>SqpvPgA+04_!G^9Y*-anKC^4KV^TLGkYgEgS3t@$JVV^QS+FEypeb*)Q3);^G8tY z*&($0w7VDS@j(;(q_^;u*BW>y1DB4|;c!s@9sLZ~{9nXJ#(eFSce7?)&vheH88bL{ zPn7P@haG+Wm*+AN>nac0b2(3=c>TaasjOLlnxXlkk>5=0D~;ZQufYC6)6awg=WFEjGZ(1PBAUM8BF1Oa#Y6vAaTWa$~bZucyhC=(B7 zBv=v15gt!tBYr$}Y4H}Uh`n{Ksw|3@wLRJ7!3vndb~uo!qnF?;Q(apG$czvd3&6pQ z700WmLF?~%72JRRO7geunBRr%&X_R!)Hz;4Kx0q`*i0H9=sOA>xo*nrjDHNJn9w-5 z14PUj{7W%@TXQG+8-6ML5L_w)O5g$LhZHSogd&rMbTQF^ijM`6 z8%x3;z#g?PK}@kpCmic2w~$8iIp}v!8(I*f@d=oNOUrv4>T3T(I}eEwwAIe6#+L9e z72y0z>o)4&5gpSnBQ#1QAYAwynak}tOHhmV?>tl8!3{km(-w~sJOqOmnv?M0 z#{=>R$j{~ERd7pqu@M-SlzC45odAqXFp*B-`jLp9mJ3=_t`pUzYm1wKm(irm$L+HS zNn|5YPcz;Sf{3ek{&n{bvA|XUjH8y{TetpB#Dn|b?`wjBcZ`wlzLNWPsQNUV&8Jz* zLIB1jyA-M(nP6L|%iw8~5So)QlLzf80-Vb5P%&y^d!y~tgQ%&r>kiwRG4c#kyH+Lw zRw{ti059(PZYaR4ioVR*M!^fq#6&nSrBl>-qo#)SigB$K=gZnu)GwcHv zY!><202Duyn1Lte$NR)atcvw1`o_)OikvOn}5@oFSf zYfgt1odF~z^p8bO@tqj3|Ps%;iyUlIr@2Jq5ae9&$U4_jg)*_=l6PeW~wMuwYC#8d!wU+zi~o%k|yS4>~n)4N(iDtYPF|Lem=O5mo+x+kLq@mvg&4lI}u3fo)#Q zc`MohRfG=wokmvQlcNqp{q39z6VCj+)Z}ry(8wFm+pO^iS-Bt2WX-_|JUeT)+VuOP zA5=Iu0xYN^D9h&llwtD^B{sDYcqx|ec0cd2I{liqEtR8&v;`ZT7~dy1a>a;*vhG5i zIuOt=k_yWdFAD96Yc=mV8_f0S4gFWYNwJwXBM0DgZ;jpV{fES$5nMD@BVjhv&1OXT zI#pn;SF*901JuKbJdFOCxxKXe{vM9W{p3A}Luvml^krVhSCxvl%O~JbacS9+tE1XB z;rVlVwe*X{Gy?cNH8~x6+z}?(l*{k}Ch+3yE3fWijo4}Ft!kQXPI@5lL8JD0TxH#5jnUZ)m;(+l(XczORC+G_&bwwkK z)e2l6_#8rfQA!<{32t8y@9X?nCOYTVCJVOA-|uV@M0|rlT0$xD)^~$r9LTG5x$p?fWaxCS`$*Fm%BQr3$#^`L*P!RDja9y$AtjkqNE~pdNV& z>f9VE{H)Cy`>gXJ1Th*JSqi}C*m`bWK2G^&y}A#`hgSl76hb=>xTkDFhY6pk&g|E8 z)1-o0R$sIGWHH-&xmr)8bHrZoTY5uRsM$EHyEs_s)SwX$iYOiVm`U0nD)9b`D382>FLObCB zZhc|yJ~h|l+YdOcDfg}&?kO+}MkX*ZLwHxa8b3~T$ZpjD=S`7#aexT_u&Arw1K>1S z(RX31ozO2v2VkNSJS>94(j|8AcB$mzqV7E*U>c}W{->dP6lz=+qJk3(;*H=}z;Y7q z#S=1|W$SAs2{qmjYX?;TDm{7xPH1eQt(ssRhs$VE6K3=sBCK?@!h~!?w+gJ&-@4zS zUoQTPHR0X~OXmBsy}QB*ws$GVh-p9pCiYVe$cd|yX68+Ad+{-Sjd%gL3K$?Nr6|~< zP4hsZzqb#JJ>Pw4!=VM?D$)*UiW0crd8LG1V#9~nsm-LkqMuBtgK3o|^}wF9csE2d zrd@E=)!d=NY&d8lUxZ4QDqiGlvXggM^5dmORHN;ZMrnMThW}i@BJn$oc{2bcvWXpm zs3r5U#e_cy<1I$aMZVX=S;C$Add#vh3-hrb?sKT-r;^{O_+Q6+`+CvbF@$tPWe2_? zKza82_J7ufjlBu3;40akKo!8BA+*=d!1mISAqYfnPnrW$09^=Lrc=Pn0$$h( zOS=4wR`Ro%i%`2;@^i*1ht>PrN=tm5dr|22?duKOzWs4Zv;S5Qhv+qL%{@QZVLbA; zPzh0ZMR&y1V(P!eFU=yZzKDzHiOAhtkB;Af%X+J}F}*Y4+P+BQy?r_~#u{rqv4hOi z{grryzY|Fvf$TJNj?K>THNqd*WJm^RPE%D~{zkCm7Rg_dt}Q~@qO}F!zvCO@mCv6u z)gSUnR^JY{&uqCj`dOPZSQ}w#7&zD>iTETNhz8~`9Z|XCFyWL25gKA_ls*dn^FWwj z1gyCbd!HQ_2Xi@E?5*f6oHP&@I*Rs(0i7OH?v2cndj^ zZtC{K_6Pj+pxpt$V0-)|b$}N0wf$*#hc3~{6K-^JVUlOfE}0uPn6djLuTwDY76A&w zDSKq45l;AvM!=0?PJB-w7C1aT?(o-!E~>*#XhmU)ho_PMBE% z782+aa7u^&hP8d_Gu6DMH<6Qj_;5HO^HpzBDl0om{~tgxdM-6Q;&uyFvz zJ(H9JKpD(6d(Of@WuLY(%)Thl!#1}Rv{|CPZ0dev@5?I)G zXBf9q8XJ$qb!^g4RZ4zMe;qGEf%^0^mR^W;neEWReLJkd?`OWd9enSiMiZ z%uT)ea;!B#^eRZ5q7e`c{ry8V-b zCj5%t#h5A>-`@Zg-|UqbHeIj zmNbK}>uJ(I*Y^0Cx+THCTe-mBv-iQU>XJN@v}kUuVohATyed9OKtS6l)09((8~P3( zv;!UP;t=JEc1?Q&94?tMk835hX5{sCQGmt;unT;atwCbET> zPfWXWo@^w#18|{E!J*Sp3%ltCJAOO!I1~J>XdL+gs^mJcw9lQVgyzpnzm;GAjR~zd zSx!Hp=h|wnhJEABGD!Sj^co!^>%i!JrRXe$nYpJJbG)TlzJw8SB3dqeZ^o>-7z3Pe zjw!L#J`cb}R3QI-Ew87CAMWXFcaL(+`0Jc4sFPF#0N=b^3f*YNHu|zw+LxEh6(0l7 z+GP|EdUHAr^S4t)j2un;z{pq8N9>ixVGF6_w`kDiIMSaUL@SDiFQ@gWkuRg9hSS|lL;fc z)hCq?u1SaM@y7yAZPuki%z(;aY57CnECb-^t)zRp+nzq)sQ^GWYAM^HCvsV$$D z9Go;rDg}i1jR2Ky?Y4cBTH;jb7aT2^*vIP$=C1^dB6`g!(%pkkY{ZqF`ilAv&UD1R zcR|f+$%sG4>DVu{;#-7H<}l0=YbQ3sdj{hVWZbXRu>;DNqaTo82(-6YT)O@XpcjwhscytL=O_} z0$^1&iT7C_&L7ZO?n3zkczL$0(W8GH|H7-a>no*aaj7{Eq+hs-Hd+G>;1ABO&*j8s zygd1su!>(T55h=qBDlbW=hW+!{7Jmj1iOn3dYo)%H{jHXuxLON>&-*QnW3-@OdA3v zOstlK5ckzxxW?GJm5IF2ESiq|fy6jKv+)JsuRkt6Za_Zx~d>pq&X74;?3n-SG4mmFmF1gXC zKzj%C{_Ru3PAm)G+PMRCq;>a%}-v!=$o%h6^&_go^+GlOwUwt}u zlnt+7N>}$_rdBg8`v|Gp1^or_v%qP6CI9`3tOGon&6z-eV)WQI{@Et1%#=ZV51>Dm z!gsTs^-8V>I4P;6OtKk{eC1}QEFJc6Lm&?uQ~b{lvs1SWS!frfBKbM>Ho8-D6C(>; zYOe?r<+KerDsiw<$3-8kPR!2)h2n0-J%9*?qZ*RKoz(PSJIuKVyQiZM1el~ z6vrv`2JvT1%9fZp(h8#8;F>ywK1=pj&0=|tpI8xoo)85PTzn}`vGgc3sZijbX58%H zu){)s%KC0ram!P0f&lZ4*csM*i#+uP->tn9#Zm*Y)jm2eMqtp?#-Y%C{d(!l^}gf znV%i7#^Rd9O=LoFgHFsbydbW*^t28nsibLc)giq9nmJDbSy6wyXH+Zo>DB1(RB75w zp#%M2P3*IpAi6GPTs>Mcy?6_C`$e&%SzjmNP!8~r(!|<;oB42P`h-sRVRRR0h=4}~ z)v#F)xR4JHDeAB3yYSsKDkeYY6l~2WmHJKmEFv`t%X3k3fn|J11rj$!>{IH=#KGyI zIbjwZJ#K1Q|0B-J^U)`yAfkzV6l#(FRdn%9iKpsN8a$%~Z1~SaOA|=(EEyH^@erVI z)X8f#`~)---DXjusB|7K2zbn5Eg?=juQ#Pv>bjyz+$xL%(he{{LPGcN0!DQ~iI^}9 z-`zwRM278M+ca$nT96!~%7{``(a5oN>#3TNW8Mjn5$F|sCq3+o#tC2SKhbT&_*mC_z02VrEz5C9pzEWk*rt-6|QxA*KfBV^iHkxx>WjJs$l>=qB8ixf=ul(<+2An%C!#KxMM6hNHih_*XUcs-_m|>%`e< zyQ_rGvXQ=TQdk#veUr+30Y^=fTfYi@q#gd_P|+KIB&rV0Li$f}In^Upu%R?KtEoZ&4O(1Dotrr_NA*!0>x8?C|g!Lsh}ffM4Qe{E>PP1E?_ z=dztuK$a+0%i#DjaXy{+njJew=>HOZ8~@Y1&dxauZJS~4ZfV+TSqBawIvd_D zH@3!zo?)`10FE!Oe*;7)K+7aX+0bQ@kY5K(Og5-cZh}q@S+maqkFCo+3n)55di0|N z2%5p&FkhSl_(~EnmY6Fq8)*5O$uw0poR zMCps;%}pSRee6F=l}iqR((LDlOQh$tX)m>C|8qb;nA%+KW?U6o`NT%Jwph)DVKRh9 zD?7oJQaK{4!IOc=zAf;t8R*TNF&pZK!9knuNO^K-jd@b(=+Q5`w5ni>n4D0!o6~S^ z=(!8Er|3Fy>0st$Y))V1v$je+FAS^eK>Zshs%@P%g$fuLpXzE@ckwc4T*;aGoEh^% z7l6tR4H@a3z{cFO5X1DL#as63F1+qeUY$Z;_JRGCcyaF=4SMuF{taz+AE^IBHre49 zuF-)TVVo5vtWbvrfU{WcoW#{M%*V6*8??9?6M?ifCH1J-tSI`XBP(=MbO;v>mZ&Yx z^V<4x0Il`|zlxr1`zk(3w{3oP*W%Qt$E&T*6N(1A)ZPM$XZg7?YQ_s>5W-gbx<@LL zUT-BlGVNYmU%&IP_cV-9cT%q>q_#N?b~NG!rBs6r)~ftGFwKy^x39wY99e1HVn+F+ zy3Jpy@P@1z+>hy3y7@OSEFEOqeX`t`Aeqpr)MV)e7gCTweHcZT;YbV8ta-R>9IJcr zBgG@55SHvn~ua-y2s zJ%Dn#AcEQ1W-lZViuaNzNdoS^=PYFBO;5}7aUcdl4@1nmXH*s1JO8u{FywLw=a~W5 z?m#5*jJv61Vfy)Iz z(lmv;+*EkEn)!NZGXPJ>NB&)ZT0nJshP=c=0Y%9C0Usn4wknC$P6`-s$Y_8=0E+}3Se*UXs|IJz|^anMJW7(Od%V%zx4~{YDhCYQ|%GU zeVr{GwY9`;JIXUo^4(2vo7qf65NLBga2El(Iyb&Mqv-oCT(I*NcqbNT*2Z)e^K#HR zV8TSn&~O!VCq`a5qIfj3Kaz6vFtv+%C!8tYH>vEM&Cyg>OElLlogeJ=c635gpwc$B z6u1^Cj{uz&q=Vq^^eqNrn<-zKb3KG0=d0PhB&G=T`*ls!0jqPZLQbbcs*tsEM=PKv zL@hP3&vV@B#lBhObmnDeiqGW=UY}k@xU{cxJjaivi6vRF9oRA8fOjSpFx!aCcPtzv zQC;V|Or*QXZ6CkGCS2~^o6A{!vnod+{&gmcD+D+@t$i=TvW4yhYcZ(~CU3*D!ev-( zM4a%~)+=rfVC?Uh_}&S@#I)TmpZ9}Xg2JpoY2RZAvW4^xK+ykTznRNtZ`B2lIL zwjFF%f}Kia@)_s%NeB@D_&FAG0)3*_v2otr(|P=A7jieorfyM zUjT)LJvJ9slg#v+qE&~=>F<|2?N0B{YWz<%HwpN^Vgj4F5nwilDrn?tGEytcv1T4T zd;A?5tWBFh3!*;8^MRG7D8M0V!MWTefhuQ>%L&>V{Di40KG|9#hDv(WoyUR`ise2< z+2!&vE2;~5nDMs-kU~Hfcd~F%2;fzF?#X8k^AHQ0L&V1^fZTYr6874KMuc!j*8J42 za_`ax&bRc{T~5~*--5KWP{<(4*W9jHVO6dW^6hxE+?Y$uBY>DUb=Cq3+xnPzL)I)b z;da_7XgOgiF{hqWtce%8PsTC;`PGN24mmRNi4qup0OX_9PCpx}1wW)LNN|i;S0xZ^ zSRf?6_!wY4c5HM0X^DSn?*vgpKR_bj_r968YC8Yt$ynjC;5_vWowZj$kv#Q;*Af() zTt=$cM*mfYBN3(AOr(PMN^Ir<0!Y3V&`~Jv+p)mA)MoWAy}!n{v|!8Bez50q9T@X; z*bMS@?MSU|l#ThA>_S9Vn=z<=xYYeESHj~=aB-9(dESdE=P94q$oNkJdsUS|y`S+c zEkG^`7Lr32-_k2}PGM>6FhrcEt6{i;Js!Lz%t8aJ0grIKpmdD-zFSd`7iIgl+O5eQ zf&I8CwZj$(c8DxJQXcmKXhZbg56&WL58sc!<;?gV;vfy|X_BmT1FN8{efs?1RNy#c zVxldU8m5EH11IRV@Zxgg#mEBxQqZ^5WKs(w_XB+>GdlO<7CEQT>U=ubM#9~3kCx9m@b4XCsuFiltyVu8)syR<{L;4vtUNcs-g1SGj8TmS69U}l>o za{q&e;g2UW-^Q0skgmBfwM^ZkV+x7#$o&v-f;>Ym2GJbb>wnz$&76Ap75Z7&j1%DR zyf#oC?qX`zl8b`7hjc_a=m!6tLhdLRI7s-USEto9(UD^l`z!hmyWN#SfH+<~n%}vn z^{fgT;=5noNRda|d})+d)LSs^Zneb5cjJC0TO)Y|qD?fwl z@hifBHLw(<7fJ#Ev%;b-2T!TQZHn*hY8N4uXFk!efl?49mGk+Vr_cBK!w*hh%FY@* zzAAZ%QsEWl=4U`bY3c3pq#n-a*xJ{29$K88_dz)OFgWH!W?mpqPBk6nGVf4i|Lk`+ zvBG&a@GoZU3?UEP61rP6X61tS5ma#kSxpxTwm1V1cIK%#o$#>5`M#}Iv*8fP@dI}L zYdF~`fXPV3vhXAm|HaI;y$Dj@w-X?fRIN-E!lh;9K`sc+Ind|o3Dr`stAPoOf=C_Y zhj6qimDJoe$Q{*qKY`#Kn$Hwc>N*Ff9rg>D_GuhCYHmLSLaY(LX))pErW>*d6oFK9 zHXCmD%$AE-l9Dz`QA*xXJo3Qv=a}B5&A7DYAGX)?RCt*2)+s28aW}4UZd?NTKj5C*3AtI7xWM@{;DRAUm&@#njaxHMv9(olrb7bhnaz*5 zHRW4nqzj>Fmts65IYzn2SrVeGWMQ%5Uyxr|bY$ZO`16mWN91i;)LTw}Thnz{WeUE6 zAn$YUzNvY{*oG`+^hz`>xbn!qDL*m`5YyIn73Pzd4a1-JEDIcy zJJL8+xLTXmS^9nf>Ng#8M(Ts;F{ERxEq$OzbmN7xEKx~{Q~|$g`u$8{(b|u7x*n=k zY{0YW>2=Wvo>^UaV5_13Ab2WJ>-(9)3i_NPG$|`#t7_&6nvvyv!fHIY(0AaVy_kfJ zjg3ZhCWsvJ>-S{g?g6O{d@?~=yTmu|^+Bp3QKaRQupDQ^p*tWj%?&_)!m^rwHR;!< z_Y{q6B^7en9aEj&@IPU-PgZ8$DH<+n$9C{?L4g9v3-aF|%sd?kYNnc$3v-1aT*Xzw zJT~)FO|N?Z{%7^_*22CobhzQjC6~?!>Dr54BD#i0~RoUOBZ~JL0%6#qG$0c zIXkSRe(6CwH6OV&z3uHm1mQSB??hQ``e{wlM`;s-O-^a(roX&b1!NTlj<_gbCu3PU&Gr?FX1v$Qy` z*quMt9yLq+kT(5WYzQx9r=C#C{xUN;IKO+MLmGmZij!N}2p%%+hkQ^tVe&Jxd;>qqW~!>3D#N9AiT}Wx-=v=#y%=oF z_f3JOz5jGm^U4g&b2UC<8ElYB-}=aEQ$xb@srclA$W3zI_5G{e+ujuW>d&cq<^YS)I}CS`YES) z_}Kw|yxuM6e7zL@9cxQ1rab7xS!&Ep;0bZ<1A$dmnxa)&Na?@ zm>#u?(viQH5g>hRc1fBs9K9PU)Pln@=#UB&8Vid=A3NTHW;^tA@l6>7-W@NQC0OD| zvfqWQimsvd8_McNh*c>yfF0!UQ(t9V@ty9T2)y{HRd2-thjE;vzHoHKf zW~UYi*kq!bj+qpjMNhLUX0nVeRj&?90qt~gRp8&;;J+%ZH8(AaJmemY?{@q31b;e) z2p?)aw<0vT`gD1$3N8quI`9VQy_-PehtW@bjVdlQ1Rj((Qi*4$3NP1LdY7m|yMcly zB1@_c^?h4+-;RcZ%~XN7m#~5C6+Wd9{zs;Q?XyBczs2~d9Ke^9qSah*_uk~cOT*{F zgm=Hh(m!VQRJ0T`zb5VB)x~JPF?}57R`?1ChtPWXm_bd&!V>;>V?@*&u;tCsb*{s=cCT$ zeh#*{fwzag0RT6jc~J1)f-IR~{c^qy51TrBC#-={2-FK--9?M1^@_UFGV(pDtE)PR znH2TPCT>iUCn_w;(ln@Um^JSOTtZ)PsmjVo@UaO=)A?O+Myg{EX)j5V7-3=$C?w!5 zF4tlBM#!Y*!p{8isoPINt(5{QijLqp&ed$w-2~SIIbi7T*}@ga%0sOust4DvUvM}M71>^_OntZ-+%Q>|Q{x)Gwb#_)?;W>=-KlFe>z_rsVVL8>qg|FUOU z>DTt*J%w>vCcNO_M_JZtjP_m@p(6u$Cm=;L;)uX5hmmPbSUz& zP8YHPp{WY9+C+i;-2xp5(yJKXBM{Ea?j?HJnw+3V7cXW$PT4YNaUM;TN8YhA)Gdi& zoM*g4xq56eWzAh_1pY`Ze1|plD>y^_liTcz1AFw!^f!UyFk(Nl(8tSArl{)%g7dNo zLt@H{_8P=hE4;rwKYy*@ZfRaR_)4a%`?mnwDF#%7B_y6puP8zf00EZyU-_d1_wUL| zr>kcTIo!ssXNeU)qbL~a-VpG{w3^J>W)c^T*Vs>Nua6x zpOBge&MO0bosvJK>pIV^p{q)3_0lQp*hWX5!bghDy(@{@z*Onmy~5Lk9nB?df!V_M zV`a-BCk*`_z)hmW!_c<|)@ylp82DaKGsrHy@kjQYWwYm-n;k({V%7riOm7%jwe!$I z?^Q_cPVk%Xw^9o4WJ&+z#D0B#Vt%=C^gU+q9gn^s+MES7DCfK@4*>IK__{)Dl{Ot( zOzU8q^hM)MKOj#+9y_rtQ>d+958qxmnORSd%;$9a1>#`%H70WVAJ0|xmD@fDTXQ$c zvhFtezhM99G7myJsY<=3b5S!~T~XujbMvE4_$CQ_lL6-m8(TA?mN2$g)338*bv^n5 z@lmF>%LCs%LC;4|2AjAd5}c-Gp?WLBnttzgQztIgeGo1YAMqhazONKMp2W4y`fQUn z(O?bTMG|Xrd2)h70a*=F6SORGD`@8+WKG_xK?{A-^XFECHx}cz&}DZ=xpDu$t>Gs% zH(HGRF-l6z>HViJ^nCBcidsMutVY+jm|E9dB~?T^J&miKuNUJ77H00UrZ#`|4$fvW z6go^U9B^~-e*p2Iiqr4y3+|r?Ni9wIJFy+CZ$D6PNxvm%;aR{)rH;}|pTnozxUoKQ z?Nlyz$}wI92~Ej7ZPd5I^dUiDm#_tfstytef=eA1Uu+nKmi3C1`~HBn46Eu3E5@gx(|_;lW2>eJ+5k{FtOeRb2eFo=fz= zBt#8TuuIJWgNt^q;Q_J4L_5l~%g?;QlZ)Y;| z&inno?|k3y&(Ca*peBFrV{kE5q+6AUZF{QK?@o?Y&yV-gvxNIi=?qj~I?%qSr7+f= zKYHgbgnX+dpIPYgl-k(;Y@K;kY%Au^&<*CV=pYfl>d?f(&y1FLH%{5~COg3(zllWm zYo=MQ5~zWqfQ^|}>kTW-@%x~|>Z$prT#Ey_&d0MY#@dhAE10AaaBr*%R`pzy^m37W z9As|YbmK!t?<>J%mG?)utA_bK^Gw*hne7*miJ*?kVCRFW)+^d4RH+I_bic)>_Q6e( zVQW*&1aJ1##}P`tz3_!i`*Wq<6TPuQ!; zAng2ix+*=xR~6mzsok9R1y#~VYQ9qitiFou+hZK3m?w rFa$%rXzpl6-9FpU~0W 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 KS1$m+@b|ysU?E}v literal 0 HcmV?d00001 diff --git a/addons/clgp/data/cu_mat.rvmat b/addons/clgp/data/cu_mat.rvmat new file mode 100644 index 00000000000..ea44aba3bb6 --- /dev/null +++ b/addons/clgp/data/cu_mat.rvmat @@ -0,0 +1,92 @@ +ambient[]={1,0.98500001,0.97000003,1}; +diffuse[]={1,0.98500001,0.97000003,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={0.0001,0.0001,0.0001,0}; +specularPower=2000; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 +{ + texture="#(argb,8,8,3)color(0.5,0.5,1,1)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage2 +{ + texture = "#(argb,8,8,3)color(0.5,0.5,0.5,1,DT)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {5,-4,0}; + up[] = {8,1.931601,0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage3 +{ + texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage4 +{ + texture="#(argb,8,8,3)color(0,1,1,1)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage5 +{ + texture="#(argb,8,8,3)color(1,1,1,1)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage6 +{ + texture = "#(ai,64,128,1)fresnel(1.5,1.22)"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; +class Stage7 +{ + texture = "a3\data_f\env_land_co.paa"; + uvSource = "tex"; + class uvTransform + { + aside[] = {1.0,0.0,0.0}; + up[] = {0.0,1.0,0.0}; + dir[] = {0.0,0.0,0.0}; + pos[] = {0.0,0.0,0.0}; + }; +}; \ No newline at end of file diff --git a/addons/clgp/data/cu_shell_co.paa b/addons/clgp/data/cu_shell_co.paa new file mode 100644 index 0000000000000000000000000000000000000000..6731f09e1dc8393035d1ed0d719b2ca480a04e7f GIT binary patch literal 28407 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 literal 0 HcmV?d00001 diff --git a/addons/clgp/data/model.cfg b/addons/clgp/data/model.cfg new file mode 100644 index 00000000000..e4a84e5c9eb --- /dev/null +++ b/addons/clgp/data/model.cfg @@ -0,0 +1,66 @@ +class CfgSkeletons { + class Default { + isDiscrete = 1; + skeletonInherit = ""; + skeletonBones[] = {}; + }; + class ace_cuhead_Skeleton: Default { + isDiscrete = 1; + skeletonInherit = "Default"; + skeletonBones[]={ + "dial1","", + "dial2","", + "dial3","", + "dial4","", + "dial5","" + }; + }; +}; + +class CfgModels { + class Default { + sections[] = {}; + sectionsInherit=""; + skeletonName = ""; + }; + class ace_cuhead: Default { + sections[]={}; + skeletonName="ace_cuhead_Skeleton"; + sectionsInherit = "Default"; + class Animations { + class Dial1 { + type="rotation"; + source="Dial1"; // used in ctrlAnimateModel + AnimPeriod = 1; + selection="dial1"; + axis="axis1"; + angle0="rad 7"; + angle1="rad (7 - 7*40)"; + }; + class Dial2: Dial1 { + source="Dial2"; + selection="dial2"; + axis="axis2"; + }; + class Dial3: Dial1 { + source="Dial3"; + selection="dial3"; + axis="axis3"; + }; + class Dial4: Dial1 { + source="Dial4"; + selection="dial4"; + axis="axis4"; + angle0="rad 0"; + angle1="rad (0 + 7*40)"; // lol why is this different + }; + class Dial5: Dial1 { + source="Dial5"; + selection="dial5"; + axis="axis5"; + angle0="rad 0"; + angle1="rad (0 + 7*40)"; + }; + }; + }; +}; diff --git a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf new file mode 100644 index 00000000000..7c2f0f0972a --- /dev/null +++ b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf @@ -0,0 +1,69 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Copperhead: attack profile + * + * Arguments: + * 0: Seeker Target PosASL + * 1: Guidance Arg Array + * 2: Attack Profile State + * + * Return Value: + * Missile Aim PosASL + * + * Example: + * [[1,2,3], [], []] call ace_copperhead_fnc_attackProfile + * + * Public: No + */ + +params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; +_args params ["_firedEH"]; +_firedEH params ["","","","","","","_projectile"]; +_attackProfileStateParams params ["", "_trajectoryBallistic", "_checkOrientation"]; + +private _projectilePos = getPosASL _projectile; +private _projectileVelocity = velocity _projectile; +private _velocityElev = acos (_projectileVelocity vectorCos [0,0,-1]); // referenced to straight down +private _isFalling = _velocityElev < 90; + +private _aimASL = []; // return + +if (_seekerTargetPos isEqualTo [0,0,0]) then { + // no target + _aimASL = _projectilePos vectorAdd _projectileVelocity; + if (_isFalling && {!_trajectoryBallistic}) then { + // Shaped Trajectory - Try to glide level - adjusted to correct AoA below + _aimASL set [2, _projectilePos # 2]; + }; + } else { + // have valid seeker target + _aimASL = _seekerTargetPos; + // aim above target due to gravity drop + private _distance2d = _projectilePos distance2d _aimASL; + private _speed2d = vectorMagnitude [_projectileVelocity#0, _projectileVelocity#1, 0]; + private _tof = (_distance2d / (_speed2d max 1)) min 15; + if (_tof > 1.5) then { + _aimASL = _aimASL vectorAdd [0,0, 2 * _tof ^2]; + }; + }; + +// Limit max elevation to prevent stalling - unpowered gliding +private _maxElev = 68; // ~2.5 glide ratio +private _aimDiff = _aimASL vectorDiff _projectilePos; +private _aimElev = acos (_aimDiff vectorCos [0,0,-1]); +if (_aimElev > _velocityElev) then { + private _adjustAngle = (_maxElev max _velocityElev) - _aimElev; + if (_adjustAngle >= 0) exitWith {}; + private _adjustOffset = (sin _adjustAngle) * vectorMagnitude _aimDiff; + _aimASL = _aimASL vectorAdd [0,0,_adjustOffset]; +}; + +// prevent rare "boomerang" at extremely high elevation shots the round won't flip correctly at apex +if (_isFalling && _checkOrientation) then { + _attackProfileStateParams set [2, false]; + [_projectile, vectorNormalized _projectileVelocity] call EFUNC(missileguidance,changeMissileDirection); +}; + +_aimASL + diff --git a/addons/clgp/functions/fnc_copperhead_onfired.sqf b/addons/clgp/functions/fnc_copperhead_onfired.sqf new file mode 100644 index 00000000000..5794ef1a273 --- /dev/null +++ b/addons/clgp/functions/fnc_copperhead_onfired.sqf @@ -0,0 +1,41 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Copperhead: On fired - set attack profile settings + * + * Arguments: + * Args + * + * Return Value: + * None + * + * Example: + * [] call ace_clgp_fnc_copperhead_onfired + * + * Public: No + */ + +params ["_firedEH", "_launchParams", "", "", "_stateParams"]; +_launchParams params ["","","","","","_laserInfo"]; +_firedEH params ["_shooter","","","","","","_projectile"]; +_stateParams params ["", "", "_attackProfileStateParams"]; + +private _settings = _shooter getVariable [QGVAR(copperhead_settings), COPPERHEAD_DEFUALT_SETTINGS]; + +_settings params [["_trajectorySetting", 1], ["_delaySetting", 1], ["_laserCodeA", 1], ["_laserCodeB", 1], ["_laserCodeC", 1]]; + +// Set trajectory and delay from first 2 dials +private _trajectoryBallistic = _trajectorySetting in [1,2]; // 1-2 = ballisitic, any other is shaped +private _delayDeployment = linearConversion [1, 8, _delaySetting, 0, [48, 45] select _trajectoryBallistic, true]; + +_attackProfileStateParams set [0, _delayDeployment]; +_attackProfileStateParams set [1, _trajectoryBallistic]; +_attackProfileStateParams set [2, true]; // _checkOrientation + +// Set laser guidance info from last 3 dials +// Note: copperhead uses a 3 digit code - techinally 111 should be able to lock onto any X111 4 digit code +// not sure if worth modifying ace_laser for this, for now just assume high digit is 1 +private _laserCode = 1000 + 100 * _laserCodeA + 10 * _laserCodeB + _laserCodeC; +_laserInfo set [0, _laserCode]; + +TRACE_4("copperhead_onfired",_projectile,_trajectoryBallistic,_delayDeployment,_laserCode); diff --git a/addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf b/addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf new file mode 100644 index 00000000000..a3d75f96e81 --- /dev/null +++ b/addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf @@ -0,0 +1,23 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Copperhead: submunition condition, checks if shell should become missile (wings deploy) + * + * Arguments: + * Args + * + * Return Value: + * None + * + * Example: + * [any, vehicle player] call ace_clgp_fnc_copperhead_submunitionCondition + * + * Public: No + */ + +params ["", "", "", "", "_stateParams"]; +_stateParams params ["_lastRunTime", "", "_attackProfileStateParams"]; +_attackProfileStateParams params ["_delayDeployment"]; + +private _runtimeDelta = cba_missionTime - _lastRunTime; +_runtimeDelta > _delayDeployment // return diff --git a/addons/clgp/functions/fnc_copperhead_uiCanOpen.sqf b/addons/clgp/functions/fnc_copperhead_uiCanOpen.sqf new file mode 100644 index 00000000000..bb77104b05c --- /dev/null +++ b/addons/clgp/functions/fnc_copperhead_uiCanOpen.sqf @@ -0,0 +1,33 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Condition for showing copperhead interface, used in both interaction menu and inside dialog loop + * + * Arguments: + * Args + * + * Return Value: + * None + * + * Example: + * [vehicle, player] call ace_clgp_fnc_copperhead_uiCanOpen + * + * Public: No + */ + +params ["_vehicle", "_player"]; +// TRACE_2("copperhead_uiCanOpen",_vehicle,_player); + +(_player in _vehicle) +&& {(_vehicle unitTurret _player) isEqualTo [0]} +&& {alive _vehicle} +&& { + private _hasCopperheadAmmo = false; + { + _x params ["_xMag", "_xTurret", "_xAmmo"]; + if ((_xTurret isEqualTo [0]) && {_xAmmo > 0} && {_xMag == "ace_1rnd_155mm_m712"}) exitWith { + _hasCopperheadAmmo = true; + }; + } forEach (magazinesAllTurrets _vehicle); + _hasCopperheadAmmo +} diff --git a/addons/clgp/functions/fnc_copperhead_uiCreate.sqf b/addons/clgp/functions/fnc_copperhead_uiCreate.sqf new file mode 100644 index 00000000000..0517b854abe --- /dev/null +++ b/addons/clgp/functions/fnc_copperhead_uiCreate.sqf @@ -0,0 +1,87 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Shows copperhead dialog + * + * Arguments: + * Args + * + * Return Value: + * None + * + * Example: + * [vehicle, player] call ace_clgp_fnc_copperhead_uiCreate + * + * Public: No + */ + +[{ // execNextFrame to prevent issues with interaction menu closing + + params ["_vehicle", "_player"]; + TRACE_2("copperhead_uiCreate",_vehicle,_player); + + createDialog QGVAR(copperhead_dialog); + + private _display = uiNamespace getVariable [QGVAR(copperhead_dialog), displayNull]; + if (isNull _display) exitWith { ERROR("bad dialog");}; + + private _copperheadSettings = _vehicle getVariable [QGVAR(copperhead_settings), COPPERHEAD_DEFUALT_SETTINGS]; + TRACE_1("current",_copperheadSettings); + _display setVariable ["vehicle", _vehicle]; + _display setVariable ["settings", _copperheadSettings]; + + + // Scale and center model + private _scale = 1 / (getResolution # 5); // keep object the same size for any interface size + private _base = ["3d", [0,-0.338, 0.3333], _scale] call EFUNC(common,rscObjectHelper); + (_display displayCtrl 100) ctrlSetPosition _base; + (_display displayCtrl 100) ctrlSetModelScale _scale; + + + // Handle mouse clicks on the dials + private _fnc_dialClick = { + params ["_control", "_button", "_xPos", "_yPos", "_shift", "_ctrl", "_alt"]; + private _display = ctrlParent _control; + private _settings = _display getVariable "settings"; + + private _add = if (_button == 0) then { 1 } else { -1 }; + + private _dialIndex = ((ctrlIDC _control) % 10) - 1; + private _newValue = ((_add + _settings # _dialIndex) max 1) min 8; + _settings set [_dialIndex, _newValue]; + }; + { + (_display displayCtrl _x) ctrlAddEventHandler ["MouseButtonUp", _fnc_dialClick]; + } forEach [111, 112, 113,114, 115]; + + + // Update display each frame + private _fnc_eachFrame = { + params ["_display"]; + private _vehicle = _display getVariable "vehicle"; + private _settings = _display getVariable "settings"; + + if (!([_vehicle, ace_player] call FUNC(copperhead_uiCanOpen))) exitWith { + closeDialog 5; + }; + { + private _animName = format ["Dial%1", _forEachIndex + 1]; + private _phase = linearConversion [1,8,_x,0,1]; // ~40deg per click, handled by model.cfg + (_display displayCtrl 100) ctrlAnimateModel [_animName, _phase]; + } forEach _settings; + }; + _display displayAddEventHandler ["MouseMoving", _fnc_eachFrame]; + _display displayAddEventHandler ["MouseHolding", _fnc_eachFrame]; + + + // Save data to vehicle on close + _display displayAddEventHandler ["Unload", { + params ["_display", "_exitCode"]; + private _vehicle = _display getVariable "vehicle"; + private _settings = _display getVariable "settings"; + TRACE_3("Unload",_exitCode,_vehicle,_settings); + if ((!alive _vehicle) || {_settings isEqualTo []}) exitWith { ERROR_2("unloaded with bad input %1-%2",_vehicle,_settings); }; + + _vehicle setVariable [QGVAR(copperhead_settings), _settings, true]; // global + }]; +}, _this] call CBA_fnc_execNextFrame; \ No newline at end of file diff --git a/addons/clgp/functions/script_component.hpp b/addons/clgp/functions/script_component.hpp new file mode 100644 index 00000000000..4b442f1884d --- /dev/null +++ b/addons/clgp/functions/script_component.hpp @@ -0,0 +1 @@ +#include "\z\ace\addons\clgp\script_component.hpp" diff --git a/addons/clgp/script_component.hpp b/addons/clgp/script_component.hpp new file mode 100644 index 00000000000..d2a03597d3b --- /dev/null +++ b/addons/clgp/script_component.hpp @@ -0,0 +1,11 @@ +#define COMPONENT clgp +#define COMPONENT_BEAUTIFIED Cannon Launched Guided Projectiles +#include "\z\ace\addons\main\script_mod.hpp" + +#define DEBUG_MODE_FULL +#define DISABLE_COMPILE_CACHE +#define ENABLE_PERFORMANCE_COUNTERS + +#include "\z\ace\addons\main\script_macros.hpp" + +#define COPPERHEAD_DEFUALT_SETTINGS [ARR_5(1,1,1,1,1)] diff --git a/addons/clgp/stringtable.xml b/addons/clgp/stringtable.xml new file mode 100644 index 00000000000..ac54bf6f067 --- /dev/null +++ b/addons/clgp/stringtable.xml @@ -0,0 +1,8 @@ + + + + + Configure M712 Shell + + + diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index 4b547655394..b6d5913fd0c 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -145,6 +145,7 @@ PREP(removeSpecificMagazine); PREP(requestCallback); PREP(resetAllDefaults); PREP(restoreVariablesJIP); +PREP(rscObjectHelper); PREP(runAfterSettingsInit); PREP(runTests); PREP(sanitizeString); diff --git a/addons/common/functions/fnc_rscObjectHelper.sqf b/addons/common/functions/fnc_rscObjectHelper.sqf new file mode 100644 index 00000000000..fac7e6ed332 --- /dev/null +++ b/addons/common/functions/fnc_rscObjectHelper.sqf @@ -0,0 +1,64 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Convert between screen and 3d object cordinates + * + * Arguments: + * 0: Function + * 1: Input array + * 2: Scale (optional: 1) + * + * Return Value: + * Value + * + * Example: + * ["2d", [0,0,0], 1] call ace_common_fnc_rscObjectHelper + * + * Public: Maybe + */ + +params ["_func", "_array", ["_scale", 1]]; + +private _adjustCam = 1; +private _topFOV = getResolution # 6; +private _leftFOV = getResolution # 7; + +private _topLeftX = (_leftFOV-1)*0.5/_leftFOV; +private _bottomRightX = 1-_topLeftX; +private _topLeftY = 0; +private _bottomRightY = 1; + +private _return = []; + +switch (toLower _func) do { + case ("2d"): { + _array params ["_pointX", "_z", "_pointY"]; + + private _scrX = _pointX * (_bottomRightX - _topLeftX) + _topLeftX; + private _vX = _leftFOV * (_scrX - 0.5) * _adjustCam * _z; + + private _scrY = _pointY * (_bottomRightY - _topLeftY) + _topLeftY; + private _vY = _topFOV * (0.5 - _scrY) * _adjustCam * _z; + + _vX = _vX / _scale; + _vY = _vY / _scale; + + _return = [_vX, _vY, _z]; + }; + case ("3d"): { + _array params ["_vX", "_vY", "_z"]; // z is distance from screen + + _vX = _vX * _scale; + _vY = _vY * _scale; + + private _scrX = _vX / (_leftFOV * _adjustCam * _z) + 0.5; + private _pointX = (_scrX - _topLeftX) / (_bottomRightX - _topLeftX); + + private _scrY = 0.5 - _vY / (_topFOV * _adjustCam * _z); + private _pointY = (_scrY - _topLeftY) / (_bottomRightY - _topLeftY); + + _return = [_pointX, _z, _pointY]; + }; +}; + +_return diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 075f2f03c59..77d63559916 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -6,6 +6,7 @@ PREP(changeMissileDirection); PREP(checkSeekerAngle); PREP(checkLos); +PREP(deploySubmunition); PREP(onFired); PREP(onIncomingMissile); diff --git a/addons/missileguidance/XEH_post_init.sqf b/addons/missileguidance/XEH_post_init.sqf index cc09b1f0ac7..9f62f3bea4d 100644 --- a/addons/missileguidance/XEH_post_init.sqf +++ b/addons/missileguidance/XEH_post_init.sqf @@ -11,3 +11,9 @@ false }, [15, [false, true, false]], false] call CBA_fnc_addKeybind; //Ctrl+Tab Key + +#ifdef DRAW_GUIDANCE_INFO +if (productVersion #4 == "Diag") then { + call compile "'Shots' diag_enable false; [{'Shots' diag_enable true;}] call CBA_fnc_execNextFrame;"; +}; +#endif diff --git a/addons/missileguidance/functions/fnc_deploySubmunition.sqf b/addons/missileguidance/functions/fnc_deploySubmunition.sqf new file mode 100644 index 00000000000..defd107cb6c --- /dev/null +++ b/addons/missileguidance/functions/fnc_deploySubmunition.sqf @@ -0,0 +1,58 @@ +#include "script_component.hpp" +/* + * Author: PabstMirror + * Fired event handler for submunition projectiles that will become missiles + * + * Arguments: + * Guidance Arg Array + * + * Return Value: + * Handeled + * + * Example: + * [args] call ace_missileguidance_fnc_deploySubmunition + * + * Public: No + */ + +params ["_firedEH", "", "", "", "_stateParams"]; +_firedEH params ["","","","","_ammo","","_projectile"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_submunitionArray"]; +_submunitionArray params ["_submunitionCondition", "_replacementAmmo", "_curPosASL"]; + + +#ifdef DRAW_GUIDANCE_INFO +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL getPosASL _projectile, 0.75, 0.75, 0, format ["Sub: %1", _ammo], 1, 0.025, "TahomaB"]; +#endif + +private _handled = false; // return value + +if (_submunitionCondition != "#Triggered") then { + if (isNull _projectile) exitWith { WARNING_1("projectile became null before triggered - %1", _this); }; + _handled = true; // exit back in main loop + if (_this call (missionNamespace getVariable _submunitionCondition)) then { + private _curPosASL = getPosASL _projectile; + triggerAmmo _projectile; // will be available next frame + _submunitionArray set [0, "#Triggered"]; + _submunitionArray set [2, _curPosASL]; + TRACE_2("triggered shell",_projectile,_submunitionArray); + }; +} else { + private _matches = ((ASLtoAGL _curPosASL) nearObjects [_replacementAmmo, 100]); + _matches = _matches apply { [_curPosASL vectorDistance (getPosASL _x), _x] }; + _matches sort true; + TRACE_2("",_replacementAmmo,_matches); + private _newProjectile = (_matches param [0, [0, objNull]]) select 1; + + if (!alive _newProjectile || {!local _newProjectile}) exitWith { + WARNING_3("submunition null %1",_newProjectile,alive _newProjectile, local _newProjectile); + }; + _stateParams set [0, cba_missionTime]; // reset guidance time to now + _stateParams set [4, []]; // so this never runs anymore + _firedEH set [4, _replacementAmmo]; + _firedEH set [6, _newProjectile]; + + m = _newProjectile; +}; + +_handled diff --git a/addons/missileguidance/functions/fnc_doAttackProfile.sqf b/addons/missileguidance/functions/fnc_doAttackProfile.sqf index 53d43883d3f..29a33758173 100644 --- a/addons/missileguidance/functions/fnc_doAttackProfile.sqf +++ b/addons/missileguidance/functions/fnc_doAttackProfile.sqf @@ -26,12 +26,16 @@ private _attackProfileFunction = getText (configFile >> QGVAR(AttackProfiles) >> private _attackProfilePos = _this call (missionNamespace getVariable _attackProfileFunction); if ((isNil "_attackProfilePos") || {_attackProfilePos isEqualTo [0,0,0]}) exitWith { - ERROR_1("attack profile returned bad pos",_attackProfilePos); +#ifdef DRAW_GUIDANCE_INFO + private _forwardPosition = _projectilePos vectorAdd (velocity _projectile); + drawLine3D [ASLtoAGL _projectilePos, ASLtoAGL _forwardPosition, [0,0,1,1]]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,1,1], ASLtoAGL _forwardPosition, 0.5, 0.5, 0, format ["%1: NONE", _attackProfileName], 1, 0.025, "TahomaB"]; +#endif [0,0,0] }; #ifdef DRAW_GUIDANCE_INFO -drawLine3D [(ASLtoAGL _attackProfilePos), (ASLtoAGL _seekerTargetPos), [0,1,1,1]]; +if (_seekerTargetPos isNotEqualTo [0,0,0]) then { drawLine3D [(ASLtoAGL _attackProfilePos), (ASLtoAGL _seekerTargetPos), [0,1,1,1]]; }; drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,1,1], ASLtoAGL _attackProfilePos, 0.5, 0.5, 0, _attackProfileName, 1, 0.025, "TahomaB"]; #endif diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 8050dfcff53..45c3f381cff 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -24,27 +24,19 @@ params ["_args", "_pfID"]; _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; _firedEH params ["_shooter","","","","_ammo","","_projectile"]; _launchParams params ["","_targetLaunchParams"]; -_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +_flightParams params ["_minDeflection", "_maxDeflection", "_incDeflection", "_useVanillaDeflection"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_submunitionArray"]; + +if ((_submunitionArray isNotEqualTo []) && {_args call FUNC(deploySubmunition)}) exitWith {}; if (!alive _projectile || isNull _projectile || isNull _shooter) exitWith { [_pfID] call CBA_fnc_removePerFrameHandler; END_COUNTER(guidancePFH); }; -private _runtimeDelta = diag_tickTime - _lastRunTime; -private _adjustTime = 1; - -if (accTime > 0) then { - _adjustTime = 1/accTime; - _adjustTime = _adjustTime * (_runtimeDelta / TIMESTEP_FACTOR); - TRACE_4("Adjust timing", 1/accTime, _adjustTime, _runtimeDelta, (_runtimeDelta / TIMESTEP_FACTOR) ); -} else { - _adjustTime = 0; -}; - -private _minDeflection = ((_flightParams select 0) - ((_flightParams select 0) * _adjustTime)) max 0; -private _maxDeflection = (_flightParams select 1) * _adjustTime; -// private _incDeflection = _flightParams select 2; // todo +private _runtimeDelta = cba_missionTime - _lastRunTime; +_stateParams set [0, cba_missionTime]; +private _adjustTime = _runtimeDelta / TIMESTEP_FACTOR; private _projectilePos = getPosASL _projectile; @@ -55,8 +47,20 @@ private _seekerTargetPos = [[0,0,0], _args, _seekerStateParams, _lastKnownPosSta private _profileAdjustedTargetPos = [_seekerTargetPos, _args, _attackProfileStateParams] call FUNC(doAttackProfile); // If we have no seeker target, then do not change anything -// If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection -if ((_minDeflection != 0 || {_maxDeflection != 0}) && {_profileAdjustedTargetPos isNotEqualTo [0,0,0]}) then { +if (_profileAdjustedTargetPos isNotEqualTo [0,0,0]) then { + if (_useVanillaDeflection) exitWith { + _projectile setMissileTargetPos ASLtoAGL _profileAdjustedTargetPos; + #ifdef DRAW_GUIDANCE_INFO + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0.5,1,0,1], ASLtoAGL (missileTargetPos _projectile), 1, 1, diag_tickTime * 60, "", 1, 0.025, "TahomaB"]; + #endif + }; + + _minDeflection = _minDeflection * _adjustTime; + _maxDeflection = _maxDeflection * _adjustTime; + // _incDeflection = _flightParams select 2; // todo + // If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection + if ((_minDeflection == 0) && {_maxDeflection == 0}) exitWith {}; + private _targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos; private _adjustVector = _targetVector vectorDiff (vectorDir _projectile); @@ -92,23 +96,24 @@ if ((_minDeflection != 0 || {_maxDeflection != 0}) && {_profileAdjustedTargetPos TRACE_3("", _pitch, _yaw, _roll); TRACE_3("", _targetVector, _adjustVector, _finalAdjustVector); - if (accTime > 0) then { - private _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; - TRACE_2("",_projectile,_changeVector); - [_projectile, _changeVector] call FUNC(changeMissileDirection); - }; + private _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; + TRACE_2("",_projectile,_changeVector); + [_projectile, _changeVector] call FUNC(changeMissileDirection); }; #ifdef DRAW_GUIDANCE_INFO TRACE_3("",_projectilePos,_seekerTargetPos,_profileAdjustedTargetPos); drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; - -private _ps = "#particlesource" createVehicleLocal (ASLtoAGL _projectilePos); -_PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 2], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil]; -_PS setDropInterval 3.0; +private _forwardPosition = _projectilePos vectorAdd ((vectorNormalized (velocity _projectile)) vectorMultiply 15); +drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0.5,0,1,1], ASLtoAGL _forwardPosition, 0.75, 0.75, 0, + format ["V: %1 (%2)", round vectorMagnitude velocity _projectile, round ((velocity _projectile) # 2)], 1, 0.025, "TahomaB"]; +drawLine3D [ASLtoAGL _projectilePos, ASLtoAGL _forwardPosition, [0.5,0,1,1]]; + +if (productVersion #4 != "Diag") then { + private _ps = "#particlesource" createVehicleLocal (ASLtoAGL _projectilePos); + _PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 2], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil]; + _PS setDropInterval 3.0; +}; #endif -_stateParams set [0, diag_tickTime]; - END_COUNTER(guidancePFH); - diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 422639c452a..1302ec64301 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -17,13 +17,10 @@ * Public: No */ -params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; - -// Bail on not missile -if (!(_ammo isKindOf "MissileBase")) exitWith {}; +params ["_shooter","_weapon","","_mode","_ammo","","_projectile","_gunner"]; // Bail if guidance is disabled for this ammo -if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; +if ((getNumber (configOf _projectile >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; // Bail on locality of the projectile, it should be local to us if (GVAR(enabled) < 1 || {!local _projectile} ) exitWith {}; @@ -31,6 +28,10 @@ if (GVAR(enabled) < 1 || {!local _projectile} ) exitWith {}; // Bail if shooter isn't player AND system not enabled for AI: if ( !isPlayer _shooter && { GVAR(enabled) < 2 } ) exitWith {}; +// For submuntion's that will become missiles - Note that _projectile will be local to everyone +private _submunitionCondition = getText (configOf _projectile >> QUOTE(ADDON) >> "submunitionCondition"); +if ((_submunitionCondition != "") && {!local _gunner}) exitWith {}; + // Verify ammo has explicity added guidance config (ignore inheritances) private _configs = configProperties [(configFile >> "CfgAmmo" >> _ammo), QUOTE(configName _x == QUOTE(QUOTE(ADDON))), false]; if ((count _configs) < 1) exitWith {}; @@ -38,6 +39,13 @@ if ((count _configs) < 1) exitWith {}; // MissileGuidance is enabled for this shot TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); +private _submunitionArray = []; +if (_submunitionCondition != "") then { + TRACE_1("using submunition for seeker/attack configs",_ammo); + _ammo = getText (configOf _projectile>> "submunitionAmmo"); + _submunitionArray = [_submunitionCondition, _ammo, []]; +}; + private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); private _target = _shooter getVariable [QGVAR(target), nil]; @@ -107,7 +115,8 @@ private _args = [_this, [ getNumber ( _config >> "minDeflection" ), getNumber ( _config >> "maxDeflection" ), - getNumber ( _config >> "incDeflection" ) + getNumber ( _config >> "incDeflection" ), + 1 == getNumber ( _config >> "useVanillaDeflection" ) ], [ getNumber ( _config >> "seekerAngle" ), @@ -115,24 +124,21 @@ private _args = [_this, getNumber ( _config >> "seekerMaxRange" ), getNumber ( _config >> "seekerMinRange" ) ], - [ diag_tickTime, [], [], _lastKnownPosState] + [ cba_missionTime, [], [], _lastKnownPosState, _submunitionArray ] ]; private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); -TRACE_1("",_onFiredFunc); +TRACE_1("seeker",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; - _onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); -TRACE_1("",_onFiredFunc); +TRACE_1("attackProfile",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; - -// Run the "onFired" function passing the full guidance args array _onFiredFunc = getText (_config >> "onFired"); -TRACE_1("",_onFiredFunc); +TRACE_1("ammo",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; @@ -142,10 +148,10 @@ if (_onFiredFunc != "") then { // _firedEH params ["_shooter","","","","_ammo","","_projectile"]; // _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; // _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; -// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_submunitionArray"]; // _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; -[FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; +[FUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; /* Clears locking settings From 9d18dc61288b1d0273292745d55d8b5a9deae79f Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sat, 14 Oct 2023 21:47:07 -0500 Subject: [PATCH 07/23] redo using ammo events --- addons/missileguidance/XEH_PREP.hpp | 1 + .../functions/fnc_onFiredDeffered.sqf | 135 ++++++++++++++++++ addons/pike/$PBOPREFIX$ | 2 +- addons/pike/CfgAmmo.hpp | 53 ++++--- addons/pike/CfgEventhandlers.hpp | 12 +- addons/pike/CfgMagazines.hpp | 14 +- addons/pike/README.md | 7 - addons/pike/XEH_PREP.hpp | 3 +- addons/pike/XEH_postInit.sqf | 5 - addons/pike/functions/fnc_ammoFired.sqf | 61 ++++++++ addons/pike/functions/fnc_handleFired.sqf | 58 -------- addons/pike/functions/script_component.hpp | 1 - addons/pike/script_component.hpp | 6 +- addons/pike/stringtable.xml | 10 +- addons/pike/ui/gear_pike_ca.paa | Bin 0 -> 25111 bytes 15 files changed, 257 insertions(+), 111 deletions(-) create mode 100644 addons/missileguidance/functions/fnc_onFiredDeffered.sqf delete mode 100644 addons/pike/XEH_postInit.sqf create mode 100644 addons/pike/functions/fnc_ammoFired.sqf delete mode 100644 addons/pike/functions/fnc_handleFired.sqf delete mode 100644 addons/pike/functions/script_component.hpp create mode 100644 addons/pike/ui/gear_pike_ca.paa diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 075f2f03c59..3b807721af2 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -7,6 +7,7 @@ PREP(checkSeekerAngle); PREP(checkLos); PREP(onFired); +PREP(onFiredDeffered); PREP(onIncomingMissile); PREP(guidancePFH); diff --git a/addons/missileguidance/functions/fnc_onFiredDeffered.sqf b/addons/missileguidance/functions/fnc_onFiredDeffered.sqf new file mode 100644 index 00000000000..3b1a61ebca7 --- /dev/null +++ b/addons/missileguidance/functions/fnc_onFiredDeffered.sqf @@ -0,0 +1,135 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Gathers onFired args for later use + * + * Arguments: + * 0: Shooter (Man/Vehicle) + * 4: Ammo + * 6: Projectile + * + * Return Value: + * Args + * + * Example: + * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFiredDeffered + * + * Public: No + */ + +params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; + +// Bail if guidance is disabled for this ammo +if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 2) exitWith { ERROR("not enabled=2"); [] }; + +// MissileGuidance is enabled for this shot +TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); + +private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); + +private _target = _shooter getVariable [QGVAR(target), nil]; +private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; +private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; +private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; +if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "useModeForAttackProfile")) == 1) then { + _attackProfile = getText (configFile >> "CfgWeapons" >> _weapon >> _mode >> QGVAR(attackProfile)) +}; +private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; + +private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; +private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; + +TRACE_6("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode); + +private _launchPos = getPosASL (vehicle _shooter); + +if (isNil "_seekerType" || {!(_seekerType in (getArray (_config >> "seekerTypes")))}) then { + _seekerType = getText (_config >> "defaultSeekerType"); +}; +if (isNil "_attackProfile" || {!(_attackProfile in (getArray (_config >> "attackProfiles")))}) then { + _attackProfile = getText (_config >> "defaultAttackProfile"); +}; +if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes")))}) then { + _lockMode = getText (_config >> "defaultSeekerLockMode"); +}; + +// If we didn't get a target, try to fall back on tab locking +if (isNil "_target") then { + if (!isPlayer _shooter) then { + // This was an AI shot, lets still guide it on the AI target + _target = _shooter getVariable [QGVAR(vanilla_target), nil]; + TRACE_1("Detected AI Shooter!", _target); + } else { + private _canUseLock = getNumber (_config >> "canVanillaLock"); + // @TODO: Get vanilla target + if (_canUseLock > 0 || difficulty < 1) then { + private _vanillaTarget = cursorTarget; + + TRACE_1("Using Vanilla Locking", _vanillaTarget); + if (!isNil "_vanillaTarget") then { + _target = _vanillaTarget; + }; + }; + }; +}; + +// Array for seek last target position +private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; +private _lastKnownPosState = [_seekLastTargetPos]; +if (_seekLastTargetPos && {!isNil "_target"}) then { + _lastKnownPosState set [1, (getPosASL _target)]; +} else { + _lastKnownPosState set [1, [0,0,0]]; +}; + +TRACE_4("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile); +private _args = [_this, + [ _shooter, + [_target, _targetPos, _launchPos], + _seekerType, + _attackProfile, + _lockMode, + _laserInfo + ], + [ + getNumber ( _config >> "minDeflection" ), + getNumber ( _config >> "maxDeflection" ), + getNumber ( _config >> "incDeflection" ) + ], + [ + getNumber ( _config >> "seekerAngle" ), + getNumber ( _config >> "seekerAccuracy" ), + getNumber ( _config >> "seekerMaxRange" ), + getNumber ( _config >> "seekerMinRange" ) + ], + [ diag_tickTime, [], [], _lastKnownPosState] + ]; + +private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); +TRACE_1("",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +_onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); +TRACE_1("",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +// Run the "onFired" function passing the full guidance args array +_onFiredFunc = getText (_config >> "onFired"); +TRACE_1("",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +// Reverse: +// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +// _firedEH params ["_shooter","","","","_ammo","","_projectile"]; +// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; +// _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; +// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; + +_args diff --git a/addons/pike/$PBOPREFIX$ b/addons/pike/$PBOPREFIX$ index 2eefcc6075b..abc9bbeaaef 100644 --- a/addons/pike/$PBOPREFIX$ +++ b/addons/pike/$PBOPREFIX$ @@ -1 +1 @@ -z\ace\addons\pike \ No newline at end of file +z\ace\addons\pike diff --git a/addons/pike/CfgAmmo.hpp b/addons/pike/CfgAmmo.hpp index a82c09db0de..80e6ea54d53 100644 --- a/addons/pike/CfgAmmo.hpp +++ b/addons/pike/CfgAmmo.hpp @@ -1,10 +1,14 @@ class CfgAmmo { - class FlareBase; - class GVAR(ammo_gl): FlareBase { + class SubmunitionBase; + class GVAR(ammo_gl): SubmunitionBase { model = QPATHTOF(models\ace_pike_ammo.p3d); - lightColor[] = {0, 0, 0, 0}; - smokeColor[] = {0, 0, 0, 0}; - timeToLive = 1; + submunitionAmmo = QGVAR(ammo_rocket); + submunitionCount = 1; + submunitionConeAngle = 0; + EGVAR(frag,skip) = 1; // don't frag because this is a scripted ammo + class Eventhandlers { + fired = QUOTE(call FUNC(ammoFired)); + }; }; class MissileBase; @@ -13,29 +17,44 @@ class CfgAmmo { laserLock = 0; airLock = 0; manualControl = 0; - - timeToLive = 30; + timeToLive = 22; model = QPATHTOF(models\ace_pike_ammo.p3d); - maxSpeed = 150; - thrust = 15; - thrustTime = 8; + maxSpeed = 150; // ~2km in 15sec + thrust = 19; + thrustTime = 14; initTime = 0; airFriction = 0.1; - hit = 100; - indirectHit = 8; - indirectHitRange = 6; + hit = 120; + indirectHit = 10; + indirectHitRange = 10; + warheadName = "HE"; + + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,classes)[] = {QEGVAR(frag,tiny_HD)}; + EGVAR(frag,metal) = 200; + EGVAR(frag,charge) = 270; // ~8x a normal 40mm + EGVAR(frag,gurney_c) = 2700; + EGVAR(frag,gurney_k) = "1/2"; - CraterEffects = "AAMissileCrater"; - explosionEffects = "AAMissileExplosion"; + CraterEffects="ExploAmmoCrater"; + explosionEffects="ExploAmmoExplosion"; effectsMissileInit = "RocketBackEffectsRPG"; effectsMissile = "missile3"; + SoundSetExplosion[] = {"GrenadeHe_Exp_SoundSet", "GrenadeHe_Tail_SoundSet", "Explosion_Debris_SoundSet"}; + soundHit1[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_01", 3.1622777, 1, 1500}; + soundHit2[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_02", 3.1622777, 1, 1500}; + soundHit3[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_03", 3.1622777, 1, 1500}; + soundHit4[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_04", 3.1622777, 1, 1500}; + multiSoundHit[] = {"soundHit1", 0.25, "soundHit2", 0.25, "soundHit3", 0.25, "soundHit4", 0.25}; + whistleDist=16; // Begin ACE guidance Configs class ace_missileguidance { - enabled = 1; + enabled = 2; minDeflection = 0.0005; // Minium flap deflection for guidance maxDeflection = 0.0025; // Maximum flap deflection for guidance @@ -54,7 +73,7 @@ class CfgAmmo { seekerAccuracy = 1; // seeker accuracy multiplier seekerMinRange = 1; - seekerMaxRange = 2000; // Range from the missile which the seeker can visually search + seekerMaxRange = 3000; // Range from the missile which the seeker can visually search // Attack profile type selection defaultAttackProfile = "LIN"; diff --git a/addons/pike/CfgEventhandlers.hpp b/addons/pike/CfgEventhandlers.hpp index 5da5fd0dc24..be6bec5a73a 100644 --- a/addons/pike/CfgEventhandlers.hpp +++ b/addons/pike/CfgEventhandlers.hpp @@ -1,18 +1,10 @@ - class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; - 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) ); + init = QUOTE( call COMPILE_SCRIPT(XEH_preInit) ); }; }; diff --git a/addons/pike/CfgMagazines.hpp b/addons/pike/CfgMagazines.hpp index 99ea4056759..4258127db68 100644 --- a/addons/pike/CfgMagazines.hpp +++ b/addons/pike/CfgMagazines.hpp @@ -2,12 +2,14 @@ class CfgMagazines { class 1Rnd_HE_Grenade_shell; class ACE_40mm_Pike: 1Rnd_HE_Grenade_shell { displayName = CSTRING(magazine_displayName); - displayNameShort = "Pike SALH"; - descriptionShort = ""; - // picture = QPATHTOF(data\inventory_ca.paa); + displayNameShort = CSTRING(magazine_displayNameShort); + descriptionShort = CSTRING(magazine_descriptionShort); + picture = QPATHTOF(ui\gear_pike_ca.paa); ammo = QGVAR(ammo_gl); - model = QPATHTOF(models\ace_pike_ammo.p3d); - initSpeed = 40; - mass = 17; // 1.7 lbs + count = 1; + // model = QPATHTOF(models\ace_pike_ammo.p3d); // kinda ugly, just use pouch thing + initSpeed = 50; + mass = 17; // ~1.7 Pounds + author = ECSTRING(common,ACETeam); }; }; diff --git a/addons/pike/README.md b/addons/pike/README.md index 1e3424afa4e..a90c3570dba 100644 --- a/addons/pike/README.md +++ b/addons/pike/README.md @@ -2,10 +2,3 @@ ace_pike =========== Adds 40mm Pike semi-active laser seeking rocket, firable from the M320 or EGLM grenade launcher. - - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](http://github.com/PabstMirror) diff --git a/addons/pike/XEH_PREP.hpp b/addons/pike/XEH_PREP.hpp index 64eb51ef80f..a82521a9ae8 100644 --- a/addons/pike/XEH_PREP.hpp +++ b/addons/pike/XEH_PREP.hpp @@ -1 +1,2 @@ -PREP(handleFired); +LOG("prep"); +PREP(ammoFired); diff --git a/addons/pike/XEH_postInit.sqf b/addons/pike/XEH_postInit.sqf deleted file mode 100644 index 05f38dadaf1..00000000000 --- a/addons/pike/XEH_postInit.sqf +++ /dev/null @@ -1,5 +0,0 @@ -#include "script_component.hpp" - -if (!hasInterface) exitWith {}; - -["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; diff --git a/addons/pike/functions/fnc_ammoFired.sqf b/addons/pike/functions/fnc_ammoFired.sqf new file mode 100644 index 00000000000..545eed38804 --- /dev/null +++ b/addons/pike/functions/fnc_ammoFired.sqf @@ -0,0 +1,61 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Handles firing the 40mm pike grenade (shell) + * + * Arguments: + * FiredEH + * + * Return Value: + * Nothing + * + * Example: + * [] call ace_pike_fnc_ammoFired + * + * Public: No + */ + +params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; +TRACE_8("ammoFired",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_gunner); + +if (!local _gunner) exitWith {}; +if (isNull _projectile) exitWith {}; + +// Get MissileGuidance args now +private _firedEH = +_this; +_firedEH set [4, getText (configFile >> "CfgAmmo" >> _ammo >> "submunitionAmmo")]; +private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeffered); +_projectile setVariable [QGVAR(guidanceArgs), _guidanceArgs]; + +// On missile deploy start guidance +_projectile addEventHandler ["SubmunitionCreated", { + params ["_projectile", "_submunitionProjectile"]; + TRACE_2("SubmunitionCreated",_projectile,_submunitionProjectile); + + private _guidanceArgs = _projectile getVariable [QGVAR(guidanceArgs), []]; + if (_guidanceArgs isEqualTo []) exitWith { ERROR_1("bad args %1",_projectile); }; + _guidanceArgs params ["_firedEH", "", "", "", "_stateParams"]; + _firedEH set [6, _submunitionProjectile]; // _firedEH params ["","","","","","","_projectile"]; + _stateParams set [0, diag_tickTime]; // _stateParams params ["_lastRunTime"] + + [EFUNC(missileguidance,guidancePFH), 0, _guidanceArgs] call CBA_fnc_addPerFrameHandler; + if (!isNil QEFUNC(frag,addPfhRound)) then { + systemChat "fraggo"; + [_firedEH # 0, _firedEH # 4, _submunitionProjectile] call EFUNC(frag,addPfhRound); + }; + + #ifdef DEBUG_MODE_FULL + [{ + params ["_time", "_projectile"]; + if (isNull _projectile) exitWith {true}; + systemChat format ["%1 - %2", CBA_missionTime - _time, vectorMagnitude velocity _projectile]; + }, {}, [CBA_missionTime, _submunitionProjectile]] call CBA_fnc_waitUntilAndExecute; + #endif +}]; + +// Trigger motor after ~4 meter delay (could also use config `triggerTime`) +[{ + params ["_projectile"]; + if (isNull _projectile) exitWith { WARNING_1("null %1",_projectile); }; + triggerAmmo _projectile; +}, [_projectile], 0.1] call CBA_fnc_waitAndExecute; diff --git a/addons/pike/functions/fnc_handleFired.sqf b/addons/pike/functions/fnc_handleFired.sqf deleted file mode 100644 index 9454b7932e3..00000000000 --- a/addons/pike/functions/fnc_handleFired.sqf +++ /dev/null @@ -1,58 +0,0 @@ -#include "script_component.hpp" -/* - * Author: PabstMirror - * Handlese firing the 40mm pike grenade/rocket - * - * Arguments: - * FiredEH - * - * Return Value: - * Nothing - * - * Example: - * [] call ace_pike_fnc_handleFired - * - * Public: No - */ - -//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; -TRACE_7("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); -if (_ammo != QGVAR(ammo_gl)) exitWith {}; - -[{ - params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; - TRACE_7("rocket stage",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); - - //If null (deleted or hit water) exit: - if (isNull _projectile) exitWith {}; - - // Save grenade state - private _posASL = getPosASL _projectile; - private _vel = velocity _projectile; - TRACE_2("",_posASL,_vel); - - // Swap fired GL to a missile type - deleteVehicle _projectile; - private _rocket = QGVAR(ammo_rocket) createVehicle (getPosATL _projectile); - [QEGVAR(common,setShotParents), [_rocket, _unit, _unit]] call CBA_fnc_serverEvent; - - // Set correct position, velocity and direction (must set velocity before changeMissileDirection) - _rocket setPosASL _posASL; - _rocket setVelocity _vel; - [_rocket, vectorNormalized _vel] call EFUNC(missileguidance,changeMissileDirection); - - // Start missile guidance - [_unit, _weapon, _muzzle, _mode, QGVAR(ammo_rocket), _magazine, _rocket] call EFUNC(missileguidance,onFired); - TRACE_2("starting missile guidance",_rocket,typeOf _rocket); - - #ifdef DEBUG_MODE_FULL - [{ - params ["_args", "_pfID"]; - _args params [["_rocket", objNull], "_startTime"]; - if (!alive _rocket) exitWith {systemChat "done"; [_pfID] call CBA_fnc_removePerFrameHandler;}; - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,1,1], ASLtoAGL getPosASL _rocket, 0.75, 0.75, 0, "", 1, 0.025, "TahomaB"]; - hintSilent format ["vel %1\n%2 mps\n%3dist %3\ntof %4",velocity _rocket, round vectorMagnitude velocity _rocket, _rocket distance player, time - _startTime]; - }, 0.0, [_rocket, time]] call CBA_fnc_addPerFrameHandler; - #endif - -}, _this, 0.1] call CBA_fnc_waitAndExecute; diff --git a/addons/pike/functions/script_component.hpp b/addons/pike/functions/script_component.hpp deleted file mode 100644 index 85866ed86ba..00000000000 --- a/addons/pike/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\pike\script_component.hpp" \ No newline at end of file diff --git a/addons/pike/script_component.hpp b/addons/pike/script_component.hpp index 4a826ab71a5..b7bd9b4d931 100644 --- a/addons/pike/script_component.hpp +++ b/addons/pike/script_component.hpp @@ -2,9 +2,9 @@ #define COMPONENT_BEAUTIFIED Pike #include "\z\ace\addons\main\script_mod.hpp" -#define DEBUG_MODE_FULL -#define DISABLE_COMPILE_CACHE -#define ENABLE_PERFORMANCE_COUNTERS +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_PIKE #define DEBUG_MODE_FULL diff --git a/addons/pike/stringtable.xml b/addons/pike/stringtable.xml index 3ed702fccee..2ea6f88c7b4 100644 --- a/addons/pike/stringtable.xml +++ b/addons/pike/stringtable.xml @@ -1,8 +1,14 @@  - - + + 40mm Pike + + Pike SALH + + + Semi-Active Laser Guided 40mm Grenade + \ No newline at end of file diff --git a/addons/pike/ui/gear_pike_ca.paa b/addons/pike/ui/gear_pike_ca.paa new file mode 100644 index 0000000000000000000000000000000000000000..1b0ecb3807810796e38ebe0a352bfca928621615 GIT binary patch literal 25111 zcmd^n4Rln;eec}eyONf#9Vt?@#!wALLPDS~Y-}X1q`O!G;W%N1r6>dwz{Dv@Y{0eS z5PXpqHI7f}rc%_Nq&ba)la{o}D~0&A^fYHN>*Uq>IHxxBh&<=Hj{WMqho940wqKpv z?OknuGjr$e?r5cz49R=v^d1TE-kb?LPvG~esF+$c7!bpQfmQ<7N6SdpNYcrXKEri&NI)oX=jqsk*iN{LmbT~ZmLYOjQxFOcx z8R)A&Ut+MGE@A(xv#jE0F=Dc@q_HPFI^9hSR_>Ce&3n$>`~128>1Hw~$_Po_dD1wM z?tapUTxM0n!3p-l^_0~m%}tikoO}=a+vFm4ofCSjv@iXX!QMO`jn#LCO|~IPSiGB5 zlfWQ(sWe#HVITO}17!4`pgH}oqck<}R{c-Nw{BY&92|5?o-}^E(=h@GvggtxM^4-s z3dYKoULMKZ8UFC->%kK9;kAK4D8y>5#Z8@y%=A}mMt;j(&h9uKWa$`Xm1$B@e|&{` zlVh;m$#Ao~rr8Q~IW^~B9RG(G+pIS8Zyr3Hd3wrqf<`<(Fz_!l^y<#f-`2Evalkb~ z@y{;aJvjJQ)3kBl?+zP#oyH_789w^TOIu$Vachn&{>bO620!{a)|4z^e_}0Ti>#G< zLgVSpHtTW1>BA9Y5ZA zx~ZwDAro1*yUr%!@0~UQ2a9)q>$YRV!^avfu!q+kwFvy7ciwz7y5Zcf&*j8oU; zRI`K?Hml!0nR$CG^VrDX`gEj;ElWp+ZPMjNZgl%uqh+&!WGP#eT*6wcPL{E5>T*h$ z;r6kbY|X5F68oUuvTIMR}iypL775!T||%m`U!5muRO z?kjoWlXe#bN_2j_dgsX7Cog0M1_qnbHFcZZNL#w*SS$WmCR=Z9W`sGPWF%y@uoX^> zt+Y0>Zg<A7YNoH2P-QARq)WJ9{Ebbo0tlcbPUB~t&4VFlLg^|M+ z+3eP|r@Oz%9(21|<&zI>AN^SfaquZ?9s7(EV9z=mZ#+KI=Z0Cx{WM$W{t*~&z~6{* z?AWlw+R}$(_3j4-KVz~Q>-(%5wyUvjz~4V%f9d=_Yji5vt=3xB>6Eru3Cp>amAGTf zoQ@11gT}iVSz=vaq!k)JoZQR0ll9HX_jjgiPO&AKmSfIQ@Y~Xs{20{sLAJ_y0ajeu z<(4tid53-2`Yw38iQQ=Z8C&eE>VT9Gq%A$>u>0H*w%1()RV-o;Tjgwfa)=}9PBwM8 zdpA!|oDYXTj%p*(t|lKXL|GOVa90x74wv>Buqmxced_uUo|VyZZA>d)O1n zAZx^$JK!Z#&P5p9eH;h~yUy+2kUo5r-Ric`Qc}s*CvWRYKFRhvo7fHRG1h7Qi1k`G zv7=5G8?%;M0zYt!0@rukhZy;bWKDB&8zg_UGu?f<-Ho(lx}D);8{H{-iF7dX&E!&K zmql#9)j%7`^2V-R)$i1&GlR|P%qg}E8rki2S>)<&;#Ueh-!pv6LI6m4q?s zPVtO8*6O~(NV78qLS^*s)bh>g?mD{0u#eF(Wa?ecQp5uNYw`diU$-`Fp6;$|g6-hS z$=~U6VK%F}*)`}R2@`5uy4iXeu24por%teYt;O^=$dN9@F+Bu&CzC%x?3P=EZcbd+ zXf?8G_YAEe33!9KJ~@aKzl}B~;Qh$U-*C>tSieUrZIdm5WzQzJcBETQ3w=J}W}v6T z?6CV07`Tn~J0W<bo#uw*&i3h(b*EX_tx1lw!n+Np4pzP;`cHO@ zecO#8Ev%0IW~vb?f2hU1YxDG()29&%Ek`M7Cl}d(wIoVP;20~C_0Z2>Ja$W8`YWiG z$e1PW1^m{~=g1K-y$ZiP{6cUY%9@-~#@yfGDriQ^h=2Cgoz6o|=^Y25uLwm6w?BYN zSsg7)v^H9gcBJ>7f&%y23HmKUyE;D*t54rzMt_{Ti%nU_*8*ok4Y!lciq-@AP5@ct;|HI zFD6H5UE)U6DoT$g_S3r557@93L|aK3BBF4&ayY8 z_wHL7dw%TP1U{C;EoL&cYdVtJQ;S<<^!2GYBFzh9}ia<1X1R$U>~&t zQ9>&11Zy2Gd*FxlZg-mK)P!M_4~RFOs}5 zdY#<_J+7yVQeTWNPXsC1X-_2E(w~pBI?G_!Tm7^ma0H1Z>^@5mlYLPVO}q{#{x^14 zGDvSCRgcy6rRxmNc$d>1?Kj3xw@;%_p}XPuElE@OSa)q~Fx24tn6#Hj)7s^_42RniKcE~x^o__Wey9+7eR_jnSnz)x8 zvz}lT?yX2a*F~?`m!eJf%IFh`btnMqF)J{A=HO8pMKp(FJNxP{gbcV$wY!YHlH?ie z0DBSjJYqG{C8@V)<%zGy>N8OjeQb|g8tpb7Zvy)*4ji|JopHBEE%MW7ec~TCTkq@% zmZgK`8yrGORjP%(glzd9^7z{Hvyo0Wax=WE#;uL+N=>pCtSyvmB5$%0)Jon|0Jny z-fNs#`uxf8V8~!`#1}e#YXu_@IPYb@NUld4^T*|UW064DPt?WtA?pA9@2?6j5xb5F zCU+fBsdvqn9@baXZXcDq7UTp8Pbe7K7Q33T2LpWxiA|XJh|@D|LaHC-yOeuZXEHA% z-bj4t8ysHwTqaYy3UJ6{$CqF7TjA}Jh*@}i!t~^^<$QlvrKacN1OHim)r9%W58=G^ zzVd)XtuG;bT=I+YS@<1Q{KghaU!Ok@c{O{0`RuL}_UZHGfolUUCLh*giqto^FJME# zl@i`Q?#XA{C9j;@zx&*QUt}`aOxkwbe(Z-_RhifBAEiV8<=c&!2T}np(`)yCgI<31 z+kf`x-=16f{3Ge-GnsF;5hD~5_+tvcDeyCp6!f8B?qA9tzOsQ&*@NTe*Sm$Kek(kA zi8&vA=kr%UUr@Q!AJ@3Nu7=A!T#NJS&W*Sf9C3cU^G;kDVh3vRlgT{Y7Q*G(-<0~|8AM+1USIkCBJDYQ zKGf~6)7Slh!*l5iwiGMW00c)Y);{Ygpp>%s2VQ6K6%VE$ggUtau&{dnj3SB&E$ zm5+4({R^m3#K}>Nm}Lpo%9xKi7YB{b77u`LC@8@mH-^A1OHTDD3~scOU;c zzG84O{)?~g^X2o4GZra%gg*29ac+GqRA0sTD>e>#70N!m`_SXF*!p7Qz`vmUCGx+B z|NQ*licNKH{%@Hh|L5i_oj+j@mEX`$7n4`c&-RNtJ{{)sbLq?VDxPNP@2+8e*ZEl} zEcngwSAD&dhccNz?aG4VMc2=v&xF0~=lH>07UchI{hzP>3-S|I^_o(_e~!KZ=lLfe zFOtuAJ@Mox5?>K{nHs0rj#K4_g8ZuaS$FaCi9Ua!@WSN-GhY4Aa-Yp_I(@yr7W!8E zKY6=MEK%~8kTM@XcDbY^@!+8=4<3U3dHs(MsD5w0_6I#bAKQvK{LRvXFd!-Yms6CN z8ZQP*d5XmI0_>;jN5`*^7vrzkIL9}af9vaYe)Mr2=JRv&pFXa`!e6|2#PNW%|5nxi z4fy@veC@B}*I^+~PWswC{craCwNU&5-&MrZ40?Y3 zUuggLO|k!x;KP#qfLa@9qDK*MEZje<_Xt#Qwi3G~+y2=U;~< zKPtc3YS_1j`e1hX&`%&m&!&%J^3DtYwTv&1ppu94x3GH6`zwCl*09AcaQ?2#1N^@I zbK2Qi^?R-Jzo-9M?Nfl?JblRZ^Y@P>GtS3_e=yHK{EVaYuhai^!^P|`<@e5i3iR(f zzxsX}>*wsp_4VTXufX~5eEUDp3#k1{_U=%&|JUhZ{(}5dU$4VbUlq#U1^36Q{_wkL z*P6c0&#xQyuZ07`MnVTx%`2j1;u9peA@ZR-2ID?e~x}v?*Esm`rkj>{(rXnKRSOp z%<1RKUuYcm@Z#6F=J{IMKihvxxJdsnhrV?F7Yc)Zh425!R)FX92aM<0Tc;=FQSp#{ zTwvCC*XJi5#o>Q}^WXX2|I_&?1`GPz$31)7Gwh9Vt`E^a*f|ei%(s4HJ+ChkznN9Y z{MSR7UjFo%gHZEbugkCRXJ(FrSdRUqezN{4;R@AH^%Pv6lg~W)Wjzr6f4)4jUy%I; zF5G`+;*a_Lj+t|y`>XON zoxTop{jsnYAC%H;|A+J6f$aHzWS0B?eE%05@%DeADt`YT`N^}7VJmW15ij}qP}qBp ze6067I;u1og0UodQ`Dt}Oe@bjN51^U0)>@V`ac>brs}i;BgQzJ8%F=Z7i#qX84J;?LX9 zB43*xKlZ}$1DS_^KK(22|9*}XAnyOpQU9kNlF$DYtN%jZbKHL}CQpI$EXecj<5Rc4 zod|LXCt>|ZSZ&$M5kAMZxaft1Rp z(jK|-x3K-2xBgwnOELXl>v8al`X%>YHs600xj$BnKJfYa%|0zS`+imGD|^1&FQ5Ow z^S@W}p8uVCDF6Ad*Y20`U-Hg{^z#?eDgL}Tp8u>W#-Bb8`g7)Q!Jn#6IRYtvDS&T6 z^~*Vr^XJvm-1vjO1IqtR+`U>TJ)QowhB-gE{1(HH`E%MI;}xdr7kb3=!+HJFp2WGs z|1Ro3fBrw)|8sj^&UyZu!$WxfJMq{f>F3}A>iO?t{ORLD-#PV7msgI@emJ z-#?lK`$y!z+4~b6->)0i^-+wz+~3VEkJM*2zv}q-`5*efsZ8d7x8*+nr|18xIse6Z zgX~w)->6H)v#^&}k9fO#wflD+zYa_Ndi7sCZ;xW{(dWBAjL#WQI=+R%#pFYN^68re z>m`)w@yoR-?2C_Nzc}-Lh>%x}XOCO`{3zG3b^Q{X(GkNftqr9U%euWY*T{Z*I07|ikK z;*0 zpR&~iHU8^{g@4V_pA_>Sn~UIkq3_nZ7y+JRa<&y5#pyl>*8+n)&Waok1gt@!J6_wL^M+O*ha+XItrnR82@U;EWbzU?ALRWlV5X(fH4j;e8lP7)W-Vl6F@1$FivJXRy9+8-bTyy{4v`A ziQzUD75I8ckICgF+Y``V!xkF1`!UYbf*9v*H>a2THTA$#&rG?`jNxTzeOo3cCokj0 zA>xf7e0_Cw^$_La1_ULD5zyxaIe zvi);SyQF+}mC5Plg}H!1Lg>4If2F?n%vAd6skA5mB;Gv{VEEz3w2+_MKkwK>;+Oii z@wIRKGD*_=M1CiUzgV2H0^-#)s$I$VIC(b{l@SdZ81nb5}urCe_ejyn=n27LR{br!=3@L9(OfD1^lamfuz7+NqD@# z-z9A0Yqo-aRd$5@7)0kK<{QNS-qLJoOwjX=jq%PD!ueaT^pE(SsW09C!~Sg<3IX8% zV=h!6?0l7Au^Fx(WiJf-m%^t$ zP%!4}@r3yE_`$gxr^ggbCG6Xqz}^_oo3Ghl#{d7V;rt@}t7p=;v0k=ua4%c>gOm^I z1b!q(ZyX@TIlXM#hw%y}uOZ@J%oqB=e7^uFd1un+`jY-@i~J|>OMPN}knHmH!?*Q3 zAJ!s8a(QyT#ZMIe)Khr3qOv~{U?KnisLJ;?&-b7Ql)|21m;0lMk2sutDMPkx3_>5M zH+6g*^#<{R$%b0*r+c3tU0xj)>pgi$_N@f|`kDNNdHhTHabG};!-XXOh(|5|>+ z^Jn5DPUzRp9>gjA6rczBy!s{LUzbCF|KauD z^G{yCXXtYxgpUOO!r#FhSmLmq6_+S^#CnyVWxj@gR><{c_IuQ7egXNl_={C2|1%|h zUtX*g^;h|ejSqDGh5fz!hw@j@{>;<2QE7{MtMUoZb9|6j`a9%B{6RRS4+LZ(c@@7r zeerRo=KJ1}&7XzjSMzPm4-j6Dq(6kR;gzFr*dIUK9(WC#q-T5mJnc0SsDIN>Poe+k z{qMkJ;0Kv>&4~LVpU?e&CVd!J#WUgi3G^SkWPGE)<0=-HvLD8usQr;QZcsZ!*7Ef? zas0^s+@JE|MPIMOLZ4uPug7w3k1yr=o78tUJ}?gaUlR3)7@}XTsKt|#V!dgassHxO z;q=po{rY#UnPAL-!l~P?e$~j*>)&L|J$K|j~+32e==^uWSqVYZ4_HS zQ+^N!O1_@E3zrxDwUh_p!|hSG+mqky#W;_DIqv66piufteeY+y|5y7T;r}(6Z2tp% zH)H+Xg5QwXUsfo5TwLe_{YZtt2Y2T3`Tpj`2hYzQy%_l0HL*VSB>|hXhx13(dc2n# z80Dq>M~69n)02n0yP&7!$8u2*Jvawlu08Vd$9~@bZ9RZv2(kYo52rHe7gyZ_SnPi! zzOeLPw5vAgp?-V%g9D@9`1uFo_?P0pp#JmxDPLcVFlccG8iVg?%P7Qv+w}JjfQ@r^ zKea)q(eAAb8UKtoT>f&|KV>pyTLuR&UZ#n&>7S0J@ix8Ej`G3kAp_?tY8%^&Z9MRe z^U5Uf#mkWxVwBj@Og#g=1?b}yD1U8DSo%Vw0c`L<_An7%aGYy1^TgZu*5k1o_KG$LCSa;5ctYXyyMfmlo}1v zmoU9=Z^U8-I_)sZl5C^U<;RTuTbEsVkbk?Rv}5wp#Y-d+d7a=#&@U}5#ro0OGAiUX zjDFNv2-_#qb}un{Fi!FI2$S;@Gt2Fn^m&;Hi1jElIFRZaCs2u)ACFh=+mBmY;_eog z|KcUc{|4lT{;#xetKJ6sVG4f5{J3dC-taghQvY#U1^olL9T4;h-gY&UzA=hO7W%2| zH{#IOC^C_lU*2!_aQS}@6-@st8Dc>SI{r5t_FP`rk;HfH=sw%GWm8sySLvK z{@}F*csHM4h_d=eTWiR&VfPHceq{&)371#GpZ44Q>8_u1`j;m!3j0INqy`8GAZZoId*A268r+>WpR z)Y)?fHlI6iy`(?bKf>34XDPC6!xoUod}9J42({pK^#f(3j3@aI8N6wi-U=xP_8ITP zrf#&Bv++SL_O6n Date: Sat, 14 Oct 2023 21:51:39 -0500 Subject: [PATCH 08/23] bom --- addons/pike/functions/fnc_ammoFired.sqf | 1 - addons/pike/stringtable.xml | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/addons/pike/functions/fnc_ammoFired.sqf b/addons/pike/functions/fnc_ammoFired.sqf index 545eed38804..118473e9da3 100644 --- a/addons/pike/functions/fnc_ammoFired.sqf +++ b/addons/pike/functions/fnc_ammoFired.sqf @@ -40,7 +40,6 @@ _projectile addEventHandler ["SubmunitionCreated", { [EFUNC(missileguidance,guidancePFH), 0, _guidanceArgs] call CBA_fnc_addPerFrameHandler; if (!isNil QEFUNC(frag,addPfhRound)) then { - systemChat "fraggo"; [_firedEH # 0, _firedEH # 4, _submunitionProjectile] call EFUNC(frag,addPfhRound); }; diff --git a/addons/pike/stringtable.xml b/addons/pike/stringtable.xml index 2ea6f88c7b4..2fdc40161b3 100644 --- a/addons/pike/stringtable.xml +++ b/addons/pike/stringtable.xml @@ -1,4 +1,4 @@ - + @@ -11,4 +11,4 @@ Semi-Active Laser Guided 40mm Grenade - \ No newline at end of file + From 1c4397d42ea8a6d48dd5d5b4ffcfa2d0915648a3 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Mon, 23 Oct 2023 17:25:55 -0500 Subject: [PATCH 09/23] Remove RVMAT for ammo model --- addons/pike/CfgEventhandlers.hpp | 2 +- addons/pike/functions/fnc_ammoFired.sqf | 7 ++- addons/pike/models/ace_pike_ammo.p3d | Bin 20548 -> 16967 bytes addons/pike/models/pike_surface.rvmat | 76 ------------------------ 4 files changed, 6 insertions(+), 79 deletions(-) delete mode 100644 addons/pike/models/pike_surface.rvmat diff --git a/addons/pike/CfgEventhandlers.hpp b/addons/pike/CfgEventhandlers.hpp index be6bec5a73a..f72363981a4 100644 --- a/addons/pike/CfgEventhandlers.hpp +++ b/addons/pike/CfgEventhandlers.hpp @@ -5,6 +5,6 @@ class Extended_PreStart_EventHandlers { }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE( call COMPILE_SCRIPT(XEH_preInit) ); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; diff --git a/addons/pike/functions/fnc_ammoFired.sqf b/addons/pike/functions/fnc_ammoFired.sqf index 118473e9da3..e161c92c4a4 100644 --- a/addons/pike/functions/fnc_ammoFired.sqf +++ b/addons/pike/functions/fnc_ammoFired.sqf @@ -15,14 +15,15 @@ * Public: No */ -params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; -TRACE_8("ammoFired",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_gunner); +params ["_unit", "", "", "", "_ammo", "", "_projectile", "_gunner"]; +TRACE_4("ammoFired",_unit,_ammo,_projectile,_gunner); if (!local _gunner) exitWith {}; if (isNull _projectile) exitWith {}; // Get MissileGuidance args now private _firedEH = +_this; +// Inject the submuntion ammo into guidance args _firedEH set [4, getText (configFile >> "CfgAmmo" >> _ammo >> "submunitionAmmo")]; private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeffered); _projectile setVariable [QGVAR(guidanceArgs), _guidanceArgs]; @@ -34,6 +35,7 @@ _projectile addEventHandler ["SubmunitionCreated", { private _guidanceArgs = _projectile getVariable [QGVAR(guidanceArgs), []]; if (_guidanceArgs isEqualTo []) exitWith { ERROR_1("bad args %1",_projectile); }; + // Inject the submuntion projectile and time into guidance args _guidanceArgs params ["_firedEH", "", "", "", "_stateParams"]; _firedEH set [6, _submunitionProjectile]; // _firedEH params ["","","","","","","_projectile"]; _stateParams set [0, diag_tickTime]; // _stateParams params ["_lastRunTime"] @@ -48,6 +50,7 @@ _projectile addEventHandler ["SubmunitionCreated", { params ["_time", "_projectile"]; if (isNull _projectile) exitWith {true}; systemChat format ["%1 - %2", CBA_missionTime - _time, vectorMagnitude velocity _projectile]; + false }, {}, [CBA_missionTime, _submunitionProjectile]] call CBA_fnc_waitUntilAndExecute; #endif }]; diff --git a/addons/pike/models/ace_pike_ammo.p3d b/addons/pike/models/ace_pike_ammo.p3d index c98ca0fff56881a68d586650482b91113042f32e..9a60996295df1a501441562028c3c8632c30af12 100644 GIT binary patch literal 16967 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 literal 20548 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 diff --git a/addons/pike/models/pike_surface.rvmat b/addons/pike/models/pike_surface.rvmat deleted file mode 100644 index 043d6baa363..00000000000 --- a/addons/pike/models/pike_surface.rvmat +++ /dev/null @@ -1,76 +0,0 @@ -class StageTI { - texture = "a3\data_f\default_glass_ti_ca.paa"; -}; -ambient[] = {1,1,1,1}; -diffuse[] = {1,1,1,1}; -forcedDiffuse[] = {0,0,0,1}; -emmisive[] = {0,0,0,0}; -specular[] = {0.2,0.2,0.2,1}; -specularPower = 500; -PixelShaderID = "Super"; -VertexShaderID = "Super"; -class Stage1 { - texture="#(argb,8,8,3)color(0.5,0.5,0.5,1)"; - uvSource = "tex"; - class uvTransform { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,1}; - pos[] = {0,0,0}; - }; -}; -class Stage2 { - texture = "#(argb,8,8,3)color(0.5,0.5,0.5,0.5,DT)"; - uvSource = "tex"; - class uvTransform { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,1}; - pos[] = {0,0,0}; - }; -}; -class Stage3 { - texture = "#(argb,8,8,3)color(0,0,0,0,MC)"; - uvSource = "tex"; - class uvTransform { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,1}; - pos[] = {0,0,0}; - }; -}; -class Stage4 { - texture = "#(argb,8,8,3)color(1,1,1,1,AS)"; - uvSource = "tex"; - class uvTransform { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,1}; - pos[] = {0,0,0}; - }; -}; -class Stage5 { - texture = "#(argb,8,8,3)color(0,0.6,1,1,SMDI)"; - uvSource = "tex"; - class uvTransform { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,1}; - pos[] = {0,0,0}; - }; -}; -class Stage6 { - texture = "#(ai,32,128,1)fresnel(1.6,1.4)"; - uvSource="none"; -}; -class Stage7 { - useWorldEnvMap = "true"; - texture = "a3\data_f\env_interier_car_ca.paa"; - uvSource = "tex"; - class uvTransform { - aside[] = {1,0,0}; - up[] = {0,1,0}; - dir[] = {0,0,1}; - pos[] = {0,0,0}; - }; -}; From e8ce14fb6cadde3d604dc872a60fe2baba8d53d3 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Tue, 24 Oct 2023 15:12:22 -0500 Subject: [PATCH 10/23] spelling of word --- addons/missileguidance/XEH_PREP.hpp | 2 +- .../{fnc_onFiredDeffered.sqf => fnc_onFiredDeferred.sqf} | 2 +- addons/pike/functions/fnc_ammoFired.sqf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename addons/missileguidance/functions/{fnc_onFiredDeffered.sqf => fnc_onFiredDeferred.sqf} (99%) diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 3b807721af2..1a0191992ce 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -7,7 +7,7 @@ PREP(checkSeekerAngle); PREP(checkLos); PREP(onFired); -PREP(onFiredDeffered); +PREP(onFiredDeferred); PREP(onIncomingMissile); PREP(guidancePFH); diff --git a/addons/missileguidance/functions/fnc_onFiredDeffered.sqf b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf similarity index 99% rename from addons/missileguidance/functions/fnc_onFiredDeffered.sqf rename to addons/missileguidance/functions/fnc_onFiredDeferred.sqf index 3b1a61ebca7..ffa3970fe13 100644 --- a/addons/missileguidance/functions/fnc_onFiredDeffered.sqf +++ b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf @@ -12,7 +12,7 @@ * Args * * Example: - * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFiredDeffered + * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFiredDeferred * * Public: No */ diff --git a/addons/pike/functions/fnc_ammoFired.sqf b/addons/pike/functions/fnc_ammoFired.sqf index e161c92c4a4..6d6bd18168a 100644 --- a/addons/pike/functions/fnc_ammoFired.sqf +++ b/addons/pike/functions/fnc_ammoFired.sqf @@ -25,7 +25,7 @@ if (isNull _projectile) exitWith {}; private _firedEH = +_this; // Inject the submuntion ammo into guidance args _firedEH set [4, getText (configFile >> "CfgAmmo" >> _ammo >> "submunitionAmmo")]; -private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeffered); +private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeferred); _projectile setVariable [QGVAR(guidanceArgs), _guidanceArgs]; // On missile deploy start guidance From b0f032117856e5c32b0e8695bad5186a9541a451 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Tue, 24 Oct 2023 15:15:16 -0500 Subject: [PATCH 11/23] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jouni Järvinen --- addons/pike/CfgAmmo.hpp | 2 +- addons/pike/functions/fnc_ammoFired.sqf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/pike/CfgAmmo.hpp b/addons/pike/CfgAmmo.hpp index 80e6ea54d53..224f820fadb 100644 --- a/addons/pike/CfgAmmo.hpp +++ b/addons/pike/CfgAmmo.hpp @@ -77,7 +77,7 @@ class CfgAmmo { // Attack profile type selection defaultAttackProfile = "LIN"; - attackProfiles[] = { "LIN" }; + attackProfiles[] = {"LIN"}; }; }; }; diff --git a/addons/pike/functions/fnc_ammoFired.sqf b/addons/pike/functions/fnc_ammoFired.sqf index 6d6bd18168a..dd99c5f60f6 100644 --- a/addons/pike/functions/fnc_ammoFired.sqf +++ b/addons/pike/functions/fnc_ammoFired.sqf @@ -23,7 +23,7 @@ if (isNull _projectile) exitWith {}; // Get MissileGuidance args now private _firedEH = +_this; -// Inject the submuntion ammo into guidance args +// Inject the submunition ammo into guidance args _firedEH set [4, getText (configFile >> "CfgAmmo" >> _ammo >> "submunitionAmmo")]; private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeferred); _projectile setVariable [QGVAR(guidanceArgs), _guidanceArgs]; @@ -35,7 +35,7 @@ _projectile addEventHandler ["SubmunitionCreated", { private _guidanceArgs = _projectile getVariable [QGVAR(guidanceArgs), []]; if (_guidanceArgs isEqualTo []) exitWith { ERROR_1("bad args %1",_projectile); }; - // Inject the submuntion projectile and time into guidance args + // Inject the submunition projectile and time into guidance args _guidanceArgs params ["_firedEH", "", "", "", "_stateParams"]; _firedEH set [6, _submunitionProjectile]; // _firedEH params ["","","","","","","_projectile"]; _stateParams set [0, diag_tickTime]; // _stateParams params ["_lastRunTime"] From a4fbbffd5e94f9f9e259df3a7837e98109b95e61 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 26 Oct 2023 13:09:34 -0500 Subject: [PATCH 12/23] update clgp --- addons/clgp/CfgEventhandlers.hpp | 6 +++--- addons/clgp/GUI.hpp | 4 ++-- .../clgp/data/ace_copperhead_interactive.p3d | Bin 0 -> 306949 bytes addons/clgp/data/ace_cuhead.p3d | Bin 292069 -> 0 bytes .../{cu_dial_co.paa => copperhead_dial_co.paa} | Bin .../{cu_mat.rvmat => copperhead_mat.rvmat} | 0 ...cu_shell_co.paa => copperhead_shell_co.paa} | Bin addons/clgp/data/model.cfg | 6 +++--- .../functions/fnc_copperhead_attackprofile.sqf | 2 +- .../clgp/functions/fnc_copperhead_onfired.sqf | 2 +- .../fnc_copperhead_submunitionCondition.sqf | 2 +- .../functions/fnc_copperhead_uiCanOpen.sqf | 2 +- .../clgp/functions/fnc_copperhead_uiCreate.sqf | 2 +- addons/clgp/functions/script_component.hpp | 1 - addons/clgp/stringtable.xml | 2 +- 15 files changed, 14 insertions(+), 15 deletions(-) create mode 100644 addons/clgp/data/ace_copperhead_interactive.p3d delete mode 100644 addons/clgp/data/ace_cuhead.p3d rename addons/clgp/data/{cu_dial_co.paa => copperhead_dial_co.paa} (100%) rename addons/clgp/data/{cu_mat.rvmat => copperhead_mat.rvmat} (100%) rename addons/clgp/data/{cu_shell_co.paa => copperhead_shell_co.paa} (100%) delete mode 100644 addons/clgp/functions/script_component.hpp diff --git a/addons/clgp/CfgEventhandlers.hpp b/addons/clgp/CfgEventhandlers.hpp index ae3e5ad2c6f..d05dde2d531 100644 --- a/addons/clgp/CfgEventhandlers.hpp +++ b/addons/clgp/CfgEventhandlers.hpp @@ -1,15 +1,15 @@ class Extended_PreStart_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preStart)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); }; }; class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_preInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_FILE(XEH_postInit)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/clgp/GUI.hpp b/addons/clgp/GUI.hpp index 90dc1362c8c..48b172e211b 100644 --- a/addons/clgp/GUI.hpp +++ b/addons/clgp/GUI.hpp @@ -31,7 +31,7 @@ class GVAR(copperhead_dialog) { class TheThing: RscObject { type = 82; idc = 100; - model = QPATHTOF(data\ace_cuhead.p3d); + model = QPATHTOF(data\ace_copperhead_interactive.p3d); direction[] = {0,0,1}; up[] = {0,1,0}; position[] = {0,-0.338,0.5}; @@ -39,7 +39,7 @@ class GVAR(copperhead_dialog) { enableZoom = 0; zoomDuration = 1; scale = 1; - inBack = 0; + inBack = 0; class Areas { class Dial1 { selection = "dial1"; diff --git a/addons/clgp/data/ace_copperhead_interactive.p3d b/addons/clgp/data/ace_copperhead_interactive.p3d new file mode 100644 index 0000000000000000000000000000000000000000..fda135110be169bd5d464ecaaca46c6a8281a141 GIT binary patch literal 306949 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 literal 0 HcmV?d00001 diff --git a/addons/clgp/data/ace_cuhead.p3d b/addons/clgp/data/ace_cuhead.p3d deleted file mode 100644 index 8f3d2efb62eb93c00453278935c8fc43e3eaeae8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 292069 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 F{{YL{c47bk diff --git a/addons/clgp/data/cu_dial_co.paa b/addons/clgp/data/copperhead_dial_co.paa similarity index 100% rename from addons/clgp/data/cu_dial_co.paa rename to addons/clgp/data/copperhead_dial_co.paa diff --git a/addons/clgp/data/cu_mat.rvmat b/addons/clgp/data/copperhead_mat.rvmat similarity index 100% rename from addons/clgp/data/cu_mat.rvmat rename to addons/clgp/data/copperhead_mat.rvmat diff --git a/addons/clgp/data/cu_shell_co.paa b/addons/clgp/data/copperhead_shell_co.paa similarity index 100% rename from addons/clgp/data/cu_shell_co.paa rename to addons/clgp/data/copperhead_shell_co.paa diff --git a/addons/clgp/data/model.cfg b/addons/clgp/data/model.cfg index e4a84e5c9eb..8d3a9bdb2e8 100644 --- a/addons/clgp/data/model.cfg +++ b/addons/clgp/data/model.cfg @@ -4,7 +4,7 @@ class CfgSkeletons { skeletonInherit = ""; skeletonBones[] = {}; }; - class ace_cuhead_Skeleton: Default { + class ace_copperhead_interactive_Skeleton: Default { isDiscrete = 1; skeletonInherit = "Default"; skeletonBones[]={ @@ -23,9 +23,9 @@ class CfgModels { sectionsInherit=""; skeletonName = ""; }; - class ace_cuhead: Default { + class ace_copperhead_interactive: Default { sections[]={}; - skeletonName="ace_cuhead_Skeleton"; + skeletonName="ace_copperhead_interactive_Skeleton"; sectionsInherit = "Default"; class Animations { class Dial1 { diff --git a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf index 7c2f0f0972a..a94d8004421 100644 --- a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf +++ b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Copperhead: attack profile diff --git a/addons/clgp/functions/fnc_copperhead_onfired.sqf b/addons/clgp/functions/fnc_copperhead_onfired.sqf index 5794ef1a273..98ec8422340 100644 --- a/addons/clgp/functions/fnc_copperhead_onfired.sqf +++ b/addons/clgp/functions/fnc_copperhead_onfired.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Copperhead: On fired - set attack profile settings diff --git a/addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf b/addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf index a3d75f96e81..772c5426e10 100644 --- a/addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf +++ b/addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Copperhead: submunition condition, checks if shell should become missile (wings deploy) diff --git a/addons/clgp/functions/fnc_copperhead_uiCanOpen.sqf b/addons/clgp/functions/fnc_copperhead_uiCanOpen.sqf index bb77104b05c..a75b755a552 100644 --- a/addons/clgp/functions/fnc_copperhead_uiCanOpen.sqf +++ b/addons/clgp/functions/fnc_copperhead_uiCanOpen.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Condition for showing copperhead interface, used in both interaction menu and inside dialog loop diff --git a/addons/clgp/functions/fnc_copperhead_uiCreate.sqf b/addons/clgp/functions/fnc_copperhead_uiCreate.sqf index 0517b854abe..59f3753f07f 100644 --- a/addons/clgp/functions/fnc_copperhead_uiCreate.sqf +++ b/addons/clgp/functions/fnc_copperhead_uiCreate.sqf @@ -1,4 +1,4 @@ -#include "script_component.hpp" +#include "..\script_component.hpp" /* * Author: PabstMirror * Shows copperhead dialog diff --git a/addons/clgp/functions/script_component.hpp b/addons/clgp/functions/script_component.hpp deleted file mode 100644 index 4b442f1884d..00000000000 --- a/addons/clgp/functions/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "\z\ace\addons\clgp\script_component.hpp" diff --git a/addons/clgp/stringtable.xml b/addons/clgp/stringtable.xml index ac54bf6f067..d7ba4fb69f3 100644 --- a/addons/clgp/stringtable.xml +++ b/addons/clgp/stringtable.xml @@ -1,6 +1,6 @@ - + Configure M712 Shell From 648020301a3eed18965b0d94ad3a89089acd1b54 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 26 Oct 2023 13:13:01 -0500 Subject: [PATCH 13/23] reduce change to mg --- addons/missileguidance/XEH_PREP.hpp | 2 +- .../functions/fnc_deploySubmunition.sqf | 58 -------- .../functions/fnc_doAttackProfile.sqf | 5 - .../functions/fnc_guidancePFH.sqf | 20 ++- .../missileguidance/functions/fnc_onFired.sqf | 24 ++-- .../functions/fnc_onFiredDeferred.sqf | 133 ++++++++++++++++++ 6 files changed, 150 insertions(+), 92 deletions(-) delete mode 100644 addons/missileguidance/functions/fnc_deploySubmunition.sqf create mode 100644 addons/missileguidance/functions/fnc_onFiredDeferred.sqf diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 77d63559916..1a0191992ce 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -6,8 +6,8 @@ PREP(changeMissileDirection); PREP(checkSeekerAngle); PREP(checkLos); -PREP(deploySubmunition); PREP(onFired); +PREP(onFiredDeferred); PREP(onIncomingMissile); PREP(guidancePFH); diff --git a/addons/missileguidance/functions/fnc_deploySubmunition.sqf b/addons/missileguidance/functions/fnc_deploySubmunition.sqf deleted file mode 100644 index defd107cb6c..00000000000 --- a/addons/missileguidance/functions/fnc_deploySubmunition.sqf +++ /dev/null @@ -1,58 +0,0 @@ -#include "script_component.hpp" -/* - * Author: PabstMirror - * Fired event handler for submunition projectiles that will become missiles - * - * Arguments: - * Guidance Arg Array - * - * Return Value: - * Handeled - * - * Example: - * [args] call ace_missileguidance_fnc_deploySubmunition - * - * Public: No - */ - -params ["_firedEH", "", "", "", "_stateParams"]; -_firedEH params ["","","","","_ammo","","_projectile"]; -_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_submunitionArray"]; -_submunitionArray params ["_submunitionCondition", "_replacementAmmo", "_curPosASL"]; - - -#ifdef DRAW_GUIDANCE_INFO -drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL getPosASL _projectile, 0.75, 0.75, 0, format ["Sub: %1", _ammo], 1, 0.025, "TahomaB"]; -#endif - -private _handled = false; // return value - -if (_submunitionCondition != "#Triggered") then { - if (isNull _projectile) exitWith { WARNING_1("projectile became null before triggered - %1", _this); }; - _handled = true; // exit back in main loop - if (_this call (missionNamespace getVariable _submunitionCondition)) then { - private _curPosASL = getPosASL _projectile; - triggerAmmo _projectile; // will be available next frame - _submunitionArray set [0, "#Triggered"]; - _submunitionArray set [2, _curPosASL]; - TRACE_2("triggered shell",_projectile,_submunitionArray); - }; -} else { - private _matches = ((ASLtoAGL _curPosASL) nearObjects [_replacementAmmo, 100]); - _matches = _matches apply { [_curPosASL vectorDistance (getPosASL _x), _x] }; - _matches sort true; - TRACE_2("",_replacementAmmo,_matches); - private _newProjectile = (_matches param [0, [0, objNull]]) select 1; - - if (!alive _newProjectile || {!local _newProjectile}) exitWith { - WARNING_3("submunition null %1",_newProjectile,alive _newProjectile, local _newProjectile); - }; - _stateParams set [0, cba_missionTime]; // reset guidance time to now - _stateParams set [4, []]; // so this never runs anymore - _firedEH set [4, _replacementAmmo]; - _firedEH set [6, _newProjectile]; - - m = _newProjectile; -}; - -_handled diff --git a/addons/missileguidance/functions/fnc_doAttackProfile.sqf b/addons/missileguidance/functions/fnc_doAttackProfile.sqf index 2fcf8a99ad9..0b81328c683 100644 --- a/addons/missileguidance/functions/fnc_doAttackProfile.sqf +++ b/addons/missileguidance/functions/fnc_doAttackProfile.sqf @@ -26,11 +26,6 @@ private _attackProfileFunction = getText (configFile >> QGVAR(AttackProfiles) >> private _attackProfilePos = _this call (missionNamespace getVariable _attackProfileFunction); if ((isNil "_attackProfilePos") || {_attackProfilePos isEqualTo [0,0,0]}) exitWith { -#ifdef DRAW_GUIDANCE_INFO - private _forwardPosition = _projectilePos vectorAdd (velocity _projectile); - drawLine3D [ASLtoAGL _projectilePos, ASLtoAGL _forwardPosition, [0,0,1,1]]; - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,1,1], ASLtoAGL _forwardPosition, 0.5, 0.5, 0, format ["%1: NONE", _attackProfileName], 1, 0.025, "TahomaB"]; -#endif [0,0,0] }; diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index d5f5312a115..4c482d3db1d 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -24,18 +24,16 @@ params ["_args", "_pfID"]; _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; _firedEH params ["_shooter","","","","_ammo","","_projectile"]; _launchParams params ["","_targetLaunchParams"]; -_flightParams params ["_minDeflection", "_maxDeflection", "_incDeflection", "_useVanillaDeflection"]; -_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_submunitionArray"]; - -if ((_submunitionArray isNotEqualTo []) && {_args call FUNC(deploySubmunition)}) exitWith {}; +_flightParams params ["_minDeflection", "_maxDeflection", "", "_useVanillaDeflection"]; +_stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; if (!alive _projectile || isNull _projectile || isNull _shooter) exitWith { [_pfID] call CBA_fnc_removePerFrameHandler; END_COUNTER(guidancePFH); }; -private _runtimeDelta = cba_missionTime - _lastRunTime; -_stateParams set [0, cba_missionTime]; +private _runtimeDelta = CBA_missionTime - _lastRunTime; +_stateParams set [0, CBA_missionTime]; private _adjustTime = _runtimeDelta / TIMESTEP_FACTOR; private _projectilePos = getPosASL _projectile; @@ -57,7 +55,6 @@ if (_profileAdjustedTargetPos isNotEqualTo [0,0,0]) then { _minDeflection = _minDeflection * _adjustTime; _maxDeflection = _maxDeflection * _adjustTime; - // _incDeflection = _flightParams select 2; // todo // If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection if ((_minDeflection == 0) && {_maxDeflection == 0}) exitWith {}; @@ -109,11 +106,10 @@ drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0.5,0,1,1], ASL format ["V: %1 (%2)", round vectorMagnitude velocity _projectile, round ((velocity _projectile) # 2)], 1, 0.025, "TahomaB"]; drawLine3D [ASLtoAGL _projectilePos, ASLtoAGL _forwardPosition, [0.5,0,1,1]]; -if (productVersion #4 != "Diag") then { - private _ps = "#particlesource" createVehicleLocal (ASLtoAGL _projectilePos); - _PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 2], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil]; - _PS setDropInterval 3.0; -}; + +private _ps = "#particlesource" createVehicleLocal (ASLtoAGL _projectilePos); +_PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0141, [0, 0, 2], [0, 0, 0], 1, 1.275, 1, 0, [1, 1], [[1, 0, 0, 1], [1, 0, 0, 1], [1, 0, 0, 1]], [1], 1, 0, "", "", nil]; +_PS setDropInterval 3.0; #endif END_COUNTER(guidancePFH); diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 9d655c62b2c..0a770fbf35a 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -17,10 +17,13 @@ * Public: No */ -params ["_shooter","_weapon","","_mode","_ammo","","_projectile","_gunner"]; +params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; + +// Bail on not missile +if (!(_ammo isKindOf "MissileBase")) exitWith {}; // Bail if guidance is disabled for this ammo -if ((getNumber (configOf _projectile >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; +if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; // Bail on locality of the projectile, it should be local to us if (GVAR(enabled) < 1 || {!local _projectile} ) exitWith {}; @@ -28,10 +31,6 @@ if (GVAR(enabled) < 1 || {!local _projectile} ) exitWith {}; // Bail if shooter isn't player AND system not enabled for AI: if ( !isPlayer _shooter && { GVAR(enabled) < 2 } ) exitWith {}; -// For submuntion's that will become missiles - Note that _projectile will be local to everyone -private _submunitionCondition = getText (configOf _projectile >> QUOTE(ADDON) >> "submunitionCondition"); -if ((_submunitionCondition != "") && {!local _gunner}) exitWith {}; - // Verify ammo has explicity added guidance config (ignore inheritances) private _configs = configProperties [(configFile >> "CfgAmmo" >> _ammo), QUOTE(configName _x == QUOTE(QUOTE(ADDON))), false]; if ((count _configs) < 1) exitWith {}; @@ -39,13 +38,6 @@ if ((count _configs) < 1) exitWith {}; // MissileGuidance is enabled for this shot TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); -private _submunitionArray = []; -if (_submunitionCondition != "") then { - TRACE_1("using submunition for seeker/attack configs",_ammo); - _ammo = getText (configOf _projectile>> "submunitionAmmo"); - _submunitionArray = [_submunitionCondition, _ammo, []]; -}; - private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); private _target = _shooter getVariable [QGVAR(target), nil]; @@ -115,7 +107,7 @@ private _args = [_this, [ getNumber ( _config >> "minDeflection" ), getNumber ( _config >> "maxDeflection" ), - getNumber ( _config >> "incDeflection" ), + getNumber ( _config >> "incDeflection" ), // not used? 1 == getNumber ( _config >> "useVanillaDeflection" ) ], [ @@ -124,7 +116,7 @@ private _args = [_this, getNumber ( _config >> "seekerMaxRange" ), getNumber ( _config >> "seekerMinRange" ) ], - [ cba_missionTime, [], [], _lastKnownPosState, _submunitionArray ] + [ CBA_missionTime, [], [], _lastKnownPosState, _submunitionArray ] ]; private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); @@ -148,7 +140,7 @@ if (_onFiredFunc != "") then { // _firedEH params ["_shooter","","","","_ammo","","_projectile"]; // _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; // _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; -// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_submunitionArray"]; +// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; // _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; [FUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; diff --git a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf new file mode 100644 index 00000000000..a3ecca5c57c --- /dev/null +++ b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf @@ -0,0 +1,133 @@ +#include "..\script_component.hpp" +/* + * Author: jaynus / nou + * Fired event handler, starts guidance if enabled for ammo + * + * Arguments: + * 0: Shooter (Man/Vehicle) + * 4: Ammo + * 6: Projectile + * + * Return Value: + * None + * + * Example: + * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFired; + * + * Public: No + */ + +params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; + +// Bail if guidance is disabled for this ammo +if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 2) exitWith { ERROR("not enabled=2"); [] }; + +// MissileGuidance is enabled for this shot +TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); + +private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); + +private _target = _shooter getVariable [QGVAR(target), nil]; +private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; +private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; +private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; +if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "useModeForAttackProfile")) == 1) then { + _attackProfile = getText (configFile >> "CfgWeapons" >> _weapon >> _mode >> QGVAR(attackProfile)) +}; +private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; + +private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; +private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; + +TRACE_6("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode); + +private _launchPos = getPosASL (vehicle _shooter); + +if (isNil "_seekerType" || {!(_seekerType in (getArray (_config >> "seekerTypes")))}) then { + _seekerType = getText (_config >> "defaultSeekerType"); +}; +if (isNil "_attackProfile" || {!(_attackProfile in (getArray (_config >> "attackProfiles")))}) then { + _attackProfile = getText (_config >> "defaultAttackProfile"); +}; +if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes")))}) then { + _lockMode = getText (_config >> "defaultSeekerLockMode"); +}; + +// If we didn't get a target, try to fall back on tab locking +if (isNil "_target") then { + if (!isPlayer _shooter) then { + // This was an AI shot, lets still guide it on the AI target + _target = _shooter getVariable [QGVAR(vanilla_target), nil]; + TRACE_1("Detected AI Shooter!", _target); + } else { + private _canUseLock = getNumber (_config >> "canVanillaLock"); + // @TODO: Get vanilla target + if (_canUseLock > 0 || difficulty < 1) then { + private _vanillaTarget = cursorTarget; + + TRACE_1("Using Vanilla Locking", _vanillaTarget); + if (!isNil "_vanillaTarget") then { + _target = _vanillaTarget; + }; + }; + }; +}; + +// Array for seek last target position +private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; +private _lastKnownPosState = [_seekLastTargetPos]; +if (_seekLastTargetPos && {!isNil "_target"}) then { + _lastKnownPosState set [1, (getPosASL _target)]; +} else { + _lastKnownPosState set [1, [0,0,0]]; +}; + +TRACE_4("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile); +private _args = [_this, + [ _shooter, + [_target, _targetPos, _launchPos], + _seekerType, + _attackProfile, + _lockMode, + _laserInfo + ], + [ + getNumber ( _config >> "minDeflection" ), + getNumber ( _config >> "maxDeflection" ), + getNumber ( _config >> "incDeflection" ), // not used? + 1 == getNumber ( _config >> "useVanillaDeflection" ) + ], + [ + getNumber ( _config >> "seekerAngle" ), + getNumber ( _config >> "seekerAccuracy" ), + getNumber ( _config >> "seekerMaxRange" ), + getNumber ( _config >> "seekerMinRange" ) + ], + [ CBA_missionTime, [], [], _lastKnownPosState, _submunitionArray ] + ]; + +private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); +TRACE_1("seeker",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; +_onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); +TRACE_1("attackProfile",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; +_onFiredFunc = getText (_config >> "onFired"); +TRACE_1("ammo",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +// Reverse: +// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; +// _firedEH params ["_shooter","","","","_ammo","","_projectile"]; +// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; +// _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; +// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; +// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; + +_args From 986d4f3f63b3d8e7445bdea57e319d0c2eb2dc59 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 26 Oct 2023 15:08:38 -0500 Subject: [PATCH 14/23] More rework --- addons/clgp/CfgAmmo.hpp | 19 +++--- addons/clgp/CfgEventhandlers.hpp | 4 +- addons/clgp/README.md | 6 -- addons/clgp/XEH_PREP.hpp | 4 +- addons/clgp/XEH_postInit.sqf | 37 +++++++++- .../fnc_copperhead_attackprofile.sqf | 6 +- .../fnc_copperhead_deployCondition.sqf | 21 ++++++ .../clgp/functions/fnc_copperhead_onfired.sqf | 16 +++-- .../fnc_copperhead_submunitionCondition.sqf | 23 ------- .../functions/fnc_submunition_ammoFired.sqf | 68 +++++++++++++++++++ addons/clgp/script_component.hpp | 6 +- addons/missileguidance/XEH_post_init.sqf | 6 -- .../functions/fnc_guidancePFH.sqf | 39 +++++++---- .../missileguidance/functions/fnc_onFired.sqf | 2 +- .../functions/fnc_onFiredDeferred.sqf | 4 +- 15 files changed, 183 insertions(+), 78 deletions(-) create mode 100644 addons/clgp/functions/fnc_copperhead_deployCondition.sqf delete mode 100644 addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf create mode 100644 addons/clgp/functions/fnc_submunition_ammoFired.sqf diff --git a/addons/clgp/CfgAmmo.hpp b/addons/clgp/CfgAmmo.hpp index 08d0815c0af..52e610ef169 100644 --- a/addons/clgp/CfgAmmo.hpp +++ b/addons/clgp/CfgAmmo.hpp @@ -3,10 +3,11 @@ class CfgAmmo { class SubmunitionBase; class ace_155mm_m712_launch: SubmunitionBase { model = "\A3\weapons_f\ammo\shell"; - hit = 160; + hit = 160; // low for testing indirectHit = 50; indirectHitRange = 8; + GVAR(deployCondition) = QFUNC(copperhead_deployCondition); submunitionAmmo = "ace_155mm_m712_guidance"; submunitionCount = 1; submunitionConeAngle = 0; @@ -15,7 +16,9 @@ class CfgAmmo { airFriction = 0; EGVAR(frag,skip) = 1; // don't frag because this is a scripted ammo - + class Eventhandlers { + fired = QUOTE(call FUNC(submunition_ammoFired)); + }; class CamShakeFire { power = 3.00922; duration = 1.8; @@ -28,10 +31,6 @@ class CfgAmmo { frequency = 20; distance = 1; }; - class ace_missileguidance { - enabled = 1; - submunitionCondition = QFUNC(copperhead_submunitionCondition); - }; }; class ammo_Bomb_LaserGuidedBase; @@ -72,9 +71,11 @@ class CfgAmmo { timeToLive = 200; class ace_missileguidance { - enabled = 1; + enabled = 2; useVanillaDeflection = 1; // use missileTarget for deflection + minDeflection = 0.01; // Minium flap deflection for guidance + maxDeflection = 0.01; // Maximum flap deflection for guidance canVanillaLock = 0; @@ -85,11 +86,11 @@ class CfgAmmo { defaultSeekerLockMode = "LOAL"; seekerLockModes[] = { "LOAL" }; - seekerAngle = 30; // Angle in front of the missile which can be searched + seekerAngle = 70; // Angle in front of the missile which can be searched seekerAccuracy = 1; // seeker accuracy multiplier seekerMinRange = 0; - seekerMaxRange = 1750; // Range from the missile which the seeker can visually search + seekerMaxRange = 3000; // Range from the missile which the seeker can visually search seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos] diff --git a/addons/clgp/CfgEventhandlers.hpp b/addons/clgp/CfgEventhandlers.hpp index d05dde2d531..2a3f71f852d 100644 --- a/addons/clgp/CfgEventhandlers.hpp +++ b/addons/clgp/CfgEventhandlers.hpp @@ -4,12 +4,12 @@ class Extended_PreStart_EventHandlers { }; }; class Extended_PreInit_EventHandlers { - class ADDON { + class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { - class ADDON { + class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/clgp/README.md b/addons/clgp/README.md index 33ba2ed87e6..d876214f7b3 100644 --- a/addons/clgp/README.md +++ b/addons/clgp/README.md @@ -2,9 +2,3 @@ ace_clgp =================== Cannon Launched Guided Projectiles - -## Maintainers - -The people responsible for merging changes to this component or answering potential questions. - -- [PabstMirror](https://github.com/PabstMirror) diff --git a/addons/clgp/XEH_PREP.hpp b/addons/clgp/XEH_PREP.hpp index 88acc80e428..341c6877a8a 100644 --- a/addons/clgp/XEH_PREP.hpp +++ b/addons/clgp/XEH_PREP.hpp @@ -1,7 +1,9 @@ LOG("prep"); PREP(copperhead_attackprofile); +PREP(copperhead_deployCondition); PREP(copperhead_onfired); -PREP(copperhead_submunitionCondition); PREP(copperhead_uiCanOpen); PREP(copperhead_uiCreate); + +PREP(submunition_ammoFired); diff --git a/addons/clgp/XEH_postInit.sqf b/addons/clgp/XEH_postInit.sqf index a82d357ab3c..6dd3dd60a27 100644 --- a/addons/clgp/XEH_postInit.sqf +++ b/addons/clgp/XEH_postInit.sqf @@ -4,10 +4,10 @@ if (hasInterface) then { ["turret", { params ["_player", "_turret"]; - TRACE_2("turret",_player,_turret); + TRACE_3("turret",_player,_turret,typeOf vehicle _player); if (_turret isNotEqualTo [0]) exitWith {}; private _vehicle = vehicle _player; - if ((!alive _player) || {!alive _vehicle} || {_vehicle getVariable [QGVAR(copperhead_actionHandled), false]}) exitWith { TRACE_1("exit?"); }; + if ((!alive _player) || {!alive _vehicle} || {_vehicle getVariable [QGVAR(copperhead_actionHandled), false]}) exitWith { TRACE_1("exit",_vehicle); }; private _canFireCopperhead = false; { @@ -23,3 +23,36 @@ if (hasInterface) then { _vehicle setVariable [QGVAR(copperhead_actionHandled), true]; }, true] call CBA_fnc_addPlayerEventHandler }; + + +#ifdef ENABLE_QUICK_TESTING +["recompile", "recompile", "recompile", { + private _start = diag_tickTime; + [] call ACE_PREP_RECOMPILE; + [] call ace_common_fnc_dumpPerformanceCounters; + private _end = diag_tickTime; + systemChat format ["recompile took [%1 ms]", (1000 * (_end - _start)) toFixed 1]; + + if (productVersion #4 == "Diag") then { + call compile "diag_mergeConfigFile ['P:\z\ace\addons\clgp\config.cpp']"; + }; + false +}, {false}, [33, [false, false, false]], false] call CBA_fnc_addKeybind; // F Key + + ["turret", { + params ["_player", "_turret"]; + private _veh = vehicle _player; + if (currentWeapon _veh == "mortar_155mm_AMOS") then { + systemChat "loading"; + _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; + _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; + _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; + _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; + _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; + _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; + _veh loadMagazine [[0], "mortar_155mm_AMOS", "ace_1rnd_155mm_m712"]; + }; + }, true] call CBA_fnc_addPlayerEventHandler + + +#endif diff --git a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf index a94d8004421..27430c9bde3 100644 --- a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf +++ b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf @@ -20,7 +20,7 @@ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; _args params ["_firedEH"]; _firedEH params ["","","","","","","_projectile"]; -_attackProfileStateParams params ["", "_trajectoryBallistic", "_checkOrientation"]; +_attackProfileStateParams params ["_trajectoryBallistic", "_checkOrientation"]; private _projectilePos = getPosASL _projectile; private _projectileVelocity = velocity _projectile; @@ -61,9 +61,9 @@ if (_aimElev > _velocityElev) then { // prevent rare "boomerang" at extremely high elevation shots the round won't flip correctly at apex if (_isFalling && _checkOrientation) then { - _attackProfileStateParams set [2, false]; + TRACE_1("kicking missle over",_projectile); + _attackProfileStateParams set [1, false]; [_projectile, vectorNormalized _projectileVelocity] call EFUNC(missileguidance,changeMissileDirection); }; _aimASL - diff --git a/addons/clgp/functions/fnc_copperhead_deployCondition.sqf b/addons/clgp/functions/fnc_copperhead_deployCondition.sqf new file mode 100644 index 00000000000..d80bf9433fe --- /dev/null +++ b/addons/clgp/functions/fnc_copperhead_deployCondition.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Copperhead: submunition condition, checks if shell should become missile (wings deploy) + * + * Arguments: + * 0: Projectile + * + * Return Value: + * + * + * Example: + * [any, vehicle player] call ace_clgp_fnc_copperhead_deployCondition + * + * Public: No + */ + +params ["_projectile"]; + +private _deployTime = _projectile getVariable [QGVAR(deployTime), -1]; +CBA_missionTime > _deployTime diff --git a/addons/clgp/functions/fnc_copperhead_onfired.sqf b/addons/clgp/functions/fnc_copperhead_onfired.sqf index 98ec8422340..c039c83ede8 100644 --- a/addons/clgp/functions/fnc_copperhead_onfired.sqf +++ b/addons/clgp/functions/fnc_copperhead_onfired.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Copperhead: On fired - set attack profile settings + * Copperhead: Missile Guidance's On fired - set attack profile settings * * Arguments: - * Args + * Guidance Args * * Return Value: * None @@ -21,16 +21,18 @@ _firedEH params ["_shooter","","","","","","_projectile"]; _stateParams params ["", "", "_attackProfileStateParams"]; private _settings = _shooter getVariable [QGVAR(copperhead_settings), COPPERHEAD_DEFUALT_SETTINGS]; - _settings params [["_trajectorySetting", 1], ["_delaySetting", 1], ["_laserCodeA", 1], ["_laserCodeB", 1], ["_laserCodeC", 1]]; +TRACE_6("",_projectile,_trajectorySetting,_delaySetting,_laserCodeA,_laserCodeB,_laserCodeC); // Set trajectory and delay from first 2 dials private _trajectoryBallistic = _trajectorySetting in [1,2]; // 1-2 = ballisitic, any other is shaped -private _delayDeployment = linearConversion [1, 8, _delaySetting, 0, [48, 45] select _trajectoryBallistic, true]; +private _delayDeployment = linearConversion [1, 8, _delaySetting, 1, [48, 45] select _trajectoryBallistic, true]; + +// set var for submuntion's deployCondition +_projectile setVariable [QGVAR(deployTime), _delayDeployment + CBA_missionTime]; -_attackProfileStateParams set [0, _delayDeployment]; -_attackProfileStateParams set [1, _trajectoryBallistic]; -_attackProfileStateParams set [2, true]; // _checkOrientation +_attackProfileStateParams set [0, _trajectoryBallistic]; +_attackProfileStateParams set [1, true]; // _checkOrientation // Set laser guidance info from last 3 dials // Note: copperhead uses a 3 digit code - techinally 111 should be able to lock onto any X111 4 digit code diff --git a/addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf b/addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf deleted file mode 100644 index 772c5426e10..00000000000 --- a/addons/clgp/functions/fnc_copperhead_submunitionCondition.sqf +++ /dev/null @@ -1,23 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: PabstMirror - * Copperhead: submunition condition, checks if shell should become missile (wings deploy) - * - * Arguments: - * Args - * - * Return Value: - * None - * - * Example: - * [any, vehicle player] call ace_clgp_fnc_copperhead_submunitionCondition - * - * Public: No - */ - -params ["", "", "", "", "_stateParams"]; -_stateParams params ["_lastRunTime", "", "_attackProfileStateParams"]; -_attackProfileStateParams params ["_delayDeployment"]; - -private _runtimeDelta = cba_missionTime - _lastRunTime; -_runtimeDelta > _delayDeployment // return diff --git a/addons/clgp/functions/fnc_submunition_ammoFired.sqf b/addons/clgp/functions/fnc_submunition_ammoFired.sqf new file mode 100644 index 00000000000..17ac2248c31 --- /dev/null +++ b/addons/clgp/functions/fnc_submunition_ammoFired.sqf @@ -0,0 +1,68 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Generic handler for firing a clgp submuntion ammo + * + * Arguments: + * FiredEH + * + * Return Value: + * Nothing + * + * Example: + * [] call ace_clgp_fnc_submunition_ammoFired + * + * Public: No + */ + +params ["_unit", "", "", "", "_ammo", "", "_projectile", "_gunner"]; +if (!local _gunner) exitWith {}; +if (isNull _projectile) exitWith {}; +private _cfg = configOf _projectile; +TRACE_4("ammoFired local",_unit,_ammo,_projectile,_gunner); + +// Get MissileGuidance args now +private _firedEH = +_this; +// Inject the submunition ammo into guidance args +_firedEH set [4, getText (_cfg >> "submunitionAmmo")]; +private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeferred); +if (_guidanceArgs isEqualTo []) exitWith { WARNING_1("no args %1",_projectile); }; +_projectile setVariable [QGVAR(guidanceArgs), _guidanceArgs]; + +// On missile deploy start guidance/frag +_projectile addEventHandler ["SubmunitionCreated", { + params ["_projectile", "_submunitionProjectile"]; + private _guidanceArgs = _projectile getVariable [QGVAR(guidanceArgs), []]; + private _canFrag = true; + TRACE_4("SubmunitionCreated",_projectile,_submunitionProjectile,_guidanceArgs isNotEqualTo [],_canFrag); + if (isNull _submunitionProjectile) exitWith {}; + + if (_guidanceArgs isNotEqualTo []) then { + // Inject the submunition projectile and time into guidance args + _guidanceArgs params ["_firedEH", "", "", "", "_stateParams"]; + _firedEH set [6, _submunitionProjectile]; // _firedEH params ["","","","","","","_projectile"]; + _stateParams set [0, diag_tickTime]; // _stateParams params ["_lastRunTime"] + // Start missigle guidance + [EFUNC(missileguidance,guidancePFH), 0, _guidanceArgs] call CBA_fnc_addPerFrameHandler; + }; + if (!isNil QEFUNC(frag,addPfhRound)) then { + // Start frag tracking + [_firedEH # 0, _firedEH # 4, _submunitionProjectile] call EFUNC(frag,addPfhRound); + }; +}]; + +// Trigger ammo when conditions are met +private _deployCondition = getText (_cfg >> QGVAR(deployCondition)); +if (_deployCondition != "") then { + _deployCondition = missionNamespace getVariable [_deployCondition, {ERROR("bad func"); true}]; + [{ + params ["_projectile", "", "_deployCondition"]; + if (isNull _projectile) exitWith { true }; + _this call _deployCondition + }, { + params ["_projectile"]; + if (isNull _projectile) exitWith { WARNING_1("null at trigger condition %1",_projectile); }; // ToDo + TRACE_1("triggerAmmo",_projectile); + triggerAmmo _projectile; + }, [_projectile, _guidanceArgs, _deployCondition]] call CBA_fnc_waitUntilAndExecute; +}; diff --git a/addons/clgp/script_component.hpp b/addons/clgp/script_component.hpp index d2a03597d3b..82477ae9a12 100644 --- a/addons/clgp/script_component.hpp +++ b/addons/clgp/script_component.hpp @@ -4,8 +4,10 @@ #define DEBUG_MODE_FULL #define DISABLE_COMPILE_CACHE -#define ENABLE_PERFORMANCE_COUNTERS +#define ENABLE_QUICK_TESTING +// #define ENABLE_PERFORMANCE_COUNTERS #include "\z\ace\addons\main\script_macros.hpp" -#define COPPERHEAD_DEFUALT_SETTINGS [ARR_5(1,1,1,1,1)] +// #define COPPERHEAD_DEFUALT_SETTINGS [ARR_5(1,1,1,1,1)] +#define COPPERHEAD_DEFUALT_SETTINGS [ARR_5(1,1,6,8,8)] diff --git a/addons/missileguidance/XEH_post_init.sqf b/addons/missileguidance/XEH_post_init.sqf index 9f62f3bea4d..cc09b1f0ac7 100644 --- a/addons/missileguidance/XEH_post_init.sqf +++ b/addons/missileguidance/XEH_post_init.sqf @@ -11,9 +11,3 @@ false }, [15, [false, true, false]], false] call CBA_fnc_addKeybind; //Ctrl+Tab Key - -#ifdef DRAW_GUIDANCE_INFO -if (productVersion #4 == "Diag") then { - call compile "'Shots' diag_enable false; [{'Shots' diag_enable true;}] call CBA_fnc_execNextFrame;"; -}; -#endif diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 4c482d3db1d..964c2aaf3d2 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -24,7 +24,7 @@ params ["_args", "_pfID"]; _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; _firedEH params ["_shooter","","","","_ammo","","_projectile"]; _launchParams params ["","_targetLaunchParams"]; -_flightParams params ["_minDeflection", "_maxDeflection", "", "_useVanillaDeflection"]; +_flightParams params ["", "", "", "_useVanillaDeflection"]; _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; if (!alive _projectile || isNull _projectile || isNull _shooter) exitWith { @@ -32,9 +32,20 @@ if (!alive _projectile || isNull _projectile || isNull _shooter) exitWith { END_COUNTER(guidancePFH); }; -private _runtimeDelta = CBA_missionTime - _lastRunTime; -_stateParams set [0, CBA_missionTime]; -private _adjustTime = _runtimeDelta / TIMESTEP_FACTOR; +private _runtimeDelta = diag_tickTime - _lastRunTime; +private _adjustTime = 1; + +if (accTime > 0) then { + _adjustTime = 1/accTime; + _adjustTime = _adjustTime * (_runtimeDelta / TIMESTEP_FACTOR); + TRACE_4("Adjust timing", 1/accTime, _adjustTime, _runtimeDelta, (_runtimeDelta / TIMESTEP_FACTOR) ); +} else { + _adjustTime = 0; +}; + +private _minDeflection = ((_flightParams select 0) - ((_flightParams select 0) * _adjustTime)) max 0; +private _maxDeflection = (_flightParams select 1) * _adjustTime; +// private _incDeflection = _flightParams select 2; // todo private _projectilePos = getPosASL _projectile; @@ -45,7 +56,8 @@ private _seekerTargetPos = [[0,0,0], _args, _seekerStateParams, _lastKnownPosSta private _profileAdjustedTargetPos = [_seekerTargetPos, _args, _attackProfileStateParams] call FUNC(doAttackProfile); // If we have no seeker target, then do not change anything -if (_profileAdjustedTargetPos isNotEqualTo [0,0,0]) then { +// If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection +if ((_minDeflection != 0 || {_maxDeflection != 0}) && {_profileAdjustedTargetPos isNotEqualTo [0,0,0]}) then { if (_useVanillaDeflection) exitWith { _projectile setMissileTargetPos ASLtoAGL _profileAdjustedTargetPos; #ifdef DRAW_GUIDANCE_INFO @@ -53,12 +65,6 @@ if (_profileAdjustedTargetPos isNotEqualTo [0,0,0]) then { #endif }; - _minDeflection = _minDeflection * _adjustTime; - _maxDeflection = _maxDeflection * _adjustTime; - // If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection - if ((_minDeflection == 0) && {_maxDeflection == 0}) exitWith {}; - - private _targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos; private _adjustVector = _targetVector vectorDiff (vectorDir _projectile); _adjustVector params ["_adjustVectorX", "_adjustVectorY", "_adjustVectorZ"]; @@ -93,9 +99,11 @@ if (_profileAdjustedTargetPos isNotEqualTo [0,0,0]) then { TRACE_3("", _pitch, _yaw, _roll); TRACE_3("", _targetVector, _adjustVector, _finalAdjustVector); - private _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; - TRACE_2("",_projectile,_changeVector); - [_projectile, _changeVector] call FUNC(changeMissileDirection); + if (accTime > 0) then { + private _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; + TRACE_2("",_projectile,_changeVector); + [_projectile, _changeVector] call FUNC(changeMissileDirection); + }; }; #ifdef DRAW_GUIDANCE_INFO @@ -112,4 +120,7 @@ _PS setParticleParams [["\A3\Data_f\cl_basic", 8, 3, 1], "", "Billboard", 1, 3.0 _PS setDropInterval 3.0; #endif +_stateParams set [0, diag_tickTime]; + END_COUNTER(guidancePFH); + diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 0a770fbf35a..7ad6e46b500 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -116,7 +116,7 @@ private _args = [_this, getNumber ( _config >> "seekerMaxRange" ), getNumber ( _config >> "seekerMinRange" ) ], - [ CBA_missionTime, [], [], _lastKnownPosState, _submunitionArray ] + [ diag_tickTime, [], [], _lastKnownPosState, _submunitionArray ] ]; private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); diff --git a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf index a3ecca5c57c..2905c459a43 100644 --- a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf +++ b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf @@ -12,7 +12,7 @@ * None * * Example: - * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFired; + * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFiredDeferred; * * Public: No */ @@ -103,7 +103,7 @@ private _args = [_this, getNumber ( _config >> "seekerMaxRange" ), getNumber ( _config >> "seekerMinRange" ) ], - [ CBA_missionTime, [], [], _lastKnownPosState, _submunitionArray ] + [ diag_tickTime, [], [], _lastKnownPosState, _submunitionArray ] ]; private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); From 865dc3d9910cbfd2b57c102bebc2882f1e72a4b3 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Fri, 27 Oct 2023 12:25:10 -0500 Subject: [PATCH 15/23] more cleanup --- addons/missileguidance/functions/fnc_doAttackProfile.sqf | 3 ++- addons/missileguidance/functions/fnc_onFired.sqf | 2 +- addons/missileguidance/functions/fnc_onFiredDeferred.sqf | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/addons/missileguidance/functions/fnc_doAttackProfile.sqf b/addons/missileguidance/functions/fnc_doAttackProfile.sqf index 0b81328c683..cafbadf69c6 100644 --- a/addons/missileguidance/functions/fnc_doAttackProfile.sqf +++ b/addons/missileguidance/functions/fnc_doAttackProfile.sqf @@ -26,11 +26,12 @@ private _attackProfileFunction = getText (configFile >> QGVAR(AttackProfiles) >> private _attackProfilePos = _this call (missionNamespace getVariable _attackProfileFunction); if ((isNil "_attackProfilePos") || {_attackProfilePos isEqualTo [0,0,0]}) exitWith { + ERROR_1("attack profile returned bad pos",_attackProfilePos); [0,0,0] }; #ifdef DRAW_GUIDANCE_INFO -if (_seekerTargetPos isNotEqualTo [0,0,0]) then { drawLine3D [(ASLtoAGL _attackProfilePos), (ASLtoAGL _seekerTargetPos), [0,1,1,1]]; }; +drawLine3D [(ASLtoAGL _attackProfilePos), (ASLtoAGL _seekerTargetPos), [0,1,1,1]]; drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,0,1,1], ASLtoAGL _attackProfilePos, 0.5, 0.5, 0, _attackProfileName, 1, 0.025, "TahomaB"]; #endif diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 7ad6e46b500..f35fe6ecd4f 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -116,7 +116,7 @@ private _args = [_this, getNumber ( _config >> "seekerMaxRange" ), getNumber ( _config >> "seekerMinRange" ) ], - [ diag_tickTime, [], [], _lastKnownPosState, _submunitionArray ] + [ diag_tickTime, [], [], _lastKnownPosState ] ]; private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); diff --git a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf index 2905c459a43..81a79b45e5e 100644 --- a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf +++ b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf @@ -103,7 +103,7 @@ private _args = [_this, getNumber ( _config >> "seekerMaxRange" ), getNumber ( _config >> "seekerMinRange" ) ], - [ diag_tickTime, [], [], _lastKnownPosState, _submunitionArray ] + [ diag_tickTime, [], [], _lastKnownPosState ] ]; private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); From 590932bff49e8503c83df8b9633439bdbd9e2d93 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Fri, 27 Oct 2023 20:11:03 -0500 Subject: [PATCH 16/23] Fly straight when no target data --- addons/clgp/CfgAmmo.hpp | 31 +++++++------------ addons/clgp/XEH_postInit.sqf | 9 +++--- .../fnc_copperhead_attackprofile.sqf | 27 +++++++++------- .../functions/fnc_submunition_ammoFired.sqf | 4 ++- .../functions/fnc_doAttackProfile.sqf | 2 +- .../functions/fnc_guidancePFH.sqf | 7 ----- .../missileguidance/functions/fnc_onFired.sqf | 16 +++++----- .../functions/fnc_onFiredDeferred.sqf | 24 ++++++++------ addons/missileguidance/script_component.hpp | 6 ++-- 9 files changed, 60 insertions(+), 66 deletions(-) diff --git a/addons/clgp/CfgAmmo.hpp b/addons/clgp/CfgAmmo.hpp index 52e610ef169..3dfacabe88e 100644 --- a/addons/clgp/CfgAmmo.hpp +++ b/addons/clgp/CfgAmmo.hpp @@ -3,9 +3,9 @@ class CfgAmmo { class SubmunitionBase; class ace_155mm_m712_launch: SubmunitionBase { model = "\A3\weapons_f\ammo\shell"; - hit = 160; // low for testing - indirectHit = 50; - indirectHitRange = 8; + hit = 1200; + indirectHit = 200; + indirectHitRange = 4; GVAR(deployCondition) = QFUNC(copperhead_deployCondition); submunitionAmmo = "ace_155mm_m712_guidance"; @@ -36,9 +36,10 @@ class CfgAmmo { class ammo_Bomb_LaserGuidedBase; class ace_155mm_m712_guidance: ammo_Bomb_LaserGuidedBase { model = "\A3\Weapons_F_EPC\Ammo\Bomb_04_fly_F.p3d"; - hit = 160; - indirectHit = 50; - indirectHitRange = 8; + hit = 1200; + indirectHit = 200; + indirectHitRange = 4; + // todo frag maneuvrability = 12; airFriction = 0.04; // note: works differently from shell (v^3...) @@ -50,18 +51,8 @@ class CfgAmmo { thrustTime = 0; thrust = 0; // free fall - flightProfiles[] = { "Direct" }; - class Direct {}; - class Components {}; - - manualControl = 1; - maxControlRange = 100000; - missileManualControlCone = 360; - missileLockCone = 360; - missileKeepLockedCone = 360; - missileLockMaxDistance = 100000; - missileLockMinDistance = 0; - + manualControl = 0; + flightProfiles[] = {}; autoSeekTarget = 0; weaponLockSystem = 0; irLock = 0; @@ -74,8 +65,8 @@ class CfgAmmo { enabled = 2; useVanillaDeflection = 1; // use missileTarget for deflection - minDeflection = 0.01; // Minium flap deflection for guidance - maxDeflection = 0.01; // Maximum flap deflection for guidance + minDeflection = 0.002; // Minium flap deflection for guidance + maxDeflection = 0.002; // Maximum flap deflection for guidance canVanillaLock = 0; diff --git a/addons/clgp/XEH_postInit.sqf b/addons/clgp/XEH_postInit.sqf index 6dd3dd60a27..d55ab380815 100644 --- a/addons/clgp/XEH_postInit.sqf +++ b/addons/clgp/XEH_postInit.sqf @@ -37,13 +37,14 @@ if (hasInterface) then { call compile "diag_mergeConfigFile ['P:\z\ace\addons\clgp\config.cpp']"; }; false -}, {false}, [33, [false, false, false]], false] call CBA_fnc_addKeybind; // F Key +}, {false}, [59, [false, false, false]], false] call CBA_fnc_addKeybind; // F1 Key ["turret", { params ["_player", "_turret"]; private _veh = vehicle _player; if (currentWeapon _veh == "mortar_155mm_AMOS") then { - systemChat "loading"; + if (currentMagazine _veh == "ace_1rnd_155mm_m712") exitWith {}; + systemChat "loading mags"; _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; @@ -52,7 +53,5 @@ if (hasInterface) then { _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; _veh loadMagazine [[0], "mortar_155mm_AMOS", "ace_1rnd_155mm_m712"]; }; - }, true] call CBA_fnc_addPlayerEventHandler - - + }, true] call CBA_fnc_addPlayerEventHandler; #endif diff --git a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf index 27430c9bde3..4f976727626 100644 --- a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf +++ b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf @@ -12,7 +12,7 @@ * Missile Aim PosASL * * Example: - * [[1,2,3], [], []] call ace_copperhead_fnc_attackProfile + * [[1,2,3], [], []] call ace_clgp_fnc_copperhead_attackProfile * * Public: No */ @@ -30,10 +30,9 @@ private _isFalling = _velocityElev < 90; private _aimASL = []; // return if (_seekerTargetPos isEqualTo [0,0,0]) then { - // no target - _aimASL = _projectilePos vectorAdd _projectileVelocity; - if (_isFalling && {!_trajectoryBallistic}) then { + if (_isFalling && {!_trajectoryBallistic}) then { // Shaped Trajectory - Try to glide level - adjusted to correct AoA below + _aimASL = _projectile modelToWorldWorld [0,50,0]; _aimASL set [2, _projectilePos # 2]; }; } else { @@ -49,14 +48,18 @@ if (_seekerTargetPos isEqualTo [0,0,0]) then { }; // Limit max elevation to prevent stalling - unpowered gliding -private _maxElev = 68; // ~2.5 glide ratio -private _aimDiff = _aimASL vectorDiff _projectilePos; -private _aimElev = acos (_aimDiff vectorCos [0,0,-1]); -if (_aimElev > _velocityElev) then { - private _adjustAngle = (_maxElev max _velocityElev) - _aimElev; - if (_adjustAngle >= 0) exitWith {}; - private _adjustOffset = (sin _adjustAngle) * vectorMagnitude _aimDiff; - _aimASL = _aimASL vectorAdd [0,0,_adjustOffset]; +if (_aimASL isEqualTo []) then { + _aimASL = [0,0,0]; +} else { + private _maxElev = 68; // ~2.5 glide ratio (another source says 20-25deg flyout angle) + private _aimDiff = _aimASL vectorDiff _projectilePos; + private _aimElev = acos (_aimDiff vectorCos [0,0,-1]); + if (_aimElev > _velocityElev) then { + private _adjustAngle = (_maxElev max _velocityElev) - _aimElev; + if (_adjustAngle >= 0) exitWith {}; + private _adjustOffset = (sin _adjustAngle) * vectorMagnitude _aimDiff; + _aimASL = _aimASL vectorAdd [0,0,_adjustOffset]; + }; }; // prevent rare "boomerang" at extremely high elevation shots the round won't flip correctly at apex diff --git a/addons/clgp/functions/fnc_submunition_ammoFired.sqf b/addons/clgp/functions/fnc_submunition_ammoFired.sqf index 17ac2248c31..7085e8d6617 100644 --- a/addons/clgp/functions/fnc_submunition_ammoFired.sqf +++ b/addons/clgp/functions/fnc_submunition_ammoFired.sqf @@ -21,12 +21,14 @@ if (isNull _projectile) exitWith {}; private _cfg = configOf _projectile; TRACE_4("ammoFired local",_unit,_ammo,_projectile,_gunner); +// systemChat format ["v = %1", vectorMagnitude velocity _projectile]; + // Get MissileGuidance args now private _firedEH = +_this; // Inject the submunition ammo into guidance args _firedEH set [4, getText (_cfg >> "submunitionAmmo")]; private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeferred); -if (_guidanceArgs isEqualTo []) exitWith { WARNING_1("no args %1",_projectile); }; +if (_guidanceArgs isEqualTo []) then { WARNING_1("no args %1",_projectile); }; _projectile setVariable [QGVAR(guidanceArgs), _guidanceArgs]; // On missile deploy start guidance/frag diff --git a/addons/missileguidance/functions/fnc_doAttackProfile.sqf b/addons/missileguidance/functions/fnc_doAttackProfile.sqf index cafbadf69c6..8dd3f495ede 100644 --- a/addons/missileguidance/functions/fnc_doAttackProfile.sqf +++ b/addons/missileguidance/functions/fnc_doAttackProfile.sqf @@ -26,7 +26,7 @@ private _attackProfileFunction = getText (configFile >> QGVAR(AttackProfiles) >> private _attackProfilePos = _this call (missionNamespace getVariable _attackProfileFunction); if ((isNil "_attackProfilePos") || {_attackProfilePos isEqualTo [0,0,0]}) exitWith { - ERROR_1("attack profile returned bad pos",_attackProfilePos); + // ERROR_1("attack profile returned bad pos",_attackProfilePos); [0,0,0] }; diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 964c2aaf3d2..3429a09d641 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -24,7 +24,6 @@ params ["_args", "_pfID"]; _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; _firedEH params ["_shooter","","","","_ammo","","_projectile"]; _launchParams params ["","_targetLaunchParams"]; -_flightParams params ["", "", "", "_useVanillaDeflection"]; _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; if (!alive _projectile || isNull _projectile || isNull _shooter) exitWith { @@ -58,12 +57,6 @@ private _profileAdjustedTargetPos = [_seekerTargetPos, _args, _attackProfileStat // If we have no seeker target, then do not change anything // If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection if ((_minDeflection != 0 || {_maxDeflection != 0}) && {_profileAdjustedTargetPos isNotEqualTo [0,0,0]}) then { - if (_useVanillaDeflection) exitWith { - _projectile setMissileTargetPos ASLtoAGL _profileAdjustedTargetPos; - #ifdef DRAW_GUIDANCE_INFO - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0.5,1,0,1], ASLtoAGL (missileTargetPos _projectile), 1, 1, diag_tickTime * 60, "", 1, 0.025, "TahomaB"]; - #endif - }; private _targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos; private _adjustVector = _targetVector vectorDiff (vectorDir _projectile); diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index f35fe6ecd4f..1c964c51131 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -107,8 +107,7 @@ private _args = [_this, [ getNumber ( _config >> "minDeflection" ), getNumber ( _config >> "maxDeflection" ), - getNumber ( _config >> "incDeflection" ), // not used? - 1 == getNumber ( _config >> "useVanillaDeflection" ) + getNumber ( _config >> "incDeflection" ) ], [ getNumber ( _config >> "seekerAngle" ), @@ -116,21 +115,24 @@ private _args = [_this, getNumber ( _config >> "seekerMaxRange" ), getNumber ( _config >> "seekerMinRange" ) ], - [ diag_tickTime, [], [], _lastKnownPosState ] + [ diag_tickTime, [], [], _lastKnownPosState] ]; private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); -TRACE_1("seeker",_onFiredFunc); +TRACE_1("",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; + _onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); -TRACE_1("attackProfile",_onFiredFunc); +TRACE_1("",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; + +// Run the "onFired" function passing the full guidance args array _onFiredFunc = getText (_config >> "onFired"); -TRACE_1("ammo",_onFiredFunc); +TRACE_1("",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; @@ -143,7 +145,7 @@ if (_onFiredFunc != "") then { // _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; // _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; -[FUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; +[FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; /* Clears locking settings diff --git a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf index 81a79b45e5e..bbbf70f11ff 100644 --- a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf +++ b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf @@ -1,15 +1,17 @@ #include "..\script_component.hpp" /* - * Author: jaynus / nou - * Fired event handler, starts guidance if enabled for ammo + * Author: PabstMirror (mostly copy of onFired) + * Fired event handler for defered ammos (clgp), returns guidance args * * Arguments: * 0: Shooter (Man/Vehicle) - * 4: Ammo + * 1: Weapon + * 3: Mode + * 4: Ammo (in the future) * 6: Projectile * * Return Value: - * None + * * * Example: * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFiredDeferred; @@ -94,8 +96,7 @@ private _args = [_this, [ getNumber ( _config >> "minDeflection" ), getNumber ( _config >> "maxDeflection" ), - getNumber ( _config >> "incDeflection" ), // not used? - 1 == getNumber ( _config >> "useVanillaDeflection" ) + getNumber ( _config >> "incDeflection" ) ], [ getNumber ( _config >> "seekerAngle" ), @@ -103,21 +104,24 @@ private _args = [_this, getNumber ( _config >> "seekerMaxRange" ), getNumber ( _config >> "seekerMinRange" ) ], - [ diag_tickTime, [], [], _lastKnownPosState ] + [ diag_tickTime, [], [], _lastKnownPosState] ]; private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); -TRACE_1("seeker",_onFiredFunc); +TRACE_1("",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; + _onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); -TRACE_1("attackProfile",_onFiredFunc); +TRACE_1("",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; + +// Run the "onFired" function passing the full guidance args array _onFiredFunc = getText (_config >> "onFired"); -TRACE_1("ammo",_onFiredFunc); +TRACE_1("",_onFiredFunc); if (_onFiredFunc != "") then { _args call (missionNamespace getVariable _onFiredFunc); }; diff --git a/addons/missileguidance/script_component.hpp b/addons/missileguidance/script_component.hpp index 2b43be42f3c..776d820f66b 100644 --- a/addons/missileguidance/script_component.hpp +++ b/addons/missileguidance/script_component.hpp @@ -2,9 +2,9 @@ #define COMPONENT_BEAUTIFIED Missile Guidance #include "\z\ace\addons\main\script_mod.hpp" -// #define DRAW_GUIDANCE_INFO -// #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE +#define DRAW_GUIDANCE_INFO +#define DEBUG_MODE_FULL +#define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MISSILEGUIDANCE From 6e6c6b7e4a1302b95c84d71993be7781de8da699 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sun, 29 Oct 2023 18:24:36 -0500 Subject: [PATCH 17/23] use artillery drag --- .../artillerytables/functions/fnc_firedEH.sqf | 2 + addons/clgp/$PBOPREFIX$ | 2 +- addons/clgp/CfgAmmo.hpp | 20 ++--- addons/clgp/GUI.hpp | 20 ++--- addons/clgp/XEH_PREP.hpp | 3 + addons/clgp/XEH_postInit.sqf | 44 ++--------- addons/clgp/dev/quickTesting.sqf | 77 +++++++++++++++++++ .../fnc_copperhead_attackprofile.sqf | 22 ++---- .../clgp/functions/fnc_copperhead_onfired.sqf | 20 +++-- .../functions/fnc_copperhead_uiCreate.sqf | 4 +- .../functions/fnc_submunition_ammoFired.sqf | 35 ++------- .../functions/fnc_submunition_applyDrag.sqf | 39 ++++++++++ .../fnc_submunition_submunitionCreated.sqf | 47 +++++++++++ addons/clgp/stringtable.xml | 9 +++ addons/missileguidance/script_component.hpp | 6 +- 15 files changed, 229 insertions(+), 121 deletions(-) create mode 100644 addons/clgp/dev/quickTesting.sqf create mode 100644 addons/clgp/functions/fnc_submunition_applyDrag.sqf create mode 100644 addons/clgp/functions/fnc_submunition_submunitionCreated.sqf diff --git a/addons/artillerytables/functions/fnc_firedEH.sqf b/addons/artillerytables/functions/fnc_firedEH.sqf index 01947b4ebe0..ef5db9d3eff 100644 --- a/addons/artillerytables/functions/fnc_firedEH.sqf +++ b/addons/artillerytables/functions/fnc_firedEH.sqf @@ -60,6 +60,8 @@ if (_newMuzzleVelocityCoefficent != 1) then { _projectile setVelocity _bulletVelocity; }; +// For compatiblity with other addons +_projectile setVariable [QGVAR(kFactor), _kFactor]; [{ params ["_projectile", "_kFactor", "_time"]; diff --git a/addons/clgp/$PBOPREFIX$ b/addons/clgp/$PBOPREFIX$ index 87f75410bd5..104a5d3b12a 100644 --- a/addons/clgp/$PBOPREFIX$ +++ b/addons/clgp/$PBOPREFIX$ @@ -1 +1 @@ -z\ace\addons\clgp \ No newline at end of file +z\ace\addons\clgp diff --git a/addons/clgp/CfgAmmo.hpp b/addons/clgp/CfgAmmo.hpp index 3dfacabe88e..b6460ab9af9 100644 --- a/addons/clgp/CfgAmmo.hpp +++ b/addons/clgp/CfgAmmo.hpp @@ -1,5 +1,4 @@ class CfgAmmo { - class SubmunitionBase; class ace_155mm_m712_launch: SubmunitionBase { model = "\A3\weapons_f\ammo\shell"; @@ -7,6 +6,7 @@ class CfgAmmo { indirectHit = 200; indirectHitRange = 4; + GVAR(deployApplyDrag) = 1; GVAR(deployCondition) = QFUNC(copperhead_deployCondition); submunitionAmmo = "ace_155mm_m712_guidance"; submunitionCount = 1; @@ -41,9 +41,9 @@ class CfgAmmo { indirectHitRange = 4; // todo frag - maneuvrability = 12; - airFriction = 0.04; // note: works differently from shell (v^3...) - sideAirFriction = 0.225; + maneuvrability = 10; + airFriction = 0; // note: works differently from shellsim (v^3...) + sideAirFriction = 0; artilleryLock = 0; // would keep shell pointed towards velocity, but disables manuverability and airfric @@ -58,17 +58,13 @@ class CfgAmmo { irLock = 0; laserLock = 0; airLock = 0; - + timeToLive = 200; class ace_missileguidance { enabled = 2; - - useVanillaDeflection = 1; // use missileTarget for deflection - minDeflection = 0.002; // Minium flap deflection for guidance - maxDeflection = 0.002; // Maximum flap deflection for guidance - - canVanillaLock = 0; + minDeflection = 0.001; // Minium flap deflection for guidance + maxDeflection = 0.001; // Maximum flap deflection for guidance // Guidance type for munitions defaultSeekerType = "SALH"; @@ -89,7 +85,7 @@ class CfgAmmo { defaultAttackProfile = "copperhead"; attackProfiles[] = {"copperhead"}; useModeForAttackProfile = 0; + canVanillaLock = 0; }; }; - }; diff --git a/addons/clgp/GUI.hpp b/addons/clgp/GUI.hpp index 48b172e211b..c9d1625c46c 100644 --- a/addons/clgp/GUI.hpp +++ b/addons/clgp/GUI.hpp @@ -44,45 +44,45 @@ class GVAR(copperhead_dialog) { class Dial1 { selection = "dial1"; class Controls { - class ButtonDial1: GVAR(copperhead_dialButton) { + class ButtonDial: GVAR(copperhead_dialButton) { idc = 111; - tooltip = "Flight Profile"; + tooltip = CSTRING(copperhead_dial_FlightProfile); }; }; }; class Dial2 { selection = "dial2"; class Controls { - class ButtonDial2: GVAR(copperhead_dialButton) { + class ButtonDial: GVAR(copperhead_dialButton) { idc = 112; - tooltip = "Guidance Delay"; + tooltip = CSTRING(copperhead_dial_GuidanceDelay); }; }; }; class Dial3 { selection = "dial3"; class Controls { - class ButtonDial3: GVAR(copperhead_dialButton) { + class ButtonDial: GVAR(copperhead_dialButton) { idc = 113; - tooltip = "Laser Code"; + tooltip = CSTRING(copperhead_dial_LaserCode); }; }; }; class Dial4 { selection = "dial4"; class Controls { - class ButtonDial4: GVAR(copperhead_dialButton) { + class ButtonDial: GVAR(copperhead_dialButton) { idc = 114; - tooltip = "Laser Code"; + tooltip = CSTRING(copperhead_dial_LaserCode); }; }; }; class Dial5 { selection = "dial5"; class Controls { - class ButtonDial5: GVAR(copperhead_dialButton) { + class ButtonDial: GVAR(copperhead_dialButton) { idc = 115; - tooltip = "Laser Code"; + tooltip = CSTRING(copperhead_dial_LaserCode); }; }; }; diff --git a/addons/clgp/XEH_PREP.hpp b/addons/clgp/XEH_PREP.hpp index 341c6877a8a..55264097154 100644 --- a/addons/clgp/XEH_PREP.hpp +++ b/addons/clgp/XEH_PREP.hpp @@ -1,5 +1,6 @@ LOG("prep"); + PREP(copperhead_attackprofile); PREP(copperhead_deployCondition); PREP(copperhead_onfired); @@ -7,3 +8,5 @@ PREP(copperhead_uiCanOpen); PREP(copperhead_uiCreate); PREP(submunition_ammoFired); +PREP(submunition_applyDrag); +PREP(submunition_submunitionCreated); diff --git a/addons/clgp/XEH_postInit.sqf b/addons/clgp/XEH_postInit.sqf index d55ab380815..a98d308009c 100644 --- a/addons/clgp/XEH_postInit.sqf +++ b/addons/clgp/XEH_postInit.sqf @@ -7,51 +7,19 @@ if (hasInterface) then { TRACE_3("turret",_player,_turret,typeOf vehicle _player); if (_turret isNotEqualTo [0]) exitWith {}; private _vehicle = vehicle _player; - if ((!alive _player) || {!alive _vehicle} || {_vehicle getVariable [QGVAR(copperhead_actionHandled), false]}) exitWith { TRACE_1("exit",_vehicle); }; - private _canFireCopperhead = false; - { - if ("ace_1rnd_155mm_m712" in ([_x] call CBA_fnc_compatibleMagazines)) exitWith { _canFireCopperhead = true; }; - } forEach (_vehicle weaponsTurret [0]); + if ((!alive _player) || {!alive _vehicle} || {_vehicle getVariable [QGVAR(actionsAdded), false]}) exitWith {}; + _vehicle setVariable [QGVAR(actionsAdded), true]; - if (_canFireCopperhead) then { - TRACE_2("adding action to object",_vehicle,typeOf _vehicle); - private _action = [QGVAR(copperhead), LLSTRING(copperhead_action), "", - LINKFUNC(copperhead_uiCreate), LINKFUNC(copperhead_uiCanOpen)] call EFUNC(interact_menu,createAction); + if (((_vehicle weaponsTurret [0]) findIf {"ace_1rnd_155mm_m712" in (compatibleMagazines _x)}) != -1) then { + TRACE_2("adding copperhead action to object",_vehicle,typeOf _vehicle); + private _action = [QGVAR(copperhead), LLSTRING(copperhead_action), "", LINKFUNC(copperhead_uiCreate), LINKFUNC(copperhead_uiCanOpen)] call EFUNC(interact_menu,createAction); [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); }; - _vehicle setVariable [QGVAR(copperhead_actionHandled), true]; }, true] call CBA_fnc_addPlayerEventHandler }; #ifdef ENABLE_QUICK_TESTING -["recompile", "recompile", "recompile", { - private _start = diag_tickTime; - [] call ACE_PREP_RECOMPILE; - [] call ace_common_fnc_dumpPerformanceCounters; - private _end = diag_tickTime; - systemChat format ["recompile took [%1 ms]", (1000 * (_end - _start)) toFixed 1]; - - if (productVersion #4 == "Diag") then { - call compile "diag_mergeConfigFile ['P:\z\ace\addons\clgp\config.cpp']"; - }; - false -}, {false}, [59, [false, false, false]], false] call CBA_fnc_addKeybind; // F1 Key - - ["turret", { - params ["_player", "_turret"]; - private _veh = vehicle _player; - if (currentWeapon _veh == "mortar_155mm_AMOS") then { - if (currentMagazine _veh == "ace_1rnd_155mm_m712") exitWith {}; - systemChat "loading mags"; - _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; - _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; - _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; - _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; - _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; - _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; - _veh loadMagazine [[0], "mortar_155mm_AMOS", "ace_1rnd_155mm_m712"]; - }; - }, true] call CBA_fnc_addPlayerEventHandler; +call compileScript [QPATHTOF(dev\quickTesting.sqf)]; #endif diff --git a/addons/clgp/dev/quickTesting.sqf b/addons/clgp/dev/quickTesting.sqf new file mode 100644 index 00000000000..e6a8106f8b9 --- /dev/null +++ b/addons/clgp/dev/quickTesting.sqf @@ -0,0 +1,77 @@ +#include "..\script_component.hpp" + +["recompile", "recompile", "recompile", { + private _start = diag_tickTime; + [] call ACE_PREP_RECOMPILE; + [] call ace_common_fnc_dumpPerformanceCounters; + private _end = diag_tickTime; + systemChat format ["recompile took [%1 ms]", (1000 * (_end - _start)) toFixed 1]; + + if (productVersion #4 == "Diag") then { + call compile "diag_mergeConfigFile ['P:\z\ace\addons\clgp\config.cpp']"; + }; + false +}, {false}, [59, [false, false, false]], false] call CBA_fnc_addKeybind; // F1 Key + +DFUNC(dev_trackShell) = { + params ["_projectile"]; + [{ + params ["_projectile", "_time", "_lastVel"]; + if (isNull _projectile) exitWith { true }; + + private _ammo = typeOf _projectile; + if (_ammo isKindOf "SubmunitionBase") then { + private _projectilePos = getPosASL _projectile; + private _forwardPosition = _projectilePos vectorAdd ((vectorNormalized (velocity _projectile)) vectorMultiply 15); + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0.5,0,1,1], ASLtoAGL _forwardPosition, 0.75, 0.75, 0, + format ["V: %1 (%2)", round vectorMagnitude velocity _projectile, round ((velocity _projectile) # 2)], 1, 0.025, "TahomaB"]; + drawLine3D [ASLtoAGL _projectilePos, ASLtoAGL _forwardPosition, [0.5,0,1,1]]; + }; + + private _deltaT = CBA_missionTime - _time; + if (_deltaT < 0.25) exitWith { false }; + + private _curVelocity = velocity _projectile; + private _avgSpeed = 0.5 * vectorMagnitude (_curVelocity vectorAdd _lastVel); + systemChat format ["Vel %1 (%2)", _curVelocity, _avgSpeed]; + + private _diff = _curVelocity vectorDiff _lastVel; + _diff = _diff vectorMultiply (1/_deltaT); + _diff = _diff vectorAdd [0,0,GRAVITY]; + private _drag = (vectorMagnitude _diff) / ((_avgSpeed max 1) ^ 2); + systemChat format ["Drag %1", (100000 * _drag) toFixed 2]; + + // systemChat format ["E %1", (GRAVITY * ((getposasl _projectile) # 2)) + (_avgSpeed ^2)]; + + _this set[1, CBA_missionTime]; + _this set[2, _curVelocity]; + false + }, {}, [_projectile, CBA_missionTime, velocity _projectile]] call CBA_fnc_waitUntilAndExecute; +}; + + + ["turret", { + params ["_player", "_turret"]; + private _veh = vehicle _player; + if (currentWeapon _veh == "mortar_155mm_AMOS" && {_veh getVariable [QGVAR(needSetup), true]}) then { + _veh setVariable [QGVAR(needSetup), false]; + systemChat "Setting up..."; + for "_i" from 0 to 9 do { _veh addMagazineTurret ["ace_1rnd_155mm_m712", [0], 1]; }; + _veh loadMagazine [[0], "mortar_155mm_AMOS", "ace_1rnd_155mm_m712"]; + }; + }, true] call CBA_fnc_addPlayerEventHandler; + +{ + _x addEventHandler ["Fired", { + params ["", "", "", "", "", "", "_projectile"]; + _projectile call FUNC(dev_trackShell); + _projectile addEventHandler ["SubmunitionCreated", { + params ["_projectile", "_submunitionProjectile"]; + hint format ["sub\n%1\n=%2 %3\n\n%4\n%5 %6", + velocity _projectile, vectorMagnitude velocity _projectile, local _projectile, + velocity _submunitionProjectile, vectorMagnitude velocity _submunitionProjectile, local _submunitionProjectile]; + _submunitionProjectile call FUNC(dev_trackShell); + }]; + }]; +} forEach vehicles; diff --git a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf index 4f976727626..225ef1f9f00 100644 --- a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf +++ b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf @@ -20,7 +20,11 @@ params ["_seekerTargetPos", "_args", "_attackProfileStateParams"]; _args params ["_firedEH"]; _firedEH params ["","","","","","","_projectile"]; -_attackProfileStateParams params ["_trajectoryBallistic", "_checkOrientation"]; +_attackProfileStateParams params ["_trajectoryShaped"]; + +// Apply CLGP Drag +private _dragArray = _projectile getVariable [QGVAR(dragArray), []]; +if (_dragArray isNotEqualTo []) then { _dragArray call FUNC(submunition_applyDrag) }; private _projectilePos = getPosASL _projectile; private _projectileVelocity = velocity _projectile; @@ -30,7 +34,7 @@ private _isFalling = _velocityElev < 90; private _aimASL = []; // return if (_seekerTargetPos isEqualTo [0,0,0]) then { - if (_isFalling && {!_trajectoryBallistic}) then { + if (_isFalling && {_trajectoryShaped}) then { // Shaped Trajectory - Try to glide level - adjusted to correct AoA below _aimASL = _projectile modelToWorldWorld [0,50,0]; _aimASL set [2, _projectilePos # 2]; @@ -38,13 +42,6 @@ if (_seekerTargetPos isEqualTo [0,0,0]) then { } else { // have valid seeker target _aimASL = _seekerTargetPos; - // aim above target due to gravity drop - private _distance2d = _projectilePos distance2d _aimASL; - private _speed2d = vectorMagnitude [_projectileVelocity#0, _projectileVelocity#1, 0]; - private _tof = (_distance2d / (_speed2d max 1)) min 15; - if (_tof > 1.5) then { - _aimASL = _aimASL vectorAdd [0,0, 2 * _tof ^2]; - }; }; // Limit max elevation to prevent stalling - unpowered gliding @@ -62,11 +59,4 @@ if (_aimASL isEqualTo []) then { }; }; -// prevent rare "boomerang" at extremely high elevation shots the round won't flip correctly at apex -if (_isFalling && _checkOrientation) then { - TRACE_1("kicking missle over",_projectile); - _attackProfileStateParams set [1, false]; - [_projectile, vectorNormalized _projectileVelocity] call EFUNC(missileguidance,changeMissileDirection); -}; - _aimASL diff --git a/addons/clgp/functions/fnc_copperhead_onfired.sqf b/addons/clgp/functions/fnc_copperhead_onfired.sqf index c039c83ede8..76918a71a55 100644 --- a/addons/clgp/functions/fnc_copperhead_onfired.sqf +++ b/addons/clgp/functions/fnc_copperhead_onfired.sqf @@ -20,24 +20,22 @@ _launchParams params ["","","","","","_laserInfo"]; _firedEH params ["_shooter","","","","","","_projectile"]; _stateParams params ["", "", "_attackProfileStateParams"]; -private _settings = _shooter getVariable [QGVAR(copperhead_settings), COPPERHEAD_DEFUALT_SETTINGS]; -_settings params [["_trajectorySetting", 1], ["_delaySetting", 1], ["_laserCodeA", 1], ["_laserCodeB", 1], ["_laserCodeC", 1]]; -TRACE_6("",_projectile,_trajectorySetting,_delaySetting,_laserCodeA,_laserCodeB,_laserCodeC); +(_shooter getVariable [QGVAR(copperhead_settings), COPPERHEAD_DEFUALT_SETTINGS]) + params [["_trajectorySetting", 1], ["_delaySetting", 1], ["_laserCodeA", 1], ["_laserCodeB", 1], ["_laserCodeC", 1]]; +TRACE_6("copperhead_onfired",_projectile,_trajectorySetting,_delaySetting,_laserCodeA,_laserCodeB,_laserCodeC); -// Set trajectory and delay from first 2 dials -private _trajectoryBallistic = _trajectorySetting in [1,2]; // 1-2 = ballisitic, any other is shaped -private _delayDeployment = linearConversion [1, 8, _delaySetting, 1, [48, 45] select _trajectoryBallistic, true]; +// Set trajectory from first dial +private _trajectoryShaped = _trajectorySetting >= 3; // 1-2 is ballisitic, 3-8 is shaped +_attackProfileStateParams set [0, _trajectoryShaped]; -// set var for submuntion's deployCondition +// set var for submuntion's deployCondition from second dial +private _delayDeployment = linearConversion [1, 8, _delaySetting, 1, [45, 48] select _trajectoryShaped, true]; _projectile setVariable [QGVAR(deployTime), _delayDeployment + CBA_missionTime]; -_attackProfileStateParams set [0, _trajectoryBallistic]; -_attackProfileStateParams set [1, true]; // _checkOrientation - // Set laser guidance info from last 3 dials // Note: copperhead uses a 3 digit code - techinally 111 should be able to lock onto any X111 4 digit code // not sure if worth modifying ace_laser for this, for now just assume high digit is 1 private _laserCode = 1000 + 100 * _laserCodeA + 10 * _laserCodeB + _laserCodeC; _laserInfo set [0, _laserCode]; -TRACE_4("copperhead_onfired",_projectile,_trajectoryBallistic,_delayDeployment,_laserCode); +TRACE_3("",_trajectoryShaped,_delayDeployment,_laserCode); diff --git a/addons/clgp/functions/fnc_copperhead_uiCreate.sqf b/addons/clgp/functions/fnc_copperhead_uiCreate.sqf index 59f3753f07f..0fe345633a3 100644 --- a/addons/clgp/functions/fnc_copperhead_uiCreate.sqf +++ b/addons/clgp/functions/fnc_copperhead_uiCreate.sqf @@ -52,7 +52,7 @@ }; { (_display displayCtrl _x) ctrlAddEventHandler ["MouseButtonUp", _fnc_dialClick]; - } forEach [111, 112, 113,114, 115]; + } forEach [111, 112, 113, 114, 115]; // Update display each frame @@ -84,4 +84,4 @@ _vehicle setVariable [QGVAR(copperhead_settings), _settings, true]; // global }]; -}, _this] call CBA_fnc_execNextFrame; \ No newline at end of file +}, _this] call CBA_fnc_execNextFrame; diff --git a/addons/clgp/functions/fnc_submunition_ammoFired.sqf b/addons/clgp/functions/fnc_submunition_ammoFired.sqf index 7085e8d6617..c0206b87aa3 100644 --- a/addons/clgp/functions/fnc_submunition_ammoFired.sqf +++ b/addons/clgp/functions/fnc_submunition_ammoFired.sqf @@ -18,43 +18,22 @@ params ["_unit", "", "", "", "_ammo", "", "_projectile", "_gunner"]; if (!local _gunner) exitWith {}; if (isNull _projectile) exitWith {}; -private _cfg = configOf _projectile; -TRACE_4("ammoFired local",_unit,_ammo,_projectile,_gunner); - -// systemChat format ["v = %1", vectorMagnitude velocity _projectile]; +TRACE_4("ammoFired local",typeOf _unit,_ammo,_projectile,_gunner); +private _ammoCfg = configOf _projectile; // Get MissileGuidance args now private _firedEH = +_this; // Inject the submunition ammo into guidance args -_firedEH set [4, getText (_cfg >> "submunitionAmmo")]; +_firedEH set [4, getText (_ammoCfg >> "submunitionAmmo")]; private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeferred); if (_guidanceArgs isEqualTo []) then { WARNING_1("no args %1",_projectile); }; _projectile setVariable [QGVAR(guidanceArgs), _guidanceArgs]; -// On missile deploy start guidance/frag -_projectile addEventHandler ["SubmunitionCreated", { - params ["_projectile", "_submunitionProjectile"]; - private _guidanceArgs = _projectile getVariable [QGVAR(guidanceArgs), []]; - private _canFrag = true; - TRACE_4("SubmunitionCreated",_projectile,_submunitionProjectile,_guidanceArgs isNotEqualTo [],_canFrag); - if (isNull _submunitionProjectile) exitWith {}; - - if (_guidanceArgs isNotEqualTo []) then { - // Inject the submunition projectile and time into guidance args - _guidanceArgs params ["_firedEH", "", "", "", "_stateParams"]; - _firedEH set [6, _submunitionProjectile]; // _firedEH params ["","","","","","","_projectile"]; - _stateParams set [0, diag_tickTime]; // _stateParams params ["_lastRunTime"] - // Start missigle guidance - [EFUNC(missileguidance,guidancePFH), 0, _guidanceArgs] call CBA_fnc_addPerFrameHandler; - }; - if (!isNil QEFUNC(frag,addPfhRound)) then { - // Start frag tracking - [_firedEH # 0, _firedEH # 4, _submunitionProjectile] call EFUNC(frag,addPfhRound); - }; -}]; +// On missile deploy start guidance +_projectile addEventHandler ["SubmunitionCreated", LINKFUNC(submunition_submunitionCreated)]; // Trigger ammo when conditions are met -private _deployCondition = getText (_cfg >> QGVAR(deployCondition)); +private _deployCondition = getText (_ammoCfg >> QGVAR(deployCondition)); if (_deployCondition != "") then { _deployCondition = missionNamespace getVariable [_deployCondition, {ERROR("bad func"); true}]; [{ @@ -63,7 +42,7 @@ if (_deployCondition != "") then { _this call _deployCondition }, { params ["_projectile"]; - if (isNull _projectile) exitWith { WARNING_1("null at trigger condition %1",_projectile); }; // ToDo + if (isNull _projectile) exitWith { WARNING_1("null at trigger condition %1",_projectile); }; // Just for testing TRACE_1("triggerAmmo",_projectile); triggerAmmo _projectile; }, [_projectile, _guidanceArgs, _deployCondition]] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/clgp/functions/fnc_submunition_applyDrag.sqf b/addons/clgp/functions/fnc_submunition_applyDrag.sqf new file mode 100644 index 00000000000..27d55048f66 --- /dev/null +++ b/addons/clgp/functions/fnc_submunition_applyDrag.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Applies drag to a missile (based on ace_artillerytables_fnc_firedEH) + * + * Arguments: + * 0: Projectile + * 1: Drag + * 2: Last time ran (modified via _this array) + * + * Return Value: + * None + * + * Example: + * [x, 2, 2] call ace_clgp_fnc_submunition_applyDrag + * + * Public: No + */ + +params ["_projectile", "_kFactor", "_time"]; + +private _bulletVelocity = velocity _projectile; +private _deltaT = CBA_missionTime - _time; +_this set [2, CBA_missionTime]; + +if (_kFactor != 0) then { + private _trueVelocity = _bulletVelocity vectorDiff wind; + private _trueSpeed = vectorMagnitude _trueVelocity; + + private _drag = _deltaT * _kFactor * _trueSpeed; + private _accel = _trueVelocity vectorMultiply _drag; + _bulletVelocity = _bulletVelocity vectorAdd _accel; + + _projectile setVelocity _bulletVelocity; +}; + +private _dir = vectorNormalized _bulletVelocity; +_projectile setVectorDirAndUp [_dir, _dir vectorCrossProduct vectorSide _projectile]; +TRACE_2("setVectorDirAndUp",_projectile,_dir); diff --git a/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf b/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf new file mode 100644 index 00000000000..7fc81593b53 --- /dev/null +++ b/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf @@ -0,0 +1,47 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Generic handler for submunitionCreated + * + * Arguments: + * 0: Old Projectile + * 1: New Projectile + * + * Return Value: + * Nothing + * + * Example: + * [a,b] call ace_clgp_fnc_submunition_submunitionCreated + * + * Public: No + */ + +params ["_projectile", "_submunitionProjectile"]; + +private _guidanceArgs = _projectile getVariable [QGVAR(guidanceArgs), []]; +TRACE_2("submunitionCreated",typeOf _projectile,typeOf _submunitionProjectile); +if (isNull _submunitionProjectile) exitWith { WARNING_1("null %1",_this); }; + +if (_guidanceArgs isNotEqualTo []) then { // Inject the submunition projectile and time into guidance args + _guidanceArgs params ["_firedEH", "", "", "", "_stateParams"]; + _firedEH set [6, _submunitionProjectile]; // _firedEH params ["","","","","","","_projectile"]; + _stateParams set [0, diag_tickTime]; // _stateParams params ["_lastRunTime"] + TRACE_2("-Starting missileGuidance",_submunitionProjectile,count _guidanceArgs); + [EFUNC(missileguidance,guidancePFH), 0, _guidanceArgs] call CBA_fnc_addPerFrameHandler; +}; + +if (!isNil QEFUNC(frag,addPfhRound)) then { // todo make frag work for original and sub + TRACE_1("-Starting frag track",_submunitionProjectile); + [_firedEH # 0, _firedEH # 4, _submunitionProjectile] call EFUNC(frag,addPfhRound); +}; + +// if negative then ignore, any other value is a coefficent +private _deployApplyDrag = getNumber ((configOf _projectile) >> QGVAR(deployApplyDrag)); +TRACE_1("",_deployApplyDrag); +if (_deployApplyDrag >= 0) then { + private _kFactor = _projectile getVariable [QEGVAR(artillerytables,kFactor), 0]; + _kFactor = _kFactor * _deployApplyDrag; // maybe be 0 from either source + TRACE_3("-Applying Drag",_submunitionProjectile,_deployApplyDrag,_kFactor); + private _dragArray = [_submunitionProjectile, _kFactor, CBA_missionTime]; + _submunitionProjectile setVariable [QGVAR(dragArray), _dragArray]; +}; diff --git a/addons/clgp/stringtable.xml b/addons/clgp/stringtable.xml index d7ba4fb69f3..e5b3a592985 100644 --- a/addons/clgp/stringtable.xml +++ b/addons/clgp/stringtable.xml @@ -4,5 +4,14 @@ Configure M712 Shell + + Flight Profile + + + Guidance Delay + + + Laser Code + diff --git a/addons/missileguidance/script_component.hpp b/addons/missileguidance/script_component.hpp index 776d820f66b..2b43be42f3c 100644 --- a/addons/missileguidance/script_component.hpp +++ b/addons/missileguidance/script_component.hpp @@ -2,9 +2,9 @@ #define COMPONENT_BEAUTIFIED Missile Guidance #include "\z\ace\addons\main\script_mod.hpp" -#define DRAW_GUIDANCE_INFO -#define DEBUG_MODE_FULL -#define DISABLE_COMPILE_CACHE +// #define DRAW_GUIDANCE_INFO +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_MISSILEGUIDANCE From 4e72f9e4ce57d0e43dab5c511b0026d3a8363c14 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Mon, 6 Nov 2023 14:39:06 -0600 Subject: [PATCH 18/23] Update default laser code --- addons/clgp/script_component.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/addons/clgp/script_component.hpp b/addons/clgp/script_component.hpp index 82477ae9a12..5ba10922789 100644 --- a/addons/clgp/script_component.hpp +++ b/addons/clgp/script_component.hpp @@ -9,5 +9,4 @@ #include "\z\ace\addons\main\script_macros.hpp" -// #define COPPERHEAD_DEFUALT_SETTINGS [ARR_5(1,1,1,1,1)] -#define COPPERHEAD_DEFUALT_SETTINGS [ARR_5(1,1,6,8,8)] +#define COPPERHEAD_DEFUALT_SETTINGS [ARR_5(1,1,1,1,1)] From 5a624b89fa2148c0b2643fdb3e3f51bbfebdbd96 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Mon, 1 Apr 2024 00:36:02 -0500 Subject: [PATCH 19/23] Merge pike --- addons/clgp/CfgAmmo.hpp | 83 ++++++++++++++++++ addons/{pike => clgp}/CfgMagazineWells.hpp | 0 addons/clgp/CfgMagazines.hpp | 14 +++ addons/clgp/config.cpp | 4 +- .../models => clgp/data}/ace_pike_ammo.p3d | Bin addons/clgp/dev/quickTesting.sqf | 2 +- .../fnc_copperhead_attackprofile.sqf | 19 ++-- .../functions/fnc_submunition_ammoFired.sqf | 4 +- addons/clgp/stringtable.xml | 9 ++ addons/{pike => clgp}/ui/gear_pike_ca.paa | Bin .../functions/fnc_attackProfile_LIN.sqf | 4 +- .../functions/fnc_onFiredDeferred.sqf | 4 +- addons/pike/$PBOPREFIX$ | 1 - addons/pike/CfgAmmo.hpp | 83 ------------------ addons/pike/CfgEventhandlers.hpp | 10 --- addons/pike/CfgMagazines.hpp | 15 ---- addons/pike/README.md | 4 - addons/pike/XEH_PREP.hpp | 2 - addons/pike/XEH_preInit.sqf | 7 -- addons/pike/XEH_preStart.sqf | 3 - addons/pike/config.cpp | 20 ----- addons/pike/functions/fnc_ammoFired.sqf | 63 ------------- addons/pike/script_component.hpp | 17 ---- addons/pike/stringtable.xml | 14 --- 24 files changed, 126 insertions(+), 256 deletions(-) rename addons/{pike => clgp}/CfgMagazineWells.hpp (100%) rename addons/{pike/models => clgp/data}/ace_pike_ammo.p3d (100%) rename addons/{pike => clgp}/ui/gear_pike_ca.paa (100%) delete mode 100644 addons/pike/$PBOPREFIX$ delete mode 100644 addons/pike/CfgAmmo.hpp delete mode 100644 addons/pike/CfgEventhandlers.hpp delete mode 100644 addons/pike/CfgMagazines.hpp delete mode 100644 addons/pike/README.md delete mode 100644 addons/pike/XEH_PREP.hpp delete mode 100644 addons/pike/XEH_preInit.sqf delete mode 100644 addons/pike/XEH_preStart.sqf delete mode 100644 addons/pike/config.cpp delete mode 100644 addons/pike/functions/fnc_ammoFired.sqf delete mode 100644 addons/pike/script_component.hpp delete mode 100644 addons/pike/stringtable.xml diff --git a/addons/clgp/CfgAmmo.hpp b/addons/clgp/CfgAmmo.hpp index b6460ab9af9..96b404c447a 100644 --- a/addons/clgp/CfgAmmo.hpp +++ b/addons/clgp/CfgAmmo.hpp @@ -88,4 +88,87 @@ class CfgAmmo { canVanillaLock = 0; }; }; + + class GVAR(pike_launch): SubmunitionBase { + model = QPATHTOF(data\ace_pike_ammo.p3d); + submunitionAmmo = QGVAR(pike_guidance); + submunitionCount = 1; + submunitionConeAngle = 0; + triggerTime = 0.1; + EGVAR(frag,skip) = 1; // don't frag because this is a scripted ammo + class Eventhandlers { + fired = QUOTE(call FUNC(submunition_ammoFired)); + }; + GVAR(deployApplyDrag) = -1; + }; + + class MissileBase; + class GVAR(pike_guidance): MissileBase { + irLock = 0; + laserLock = 0; + airLock = 0; + manualControl = 0; + timeToLive = 22; + + model = QPATHTOF(data\ace_pike_ammo.p3d); + maxSpeed = 150; // ~2km in 15sec + thrust = 19; + thrustTime = 14; + initTime = 0; + airFriction = 0.1; + + hit = 120; + indirectHit = 10; + indirectHitRange = 10; + warheadName = "HE"; + + EGVAR(frag,enabled) = 1; + EGVAR(frag,force) = 1; + EGVAR(frag,classes)[] = {QEGVAR(frag,tiny_HD)}; + EGVAR(frag,metal) = 200; + EGVAR(frag,charge) = 270; // ~8x a normal 40mm + EGVAR(frag,gurney_c) = 2700; + EGVAR(frag,gurney_k) = "1/2"; + + CraterEffects="ExploAmmoCrater"; + explosionEffects="ExploAmmoExplosion"; + effectsMissileInit = "RocketBackEffectsRPG"; + effectsMissile = "missile3"; + + SoundSetExplosion[] = {"GrenadeHe_Exp_SoundSet", "GrenadeHe_Tail_SoundSet", "Explosion_Debris_SoundSet"}; + soundHit1[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_01", 3.1622777, 1, 1500}; + soundHit2[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_02", 3.1622777, 1, 1500}; + soundHit3[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_03", 3.1622777, 1, 1500}; + soundHit4[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_04", 3.1622777, 1, 1500}; + multiSoundHit[] = {"soundHit1", 0.25, "soundHit2", 0.25, "soundHit3", 0.25, "soundHit4", 0.25}; + whistleDist=16; + + // Begin ACE guidance Configs + class ace_missileguidance { + enabled = 2; + + minDeflection = 0.0005; // Minium flap deflection for guidance + maxDeflection = 0.0025; // Maximum flap deflection for guidance + incDeflection = 0.0005; // The incrmeent in which deflection adjusts. + + canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode + + // Guidance type for munitions + defaultSeekerType = "SALH"; + seekerTypes[] = {"SALH"}; + + defaultSeekerLockMode = "LOAL"; + seekerLockModes[] = {"LOAL"}; + + seekerAngle = 90; // Angle in front of the missile which can be searched + seekerAccuracy = 1; // seeker accuracy multiplier + + seekerMinRange = 1; + seekerMaxRange = 3000; // Range from the missile which the seeker can visually search + + // Attack profile type selection + defaultAttackProfile = "LIN"; + attackProfiles[] = {"LIN"}; + }; + }; }; diff --git a/addons/pike/CfgMagazineWells.hpp b/addons/clgp/CfgMagazineWells.hpp similarity index 100% rename from addons/pike/CfgMagazineWells.hpp rename to addons/clgp/CfgMagazineWells.hpp diff --git a/addons/clgp/CfgMagazines.hpp b/addons/clgp/CfgMagazines.hpp index 304f82d252f..1a8adc15562 100644 --- a/addons/clgp/CfgMagazines.hpp +++ b/addons/clgp/CfgMagazines.hpp @@ -8,4 +8,18 @@ class CfgMagazines { ammo = "ace_155mm_m712_launch"; count = 1; }; + + class 1Rnd_HE_Grenade_shell; + class ACE_40mm_Pike: 1Rnd_HE_Grenade_shell { + author = ECSTRING(common,ACETeam); + displayName = CSTRING(pike_magazine_displayName); + displayNameShort = CSTRING(pike_magazine_displayNameShort); + descriptionShort = CSTRING(pike_magazine_descriptionShort); + picture = QPATHTOF(ui\gear_pike_ca.paa); + ammo = QGVAR(pike_launch); + count = 1; + // model = QPATHTOF(data\ace_pike_ammo.p3d); // just use default pouch + initSpeed = 50; + mass = 17; // ~1.7 Pounds + }; }; diff --git a/addons/clgp/config.cpp b/addons/clgp/config.cpp index 02cd7dec720..9221b0b9c99 100644 --- a/addons/clgp/config.cpp +++ b/addons/clgp/config.cpp @@ -14,9 +14,9 @@ class CfgPatches { }; #include "ACE_GuidanceConfig.hpp" - -#include "CfgEventhandlers.hpp" #include "CfgAmmo.hpp" +#include "CfgEventhandlers.hpp" #include "CfgMagazines.hpp" +#include "CfgMagazineWells.hpp" #include "CfgWeapons.hpp" #include "GUI.hpp" diff --git a/addons/pike/models/ace_pike_ammo.p3d b/addons/clgp/data/ace_pike_ammo.p3d similarity index 100% rename from addons/pike/models/ace_pike_ammo.p3d rename to addons/clgp/data/ace_pike_ammo.p3d diff --git a/addons/clgp/dev/quickTesting.sqf b/addons/clgp/dev/quickTesting.sqf index e6a8106f8b9..28c1c52e6bd 100644 --- a/addons/clgp/dev/quickTesting.sqf +++ b/addons/clgp/dev/quickTesting.sqf @@ -74,4 +74,4 @@ DFUNC(dev_trackShell) = { _submunitionProjectile call FUNC(dev_trackShell); }]; }]; -} forEach vehicles; +} forEach (vehicles + [player]); diff --git a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf index 225ef1f9f00..282bca024c2 100644 --- a/addons/clgp/functions/fnc_copperhead_attackprofile.sqf +++ b/addons/clgp/functions/fnc_copperhead_attackprofile.sqf @@ -28,13 +28,12 @@ if (_dragArray isNotEqualTo []) then { _dragArray call FUNC(submunition_applyDra private _projectilePos = getPosASL _projectile; private _projectileVelocity = velocity _projectile; -private _velocityElev = acos (_projectileVelocity vectorCos [0,0,-1]); // referenced to straight down -private _isFalling = _velocityElev < 90; +private _projectileElev = acos (_projectileVelocity vectorCos [0,0,-1]); // referenced to straight down private _aimASL = []; // return if (_seekerTargetPos isEqualTo [0,0,0]) then { - if (_isFalling && {_trajectoryShaped}) then { + if (_trajectoryShaped && {_projectileElev < 90}) then { // Shaped Trajectory - Try to glide level - adjusted to correct AoA below _aimASL = _projectile modelToWorldWorld [0,50,0]; _aimASL set [2, _projectilePos # 2]; @@ -44,19 +43,25 @@ if (_seekerTargetPos isEqualTo [0,0,0]) then { _aimASL = _seekerTargetPos; }; -// Limit max elevation to prevent stalling - unpowered gliding +// systemChat format ["start %1", [0,0,0] getDir _projectileVelocity]; + if (_aimASL isEqualTo []) then { - _aimASL = [0,0,0]; + _aimASL = [0,0,0]; // Fly unchanged } else { + // Limit max elevation to prevent stalling - unpowered gliding private _maxElev = 68; // ~2.5 glide ratio (another source says 20-25deg flyout angle) private _aimDiff = _aimASL vectorDiff _projectilePos; private _aimElev = acos (_aimDiff vectorCos [0,0,-1]); - if (_aimElev > _velocityElev) then { - private _adjustAngle = (_maxElev max _velocityElev) - _aimElev; + if (_aimElev > _projectileElev) then { + private _adjustAngle = _maxElev - _aimElev; if (_adjustAngle >= 0) exitWith {}; private _adjustOffset = (sin _adjustAngle) * vectorMagnitude _aimDiff; _aimASL = _aimASL vectorAdd [0,0,_adjustOffset]; +#ifdef DEBUG_MODE_FULL + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0,1,1,1], ASLtoAGL _aimASL, 0.75, 0.75, 0, "LIMIT", 1, 0.025, "TahomaB"]; +#endif }; + TRACE_1("dir",_projectilePos getDir _aimASL); }; _aimASL diff --git a/addons/clgp/functions/fnc_submunition_ammoFired.sqf b/addons/clgp/functions/fnc_submunition_ammoFired.sqf index c0206b87aa3..04c9c9ea24d 100644 --- a/addons/clgp/functions/fnc_submunition_ammoFired.sqf +++ b/addons/clgp/functions/fnc_submunition_ammoFired.sqf @@ -35,14 +35,14 @@ _projectile addEventHandler ["SubmunitionCreated", LINKFUNC(submunition_submunit // Trigger ammo when conditions are met private _deployCondition = getText (_ammoCfg >> QGVAR(deployCondition)); if (_deployCondition != "") then { - _deployCondition = missionNamespace getVariable [_deployCondition, {ERROR("bad func"); true}]; + _deployCondition = missionNamespace getVariable [_deployCondition, { ERROR("bad func"); true} ]; [{ params ["_projectile", "", "_deployCondition"]; if (isNull _projectile) exitWith { true }; _this call _deployCondition }, { params ["_projectile"]; - if (isNull _projectile) exitWith { WARNING_1("null at trigger condition %1",_projectile); }; // Just for testing + if (isNull _projectile) exitWith { TRACE_1("null at trigger condition %1",_projectile); }; TRACE_1("triggerAmmo",_projectile); triggerAmmo _projectile; }, [_projectile, _guidanceArgs, _deployCondition]] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/clgp/stringtable.xml b/addons/clgp/stringtable.xml index e5b3a592985..e220015de3c 100644 --- a/addons/clgp/stringtable.xml +++ b/addons/clgp/stringtable.xml @@ -13,5 +13,14 @@ Laser Code + + 40mm Pike + + + Pike SALH + + + Semi-Active Laser Guided 40mm Grenade + diff --git a/addons/pike/ui/gear_pike_ca.paa b/addons/clgp/ui/gear_pike_ca.paa similarity index 100% rename from addons/pike/ui/gear_pike_ca.paa rename to addons/clgp/ui/gear_pike_ca.paa diff --git a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf index 31ee3983ed3..e346b16eb66 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf @@ -21,9 +21,7 @@ params ["_seekerTargetPos", "_args"]; _args params ["_firedEH"]; _firedEH params ["_shooter","","","","","","_projectile"]; -if (_seekerTargetPos isEqualTo [0,0,0]) exitWith { - _projectilePos vectorAdd (_projectile vectorModelToWorld [0, 50, 0]) -}; +if (_seekerTargetPos isEqualTo [0,0,0]) exitWith {_seekerTargetPos}; private _shooterPos = getPosASL _shooter; private _projectilePos = getPosASL _projectile; diff --git a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf index bbbf70f11ff..195967b74aa 100644 --- a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf +++ b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf @@ -60,14 +60,14 @@ if (isNil "_target") then { if (!isPlayer _shooter) then { // This was an AI shot, lets still guide it on the AI target _target = _shooter getVariable [QGVAR(vanilla_target), nil]; - TRACE_1("Detected AI Shooter!", _target); + TRACE_1("Detected AI Shooter!",_target); } else { private _canUseLock = getNumber (_config >> "canVanillaLock"); // @TODO: Get vanilla target if (_canUseLock > 0 || difficulty < 1) then { private _vanillaTarget = cursorTarget; - TRACE_1("Using Vanilla Locking", _vanillaTarget); + TRACE_1("Using Vanilla Locking",_vanillaTarget); if (!isNil "_vanillaTarget") then { _target = _vanillaTarget; }; diff --git a/addons/pike/$PBOPREFIX$ b/addons/pike/$PBOPREFIX$ deleted file mode 100644 index abc9bbeaaef..00000000000 --- a/addons/pike/$PBOPREFIX$ +++ /dev/null @@ -1 +0,0 @@ -z\ace\addons\pike diff --git a/addons/pike/CfgAmmo.hpp b/addons/pike/CfgAmmo.hpp deleted file mode 100644 index 224f820fadb..00000000000 --- a/addons/pike/CfgAmmo.hpp +++ /dev/null @@ -1,83 +0,0 @@ -class CfgAmmo { - class SubmunitionBase; - class GVAR(ammo_gl): SubmunitionBase { - model = QPATHTOF(models\ace_pike_ammo.p3d); - submunitionAmmo = QGVAR(ammo_rocket); - submunitionCount = 1; - submunitionConeAngle = 0; - EGVAR(frag,skip) = 1; // don't frag because this is a scripted ammo - class Eventhandlers { - fired = QUOTE(call FUNC(ammoFired)); - }; - }; - - class MissileBase; - class GVAR(ammo_rocket): MissileBase { - irLock = 0; - laserLock = 0; - airLock = 0; - manualControl = 0; - timeToLive = 22; - - model = QPATHTOF(models\ace_pike_ammo.p3d); - maxSpeed = 150; // ~2km in 15sec - thrust = 19; - thrustTime = 14; - initTime = 0; - airFriction = 0.1; - - hit = 120; - indirectHit = 10; - indirectHitRange = 10; - warheadName = "HE"; - - EGVAR(frag,enabled) = 1; - EGVAR(frag,force) = 1; - EGVAR(frag,classes)[] = {QEGVAR(frag,tiny_HD)}; - EGVAR(frag,metal) = 200; - EGVAR(frag,charge) = 270; // ~8x a normal 40mm - EGVAR(frag,gurney_c) = 2700; - EGVAR(frag,gurney_k) = "1/2"; - - CraterEffects="ExploAmmoCrater"; - explosionEffects="ExploAmmoExplosion"; - effectsMissileInit = "RocketBackEffectsRPG"; - effectsMissile = "missile3"; - - SoundSetExplosion[] = {"GrenadeHe_Exp_SoundSet", "GrenadeHe_Tail_SoundSet", "Explosion_Debris_SoundSet"}; - soundHit1[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_01", 3.1622777, 1, 1500}; - soundHit2[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_02", 3.1622777, 1, 1500}; - soundHit3[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_03", 3.1622777, 1, 1500}; - soundHit4[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_04", 3.1622777, 1, 1500}; - multiSoundHit[] = {"soundHit1", 0.25, "soundHit2", 0.25, "soundHit3", 0.25, "soundHit4", 0.25}; - whistleDist=16; - - // Begin ACE guidance Configs - class ace_missileguidance { - enabled = 2; - - minDeflection = 0.0005; // Minium flap deflection for guidance - maxDeflection = 0.0025; // Maximum flap deflection for guidance - incDeflection = 0.0005; // The incrmeent in which deflection adjusts. - - canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode - - // Guidance type for munitions - defaultSeekerType = "SALH"; - seekerTypes[] = {"SALH"}; - - defaultSeekerLockMode = "LOAL"; - seekerLockModes[] = {"LOAL"}; - - seekerAngle = 90; // Angle in front of the missile which can be searched - seekerAccuracy = 1; // seeker accuracy multiplier - - seekerMinRange = 1; - seekerMaxRange = 3000; // Range from the missile which the seeker can visually search - - // Attack profile type selection - defaultAttackProfile = "LIN"; - attackProfiles[] = {"LIN"}; - }; - }; -}; diff --git a/addons/pike/CfgEventhandlers.hpp b/addons/pike/CfgEventhandlers.hpp deleted file mode 100644 index f72363981a4..00000000000 --- a/addons/pike/CfgEventhandlers.hpp +++ /dev/null @@ -1,10 +0,0 @@ -class Extended_PreStart_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); - }; -}; -class Extended_PreInit_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); - }; -}; diff --git a/addons/pike/CfgMagazines.hpp b/addons/pike/CfgMagazines.hpp deleted file mode 100644 index 4258127db68..00000000000 --- a/addons/pike/CfgMagazines.hpp +++ /dev/null @@ -1,15 +0,0 @@ -class CfgMagazines { - class 1Rnd_HE_Grenade_shell; - class ACE_40mm_Pike: 1Rnd_HE_Grenade_shell { - displayName = CSTRING(magazine_displayName); - displayNameShort = CSTRING(magazine_displayNameShort); - descriptionShort = CSTRING(magazine_descriptionShort); - picture = QPATHTOF(ui\gear_pike_ca.paa); - ammo = QGVAR(ammo_gl); - count = 1; - // model = QPATHTOF(models\ace_pike_ammo.p3d); // kinda ugly, just use pouch thing - initSpeed = 50; - mass = 17; // ~1.7 Pounds - author = ECSTRING(common,ACETeam); - }; -}; diff --git a/addons/pike/README.md b/addons/pike/README.md deleted file mode 100644 index a90c3570dba..00000000000 --- a/addons/pike/README.md +++ /dev/null @@ -1,4 +0,0 @@ -ace_pike -=========== - -Adds 40mm Pike semi-active laser seeking rocket, firable from the M320 or EGLM grenade launcher. diff --git a/addons/pike/XEH_PREP.hpp b/addons/pike/XEH_PREP.hpp deleted file mode 100644 index a82521a9ae8..00000000000 --- a/addons/pike/XEH_PREP.hpp +++ /dev/null @@ -1,2 +0,0 @@ -LOG("prep"); -PREP(ammoFired); diff --git a/addons/pike/XEH_preInit.sqf b/addons/pike/XEH_preInit.sqf deleted file mode 100644 index a7feade1c39..00000000000 --- a/addons/pike/XEH_preInit.sqf +++ /dev/null @@ -1,7 +0,0 @@ -#include "script_component.hpp" - -ADDON = false; - -#include "XEH_PREP.hpp" - -ADDON = true; diff --git a/addons/pike/XEH_preStart.sqf b/addons/pike/XEH_preStart.sqf deleted file mode 100644 index 022888575ed..00000000000 --- a/addons/pike/XEH_preStart.sqf +++ /dev/null @@ -1,3 +0,0 @@ -#include "script_component.hpp" - -#include "XEH_PREP.hpp" diff --git a/addons/pike/config.cpp b/addons/pike/config.cpp deleted file mode 100644 index f676a6143b4..00000000000 --- a/addons/pike/config.cpp +++ /dev/null @@ -1,20 +0,0 @@ -#include "script_component.hpp" - -class CfgPatches { - class ADDON { - name = COMPONENT_NAME; - units[] = {}; - weapons[] = {}; - requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"ace_missileguidance"}; - author = ECSTRING(common,ACETeam); - authors[] = {"PabstMirror"}; - url = ECSTRING(main,URL); - VERSION_CONFIG; - }; -}; - -#include "CfgAmmo.hpp" -#include "CfgEventhandlers.hpp" -#include "CfgMagazines.hpp" -#include "CfgMagazineWells.hpp" diff --git a/addons/pike/functions/fnc_ammoFired.sqf b/addons/pike/functions/fnc_ammoFired.sqf deleted file mode 100644 index dd99c5f60f6..00000000000 --- a/addons/pike/functions/fnc_ammoFired.sqf +++ /dev/null @@ -1,63 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: PabstMirror - * Handles firing the 40mm pike grenade (shell) - * - * Arguments: - * FiredEH - * - * Return Value: - * Nothing - * - * Example: - * [] call ace_pike_fnc_ammoFired - * - * Public: No - */ - -params ["_unit", "", "", "", "_ammo", "", "_projectile", "_gunner"]; -TRACE_4("ammoFired",_unit,_ammo,_projectile,_gunner); - -if (!local _gunner) exitWith {}; -if (isNull _projectile) exitWith {}; - -// Get MissileGuidance args now -private _firedEH = +_this; -// Inject the submunition ammo into guidance args -_firedEH set [4, getText (configFile >> "CfgAmmo" >> _ammo >> "submunitionAmmo")]; -private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeferred); -_projectile setVariable [QGVAR(guidanceArgs), _guidanceArgs]; - -// On missile deploy start guidance -_projectile addEventHandler ["SubmunitionCreated", { - params ["_projectile", "_submunitionProjectile"]; - TRACE_2("SubmunitionCreated",_projectile,_submunitionProjectile); - - private _guidanceArgs = _projectile getVariable [QGVAR(guidanceArgs), []]; - if (_guidanceArgs isEqualTo []) exitWith { ERROR_1("bad args %1",_projectile); }; - // Inject the submunition projectile and time into guidance args - _guidanceArgs params ["_firedEH", "", "", "", "_stateParams"]; - _firedEH set [6, _submunitionProjectile]; // _firedEH params ["","","","","","","_projectile"]; - _stateParams set [0, diag_tickTime]; // _stateParams params ["_lastRunTime"] - - [EFUNC(missileguidance,guidancePFH), 0, _guidanceArgs] call CBA_fnc_addPerFrameHandler; - if (!isNil QEFUNC(frag,addPfhRound)) then { - [_firedEH # 0, _firedEH # 4, _submunitionProjectile] call EFUNC(frag,addPfhRound); - }; - - #ifdef DEBUG_MODE_FULL - [{ - params ["_time", "_projectile"]; - if (isNull _projectile) exitWith {true}; - systemChat format ["%1 - %2", CBA_missionTime - _time, vectorMagnitude velocity _projectile]; - false - }, {}, [CBA_missionTime, _submunitionProjectile]] call CBA_fnc_waitUntilAndExecute; - #endif -}]; - -// Trigger motor after ~4 meter delay (could also use config `triggerTime`) -[{ - params ["_projectile"]; - if (isNull _projectile) exitWith { WARNING_1("null %1",_projectile); }; - triggerAmmo _projectile; -}, [_projectile], 0.1] call CBA_fnc_waitAndExecute; diff --git a/addons/pike/script_component.hpp b/addons/pike/script_component.hpp deleted file mode 100644 index b7bd9b4d931..00000000000 --- a/addons/pike/script_component.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#define COMPONENT pike -#define COMPONENT_BEAUTIFIED Pike -#include "\z\ace\addons\main\script_mod.hpp" - -// #define DEBUG_MODE_FULL -// #define DISABLE_COMPILE_CACHE -// #define ENABLE_PERFORMANCE_COUNTERS - -#ifdef DEBUG_ENABLED_PIKE - #define DEBUG_MODE_FULL -#endif - -#ifdef DEBUG_SETTINGS_PIKE - #define DEBUG_SETTINGS DEBUG_SETTINGS_PIKE -#endif - -#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/pike/stringtable.xml b/addons/pike/stringtable.xml deleted file mode 100644 index 2fdc40161b3..00000000000 --- a/addons/pike/stringtable.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - 40mm Pike - - - Pike SALH - - - Semi-Active Laser Guided 40mm Grenade - - - From 17173859a44fbd29b02b37600250ca36a21995f1 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Mon, 1 Apr 2024 12:41:11 -0500 Subject: [PATCH 20/23] Update CfgAmmo.hpp --- addons/clgp/CfgAmmo.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/clgp/CfgAmmo.hpp b/addons/clgp/CfgAmmo.hpp index 96b404c447a..909065e32a4 100644 --- a/addons/clgp/CfgAmmo.hpp +++ b/addons/clgp/CfgAmmo.hpp @@ -132,8 +132,8 @@ class CfgAmmo { CraterEffects="ExploAmmoCrater"; explosionEffects="ExploAmmoExplosion"; - effectsMissileInit = "RocketBackEffectsRPG"; - effectsMissile = "missile3"; + effectsMissileInit = ""; + effectsMissile = "missile2"; SoundSetExplosion[] = {"GrenadeHe_Exp_SoundSet", "GrenadeHe_Tail_SoundSet", "Explosion_Debris_SoundSet"}; soundHit1[] = { "A3\Sounds_F\arsenal\explosives\Grenades\Explosion_gng_grenades_01", 3.1622777, 1, 1500}; From 3c983b60dbcaf7d1850630a8caa4dbcc21a82052 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sun, 14 Apr 2024 01:43:11 -0500 Subject: [PATCH 21/23] Add framework doc --- addons/clgp/CfgAmmo.hpp | 3 +- addons/clgp/XEH_postInit.sqf | 8 +-- .../functions/fnc_submunition_ammoFired.sqf | 2 +- .../fnc_submunition_submunitionCreated.sqf | 13 +++-- docs/wiki/framework/clgp-framework.md | 56 +++++++++++++++++++ 5 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 docs/wiki/framework/clgp-framework.md diff --git a/addons/clgp/CfgAmmo.hpp b/addons/clgp/CfgAmmo.hpp index 909065e32a4..9d48a150bf9 100644 --- a/addons/clgp/CfgAmmo.hpp +++ b/addons/clgp/CfgAmmo.hpp @@ -6,7 +6,7 @@ class CfgAmmo { indirectHit = 200; indirectHitRange = 4; - GVAR(deployApplyDrag) = 1; + GVAR(artilleryDrag) = 1; GVAR(deployCondition) = QFUNC(copperhead_deployCondition); submunitionAmmo = "ace_155mm_m712_guidance"; submunitionCount = 1; @@ -99,7 +99,6 @@ class CfgAmmo { class Eventhandlers { fired = QUOTE(call FUNC(submunition_ammoFired)); }; - GVAR(deployApplyDrag) = -1; }; class MissileBase; diff --git a/addons/clgp/XEH_postInit.sqf b/addons/clgp/XEH_postInit.sqf index a98d308009c..f298803b66c 100644 --- a/addons/clgp/XEH_postInit.sqf +++ b/addons/clgp/XEH_postInit.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" -// Add shell config action to vehicles that can fire it +// Copperhead - Add shell interface action to vehicles that can fire it if (hasInterface) then { ["turret", { params ["_player", "_turret"]; @@ -10,9 +10,9 @@ if (hasInterface) then { if ((!alive _player) || {!alive _vehicle} || {_vehicle getVariable [QGVAR(actionsAdded), false]}) exitWith {}; _vehicle setVariable [QGVAR(actionsAdded), true]; - - if (((_vehicle weaponsTurret [0]) findIf {"ace_1rnd_155mm_m712" in (compatibleMagazines _x)}) != -1) then { - TRACE_2("adding copperhead action to object",_vehicle,typeOf _vehicle); + private _copperheadMag = ["ace_1rnd_155mm_m712"] call EFUNC(common,getConfigName); + if (((_vehicle weaponsTurret [0]) findIf {_copperheadMag in (compatibleMagazines _x)}) != -1) then { + TRACE_2("adding copperhead action to vehicle",_vehicle,typeOf _vehicle); private _action = [QGVAR(copperhead), LLSTRING(copperhead_action), "", LINKFUNC(copperhead_uiCreate), LINKFUNC(copperhead_uiCanOpen)] call EFUNC(interact_menu,createAction); [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); }; diff --git a/addons/clgp/functions/fnc_submunition_ammoFired.sqf b/addons/clgp/functions/fnc_submunition_ammoFired.sqf index 04c9c9ea24d..d7ea236589c 100644 --- a/addons/clgp/functions/fnc_submunition_ammoFired.sqf +++ b/addons/clgp/functions/fnc_submunition_ammoFired.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Generic handler for firing a clgp submuntion ammo + * Generic handler for firing a clgp submuntion ammo. Called from the ammo's fired EH. * * Arguments: * FiredEH diff --git a/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf b/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf index 7fc81593b53..1550b669574 100644 --- a/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf +++ b/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf @@ -30,18 +30,19 @@ if (_guidanceArgs isNotEqualTo []) then { // Inject the submunition projectile a [EFUNC(missileguidance,guidancePFH), 0, _guidanceArgs] call CBA_fnc_addPerFrameHandler; }; +// NOTE: Probably need to remove after frag-rewrite if (!isNil QEFUNC(frag,addPfhRound)) then { // todo make frag work for original and sub TRACE_1("-Starting frag track",_submunitionProjectile); [_firedEH # 0, _firedEH # 4, _submunitionProjectile] call EFUNC(frag,addPfhRound); }; -// if negative then ignore, any other value is a coefficent -private _deployApplyDrag = getNumber ((configOf _projectile) >> QGVAR(deployApplyDrag)); -TRACE_1("",_deployApplyDrag); -if (_deployApplyDrag >= 0) then { +private _deployArtilleryDragConfig = (configOf _projectile) >> QGVAR(artilleryDrag); +if (isNumber _deployArtilleryDragConfig) then { + private _deployArtilleryDrag = getNumber _deployArtilleryDragConfig; + if (_deployArtilleryDrag < 0) exitWith { TRACE_1("-Ignoring Drag",_deployArtilleryDrag); }; private _kFactor = _projectile getVariable [QEGVAR(artillerytables,kFactor), 0]; - _kFactor = _kFactor * _deployApplyDrag; // maybe be 0 from either source - TRACE_3("-Applying Drag",_submunitionProjectile,_deployApplyDrag,_kFactor); + TRACE_2("-Drag",_deployArtilleryDrag,_kFactor); + _kFactor = _kFactor * _deployArtilleryDrag; // Can be 0 from either source (0 is valid and will keep nose pointed) private _dragArray = [_submunitionProjectile, _kFactor, CBA_missionTime]; _submunitionProjectile setVariable [QGVAR(dragArray), _dragArray]; }; diff --git a/docs/wiki/framework/clgp-framework.md b/docs/wiki/framework/clgp-framework.md new file mode 100644 index 00000000000..91c4f579c31 --- /dev/null +++ b/docs/wiki/framework/clgp-framework.md @@ -0,0 +1,56 @@ +--- +layout: wiki +title: CLGP Framework +description: Explains how to set-up ammo for the cannon-launched-guided-projectile system. +group: framework +parent: wiki +order: 7 +mod: ace +version: + major: 3 + minor: 0 + patch: 0 +--- + +## 1. Overview + +CLGP allows firing submunition shells that will deploy into missiles that can use the Missile Guidance framework. + +## 2. Config Values + +### 2.1 Example Config +```cpp +class CfgAmmo { + class x_submunition: SubmunitionBase { // this ammo can be fired normally + ace_clgp_deployCondition = "your_fnc"; // function that returns true when it should be triggered + ace_clgp_artilleryDrag = 1; + submunitionAmmo = "x_missle"; + class Eventhandlers { + fired = "call ace_clgp_fnc_submunition_ammoFired"; // need to add the EH yourself to all ammos + }; + }; + + class x_missle: MissileBase { + class ace_missileguidance { + enabled = 2; + // rest of normal ace missile guidance config +``` + +### 2.2 Configs + +`ace_clgp_deployCondition` +- A function that will trigger the ammo when returning true, passed `[_projectile, _guidanceArgs]` +- Is optional, can just use normal submuntion triggers + +`ace_clgp_artilleryDrag` +- Optional (Leave undefined (or set to -1) to ignore) +- Used as a coefficient on drag from ace_artilleryTables's advancedCorrections +- Value of 0 is valid and will not apply drag but still keep nose pointed correctly (for unpowered missiles) + +## 3. Note on adding magazines via mission + +```cpp +if (local turretLocal [0]) then { + this addMagazineTurret ["ace_1rnd_155mm_m712", [0]]; +}; +``` From e142d383aeb9c40418e3f6c8732732b80ddfbdc3 Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Thu, 23 May 2024 23:58:54 -0500 Subject: [PATCH 22/23] Disable alt flightmode for now --- addons/clgp/functions/fnc_copperhead_onfired.sqf | 6 +++++- addons/clgp/script_component.hpp | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/addons/clgp/functions/fnc_copperhead_onfired.sqf b/addons/clgp/functions/fnc_copperhead_onfired.sqf index 76918a71a55..ed843b263f5 100644 --- a/addons/clgp/functions/fnc_copperhead_onfired.sqf +++ b/addons/clgp/functions/fnc_copperhead_onfired.sqf @@ -25,7 +25,11 @@ _stateParams params ["", "", "_attackProfileStateParams"]; TRACE_6("copperhead_onfired",_projectile,_trajectorySetting,_delaySetting,_laserCodeA,_laserCodeB,_laserCodeC); // Set trajectory from first dial -private _trajectoryShaped = _trajectorySetting >= 3; // 1-2 is ballisitic, 3-8 is shaped + +// Changing path without active feedback causes problems on current missile guidance +// probably due to poor vector change in ace_missileguidance_fnc_guidancePFH, disable for now +private _trajectoryShaped = false; +// private _trajectoryShaped = _trajectorySetting >= 3; // 1-2 is ballisitic, 3-8 is shaped _attackProfileStateParams set [0, _trajectoryShaped]; // set var for submuntion's deployCondition from second dial diff --git a/addons/clgp/script_component.hpp b/addons/clgp/script_component.hpp index 5ba10922789..4bbee544afe 100644 --- a/addons/clgp/script_component.hpp +++ b/addons/clgp/script_component.hpp @@ -2,9 +2,9 @@ #define COMPONENT_BEAUTIFIED Cannon Launched Guided Projectiles #include "\z\ace\addons\main\script_mod.hpp" -#define DEBUG_MODE_FULL -#define DISABLE_COMPILE_CACHE -#define ENABLE_QUICK_TESTING +// #define DEBUG_MODE_FULL +// #define DISABLE_COMPILE_CACHE +// #define ENABLE_QUICK_TESTING // #define ENABLE_PERFORMANCE_COUNTERS #include "\z\ace\addons\main\script_macros.hpp" From c3531004db578ebe99a39e881e0d155e924e349c Mon Sep 17 00:00:00 2001 From: PabstMirror Date: Sat, 28 Sep 2024 01:16:29 -0500 Subject: [PATCH 23/23] Update for mg changes --- addons/clgp/CfgAmmo.hpp | 9 +- addons/clgp/GUI.hpp | 6 +- addons/clgp/dev/quickTesting.sqf | 6 +- .../functions/fnc_submunition_ammoFired.sqf | 2 +- .../fnc_submunition_submunitionCreated.sqf | 6 - addons/clgp/stringtable.xml | 3 - addons/missileguidance/XEH_PREP.hpp | 2 +- .../functions/fnc_doAttackProfile.sqf | 2 +- .../functions/fnc_guidancePFH.sqf | 2 +- .../missileguidance/functions/fnc_onFired.sqf | 211 +---------------- .../functions/fnc_onFiredDeferred.sqf | 137 ----------- .../functions/fnc_onFiredGetArgs.sqf | 220 ++++++++++++++++++ 12 files changed, 241 insertions(+), 365 deletions(-) delete mode 100644 addons/missileguidance/functions/fnc_onFiredDeferred.sqf create mode 100644 addons/missileguidance/functions/fnc_onFiredGetArgs.sqf diff --git a/addons/clgp/CfgAmmo.hpp b/addons/clgp/CfgAmmo.hpp index 9d48a150bf9..5be9aa432b2 100644 --- a/addons/clgp/CfgAmmo.hpp +++ b/addons/clgp/CfgAmmo.hpp @@ -115,6 +115,7 @@ class CfgAmmo { thrustTime = 14; initTime = 0; airFriction = 0.1; + sideAirFriction = 0.1; hit = 120; indirectHit = 10; @@ -146,9 +147,8 @@ class CfgAmmo { class ace_missileguidance { enabled = 2; - minDeflection = 0.0005; // Minium flap deflection for guidance - maxDeflection = 0.0025; // Maximum flap deflection for guidance - incDeflection = 0.0005; // The incrmeent in which deflection adjusts. + pitchRate = 15; + yawRate = 20; canVanillaLock = 0; // Can this default vanilla lock? Only applicable to non-cadet mode @@ -159,6 +159,9 @@ class CfgAmmo { defaultSeekerLockMode = "LOAL"; seekerLockModes[] = {"LOAL"}; + defaultNavigationType = "Direct"; + navigationTypes[] = { "Direct" }; + seekerAngle = 90; // Angle in front of the missile which can be searched seekerAccuracy = 1; // seeker accuracy multiplier diff --git a/addons/clgp/GUI.hpp b/addons/clgp/GUI.hpp index c9d1625c46c..1257bb899e4 100644 --- a/addons/clgp/GUI.hpp +++ b/addons/clgp/GUI.hpp @@ -64,7 +64,7 @@ class GVAR(copperhead_dialog) { class Controls { class ButtonDial: GVAR(copperhead_dialButton) { idc = 113; - tooltip = CSTRING(copperhead_dial_LaserCode); + tooltip = ECSTRING(laser,laserCode); }; }; }; @@ -73,7 +73,7 @@ class GVAR(copperhead_dialog) { class Controls { class ButtonDial: GVAR(copperhead_dialButton) { idc = 114; - tooltip = CSTRING(copperhead_dial_LaserCode); + tooltip = ECSTRING(laser,laserCode); }; }; }; @@ -82,7 +82,7 @@ class GVAR(copperhead_dialog) { class Controls { class ButtonDial: GVAR(copperhead_dialButton) { idc = 115; - tooltip = CSTRING(copperhead_dial_LaserCode); + tooltip = ECSTRING(laser,laserCode); }; }; }; diff --git a/addons/clgp/dev/quickTesting.sqf b/addons/clgp/dev/quickTesting.sqf index 28c1c52e6bd..fe3b62c844e 100644 --- a/addons/clgp/dev/quickTesting.sqf +++ b/addons/clgp/dev/quickTesting.sqf @@ -23,10 +23,10 @@ DFUNC(dev_trackShell) = { if (_ammo isKindOf "SubmunitionBase") then { private _projectilePos = getPosASL _projectile; private _forwardPosition = _projectilePos vectorAdd ((vectorNormalized (velocity _projectile)) vectorMultiply 15); - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLtoAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; - drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0.5,0,1,1], ASLtoAGL _forwardPosition, 0.75, 0.75, 0, + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,0,0,1], ASLToAGL _projectilePos, 0.75, 0.75, 0, _ammo, 1, 0.025, "TahomaB"]; + drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [0.5,0,1,1], ASLToAGL _forwardPosition, 0.75, 0.75, 0, format ["V: %1 (%2)", round vectorMagnitude velocity _projectile, round ((velocity _projectile) # 2)], 1, 0.025, "TahomaB"]; - drawLine3D [ASLtoAGL _projectilePos, ASLtoAGL _forwardPosition, [0.5,0,1,1]]; + drawLine3D [ASLToAGL _projectilePos, ASLToAGL _forwardPosition, [0.5,0,1,1]]; }; private _deltaT = CBA_missionTime - _time; diff --git a/addons/clgp/functions/fnc_submunition_ammoFired.sqf b/addons/clgp/functions/fnc_submunition_ammoFired.sqf index d7ea236589c..8f3b0e35210 100644 --- a/addons/clgp/functions/fnc_submunition_ammoFired.sqf +++ b/addons/clgp/functions/fnc_submunition_ammoFired.sqf @@ -25,7 +25,7 @@ private _ammoCfg = configOf _projectile; private _firedEH = +_this; // Inject the submunition ammo into guidance args _firedEH set [4, getText (_ammoCfg >> "submunitionAmmo")]; -private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredDeferred); +private _guidanceArgs = _firedEH call EFUNC(missileguidance,onFiredGetArgs); if (_guidanceArgs isEqualTo []) then { WARNING_1("no args %1",_projectile); }; _projectile setVariable [QGVAR(guidanceArgs), _guidanceArgs]; diff --git a/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf b/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf index 1550b669574..b0aaece6216 100644 --- a/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf +++ b/addons/clgp/functions/fnc_submunition_submunitionCreated.sqf @@ -30,12 +30,6 @@ if (_guidanceArgs isNotEqualTo []) then { // Inject the submunition projectile a [EFUNC(missileguidance,guidancePFH), 0, _guidanceArgs] call CBA_fnc_addPerFrameHandler; }; -// NOTE: Probably need to remove after frag-rewrite -if (!isNil QEFUNC(frag,addPfhRound)) then { // todo make frag work for original and sub - TRACE_1("-Starting frag track",_submunitionProjectile); - [_firedEH # 0, _firedEH # 4, _submunitionProjectile] call EFUNC(frag,addPfhRound); -}; - private _deployArtilleryDragConfig = (configOf _projectile) >> QGVAR(artilleryDrag); if (isNumber _deployArtilleryDragConfig) then { private _deployArtilleryDrag = getNumber _deployArtilleryDragConfig; diff --git a/addons/clgp/stringtable.xml b/addons/clgp/stringtable.xml index e220015de3c..28b954bcea5 100644 --- a/addons/clgp/stringtable.xml +++ b/addons/clgp/stringtable.xml @@ -10,9 +10,6 @@ Guidance Delay - - Laser Code - 40mm Pike diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 73018d4674d..01f65719090 100644 --- a/addons/missileguidance/XEH_PREP.hpp +++ b/addons/missileguidance/XEH_PREP.hpp @@ -9,7 +9,7 @@ PREP(checkLos); PREP(dev_ProjectileCamera); PREP(onFired); -PREP(onFiredDeferred); +PREP(onFiredGetArgs); PREP(onIncomingMissile); PREP(guidancePFH); diff --git a/addons/missileguidance/functions/fnc_doAttackProfile.sqf b/addons/missileguidance/functions/fnc_doAttackProfile.sqf index e33d2bfd9be..d6dde00f91b 100644 --- a/addons/missileguidance/functions/fnc_doAttackProfile.sqf +++ b/addons/missileguidance/functions/fnc_doAttackProfile.sqf @@ -25,7 +25,7 @@ private _attackProfileFunction = getText (configFile >> QGVAR(AttackProfiles) >> private _attackProfilePos = _this call (missionNamespace getVariable _attackProfileFunction); if ((isNil "_attackProfilePos") || {_attackProfilePos isEqualTo [0,0,0]}) exitWith { - ERROR_2("attack profile [%1] returned bad pos %2",_attackProfileName,_attackProfilePos); + // ERROR_2("attack profile [%1] returned bad pos %2",_attackProfileName,_attackProfilePos); [0,0,0] }; diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 8b8df3d5114..82d3d57a35f 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -50,7 +50,7 @@ _targetData set [1, _projectilePos vectorFromTo _profileAdjustedTargetPos]; // If we have no seeker target, then do not change anything // If there is no deflection on the missile, this cannot change and therefore is redundant. Avoid calculations for missiles without any deflection -if ((_pitchRate != 0 || {_yawRate != 0})) then { +if ((_pitchRate != 0 || {_yawRate != 0}) && {_profileAdjustedTargetPos isNotEqualTo [0,0,0]}) then { private _navigationFunction = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "functionName"); if (_navigationStateData isNotEqualTo []) then { (_navigationStateData select _currentState) params ["_transitionCondition"]; diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 9cc91f300a9..f4a1250087b 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -5,6 +5,8 @@ * * Arguments: * 0: Shooter (Man/Vehicle) + * 1: Weapon + * 3: Mode * 4: Ammo * 6: Projectile * @@ -30,214 +32,11 @@ if ( !isPlayer _shooter && { GVAR(enabled) < 2 } ) exitWith {}; // Verify ammo has explicity added guidance config (ignore inheritances) private _configs = configProperties [(configFile >> "CfgAmmo" >> _ammo), QUOTE(configName _x == QUOTE(QUOTE(ADDON))), false]; -if ((count _configs) < 1) exitWith {}; +if (_configs isEqualTo []) exitWith {}; -// MissileGuidance is enabled for this shot -TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); - -private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); - -private _target = _shooter getVariable [QGVAR(target), nil]; -private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; -private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; -private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; -private _navigationType = _shooter getVariable [QGVAR(navigationType), nil]; -if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "useModeForAttackProfile")) == 1) then { - _attackProfile = getText (configFile >> "CfgWeapons" >> _weapon >> _mode >> QGVAR(attackProfile)) -}; -private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; - -private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; -private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; - -TRACE_7("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode,_navigationType); - -private _launchPos = getPosASL (vehicle _shooter); - -if (isNil "_seekerType" || {!(_seekerType in (getArray (_config >> "seekerTypes")))}) then { - _seekerType = getText (_config >> "defaultSeekerType"); -}; -if (isNil "_attackProfile" || {!(_attackProfile in (getArray (_config >> "attackProfiles")))}) then { - _attackProfile = getText (_config >> "defaultAttackProfile"); -}; -if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes")))}) then { - _lockMode = getText (_config >> "defaultSeekerLockMode"); -}; -if (isNil "_navigationType" || {!(_navigationType in (getArray (_config >> "navigationTypes")))}) then { - _navigationType = getText (_config >> "defaultNavigationType"); -}; - -if (isNil "_navigationType" || _navigationType isEqualTo "") then { - // most missiles use ProNav by default - _navigationType = "ProportionalNavigation"; -}; - -// If we didn't get a target, try to fall back on tab locking -if (isNil "_target") then { - if (!isPlayer _shooter) then { - // This was an AI shot, lets still guide it on the AI target - _target = _shooter getVariable [QGVAR(vanilla_target), nil]; - TRACE_1("Detected AI Shooter!",_target); - } else { - private _canUseLock = getNumber (_config >> "canVanillaLock"); - // @TODO: Get vanilla target - if (_canUseLock > 0 || difficulty < 1) then { - private _vanillaTarget = missileTarget _projectile; - - TRACE_1("Using Vanilla Locking",_vanillaTarget); - if (!isNil "_vanillaTarget") then { - _target = _vanillaTarget; - }; - }; - }; -}; -_targetPos = getPosASLVisual _target; - -// Array for seek last target position -private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; -private _lastKnownPosState = [_seekLastTargetPos]; -if (_seekLastTargetPos && {!isNil "_target"}) then { - _lastKnownPosState set [1, (getPosASL _target)]; -} else { - _lastKnownPosState set [1, [0,0,0]]; -}; - -private _navigationParameters = [ - // set up in navigation type onFired function -]; - -// default config values to make sure there is backwards compat -private _pitchRate = 30; -private _yawRate = 30; -private _bangBang = false; -if (isNumber (_config >> "pitchRate")) then { - _pitchRate = getNumber ( _config >> "pitchRate" ); - _yawRate = getNumber ( _config >> "yawRate" ); - _bangBang = (1 == getNumber (_config >> "bangBangGuidance")); -}; - -// How much this projectile likes to stay toward current velocity -private _stabilityCoefficient = getNumber (_config >> "stabilityCoefficient"); - -// show a light trail in flight -private _showTrail = (1 == getNumber (_config >> "showTrail")); - -private _navigationStateSubclass = _config >> "navigationStates"; -private _states = getArray (_navigationStateSubclass >> "states"); - -private _navigationStateData = []; -private _initialState = ""; - -if (_states isNotEqualTo []) then { - _initialState = _states select 0; - { - private _stateClass = _navigationStateSubclass >> _x; - _navigationStateData pushBack [ - getText (_stateClass >> "transitionCondition"), - getText (_stateClass >> "navigationType"), - [] - ]; - } forEach _states; -}; - -private _initialRoll = getNumber (_config >> "initialRoll"); -private _initialYaw = getNumber (_config >> "initialYaw"); -private _initialPitch = getNumber (_config >> "initialPitch"); - -private _yawRollPitch = (vectorDir _projectile) call CBA_fnc_vect2Polar; - -TRACE_5("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile,_navigationType); -private _args = [_this, - [ _shooter, - [_target, _targetPos, _launchPos, vectorDirVisual vehicle _shooter, CBA_missionTime], - _seekerType, - _attackProfile, - _lockMode, - _laserInfo, - _navigationType - ], - [ - _pitchRate, - _yawRate, - _bangBang, - _stabilityCoefficient, - _showTrail - ], - [ - getNumber ( _config >> "seekerAngle" ), - getNumber ( _config >> "seekerAccuracy" ), - getNumber ( _config >> "seekerMaxRange" ), - getNumber ( _config >> "seekerMinRange" ) - ], - [ diag_tickTime, [], [], _lastKnownPosState, _navigationParameters, [_initialYaw + (_yawRollPitch select 1), _initialRoll, _initialPitch + (_yawRollPitch select 2)]], - [ - // target data from missile. Must be filled by seeker for navigation to work - [0, 0, 0], // direction to target - [0, 0, 0], // direction to attack profile - 0, // range to target - [0, 0, 0], // target velocity - [0, 0, 0] // target acceleration - ], - [0, _navigationStateData] - ]; - -private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); -TRACE_1("seeker on fired",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -_onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); -TRACE_1("attack on fired",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -if (_states isEqualTo []) then { - _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "onFired"); - TRACE_1("navigation on fired",_onFiredFunc); - if (_onFiredFunc != "") then { - private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); - (_args select 4) set [4, _navState]; - }; -} else { - { - _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _x >> "onFired"); - TRACE_1("navigation on fired",_onFiredFunc); - if (_onFiredFunc != "") then { - private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); - (_navigationStateData select _forEachIndex) set [2, _navState]; - }; - } forEach getArray (_config >> "navigationTypes"); -}; - -// Run the "onFired" function passing the full guidance args array -_onFiredFunc = getText (_config >> "onFired"); -TRACE_1("general on fired",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -// Reverse: -// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"]; -// _firedEH params ["_shooter","","","","_ammo","","_projectile"]; -// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; -// _targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"]; -// _flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"]; -// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_navigationParams", "_guidanceParameters"]; -// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; -// _targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; - -[LINKFUNC(guidancePFH),0, _args ] call CBA_fnc_addPerFrameHandler; +private _args = call FUNC(onFiredGetArgs); +[LINKFUNC(guidancePFH),0, _args] call CBA_fnc_addPerFrameHandler; if (GVAR(debug_enableMissileCamera)) then { [_projectile] call FUNC(dev_ProjectileCamera); }; - - -/* Clears locking settings -(vehicle _shooter) setVariable [QGVAR(target), nil]; -(vehicle _shooter) setVariable [QGVAR(seekerType), nil]; -(vehicle _shooter) setVariable [QGVAR(attackProfile), nil]; -(vehicle _shooter) setVariable [QGVAR(lockMode), nil]; - */ diff --git a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf b/addons/missileguidance/functions/fnc_onFiredDeferred.sqf deleted file mode 100644 index 195967b74aa..00000000000 --- a/addons/missileguidance/functions/fnc_onFiredDeferred.sqf +++ /dev/null @@ -1,137 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: PabstMirror (mostly copy of onFired) - * Fired event handler for defered ammos (clgp), returns guidance args - * - * Arguments: - * 0: Shooter (Man/Vehicle) - * 1: Weapon - * 3: Mode - * 4: Ammo (in the future) - * 6: Projectile - * - * Return Value: - * - * - * Example: - * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFiredDeferred; - * - * Public: No - */ - -params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; - -// Bail if guidance is disabled for this ammo -if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 2) exitWith { ERROR("not enabled=2"); [] }; - -// MissileGuidance is enabled for this shot -TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); - -private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); - -private _target = _shooter getVariable [QGVAR(target), nil]; -private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; -private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; -private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; -if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "useModeForAttackProfile")) == 1) then { - _attackProfile = getText (configFile >> "CfgWeapons" >> _weapon >> _mode >> QGVAR(attackProfile)) -}; -private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; - -private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; -private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; - -TRACE_6("getVars",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode); - -private _launchPos = getPosASL (vehicle _shooter); - -if (isNil "_seekerType" || {!(_seekerType in (getArray (_config >> "seekerTypes")))}) then { - _seekerType = getText (_config >> "defaultSeekerType"); -}; -if (isNil "_attackProfile" || {!(_attackProfile in (getArray (_config >> "attackProfiles")))}) then { - _attackProfile = getText (_config >> "defaultAttackProfile"); -}; -if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes")))}) then { - _lockMode = getText (_config >> "defaultSeekerLockMode"); -}; - -// If we didn't get a target, try to fall back on tab locking -if (isNil "_target") then { - if (!isPlayer _shooter) then { - // This was an AI shot, lets still guide it on the AI target - _target = _shooter getVariable [QGVAR(vanilla_target), nil]; - TRACE_1("Detected AI Shooter!",_target); - } else { - private _canUseLock = getNumber (_config >> "canVanillaLock"); - // @TODO: Get vanilla target - if (_canUseLock > 0 || difficulty < 1) then { - private _vanillaTarget = cursorTarget; - - TRACE_1("Using Vanilla Locking",_vanillaTarget); - if (!isNil "_vanillaTarget") then { - _target = _vanillaTarget; - }; - }; - }; -}; - -// Array for seek last target position -private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; -private _lastKnownPosState = [_seekLastTargetPos]; -if (_seekLastTargetPos && {!isNil "_target"}) then { - _lastKnownPosState set [1, (getPosASL _target)]; -} else { - _lastKnownPosState set [1, [0,0,0]]; -}; - -TRACE_4("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile); -private _args = [_this, - [ _shooter, - [_target, _targetPos, _launchPos], - _seekerType, - _attackProfile, - _lockMode, - _laserInfo - ], - [ - getNumber ( _config >> "minDeflection" ), - getNumber ( _config >> "maxDeflection" ), - getNumber ( _config >> "incDeflection" ) - ], - [ - getNumber ( _config >> "seekerAngle" ), - getNumber ( _config >> "seekerAccuracy" ), - getNumber ( _config >> "seekerMaxRange" ), - getNumber ( _config >> "seekerMinRange" ) - ], - [ diag_tickTime, [], [], _lastKnownPosState] - ]; - -private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); -TRACE_1("",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -_onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); -TRACE_1("",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -// Run the "onFired" function passing the full guidance args array -_onFiredFunc = getText (_config >> "onFired"); -TRACE_1("",_onFiredFunc); -if (_onFiredFunc != "") then { - _args call (missionNamespace getVariable _onFiredFunc); -}; - -// Reverse: -// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams"]; -// _firedEH params ["_shooter","","","","_ammo","","_projectile"]; -// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo"]; -// _targetLaunchParams params ["_target", "_targetPos", "_launchPos"]; -// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; -// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; - -_args diff --git a/addons/missileguidance/functions/fnc_onFiredGetArgs.sqf b/addons/missileguidance/functions/fnc_onFiredGetArgs.sqf new file mode 100644 index 00000000000..55a2e722807 --- /dev/null +++ b/addons/missileguidance/functions/fnc_onFiredGetArgs.sqf @@ -0,0 +1,220 @@ +#include "..\script_component.hpp" +/* + * Author: jaynus, nou, TCVM, PabstMirror + * Gets guidance args for a fired missile, running fired EHs and returning the full guidance arg array + * + * Arguments: + * 0: Shooter (Man/Vehicle) + * 1: Weapon + * 3: Mode + * 4: Ammo (in the future) + * 6: Projectile + * + * Return Value: + * + * + * Example: + * [player, "", "", "", "ACE_Javelin_FGM148", "", theMissile] call ace_missileguidance_fnc_onFiredGetArgs + * + * Public: No + */ + +params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; + +// MissileGuidance is enabled for this shot +TRACE_4("enabled",_shooter,_ammo,_projectile,typeOf _shooter); + +private _config = configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON); + +private _target = _shooter getVariable [QGVAR(target), nil]; +private _targetPos = _shooter getVariable [QGVAR(targetPosition), nil]; +private _seekerType = _shooter getVariable [QGVAR(seekerType), nil]; +private _attackProfile = _shooter getVariable [QGVAR(attackProfile), nil]; +private _navigationType = _shooter getVariable [QGVAR(navigationType), nil]; +if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "useModeForAttackProfile")) == 1) then { + _attackProfile = getText (configFile >> "CfgWeapons" >> _weapon >> _mode >> QGVAR(attackProfile)) +}; +private _lockMode = _shooter getVariable [QGVAR(lockMode), nil]; + +private _laserCode = _shooter getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; +private _laserInfo = [_laserCode, ACE_DEFAULT_LASER_WAVELENGTH, ACE_DEFAULT_LASER_WAVELENGTH]; + +TRACE_7("onFiredGetArgs",_target,_targetPos,_seekerType,_attackProfile,_lockMode,_laserCode,_navigationType); + +private _launchPos = getPosASL (vehicle _shooter); + +if (isNil "_seekerType" || {!(_seekerType in (getArray (_config >> "seekerTypes")))}) then { + _seekerType = getText (_config >> "defaultSeekerType"); +}; +if (isNil "_attackProfile" || {!(_attackProfile in (getArray (_config >> "attackProfiles")))}) then { + _attackProfile = getText (_config >> "defaultAttackProfile"); +}; +if (isNil "_lockMode" || {!(_lockMode in (getArray (_config >> "seekerLockModes")))}) then { + _lockMode = getText (_config >> "defaultSeekerLockMode"); +}; +if (isNil "_navigationType" || {!(_navigationType in (getArray (_config >> "navigationTypes")))}) then { + _navigationType = getText (_config >> "defaultNavigationType"); +}; + +if (isNil "_navigationType" || _navigationType isEqualTo "") then { + // most missiles use ProNav by default + _navigationType = "ProportionalNavigation"; +}; + +// If we didn't get a target, try to fall back on tab locking +if (isNil "_target") then { + if (!isPlayer _shooter) then { + // This was an AI shot, lets still guide it on the AI target + _target = _shooter getVariable [QGVAR(vanilla_target), nil]; + TRACE_1("Detected AI Shooter!",_target); + } else { + private _canUseLock = getNumber (_config >> "canVanillaLock"); + // @TODO: Get vanilla target + if (_canUseLock > 0 || difficulty < 1) then { + private _vanillaTarget = missileTarget _projectile; + + TRACE_1("Using Vanilla Locking",_vanillaTarget); + if (!isNil "_vanillaTarget") then { + _target = _vanillaTarget; + }; + }; + }; +}; +_targetPos = getPosASLVisual _target; + +// Array for seek last target position +private _seekLastTargetPos = (getNumber ( _config >> "seekLastTargetPos")) == 1; +private _lastKnownPosState = [_seekLastTargetPos]; +if (_seekLastTargetPos && {!isNil "_target"}) then { + _lastKnownPosState set [1, (getPosASL _target)]; +} else { + _lastKnownPosState set [1, [0,0,0]]; +}; + +private _navigationParameters = [ + // set up in navigation type onFired function +]; + +// default config values to make sure there is backwards compat +private _pitchRate = 30; +private _yawRate = 30; +private _bangBang = false; +if (isNumber (_config >> "pitchRate")) then { + _pitchRate = getNumber ( _config >> "pitchRate" ); + _yawRate = getNumber ( _config >> "yawRate" ); + _bangBang = (1 == getNumber (_config >> "bangBangGuidance")); +}; + +// How much this projectile likes to stay toward current velocity +private _stabilityCoefficient = getNumber (_config >> "stabilityCoefficient"); + +// show a light trail in flight +private _showTrail = (1 == getNumber (_config >> "showTrail")); + +private _navigationStateSubclass = _config >> "navigationStates"; +private _states = getArray (_navigationStateSubclass >> "states"); + +private _navigationStateData = []; +private _initialState = ""; + +if (_states isNotEqualTo []) then { + _initialState = _states select 0; + { + private _stateClass = _navigationStateSubclass >> _x; + _navigationStateData pushBack [ + getText (_stateClass >> "transitionCondition"), + getText (_stateClass >> "navigationType"), + [] + ]; + } forEach _states; +}; + +private _initialRoll = getNumber (_config >> "initialRoll"); +private _initialYaw = getNumber (_config >> "initialYaw"); +private _initialPitch = getNumber (_config >> "initialPitch"); + +private _yawRollPitch = (vectorDir _projectile) call CBA_fnc_vect2Polar; + +TRACE_5("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile,_navigationType); +private _args = [_this, + [ _shooter, + [_target, _targetPos, _launchPos, vectorDirVisual vehicle _shooter, CBA_missionTime], + _seekerType, + _attackProfile, + _lockMode, + _laserInfo, + _navigationType + ], + [ + _pitchRate, + _yawRate, + _bangBang, + _stabilityCoefficient, + _showTrail + ], + [ + getNumber ( _config >> "seekerAngle" ), + getNumber ( _config >> "seekerAccuracy" ), + getNumber ( _config >> "seekerMaxRange" ), + getNumber ( _config >> "seekerMinRange" ) + ], + [ diag_tickTime, [], [], _lastKnownPosState, _navigationParameters, [_initialYaw + (_yawRollPitch select 1), _initialRoll, _initialPitch + (_yawRollPitch select 2)]], + [ + // target data from missile. Must be filled by seeker for navigation to work + [0, 0, 0], // direction to target + [0, 0, 0], // direction to attack profile + 0, // range to target + [0, 0, 0], // target velocity + [0, 0, 0] // target acceleration + ], + [0, _navigationStateData] + ]; + +private _onFiredFunc = getText (configFile >> QGVAR(SeekerTypes) >> _seekerType >> "onFired"); +TRACE_1("seeker on fired",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +_onFiredFunc = getText (configFile >> QGVAR(AttackProfiles) >> _attackProfile >> "onFired"); +TRACE_1("attack on fired",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +if (_states isEqualTo []) then { + _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _navigationType >> "onFired"); + TRACE_1("navigation on fired",_onFiredFunc); + if (_onFiredFunc != "") then { + private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); + (_args select 4) set [4, _navState]; + }; +} else { + { + _onFiredFunc = getText (configFile >> QGVAR(NavigationTypes) >> _x >> "onFired"); + TRACE_1("navigation on fired",_onFiredFunc); + if (_onFiredFunc != "") then { + private _navState = (_args call (missionNamespace getVariable _onFiredFunc)); + (_navigationStateData select _forEachIndex) set [2, _navState]; + }; + } forEach getArray (_config >> "navigationTypes"); +}; + +// Run the "onFired" function passing the full guidance args array +_onFiredFunc = getText (_config >> "onFired"); +TRACE_1("general on fired",_onFiredFunc); +if (_onFiredFunc != "") then { + _args call (missionNamespace getVariable _onFiredFunc); +}; + +// Reverse: +// _args params ["_firedEH", "_launchParams", "_flightParams", "_seekerParams", "_stateParams", "_targetData", "_navigationStateData"]; +// _firedEH params ["_shooter","","","","_ammo","","_projectile"]; +// _launchParams params ["_shooter","_targetLaunchParams","_seekerType","_attackProfile","_lockMode","_laserInfo","_navigationType"]; +// _targetLaunchParams params ["_target", "_targetPos", "_launchPos", "_launchDir", "_launchTime"]; +// _flightParams params ["_pitchRate", "_yawRate", "_isBangBangGuidance"]; +// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState", "_navigationParams", "_guidanceParameters"]; +// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; +// _targetData params ["_targetDirection", "_attackProfileDirection", "_targetRange", "_targetVelocity", "_targetAcceleration"]; + +_args