redo using ammo events

This commit is contained in:
PabstMirror 2023-10-14 21:47:07 -05:00
parent bf1c092a3a
commit 9d18dc6128
15 changed files with 257 additions and 111 deletions

View File

@ -7,6 +7,7 @@ PREP(checkSeekerAngle);
PREP(checkLos); PREP(checkLos);
PREP(onFired); PREP(onFired);
PREP(onFiredDeffered);
PREP(onIncomingMissile); PREP(onIncomingMissile);
PREP(guidancePFH); PREP(guidancePFH);

View File

@ -0,0 +1,135 @@
#include "..\script_component.hpp"
/*
* Author: PabstMirror
* Gathers onFired args for later use
*
* Arguments:
* 0: Shooter (Man/Vehicle) <OBJECT>
* 4: Ammo <STRING>
* 6: Projectile <OBJECT>
*
* Return Value:
* Args <Array>
*
* 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

View File

@ -1 +1 @@
z\ace\addons\pike z\ace\addons\pike

View File

@ -1,10 +1,14 @@
class CfgAmmo { class CfgAmmo {
class FlareBase; class SubmunitionBase;
class GVAR(ammo_gl): FlareBase { class GVAR(ammo_gl): SubmunitionBase {
model = QPATHTOF(models\ace_pike_ammo.p3d); model = QPATHTOF(models\ace_pike_ammo.p3d);
lightColor[] = {0, 0, 0, 0}; submunitionAmmo = QGVAR(ammo_rocket);
smokeColor[] = {0, 0, 0, 0}; submunitionCount = 1;
timeToLive = 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 MissileBase;
@ -13,29 +17,44 @@ class CfgAmmo {
laserLock = 0; laserLock = 0;
airLock = 0; airLock = 0;
manualControl = 0; manualControl = 0;
timeToLive = 22;
timeToLive = 30;
model = QPATHTOF(models\ace_pike_ammo.p3d); model = QPATHTOF(models\ace_pike_ammo.p3d);
maxSpeed = 150; maxSpeed = 150; // ~2km in 15sec
thrust = 15; thrust = 19;
thrustTime = 8; thrustTime = 14;
initTime = 0; initTime = 0;
airFriction = 0.1; airFriction = 0.1;
hit = 100; hit = 120;
indirectHit = 8; indirectHit = 10;
indirectHitRange = 6; indirectHitRange = 10;
warheadName = "HE";
CraterEffects = "AAMissileCrater"; EGVAR(frag,enabled) = 1;
explosionEffects = "AAMissileExplosion"; 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"; effectsMissileInit = "RocketBackEffectsRPG";
effectsMissile = "missile3"; 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 // Begin ACE guidance Configs
class ace_missileguidance { class ace_missileguidance {
enabled = 1; enabled = 2;
minDeflection = 0.0005; // Minium flap deflection for guidance minDeflection = 0.0005; // Minium flap deflection for guidance
maxDeflection = 0.0025; // Maximum flap deflection for guidance maxDeflection = 0.0025; // Maximum flap deflection for guidance
@ -54,7 +73,7 @@ class CfgAmmo {
seekerAccuracy = 1; // seeker accuracy multiplier seekerAccuracy = 1; // seeker accuracy multiplier
seekerMinRange = 1; 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 // Attack profile type selection
defaultAttackProfile = "LIN"; defaultAttackProfile = "LIN";

View File

@ -1,18 +1,10 @@
class Extended_PreStart_EventHandlers { class Extended_PreStart_EventHandlers {
class ADDON { class ADDON {
init = QUOTE(call COMPILE_FILE(XEH_preStart)); init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
}; };
}; };
class Extended_PreInit_EventHandlers { class Extended_PreInit_EventHandlers {
class ADDON { 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) );
}; };
}; };

View File

@ -2,12 +2,14 @@ class CfgMagazines {
class 1Rnd_HE_Grenade_shell; class 1Rnd_HE_Grenade_shell;
class ACE_40mm_Pike: 1Rnd_HE_Grenade_shell { class ACE_40mm_Pike: 1Rnd_HE_Grenade_shell {
displayName = CSTRING(magazine_displayName); displayName = CSTRING(magazine_displayName);
displayNameShort = "Pike SALH"; displayNameShort = CSTRING(magazine_displayNameShort);
descriptionShort = ""; descriptionShort = CSTRING(magazine_descriptionShort);
// picture = QPATHTOF(data\inventory_ca.paa); picture = QPATHTOF(ui\gear_pike_ca.paa);
ammo = QGVAR(ammo_gl); ammo = QGVAR(ammo_gl);
model = QPATHTOF(models\ace_pike_ammo.p3d); count = 1;
initSpeed = 40; // model = QPATHTOF(models\ace_pike_ammo.p3d); // kinda ugly, just use pouch thing
mass = 17; // 1.7 lbs initSpeed = 50;
mass = 17; // ~1.7 Pounds
author = ECSTRING(common,ACETeam);
}; };
}; };

View File

@ -2,10 +2,3 @@ ace_pike
=========== ===========
Adds 40mm Pike semi-active laser seeking rocket, firable from the M320 or EGLM grenade launcher. 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)

View File

@ -1 +1,2 @@
PREP(handleFired); LOG("prep");
PREP(ammoFired);

View File

@ -1,5 +0,0 @@
#include "script_component.hpp"
if (!hasInterface) exitWith {};
["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler;

View File

@ -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;

View File

@ -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;

View File

@ -1 +0,0 @@
#include "\z\ace\addons\pike\script_component.hpp"

View File

@ -2,9 +2,9 @@
#define COMPONENT_BEAUTIFIED Pike #define COMPONENT_BEAUTIFIED Pike
#include "\z\ace\addons\main\script_mod.hpp" #include "\z\ace\addons\main\script_mod.hpp"
#define DEBUG_MODE_FULL // #define DEBUG_MODE_FULL
#define DISABLE_COMPILE_CACHE // #define DISABLE_COMPILE_CACHE
#define ENABLE_PERFORMANCE_COUNTERS // #define ENABLE_PERFORMANCE_COUNTERS
#ifdef DEBUG_ENABLED_PIKE #ifdef DEBUG_ENABLED_PIKE
#define DEBUG_MODE_FULL #define DEBUG_MODE_FULL

View File

@ -1,8 +1,14 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project name="ACE"> <Project name="ACE">
<Package name="pike"> <Package name="Pike">
<Key ID="STR_ACE_pike_magazine_displayName"> <Key ID="STR_ACE_Pike_magazine_displayName">
<English>40mm Pike</English> <English>40mm Pike</English>
</Key> </Key>
<Key ID="STR_ACE_Pike_magazine_displayNameShort">
<English>Pike SALH</English>
</Key>
<Key ID="STR_ACE_Pike_magazine_descriptionShort">
<English>Semi-Active Laser Guided 40mm Grenade</English>
</Key>
</Package> </Package>
</Project> </Project>

Binary file not shown.