diff --git a/addons/missileguidance/XEH_PREP.hpp b/addons/missileguidance/XEH_PREP.hpp index 075f2f03c5..3b807721af 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 0000000000..3b1a61ebca --- /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 2eefcc6075..abc9bbeaae 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 a82c09db0d..80e6ea54d5 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"; - CraterEffects = "AAMissileCrater"; - explosionEffects = "AAMissileExplosion"; + 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 = 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 5da5fd0dc2..be6bec5a73 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 99ea405675..4258127db6 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 1e3424afa4..a90c3570db 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 64eb51ef80..a82521a9ae 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 05f38dadaf..0000000000 --- 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 0000000000..545eed3880 --- /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 9454b7932e..0000000000 --- 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 85866ed86b..0000000000 --- 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 4a826ab71a..b7bd9b4d93 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 3ed702fcce..2ea6f88c7b 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 0000000000..1b0ecb3807 Binary files /dev/null and b/addons/pike/ui/gear_pike_ca.paa differ