Skip to content

Commit

Permalink
Missile Guidance - Add Copperhead M712 (#8210)
Browse files Browse the repository at this point in the history
* Pike prototype

* Magwells

* move include

* Update fnc_handleFired.sqf

* Update configs

* initial clgp

* redo using ammo events

* bom

* Remove RVMAT for ammo model

* spelling of word

* Apply suggestions from code review

Co-authored-by: Jouni Järvinen <[email protected]>

* update clgp

* reduce change to mg

* More rework

* more cleanup

* Fly straight when no target data

* use artillery drag

* Update default laser code

* Merge pike

* Update CfgAmmo.hpp

* Add framework doc

* Disable alt flightmode for now

* Update for mg changes

* Update fnc_onFiredGetArgs.sqf

* sort st

* Add frag configs

* refactor to missile_clgp

* various suggestions

* Non-mag-hardcoded interface, fix attack profile

---------

Co-authored-by: Jouni Järvinen <[email protected]>
  • Loading branch information
PabstMirror and rautamiekka authored Mar 2, 2025
1 parent b516b96 commit 416930e
Show file tree
Hide file tree
Showing 23 changed files with 716 additions and 21 deletions.
6 changes: 6 additions & 0 deletions addons/missile_clgp/ACE_GuidanceConfig.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class EGVAR(missileguidance,AttackProfiles) {
class copperhead {
onFired = QFUNC(copperhead_onfired);
functionName = QFUNC(copperhead_attackprofile);
};
};
101 changes: 101 additions & 0 deletions addons/missile_clgp/CfgAmmo.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,109 @@
class CfgAmmo {
class SubmunitionBase;
class ace_155mm_m712_launch: SubmunitionBase {
model = "\A3\weapons_f\ammo\shell";
hit = 1200;
indirectHit = 200;
indirectHitRange = 4;
EGVAR(frag,force) = 1;
EGVAR(frag,skip) = 0;
EGVAR(frag,charge) = 9979;
EGVAR(frag,metal) = 36000;
EGVAR(frag,gurney_c) = 2700;
EGVAR(frag,gurney_k) = 0.5;
EGVAR(frag,classes)[] = {QEGVAR(frag,small), QEGVAR(frag,small_HD), QEGVAR(frag,medium), QEGVAR(frag,medium_HD), QEGVAR(frag,large_HD)};

GVAR(artilleryDrag) = 1;
GVAR(deployCondition) = QFUNC(copperhead_deployCondition);
submunitionAmmo = "ace_155mm_m712_guidance";
submunitionCount = 1;
submunitionConeAngle = 0;
triggerDistance = 0;
muzzleEffect = "";
airFriction = 0;

class Eventhandlers {
fired = QUOTE(call FUNC(submunition_ammoFired));
};
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 ammo_Bomb_LaserGuidedBase;
class ace_155mm_m712_guidance: ammo_Bomb_LaserGuidedBase {
model = "\A3\Weapons_F_beta\Launchers\titan\titan_missile_at_fly";
hit = 1200;
indirectHit = 200;
indirectHitRange = 4;
EGVAR(frag,skip) = 0;
EGVAR(frag,charge) = 9979;
EGVAR(frag,metal) = 36000;
EGVAR(frag,gurney_c) = 2440;
EGVAR(frag,gurney_k) = "1/2";
EGVAR(frag,classes)[] = {QEGVAR(frag,large), QEGVAR(frag,large), QEGVAR(frag,large_HD), QEGVAR(frag,large), QEGVAR(frag,huge), QEGVAR(frag,huge_HD), QEGVAR(frag,huge)};

maneuvrability = 0;
airFriction = 0.01; // note: works differently from shellsim (v^3...)
sideAirFriction = 0.1;

artilleryLock = 0; // would keep shell pointed towards velocity, but disables manuverability and airfric

initTime = 0;
thrustTime = 0;
thrust = 0; // free fall

manualControl = 0;
flightProfiles[] = {};
autoSeekTarget = 0;
weaponLockSystem = 0;
irLock = 0;
laserLock = 0;
airLock = 0;

timeToLive = 200;

class ace_missileguidance {
enabled = 2;
pitchRate = 10; // replace minDeflection, maxDeflection, incDeflection
yawRate = 10;
stabilityCoefficient = 0.2; // helps make the shot follow velocity

// Guidance type for munitions
defaultSeekerType = "SALH";
seekerTypes[] = { "SALH" };

defaultSeekerLockMode = "LOAL";
seekerLockModes[] = { "LOAL" };

defaultNavigationType = "Direct";
navigationTypes[] = { "Direct" };

seekerAngle = 70; // Angle in front of the missile which can be searched
seekerAccuracy = 1; // seeker accuracy multiplier

seekerMinRange = 0;
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]

// Attack profile type selection
defaultAttackProfile = "copperhead";
attackProfiles[] = {"copperhead"};
useModeForAttackProfile = 0;
canVanillaLock = 0;
};
};

class GVAR(pike_launch): SubmunitionBase {
model = QPATHTOF(data\ace_pike_ammo.p3d);
submunitionAmmo = QGVAR(pike_guidance);
Expand Down
7 changes: 7 additions & 0 deletions addons/missile_clgp/CfgMagazineWells.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
class CfgMagazineWells {
class ACE_155mm_artillery {
ADDON[] = {"ace_1rnd_155mm_m712", "ace_8rnd_155mm_m712"};
};
class gm_magazineWell_155mm {
// gm magwells are misconfigured (extra s on weapon cfg `magazineWells[]` so it does nothing)
ADDON[] = {"ace_1rnd_155mm_m712", "ace_8rnd_155mm_m712"};
};
class CBA_40mm_EGLM { // for longer grenades that can only fit side breech-loading
ADDON[] = {"ACE_40mm_Pike"};
};
Expand Down
15 changes: 15 additions & 0 deletions addons/missile_clgp/CfgMagazines.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,19 @@
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;
GVAR(copperheadInterface) = 1;
muzzleImpulseFactor[]={0.5,1}; // needed for compat with other mods (cup howitzer goes flying)
};
class ace_8rnd_155mm_m712: ace_1rnd_155mm_m712 {
count = 8;
};

class 1Rnd_HE_Grenade_shell;
class ACE_40mm_Pike: 1Rnd_HE_Grenade_shell {
author = ECSTRING(common,ACETeam);
Expand Down
8 changes: 8 additions & 0 deletions addons/missile_clgp/CfgWeapons.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
class CfgWeapons {
class CannonCore;
class mortar_155mm_AMOS: CannonCore {
magazineWell[] += {"ACE_155mm_artillery"};
// reloadTime = 1; // dev
// magazineReloadTime = 1;
};
};
92 changes: 92 additions & 0 deletions addons/missile_clgp/GUI.hpp
Original file line number Diff line number Diff line change
@@ -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_copperhead_interactive.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 ButtonDial: GVAR(copperhead_dialButton) {
idc = 111;
tooltip = CSTRING(copperhead_dial_FlightProfile);
};
};
};
class Dial2 {
selection = "dial2";
class Controls {
class ButtonDial: GVAR(copperhead_dialButton) {
idc = 112;
tooltip = CSTRING(copperhead_dial_GuidanceDelay);
};
};
};
class Dial3 {
selection = "dial3";
class Controls {
class ButtonDial: GVAR(copperhead_dialButton) {
idc = 113;
tooltip = ECSTRING(laser,laserCode);
};
};
};
class Dial4 {
selection = "dial4";
class Controls {
class ButtonDial: GVAR(copperhead_dialButton) {
idc = 114;
tooltip = ECSTRING(laser,laserCode);
};
};
};
class Dial5 {
selection = "dial5";
class Controls {
class ButtonDial: GVAR(copperhead_dialButton) {
idc = 115;
tooltip = ECSTRING(laser,laserCode);
};
};
};
};
};
};
};
7 changes: 7 additions & 0 deletions addons/missile_clgp/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
LOG("prep");


PREP(copperhead_attackprofile);
PREP(copperhead_deployCondition);
PREP(copperhead_onfired);
PREP(copperhead_uiCanOpen);
PREP(copperhead_uiCreate);

PREP(submunition_ammoFired);
PREP(submunition_applyDrag);
PREP(submunition_submunitionCreated);
30 changes: 30 additions & 0 deletions addons/missile_clgp/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -1,5 +1,35 @@
#include "script_component.hpp"

GVAR(copperheadMagazines) = createHashMap;

// Copperhead - Add shell interface action to vehicles that can fire it
if (hasInterface) then {
["turret", {
params ["_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(actionsAdded), false]}) exitWith {};
_vehicle setVariable [QGVAR(actionsAdded), true];

if (((_vehicle weaponsTurret [0]) findIf {
private _compatibleMagazines = compatibleMagazines _x;
(_compatibleMagazines findIf {
private _magazine = _x;
GVAR(copperheadMagazines) getOrDefaultCall [_magazine, {
(getNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(copperheadInterface))) == 1
}, true]
}) != -1
}) != -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);
};
}, true] call CBA_fnc_addPlayerEventHandler
};


#ifdef ENABLE_QUICK_TESTING
call compileScript [QPATHTOF(dev\quickTesting.sqf)];
#endif
Binary file not shown.
Binary file added addons/missile_clgp/data/copperhead_dial_co.paa
Binary file not shown.
92 changes: 92 additions & 0 deletions addons/missile_clgp/data/copperhead_mat.rvmat
Original file line number Diff line number Diff line change
@@ -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};
};
};
Binary file added addons/missile_clgp/data/copperhead_shell_co.paa
Binary file not shown.
Loading

0 comments on commit 416930e

Please sign in to comment.