mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Implement M47 Dragon (#6773)
* abc * Revert "abc" This reverts commitbcb4214bd9
. * Update to current commit * Ports over NouberNou's dragon guidance * Add Dragon model * Make the Dragon CSW capable * Fix bugs regarding argument order * Add Dragon Attack Profile. Change how missileGuidance guidance_pfh works in order to allow for different types of missiles besides continious thrust * Fix bug regarding missile direction. Add official US Army training manual for the dragon for reference purposes * Adjust model to reflect real-life one * Add attackProfile and guidanceProfile onFired functions * Change Dragon "onFired" to reflect missileGuidance changes * Only implementing the Super-Dragon. Remove Tabs. Add new lines to all files. Add string-table. Tweak missile flight dynamics * Add sight description * Fix inheritance issues. Missile damage values tweaked. Fix String Table. Add backblast area. * Add feature wiki page. * Fix picture issues * Remove Dragon manual * add missing semi-colon * Tweak damage values. Fix formatting. Add lazy evaluation where applicable * Disable the ability to switch to the unusable launcher. Convert rvmat numbers to equivalent but more readable numbers. Multiple code fixes. ace_csw required. Formatting fixes. TGA -> PAA. Remove unused comments in missile guidance code * Dragon flight dynamics tweaked. Now assuming there is a booster angle creating wobble. Add a slight delay when the wire breaks to fire all of the service charges * hpp newline fixes. Case sensitivity for model and rvmat references * Update Wiki dependencies * Revert "Update Wiki dependencies" This reverts commitefc298c481
. * fix dependency component * Changed inheritance structure to be more rigid. Remove un-needed config values. Fix script issues regarding positioning and the launchers aliveness * get rid of the optic for the base dragon. fucking bi configs not making sense * Lock non-useable dragon on initialization * Add model.cfg for animations * Fix formatting. Fix M47 Dragon Optic zoom * Change LOD selection names * Revert indentation, keep parenthesis. "Start, stop, start stop! Jesus! I'm starting to think Mattis is just a big cock tease" * Re-update indentation of model.cfg * Path fix. Whitespace fix * Sight attach/detach on same vehicle * If the sight gets detached, make sure the dragon goes dumb. Remove resetting of resting position when gunner gets out - looks stupid, but when the dragon is fired weird stuff happens * disable debug * Add EOF * Maybe finally fix EOF problem
This commit is contained in:
parent
b1d5bbe450
commit
abe2ce2f6f
1
addons/dragon/$PBOPREFIX$
Normal file
1
addons/dragon/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
z\ace\addons\dragon
|
11
addons/dragon/ACE_GuidanceConfig.hpp
Normal file
11
addons/dragon/ACE_GuidanceConfig.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
class EGVAR(missileguidance,AttackProfiles) {
|
||||
class DRAGON {
|
||||
name = CSTRING(dragonName);
|
||||
visualName = CSTRING(dragonName);
|
||||
description = CSTRING(dragonName);
|
||||
|
||||
onFired = QFUNC(onFired);
|
||||
functionName = QFUNC(attackProfile_DRAGON);
|
||||
};
|
||||
};
|
||||
|
147
addons/dragon/CfgAmmo.hpp
Normal file
147
addons/dragon/CfgAmmo.hpp
Normal file
@ -0,0 +1,147 @@
|
||||
class CfgAmmo {
|
||||
class ammo_Penetrator_Base;
|
||||
class M_Scalpel_AT;
|
||||
class Rocket_03_AP_F;
|
||||
|
||||
class GVAR(penetrator_super): ammo_Penetrator_Base {
|
||||
caliber = 60;
|
||||
warheadName = "HEAT";
|
||||
hit = 460;
|
||||
fuseDistance = 75;
|
||||
};
|
||||
|
||||
class GVAR(dragonBase): Rocket_03_AP_F {
|
||||
EGVAR(frag,skip) = 1;
|
||||
scope = 1;
|
||||
aiAmmoUsageFlags = "128+512";
|
||||
model = QPATHTOF(models\dragon.p3d);
|
||||
maxSpeed = 200;
|
||||
thrust = 300;
|
||||
initTime = 0.151;
|
||||
thrustTime = 0;
|
||||
sideAirFriction = 0.05;
|
||||
effectsMissile = "missile2";
|
||||
effectFlare = "";
|
||||
airFriction = 0.5;
|
||||
fuseDistance = 75;
|
||||
whistleDist = 2;
|
||||
|
||||
hit = 100;
|
||||
indirectHit = 9;
|
||||
indirectHitRange = 1;
|
||||
explosive = 0.8;
|
||||
timeToLive = 60;
|
||||
cost = 500;
|
||||
simulationStep = 0.005;
|
||||
maxControlRange = 1500;
|
||||
|
||||
class ace_missileguidance {
|
||||
minDeflection = 0;
|
||||
maxDeflection = 0;
|
||||
incDeflection = 0;
|
||||
|
||||
canVanillaLock = 0;
|
||||
|
||||
// Guidance type for munitions
|
||||
defaultSeekerType = "SACLOS";
|
||||
seekerTypes[] = { "SACLOS" };
|
||||
|
||||
defaultSeekerLockMode = "LOAL";
|
||||
seekerLockModes[] = { "LOAL", "LOBL" };
|
||||
|
||||
seekLastTargetPos = 0;
|
||||
seekerAngle = 30;
|
||||
seekerAccuracy = 1;
|
||||
|
||||
seekerMinRange = 65;
|
||||
seekerMaxRange = 1000;
|
||||
|
||||
correctionDistance = 30;
|
||||
missileLeadDistance = 0;
|
||||
offsetFromCrosshair[] = { 0, 0, 0 };
|
||||
|
||||
serviceInterval = 0.33; // how many seconds between pops
|
||||
serviceCharges = 32; // how many charges are in this missile
|
||||
serviceChargeAcceleration = 6.5;
|
||||
dragonSpeed = 100; // meters per second
|
||||
|
||||
defaultAttackProfile = "DRAGON";
|
||||
attackProfiles[] = {"DRAGON"};
|
||||
};
|
||||
};
|
||||
|
||||
class GVAR(super) : GVAR(dragonBase) {
|
||||
submunitionAmmo = QGVAR(penetrator_super);
|
||||
submunitionDirectionType = "SubmunitionModelDirection";
|
||||
submunitionInitSpeed = 1000;
|
||||
submunitionParentSpeedCoef = 0;
|
||||
submunitionInitialOffset[] = { 0, 0, -0.2 };
|
||||
|
||||
class ace_missileguidance {
|
||||
enabled = 1;
|
||||
|
||||
// Guidance type for munitions
|
||||
defaultSeekerType = "SACLOS";
|
||||
seekerTypes[] = { "SACLOS" };
|
||||
|
||||
defaultSeekerLockMode = "LOAL";
|
||||
seekerLockModes[] = { "LOAL", "LOBL" };
|
||||
|
||||
seekLastTargetPos = 0;
|
||||
seekerAngle = 30;
|
||||
seekerAccuracy = 1;
|
||||
|
||||
seekerMinRange = 30;
|
||||
seekerMaxRange = 1500;
|
||||
|
||||
correctionDistance = 30;
|
||||
missileLeadDistance = 0;
|
||||
|
||||
serviceInterval = 0.33; // how many seconds between pops
|
||||
serviceCharges = 60; // how many charges are in this missile
|
||||
serviceChargeAcceleration = 6.5;
|
||||
dragonSpeed = 100; // meters per second
|
||||
|
||||
defaultAttackProfile = "DRAGON";
|
||||
attackProfiles[] = {"DRAGON"};
|
||||
};
|
||||
};
|
||||
|
||||
class ShellBase;
|
||||
class GVAR(serviceCharge) : ShellBase {
|
||||
hit = 1;
|
||||
indirectHit = 2;
|
||||
indirectHitRange = 1;
|
||||
typicalSpeed = 100;
|
||||
explosive = 1;
|
||||
cost = 300;
|
||||
model = "\A3\Weapons_F\empty.p3d";
|
||||
airFriction = 0;
|
||||
timeToLive = 1;
|
||||
explosionTime = 0.001;
|
||||
soundFly[] = {"",1,1};
|
||||
soundEngine[] = {"",1,4};
|
||||
CraterEffects = "";
|
||||
explosionEffects = QGVAR(serviceExplosion);
|
||||
hitarmor[] = {"soundDefault1", 1};
|
||||
hitbuilding[] = {"soundDefault1", 1};
|
||||
hitconcrete[] = {"soundDefault1", 1};
|
||||
hitdefault[] = {"soundDefault1", 1};
|
||||
hitfoliage[] = {"soundDefault1", 1};
|
||||
hitglass[] = {"soundDefault1", 1};
|
||||
hitglassarmored[] = {"soundDefault1", 1};
|
||||
hitgroundhard[] = {"soundDefault1", 1};
|
||||
hitgroundsoft[] = {"soundDefault1", 1};
|
||||
hitiron[] = {"soundDefault1", 1};
|
||||
hitman[] = {"soundDefault1", 1};
|
||||
hitmetal[] = {"soundDefault1", 1};
|
||||
hitmetalplate[] = {"soundDefault1", 1};
|
||||
hitplastic[] = {"soundDefault1", 1};
|
||||
hitrubber[] = {"soundDefault1", 1};
|
||||
hitwood[] = {"soundDefault1", 1};
|
||||
sounddefault1[] = {QPATHTOF(sounds\service_charge.wss), 56.2341, 1, 1800};
|
||||
soundHit[] = {QPATHTOF(sounds\service_charge.wss),56.23413,1,1800};
|
||||
multiSoundHit[] = {"soundDefault1", 1};
|
||||
};
|
||||
};
|
||||
|
17
addons/dragon/CfgEventHandlers.hpp
Normal file
17
addons/dragon/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,17 @@
|
||||
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));
|
||||
};
|
||||
};
|
16
addons/dragon/CfgMagazines.hpp
Normal file
16
addons/dragon/CfgMagazines.hpp
Normal file
@ -0,0 +1,16 @@
|
||||
class CfgMagazines {
|
||||
class 1Rnd_GAA_missiles;
|
||||
class GVAR(super) : 1Rnd_GAA_missiles {
|
||||
sound[] = {};
|
||||
soundFly[] = {};
|
||||
soundHit[] = {};
|
||||
model = QPATHTOF(models\dragon.p3d);
|
||||
ammo = QGVAR(super);
|
||||
initSpeed = 120;
|
||||
scope = 1;
|
||||
displayName = CSTRING(dragonName);
|
||||
displayNameShort = CSTRING(dragonName);
|
||||
descriptionShort = CSTRING(dragonDescription);
|
||||
};
|
||||
};
|
||||
|
149
addons/dragon/CfgVehicles.hpp
Normal file
149
addons/dragon/CfgVehicles.hpp
Normal file
@ -0,0 +1,149 @@
|
||||
class CfgVehicles {
|
||||
class LandVehicle;
|
||||
class StaticWeapon: LandVehicle {
|
||||
class Turrets;
|
||||
class MainTurret;
|
||||
class ACE_Actions {
|
||||
class ACE_MainActions {};
|
||||
};
|
||||
};
|
||||
|
||||
class StaticATWeapon: StaticWeapon {};
|
||||
|
||||
class GVAR(staticBase): StaticATWeapon {
|
||||
scope = 1;
|
||||
author = ECSTRING(common,ACETeam);
|
||||
displayname = CSTRING(dragonName);
|
||||
side = 1;
|
||||
faction = "BLU_F";
|
||||
crew = "B_soldier_f";
|
||||
model = QPATHTOF(models\ace_m47_static.p3d);
|
||||
picture = "\A3\Static_F_Gamma\data\UI\gear_StaticTurret_AT_CA.paa";
|
||||
UiPicture = "\A3\Static_F_Gamma\data\UI\gear_StaticTurret_AT_CA.paa";
|
||||
icon = "\A3\Static_F_Gamma\data\UI\map_StaticTurret_AT_CA.paa";
|
||||
threat[] = {0.7,1.0,0.1};
|
||||
cost = 150000;
|
||||
class Damage {
|
||||
tex[] = {};
|
||||
mat[] = {
|
||||
"a3\static_f_gamma\data\staticturret_01.rvmat",
|
||||
"a3\static_f_gamma\data\staticturret_01_damage.rvmat",
|
||||
"a3\static_f_gamma\data\staticturret_01_destruct.rvmat",
|
||||
"a3\static_f_gamma\data\staticturret_02.rvmat",
|
||||
"a3\static_f_gamma\data\staticturret_02_damage.rvmat",
|
||||
"a3\static_f_gamma\data\staticturret_02_destruct.rvmat",
|
||||
"a3\weapons_f_beta\launchers\titan\data\titan_launcher.rvmat",
|
||||
"a3\weapons_f_beta\launchers\titan\data\titan_launcher_damage.rvmat",
|
||||
"a3\weapons_f_beta\launchers\titan\data\titan_launcher_destruct.rvmat",
|
||||
"a3\weapons_f_beta\launchers\titan\data\titan_mtube.rvmat",
|
||||
"a3\weapons_f_beta\launchers\titan\data\titan_mtube_damage.rvmat",
|
||||
"a3\weapons_f_beta\launchers\titan\data\titan_mtube_destruct.rvmat"
|
||||
};
|
||||
};
|
||||
class Turrets: Turrets {
|
||||
class MainTurret: MainTurret {
|
||||
optics = 1;
|
||||
turretInfoType = "RscWeaponEmpty";
|
||||
gunnerOpticsModel = QPATHTOF(models\optics_m47.p3d);
|
||||
minElev = -30;
|
||||
maxElev = 20;
|
||||
weapons[] = { QGVAR(dummyStatic) };
|
||||
magazines[] = { QGVAR(super) };
|
||||
|
||||
gunnerAction = "gunner_static_low01";
|
||||
gunnergetInAction = "";
|
||||
gunnergetOutAction = "";
|
||||
|
||||
discreteDistance[] = {};
|
||||
discreteDistanceInitIndex = 0;
|
||||
|
||||
displayName = CSTRING(dragonName);
|
||||
|
||||
class ViewOptics {
|
||||
initAngleX = 0;
|
||||
minAngleX = -30;
|
||||
maxAngleX = 30;
|
||||
initAngleY = 5;
|
||||
minAngleY = -100;
|
||||
maxAngleY = 100;
|
||||
initFov = 0.055;
|
||||
minFov = 0.055; // 6 degree FOV
|
||||
maxFov = 0.055;
|
||||
visionMode[] = {"Normal"};
|
||||
thermalMode[] = {0};
|
||||
};
|
||||
gunnerRightHandAnimName = "OtocHlaven_shake";
|
||||
gunnerLeftHandAnimName = "OtocHlaven_shake";
|
||||
gunBeg = "spice rakety";
|
||||
gunEnd = "konec rakety";
|
||||
memoryPointGunnerOptics = "look";
|
||||
};
|
||||
};
|
||||
class AnimationSources {
|
||||
class rest_rotate {
|
||||
source="user";
|
||||
animPeriod=0.00001;
|
||||
initPhase=-0.35;
|
||||
maxValue="3.60";
|
||||
minValue="-3.60";
|
||||
};
|
||||
class optic_hide {
|
||||
source="user";
|
||||
animPeriod=0.0001;
|
||||
initPhase=1;
|
||||
maxValue="1";
|
||||
minValue="0";
|
||||
};
|
||||
class missile_hide {
|
||||
source="user";
|
||||
animPeriod=0.0001;
|
||||
initPhase=0;
|
||||
maxValue="1";
|
||||
minValue="0";
|
||||
};
|
||||
};
|
||||
soundGetOut[] = {"A3\sounds_f\dummysound",0.001,1,5};
|
||||
soundGetIn[] = {"A3\sounds_f\dummysound",0.00031622776,1,5};
|
||||
armorStructural = 10.0;
|
||||
|
||||
class ACE_CSW {
|
||||
disassembleTo = QGVAR(super);
|
||||
};
|
||||
|
||||
class ACE_Actions: ACE_Actions {
|
||||
class ACE_MainActions: ACE_MainActions {
|
||||
displayName = CSTRING(dragonName);
|
||||
class GVAR(pickUp) {
|
||||
displayName = ECSTRING(csw,Pickup_displayName);
|
||||
condition = QUOTE(call FUNC(canPickupTripod));
|
||||
statement = QUOTE(call EFUNC(csw,assemble_pickupTripod));
|
||||
};
|
||||
class GVAR(attachSight) {
|
||||
displayName = CSTRING(attachSight);
|
||||
condition = QUOTE(call FUNC(sightCanAttach));
|
||||
statement = QUOTE(call FUNC(sightAttach));
|
||||
};
|
||||
class GVAR(detachSight) {
|
||||
displayName = CSTRING(detachSight);
|
||||
condition = QUOTE(call FUNC(sightCanDetach));
|
||||
statement = QUOTE(call FUNC(sightDetach));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
class GVAR(staticAssembled): GVAR(staticBase) {
|
||||
scope = 2;
|
||||
class AnimationSources: AnimationSources {
|
||||
class optic_hide: optic_hide {
|
||||
initPhase = 0;
|
||||
};
|
||||
};
|
||||
class Turrets: Turrets {
|
||||
class MainTurret: MainTurret {
|
||||
weapons[] = { QGVAR(superStatic) };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
90
addons/dragon/CfgWeapons.hpp
Normal file
90
addons/dragon/CfgWeapons.hpp
Normal file
@ -0,0 +1,90 @@
|
||||
class CfgWeapons {
|
||||
class launch_Titan_base;
|
||||
class Launcher_Base_F;
|
||||
class missiles_titan;
|
||||
class Binocular;
|
||||
class Default;
|
||||
class missiles_titan_static: missiles_titan {
|
||||
class WeaponSlotsInfo;
|
||||
};
|
||||
class launch_Titan_F: launch_Titan_base {
|
||||
class WeaponSlotsInfo;
|
||||
};
|
||||
|
||||
class GVAR(super): launch_Titan_F {
|
||||
model = QPATHTOF(models\ace_m47_magazine.p3d);
|
||||
picture = QPATHTOF(data\m47_dragon_item_ca.paa);
|
||||
magazines[] = {};
|
||||
displayName = CSTRING(dragonName);
|
||||
descriptionShort = CSTRING(dragonDescription);
|
||||
scope = 2;
|
||||
|
||||
class ACE_CSW {
|
||||
type = "mount";
|
||||
deployTime = 2;
|
||||
pickupTime = 2;
|
||||
deploy = QGVAR(staticBase);
|
||||
};
|
||||
|
||||
class WeaponSlotsInfo: WeaponSlotsInfo {
|
||||
mass = 253;
|
||||
};
|
||||
modes[] = {};
|
||||
};
|
||||
|
||||
class GVAR(superStatic): missiles_titan_static {
|
||||
EGVAR(overpressure,angle) = 90;
|
||||
EGVAR(overpressure,range) = 30;
|
||||
EGVAR(overpressure,damage) = 0.85;
|
||||
|
||||
initSpeed = 120;
|
||||
|
||||
displayName = CSTRING(dragonName);
|
||||
descriptionShort = CSTRING(dragonDescription);
|
||||
magazines[] = { QGVAR(super) };
|
||||
};
|
||||
|
||||
// need a weapon in order to rotate turret
|
||||
class GVAR(dummyStatic): Default {
|
||||
cursor = "";
|
||||
cursorAim = "";
|
||||
scope = 1;
|
||||
displayName = CSTRING(dragonName);
|
||||
reloadTime = 0;
|
||||
canLock = 0;
|
||||
optics = 0;
|
||||
enableAttack = 0;
|
||||
};
|
||||
|
||||
class GVAR(sight): Binocular {
|
||||
displayName = CSTRING(sightName);
|
||||
model = QPATHTOF(models\ace_m47_optic.p3d);
|
||||
picture = QPATHTOF(data\m47_daysight_item_ca.paa);
|
||||
optics = 1;
|
||||
weaponInfoType = "RscWeaponEmpty";
|
||||
modelOptics = QPATHTOF(models\optics_m47);
|
||||
reloadaction = "";
|
||||
showSwitchAction = 1;
|
||||
useAsBinocular = 1;
|
||||
uipicture = "";
|
||||
descriptionShort = CSTRING(sightDescription);
|
||||
ace_disposable = 0;
|
||||
magazines[] = {};
|
||||
type = 4096;
|
||||
opticsPPEffects[] = {"OpticsCHAbera1","OpticsBlur1"};
|
||||
opticsZoomMin = 0.055;
|
||||
opticsZoomMax = 0.055;
|
||||
scope = 2;
|
||||
class ACE_CSW {
|
||||
type = "weapon";
|
||||
deployTime = 2;
|
||||
pickupTime = 1;
|
||||
class assembleTo {
|
||||
GVAR(super_noSight) = QGVAR(super_sight);
|
||||
};
|
||||
};
|
||||
class WeaponSlotsInfo {
|
||||
mass = 68;
|
||||
};
|
||||
};
|
||||
};
|
12
addons/dragon/README.md
Normal file
12
addons/dragon/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
ace_dragon
|
||||
===================
|
||||
|
||||
Adds M47 Dragon Missile.
|
||||
|
||||
|
||||
## Maintainers
|
||||
|
||||
The people responsible for merging changes to this component or answering potential questions.
|
||||
|
||||
- [Brandon-TCVM](https://github.com/TheCandianVendingMachine)
|
||||
|
7
addons/dragon/XEH_PREP.hpp
Normal file
7
addons/dragon/XEH_PREP.hpp
Normal file
@ -0,0 +1,7 @@
|
||||
PREP(attackProfile_DRAGON);
|
||||
PREP(canPickupTripod);
|
||||
PREP(onFired);
|
||||
PREP(sightAttach);
|
||||
PREP(sightCanAttach);
|
||||
PREP(sightCanDetach);
|
||||
PREP(sightDetach);
|
37
addons/dragon/XEH_postInit.sqf
Normal file
37
addons/dragon/XEH_postInit.sqf
Normal file
@ -0,0 +1,37 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
[QGVAR(detachSight), LINKFUNC(sightDetach)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(attachSight), LINKFUNC(sightAttach)] call CBA_fnc_addEventHandler;
|
||||
|
||||
["vehicle", {
|
||||
params ["","_vehicle"];
|
||||
TRACE_2("vehicle change",_vehicle,typeOf _vehicle);
|
||||
if (!(_vehicle isKindOf QGVAR(staticBase))) exitWith {};
|
||||
|
||||
_vehicle animate ["rest_rotate", 0];
|
||||
|
||||
if (isNil QGVAR(pfID)) then {GVAR(pfID) = -1};
|
||||
[GVAR(pfID)] call CBA_fnc_removePerFrameHandler;
|
||||
|
||||
private _lastView = cameraView;
|
||||
if (!(_lastView in ["INTERNAL", "EXTERNAL"])) then { _lastView == "INTERNAL"; };
|
||||
|
||||
GVAR(pfID) = [{
|
||||
params ["_args"];
|
||||
(_this select 0) params ["_vehicle", "_lastView"];
|
||||
|
||||
if ((!alive _vehicle) || {!alive ACE_player} || {(vehicle ACE_player) != _vehicle}) exitWith {
|
||||
TRACE_1("exiting PFEH",GVAR(pfID));
|
||||
[GVAR(pfID)] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
if (cameraView in ["INTERNAL", "EXTERNAL"]) then {
|
||||
_args set [1, cameraView];
|
||||
} else {
|
||||
if ((cameraOn == _vehicle) && {!(_vehicle getVariable [QGVAR(sightAttached), ((typeOf _vehicle) == QGVAR(staticAssembled))])}) then {
|
||||
_vehicle switchCamera _lastView;
|
||||
};
|
||||
};
|
||||
}, 0, [_vehicle, _lastView]] call CBA_fnc_addPerFrameHandler;
|
||||
TRACE_1("started PFEH",GVAR(pfID));
|
||||
}, true] call CBA_fnc_addPlayerEventHandler;
|
10
addons/dragon/XEH_preInit.sqf
Normal file
10
addons/dragon/XEH_preInit.sqf
Normal file
@ -0,0 +1,10 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
ADDON = false;
|
||||
|
||||
PREP_RECOMPILE_START;
|
||||
#include "XEH_PREP.hpp"
|
||||
PREP_RECOMPILE_END;
|
||||
|
||||
ADDON = true;
|
||||
|
4
addons/dragon/XEH_preStart.sqf
Normal file
4
addons/dragon/XEH_preStart.sqf
Normal file
@ -0,0 +1,4 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
#include "XEH_PREP.hpp"
|
||||
|
BIN
addons/dragon/anim/M47.rtm
Normal file
BIN
addons/dragon/anim/M47.rtm
Normal file
Binary file not shown.
119
addons/dragon/anim/model.cfg
Normal file
119
addons/dragon/anim/model.cfg
Normal file
@ -0,0 +1,119 @@
|
||||
class cfgSkeletons {
|
||||
class OFP2_ManSkeleton {
|
||||
isDiscrete = 0;
|
||||
skeletonInherit = "";
|
||||
skeletonBones[] = {
|
||||
"Pelvis","",
|
||||
"Spine","Pelvis",
|
||||
"Spine1","Spine",
|
||||
"Spine2","Spine1",
|
||||
"Spine3","Spine2",
|
||||
"camera","Pelvis",// case has changed for arma3
|
||||
"weapon","Spine1",
|
||||
"launcher","Spine1",
|
||||
"Neck","Spine3",
|
||||
"Neck1","Neck",
|
||||
"Head","Neck1", //Head skeleton in hierarchy
|
||||
//Left upper side
|
||||
"LeftShoulder","Spine3",
|
||||
"LeftArm","LeftShoulder",
|
||||
"LeftArmRoll","LeftArm",
|
||||
"LeftForeArm","LeftArmRoll",
|
||||
"LeftForeArmRoll","LeftForeArm",
|
||||
"LeftHand","LeftForeArmRoll",
|
||||
"LeftHandRing","LeftHand",
|
||||
"LeftHandRing1","LeftHandRing",
|
||||
"LeftHandRing2","LeftHandRing1",
|
||||
"LeftHandRing3","LeftHandRing2",
|
||||
"LeftHandPinky1","LeftHandRing",
|
||||
"LeftHandPinky2","LeftHandPinky1",
|
||||
"LeftHandPinky3","LeftHandPinky2",
|
||||
"LeftHandMiddle1","LeftHand",
|
||||
"LeftHandMiddle2","LeftHandMiddle1",
|
||||
"LeftHandMiddle3","LeftHandMiddle2",
|
||||
"LeftHandIndex1","LeftHand",
|
||||
"LeftHandIndex2","LeftHandIndex1",
|
||||
"LeftHandIndex3","LeftHandIndex2",
|
||||
"LeftHandThumb1","LeftHand",
|
||||
"LeftHandThumb2","LeftHandThumb1",
|
||||
"LeftHandThumb3","LeftHandThumb2",
|
||||
//Right upper side
|
||||
"RightShoulder","Spine3",
|
||||
"RightArm","RightShoulder",
|
||||
"RightArmRoll","RightArm",
|
||||
"RightForeArm","RightArmRoll",
|
||||
"RightForeArmRoll","RightForeArm",
|
||||
"RightHand","RightForeArmRoll",
|
||||
"RightHandRing","RightHand",
|
||||
"RightHandRing1","RightHandRing",
|
||||
"RightHandRing2","RightHandRing1",
|
||||
"RightHandRing3","RightHandRing2",
|
||||
"RightHandPinky1","RightHandRing",
|
||||
"RightHandPinky2","RightHandPinky1",
|
||||
"RightHandPinky3","RightHandPinky2",
|
||||
"RightHandMiddle1","RightHand",
|
||||
"RightHandMiddle2","RightHandMiddle1",
|
||||
"RightHandMiddle3","RightHandMiddle2",
|
||||
"RightHandIndex1","RightHand",
|
||||
"RightHandIndex2","RightHandIndex1",
|
||||
"RightHandIndex3","RightHandIndex2",
|
||||
"RightHandThumb1","RightHand",
|
||||
"RightHandThumb2","RightHandThumb1",
|
||||
"RightHandThumb3","RightHandThumb2",
|
||||
//Left lower side
|
||||
"LeftUpLeg","Pelvis",
|
||||
"LeftUpLegRoll","LeftUpLeg",
|
||||
"LeftLeg","LeftUpLegRoll",
|
||||
"LeftLegRoll","LeftLeg",
|
||||
"LeftFoot","LeftLegRoll",
|
||||
"LeftToeBase","LeftFoot",
|
||||
//Right lower side
|
||||
"RightUpLeg","Pelvis",
|
||||
"RightUpLegRoll","RightUpLeg",
|
||||
"RightLeg","RightUpLegRoll",
|
||||
"RightLegRoll","RightLeg",
|
||||
"RightFoot","RightLegRoll",
|
||||
"RightToeBase","RightFoot",
|
||||
//New facial features arma3 only
|
||||
"Face_Hub","Head",
|
||||
"Face_Jawbone","Face_Hub",
|
||||
"Face_Jowl","Face_Jawbone",
|
||||
"Face_chopRight","Face_Jawbone",
|
||||
"Face_chopLeft","Face_Jawbone",
|
||||
"Face_LipLowerMiddle","Face_Jawbone",
|
||||
"Face_LipLowerLeft","Face_Jawbone",
|
||||
"Face_LipLowerRight","Face_Jawbone",
|
||||
"Face_Chin","Face_Jawbone",
|
||||
"Face_Tongue","Face_Jawbone",
|
||||
"Face_CornerRight","Face_Hub",
|
||||
"Face_CheekSideRight","Face_CornerRight",
|
||||
"Face_CornerLeft","Face_Hub",
|
||||
"Face_CheekSideLeft","Face_CornerLeft",
|
||||
"Face_CheekFrontRight","Face_Hub",
|
||||
"Face_CheekFrontLeft","Face_Hub",
|
||||
"Face_CheekUpperRight","Face_Hub",
|
||||
"Face_CheekUpperLeft","Face_Hub",
|
||||
"Face_LipUpperMiddle","Face_Hub",
|
||||
"Face_LipUpperRight","Face_Hub",
|
||||
"Face_LipUpperLeft","Face_Hub",
|
||||
"Face_NostrilRight","Face_Hub",
|
||||
"Face_NostrilLeft","Face_Hub",
|
||||
"Face_Forehead","Face_Hub",
|
||||
"Face_BrowFrontRight","Face_Forehead",
|
||||
"Face_BrowFrontLeft","Face_Forehead",
|
||||
"Face_BrowMiddle","Face_Forehead",
|
||||
"Face_BrowSideRight","Face_Forehead",
|
||||
"Face_BrowSideLeft","Face_Forehead",
|
||||
"Face_Eyelids","Face_Hub",
|
||||
"Face_EyelidUpperRight","Face_Hub",
|
||||
"Face_EyelidUpperLeft","Face_Hub",
|
||||
"Face_EyelidLowerRight","Face_Hub",
|
||||
"Face_EyelidLowerLeft","Face_Hub",
|
||||
"EyeLeft","Face_Hub",
|
||||
"EyeRight","Face_Hub"
|
||||
};// end of skeleton array
|
||||
// location of pivot points (local axes) for hierarchical animation
|
||||
pivotsModel="A3\anims_f\data\skeleton\SkeletonPivots.p3d";
|
||||
};
|
||||
};
|
||||
|
42
addons/dragon/config.cpp
Normal file
42
addons/dragon/config.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
name = COMPONENT_NAME;
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ace_common","ace_missileguidance","ace_hot","ace_csw"};
|
||||
author = ECSTRING(common,ACETeam);
|
||||
authors[] = {"Brandon (TCVM)"};
|
||||
url = ECSTRING(main,URL);
|
||||
VERSION_CONFIG;
|
||||
};
|
||||
};
|
||||
|
||||
#include "ACE_GuidanceConfig.hpp"
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "CfgWeapons.hpp"
|
||||
#include "CfgMagazines.hpp"
|
||||
#include "CfgAmmo.hpp"
|
||||
#include "CfgVehicles.hpp"
|
||||
|
||||
class GVAR(serviceExplosion) {
|
||||
class Light1 {
|
||||
simulation = "light";
|
||||
type = "GrenadeExploLight";
|
||||
position[] = {0,0,0};
|
||||
intensity = 0.005;
|
||||
interval = 1;
|
||||
lifeTime = 0.5;
|
||||
};
|
||||
class GrenadeSmoke1 {
|
||||
simulation = "particles";
|
||||
type = "ImpactSmoke2";
|
||||
position[] = {0,0,0};
|
||||
intensity = 0.15;
|
||||
interval = 0.1;
|
||||
lifeTime = 0.5;
|
||||
};
|
||||
};
|
||||
|
81
addons/dragon/data/M47.rvmat
Normal file
81
addons/dragon/data/M47.rvmat
Normal file
@ -0,0 +1,81 @@
|
||||
class StageTI {
|
||||
texture="z\ace\addons\dragon\data\m47_ti_ca.paa";
|
||||
};
|
||||
ambient[]={0.958,0.984,1,1};
|
||||
diffuse[]={0.958,0.984,1,1};
|
||||
forcedDiffuse[]={0,0,0,0};
|
||||
emmisive[]={0,0,0,1};
|
||||
specular[]={0.153,0.169,0.111,1};
|
||||
specularPower=90;
|
||||
PixelShaderID="Super";
|
||||
VertexShaderID="Super";
|
||||
class Stage1 {
|
||||
texture="z\ace\addons\dragon\data\m47_nohq.paa";
|
||||
uvSource="tex";
|
||||
class uvTransform {
|
||||
aside[]={1,0,0};
|
||||
up[]={0,1,0};
|
||||
dir[]={0,0,1};
|
||||
pos[]={0,0,0};
|
||||
};
|
||||
};
|
||||
class Stage2 {
|
||||
texture="a3\weapons_f\Data\DetailMaps\Metal_rough_DT.paa";
|
||||
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="z\ace\addons\dragon\data\m47_as.paa";
|
||||
uvSource="tex";
|
||||
class uvTransform {
|
||||
aside[]={1,0,0};
|
||||
up[]={0,1,0};
|
||||
dir[]={0,0,1};
|
||||
pos[]={0,0,0};
|
||||
};
|
||||
};
|
||||
class Stage5 {
|
||||
texture="z\ace\addons\dragon\data\m47_smdi.paa";
|
||||
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(4.01,2.86)";
|
||||
uvSource="tex";
|
||||
class uvTransform {
|
||||
aside[]={1,0,0};
|
||||
up[]={0,1,0};
|
||||
dir[]={0,0,1};
|
||||
pos[]={0,0,0};
|
||||
};
|
||||
};
|
||||
class Stage7 {
|
||||
texture="a3\data_f\env_land_co.paa";
|
||||
uvSource="tex";
|
||||
class uvTransform {
|
||||
aside[]={1,0,0};
|
||||
up[]={0,1,0};
|
||||
dir[]={0,0,1};
|
||||
pos[]={0,0,0};
|
||||
};
|
||||
};
|
81
addons/dragon/data/M47mis.rvmat
Normal file
81
addons/dragon/data/M47mis.rvmat
Normal file
@ -0,0 +1,81 @@
|
||||
class StageTI {
|
||||
texture="z\ace\addons\dragon\data\m47_ti_ca.paa";
|
||||
};
|
||||
ambient[]={0.989,1,0.958,1};
|
||||
diffuse[]={0.989,1,0.958,1};
|
||||
forcedDiffuse[]={0,0,0,0};
|
||||
emmisive[]={0,0,0,1};
|
||||
specular[]={0.159,0.212,0.196,1};
|
||||
specularPower=90;
|
||||
PixelShaderID="Super";
|
||||
VertexShaderID="Super";
|
||||
class Stage1 {
|
||||
texture="z\ace\addons\dragon\data\m47mis_nohq.paa";
|
||||
uvSource="tex";
|
||||
class uvTransform {
|
||||
aside[]={1,0,0};
|
||||
up[]={0,1,0};
|
||||
dir[]={0,0,1};
|
||||
pos[]={0,0,0};
|
||||
};
|
||||
};
|
||||
class Stage2 {
|
||||
texture="a3\weapons_f\Data\DetailMaps\Metal_rough_DT.paa";
|
||||
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="z\ace\addons\dragon\data\m47mis_smdi.paa";
|
||||
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(4.01,2.86)";
|
||||
uvSource="tex";
|
||||
class uvTransform {
|
||||
aside[]={1,0,0};
|
||||
up[]={0,1,0};
|
||||
dir[]={0,0,1};
|
||||
pos[]={0,0,0};
|
||||
};
|
||||
};
|
||||
class Stage7 {
|
||||
texture="a3\data_f\env_land_co.paa";
|
||||
uvSource="tex";
|
||||
class uvTransform {
|
||||
aside[]={1,0,0};
|
||||
up[]={0,1,0};
|
||||
dir[]={0,0,1};
|
||||
pos[]={0,0,0};
|
||||
};
|
||||
};
|
BIN
addons/dragon/data/dragon_text.paa
Normal file
BIN
addons/dragon/data/dragon_text.paa
Normal file
Binary file not shown.
BIN
addons/dragon/data/m47_as.paa
Normal file
BIN
addons/dragon/data/m47_as.paa
Normal file
Binary file not shown.
BIN
addons/dragon/data/m47_co.paa
Normal file
BIN
addons/dragon/data/m47_co.paa
Normal file
Binary file not shown.
BIN
addons/dragon/data/m47_daysight_item_ca.paa
Normal file
BIN
addons/dragon/data/m47_daysight_item_ca.paa
Normal file
Binary file not shown.
BIN
addons/dragon/data/m47_dragon_item_ca.paa
Normal file
BIN
addons/dragon/data/m47_dragon_item_ca.paa
Normal file
Binary file not shown.
BIN
addons/dragon/data/m47_nohq.paa
Normal file
BIN
addons/dragon/data/m47_nohq.paa
Normal file
Binary file not shown.
BIN
addons/dragon/data/m47_smdi.paa
Normal file
BIN
addons/dragon/data/m47_smdi.paa
Normal file
Binary file not shown.
BIN
addons/dragon/data/m47_ti_ca.paa
Normal file
BIN
addons/dragon/data/m47_ti_ca.paa
Normal file
Binary file not shown.
BIN
addons/dragon/data/m47mis_co.paa
Normal file
BIN
addons/dragon/data/m47mis_co.paa
Normal file
Binary file not shown.
BIN
addons/dragon/data/m47mis_nohq.paa
Normal file
BIN
addons/dragon/data/m47mis_nohq.paa
Normal file
Binary file not shown.
BIN
addons/dragon/data/m47mis_smdi.paa
Normal file
BIN
addons/dragon/data/m47mis_smdi.paa
Normal file
Binary file not shown.
77
addons/dragon/functions/fnc_attackProfile_DRAGON.sqf
Normal file
77
addons/dragon/functions/fnc_attackProfile_DRAGON.sqf
Normal file
@ -0,0 +1,77 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM) (Code inspired by NouberNou's Dragon Guidance)
|
||||
* Attack profile: Dragon Guidance
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Seeker Target PosASL <ARRAY>
|
||||
* 1: Guidance Arg Array <ARRAY>
|
||||
* 2: Attack Profile State <ARRAY>
|
||||
*
|
||||
* Return Value:
|
||||
* Missile Aim PosASL <ARRAY> - Unused
|
||||
*
|
||||
* Example:
|
||||
* [[1,2,3], [], []] call ace_dragon_fnc_attackProfile_DRAGON;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params ["_seekerTargetPos", "_args", "_attackProfileStateParams"];
|
||||
_args params ["_firedEH", "", "", "", "_stateParams"];
|
||||
_firedEH params ["_shooter","_weapon","","","","","_projectile"];
|
||||
_attackProfileStateParams params ["_maxCorrectableDistance", "_wireCut", "_seekerMaxRangeSqr", "_seekerMinRangeSqr", "_wireCutSource", "_lastTime", "_serviceInterval", "_serviceChargeCount", "_serviceChargeAcceleration", "_dragonSpeed"];
|
||||
|
||||
private _projectilePos = getPosASL _projectile;
|
||||
private _distanceToProjectile = (getPosASL _shooter) vectorDistanceSqr _projectilePos;
|
||||
private _retPos = _projectilePos vectorAdd (AGLtoASL (_projectile vectorModelToWorld [0, 50, 0]));
|
||||
|
||||
// _shooter returns the vehicle that shot it. If the launcher dies, the wire would probably be cut so assume it
|
||||
if ((_distanceToProjectile > _seekerMaxRangeSqr) || _wireCut || { !alive _shooter }) exitWith {
|
||||
// wire snap, random direction
|
||||
if (!_wireCut) then {
|
||||
_attackProfileStateParams set [1, true];
|
||||
playSound3D ["a3\sounds_f\air\sfx\SL_rope_break.wss", objNull, false, AGLtoASL (_shooter modelToWorld _wireCutSource), 150, 1, 25];
|
||||
};
|
||||
|
||||
if (_serviceChargeCount > 0 && {(_lastTime - CBA_missionTime) <= 0}) then {
|
||||
_attackProfileStateParams set [5, CBA_missionTime + 0.05 + random 0.1];
|
||||
private _randomVector = [(random 2) - 1, random 1, (random 2) - 1];
|
||||
_projectile setVelocityModelSpace ((velocityModelSpace _projectile) vectorAdd (_randomVector vectorMultiply _serviceChargeAcceleration));
|
||||
private _charge = createVehicle [QGVAR(serviceCharge), [0, 0, 0], [], 0, "NONE"];
|
||||
_charge setPosASL (_projectilePos vectorAdd ((_randomVector vectorMultiply -1) vectorMultiply 0.025));
|
||||
_attackProfileStateParams set [7, _serviceChargeCount - 1];
|
||||
};
|
||||
|
||||
_retPos
|
||||
};
|
||||
|
||||
if (_distanceToProjectile <= _seekerMinRangeSqr || { _serviceChargeCount <= 0 } || { !(_shooter getVariable [QGVAR(sightAttached), true]) }) exitWith { _retPos };
|
||||
|
||||
// if the time between updates is less than the pop time we want to fire the rockets OR if the missile wants to make a major correction pop it rapidly
|
||||
if (((_lastTime - CBA_missionTime) <= 0) || {(_lastTime - CBA_missionTime) < (_serviceInterval / 2) && (_projectilePos vectorDistance _seekerTargetPos > 1)}) then {
|
||||
_attackProfileStateParams set [5, CBA_missionTime + _serviceInterval];
|
||||
|
||||
private _vectorToCrosshair = vectorNormalized (_projectile worldToModel (ASLToAGL _seekerTargetPos));
|
||||
private _vectorToPos = vectorNormalized (((_projectile vectorWorldToModelVisual (_shooter weaponDirection _weapon)) vectorMultiply (_dragonSpeed * _serviceInterval)) vectorAdd (_vectorToCrosshair vectorMultiply _maxCorrectableDistance));
|
||||
|
||||
if ((_vectorToPos select 2) < 0) then {
|
||||
_vectorToPos set [2, 0];
|
||||
} else {
|
||||
private _a = _vectorToPos select 1;
|
||||
private _b = _vectorToPos select 2;
|
||||
// The booster has some angle to it, so we introduce that axis if the angle is too low
|
||||
if (abs(_a) > 0 && { abs(atan (_b / _a)) < DRAGON_BOOSTER_ANGLE }) then {
|
||||
_vectorToPos set [2, abs(_a)];
|
||||
};
|
||||
};
|
||||
|
||||
_projectile setVelocityModelSpace ((velocityModelSpace _projectile) vectorAdd (_vectorToPos vectorMultiply _serviceChargeAcceleration));
|
||||
|
||||
private _charge = createVehicle [QGVAR(serviceCharge), [0, 0, 0], [], 0, "NONE"];
|
||||
_charge setPosASL (_projectilePos vectorAdd ((_vectorToCrosshair vectorMultiply -1) vectorMultiply 0.025));
|
||||
|
||||
_attackProfileStateParams set [7, _serviceChargeCount - 1];
|
||||
};
|
||||
|
||||
_retPos
|
||||
|
25
addons/dragon/functions/fnc_canPickupTripod.sqf
Normal file
25
addons/dragon/functions/fnc_canPickupTripod.sqf
Normal file
@ -0,0 +1,25 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Determines if you can pick-up the Dragon missile. If the missile was fired you will not be able to pick up the tripod.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Target <OBJECT>
|
||||
* 1: Unit Performing Action <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can Pickup Tripod <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [vehicle player, player] call ace_dragon_fnc_canPickupTripod;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params ["_target", "_unit"];
|
||||
|
||||
(alive _target)
|
||||
&& {!alive (gunner _target)}
|
||||
&& {!(_target getVariable [QGVAR(fired), false])}
|
||||
&& {!(_target getVariable [QGVAR(sightAttached), ((typeOf _target) == QGVAR(staticAssembled))])}
|
||||
&& EFUNC(csw,assemble_canPickupTripod)
|
||||
|
53
addons/dragon/functions/fnc_onFired.sqf
Normal file
53
addons/dragon/functions/fnc_onFired.sqf
Normal file
@ -0,0 +1,53 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Runs when Dragon is fired
|
||||
*
|
||||
* Arguments:
|
||||
* 0: None
|
||||
* 1: The weapon that was fired <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [any, vehicle player] call ace_dragon_fnc_onFired;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params ["_firedEH", "", "", "_seekerParams", "_stateParams"];
|
||||
_firedEH params ["_shooter","_weapon","","","","","_projectile"];
|
||||
_stateParams params ["", "", "_attackProfileStateParams"];
|
||||
_seekerParams params ["", "", "_seekerMaxRange", "_seekerMinRange"];
|
||||
|
||||
_shooter setVariable [QGVAR(fired), true, true];
|
||||
_shooter animate ["missile_hide", 1];
|
||||
|
||||
private _config = ([_projectile] call CBA_fnc_getObjectConfig) >> "ace_missileguidance";
|
||||
|
||||
private _serviceInterval = [_config >> "serviceInterval", "NUMBER", 0.33] call CBA_fnc_getConfigEntry;
|
||||
private _serviceChargeCount = [_config >> "serviceCharges", "NUMBER", 60] call CBA_fnc_getConfigEntry;
|
||||
private _serviceChargeAcceleration = [_config >> "serviceChargeAcceleration", "NUMBER", 6.5] call CBA_fnc_getConfigEntry;
|
||||
private _dragonSpeed = [_config >> "dragonSpeed", "NUMBER", 100] call CBA_fnc_getConfigEntry;
|
||||
private _maxCorrectableDistance = [_config >> "correctionDistance", "NUMBER", DEFAULT_CORRECTION_DISTANCE] call CBA_fnc_getConfigEntry;
|
||||
private _maxDistanceSqr = _seekerMaxRange * _seekerMaxRange;
|
||||
private _minDistanceSqr = _seekerMinRange * _seekerMinRange;
|
||||
|
||||
private _turretPath = [_shooter, _weapon] call CBA_fnc_turretPathWeapon;
|
||||
private _turretConfig = [_shooter, _turretPath] call CBA_fnc_getTurret;
|
||||
|
||||
private _wireCutSource = _shooter selectionPosition getText(_turretConfig >> "missileEnd");
|
||||
|
||||
_attackProfileStateParams append [
|
||||
_maxCorrectableDistance,
|
||||
false,
|
||||
_maxDistanceSqr,
|
||||
_minDistanceSqr,
|
||||
_wireCutSource,
|
||||
CBA_missionTime,
|
||||
_serviceInterval,
|
||||
_serviceChargeCount,
|
||||
_serviceChargeAcceleration,
|
||||
_dragonSpeed
|
||||
];
|
||||
|
32
addons/dragon/functions/fnc_sightAttach.sqf
Normal file
32
addons/dragon/functions/fnc_sightAttach.sqf
Normal file
@ -0,0 +1,32 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Attaches the sighting unit to the Dragon missile.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Target <OBJECT>
|
||||
* 1: Unit Performing Action <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can Attach Sighting Unit <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject, player] call ace_dragon_fnc_sightAttach
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_target", "_unit", ["_event", false]];
|
||||
TRACE_3("sightAttach",_target,_unit,_event);
|
||||
|
||||
if (_event isEqualTo true) then {
|
||||
if (!(_target turretLocal [0])) exitWith {};
|
||||
_target setVariable [QGVAR(sightAttached), true, true];
|
||||
_target animate ["optic_hide", 0];
|
||||
_target addWeapon QGVAR(superStatic);
|
||||
_target removeWeapon QGVAR(dummyStatic);
|
||||
TRACE_2("added sight",_target weaponsTurret [0],_target animationPhase "optic_hide");
|
||||
} else {
|
||||
_unit removeWeapon QGVAR(sight);
|
||||
[QGVAR(attachSight), [_target, _unit, true]] call CBA_fnc_globalEvent;
|
||||
};
|
24
addons/dragon/functions/fnc_sightCanAttach.sqf
Normal file
24
addons/dragon/functions/fnc_sightCanAttach.sqf
Normal file
@ -0,0 +1,24 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Determines if you can attach the sighting unit to the Dragon missile.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Target <OBJECT>
|
||||
* 1: Unit Performing Action <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can Attach Sighting Unit <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject, player] call ace_dragon_fnc_sightCanAttach
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_target", "_unit"];
|
||||
|
||||
(alive _target)
|
||||
// && {!(_target getVariable [QGVAR(fired), false])}
|
||||
&& {!(_target getVariable [QGVAR(sightAttached), ((typeOf _target) == QGVAR(staticAssembled))])}
|
||||
&& {QGVAR(sight) in (weapons _unit)}
|
23
addons/dragon/functions/fnc_sightCanDetach.sqf
Normal file
23
addons/dragon/functions/fnc_sightCanDetach.sqf
Normal file
@ -0,0 +1,23 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Determines if you can attach the sighting unit to the Dragon missile.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Target <OBJECT>
|
||||
* 1: Unit Performing Action <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can Attach Sighting Unit <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject, player] call ace_dragon_fnc_sightCanDetach
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_target", "_unit"];
|
||||
|
||||
(alive _target)
|
||||
// && {!(_target getVariable [QGVAR(fired), false])}
|
||||
&& {_target getVariable [QGVAR(sightAttached), ((typeOf _target) == QGVAR(staticAssembled))]}
|
38
addons/dragon/functions/fnc_sightDetach.sqf
Normal file
38
addons/dragon/functions/fnc_sightDetach.sqf
Normal file
@ -0,0 +1,38 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Attaches the sighting unit to the Dragon missile.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Target <OBJECT>
|
||||
* 1: Unit Performing Action <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can Attach Sighting Unit <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject, player] call ace_dragon_fnc_sightDetach;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_target", "_unit"];
|
||||
|
||||
params ["_target", "_unit", ["_event", false]];
|
||||
TRACE_3("sightDetach",_target,_unit,_event);
|
||||
|
||||
if (_event isEqualTo true) then {
|
||||
if (!(_target turretLocal [0])) exitWith {};
|
||||
_target setVariable [QGVAR(sightAttached), false, true];
|
||||
_target animate ["optic_hide", 1];
|
||||
_target removeWeapon QGVAR(superStatic);
|
||||
_target addWeapon QGVAR(dummyStatic);
|
||||
TRACE_2("removed sight",_target weaponsTurret [0],_target animationPhase "optic_hide");
|
||||
} else {
|
||||
if ((binocular _unit) == "") then {
|
||||
_unit addWeapon QGVAR(sight);
|
||||
} else {
|
||||
[_unit, QGVAR(sight)] call EFUNC(common,addToInventory);
|
||||
};
|
||||
[QGVAR(detachSight), [_target, _unit, true]] call CBA_fnc_globalEvent;
|
||||
};
|
1
addons/dragon/functions/script_component.hpp
Normal file
1
addons/dragon/functions/script_component.hpp
Normal file
@ -0,0 +1 @@
|
||||
#include "\z\ace\addons\dragon\script_component.hpp"
|
BIN
addons/dragon/models/M47.p3d
Normal file
BIN
addons/dragon/models/M47.p3d
Normal file
Binary file not shown.
BIN
addons/dragon/models/M47_loaded.p3d
Normal file
BIN
addons/dragon/models/M47_loaded.p3d
Normal file
Binary file not shown.
BIN
addons/dragon/models/ace_m47_magazine.p3d
Normal file
BIN
addons/dragon/models/ace_m47_magazine.p3d
Normal file
Binary file not shown.
BIN
addons/dragon/models/ace_m47_optic.p3d
Normal file
BIN
addons/dragon/models/ace_m47_optic.p3d
Normal file
Binary file not shown.
BIN
addons/dragon/models/ace_m47_static.p3d
Normal file
BIN
addons/dragon/models/ace_m47_static.p3d
Normal file
Binary file not shown.
BIN
addons/dragon/models/dragon.p3d
Normal file
BIN
addons/dragon/models/dragon.p3d
Normal file
Binary file not shown.
94
addons/dragon/models/model.cfg
Normal file
94
addons/dragon/models/model.cfg
Normal file
@ -0,0 +1,94 @@
|
||||
class CfgSkeletons {
|
||||
class Default {
|
||||
isDiscrete = 1;
|
||||
skeletonInherit = "";
|
||||
skeletonBones[] = {};
|
||||
};
|
||||
|
||||
class ace_m47_static_skeleton: Default {
|
||||
skeletonInherit = "Default";
|
||||
skeletonBones[] = {
|
||||
"bipod","",
|
||||
"grav_box","bipod",
|
||||
"launcher","grav_box",
|
||||
"optic","launcher",
|
||||
"missile","launcher"
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class CfgModels {
|
||||
class Default {
|
||||
sectionsInherit = "";
|
||||
sections[] = {};
|
||||
};
|
||||
|
||||
class ace_m47_static: Default {
|
||||
sectionsInherit = "Default";
|
||||
sections[] = {};
|
||||
skeletonName = "ace_m47_static_skeleton";
|
||||
class Animations {
|
||||
class MainGun {
|
||||
type="rotation";
|
||||
selection="launcher";
|
||||
sourceAddress = "clamp";
|
||||
source="MainGun";
|
||||
axis="elevate_axis";
|
||||
animPeriod=0.01;
|
||||
initPhase=0;
|
||||
maxValue="rad 360";
|
||||
minValue="rad -360";
|
||||
angle1="rad 360";
|
||||
angle0="rad -360";
|
||||
};
|
||||
class MainTurret {
|
||||
type="rotation";
|
||||
source="MainTurret";
|
||||
selection="bipod";
|
||||
sourceAddress = "loop";
|
||||
axis="rotate_axis";
|
||||
animPeriod=0.005;
|
||||
minValue="rad -360";
|
||||
maxValue="rad +360";
|
||||
angle0="rad -360";
|
||||
angle1="rad +360";
|
||||
};
|
||||
class rest_rotate {
|
||||
type="rotation";
|
||||
selection="grav_box";
|
||||
sourceAddress = "clamp";
|
||||
source="user";
|
||||
axis="elevate_axis";
|
||||
animPeriod=0.00001;
|
||||
initPhase=-0.35;
|
||||
maxValue="3.60";
|
||||
minValue="-3.60";
|
||||
angle1="rad -360";
|
||||
angle0="rad 360";
|
||||
};
|
||||
class optic_hide {
|
||||
type = "hide";
|
||||
source = "user";
|
||||
selection = "optic";
|
||||
animPeriod = 0.0001;
|
||||
minValue = 0;
|
||||
maxValue = 1;
|
||||
minPhase = 0;
|
||||
maxPhase = 1;
|
||||
hideValue = 0.99;
|
||||
initPhase = 1;
|
||||
};
|
||||
class missile_hide {
|
||||
type = "hide";
|
||||
source = "user";
|
||||
selection = "missile";
|
||||
animPeriod = 0.0001;
|
||||
minValue = 0;
|
||||
maxValue = 1;
|
||||
minPhase = 0;
|
||||
maxPhase = 1;
|
||||
hideValue = 0.99;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
BIN
addons/dragon/models/optics_m47.p3d
Normal file
BIN
addons/dragon/models/optics_m47.p3d
Normal file
Binary file not shown.
18
addons/dragon/script_component.hpp
Normal file
18
addons/dragon/script_component.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#define COMPONENT dragon
|
||||
#define COMPONENT_BEAUTIFIED M47 Dragon
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
// #define DEBUG_MODE_FULL
|
||||
// #define DISABLE_COMPILE_CACHE
|
||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||
|
||||
#ifdef DEBUG_ENABLED_DRAGON
|
||||
#define DEBUG_MODE_FULL
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SETTINGS_DRAGON
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_DRAGON
|
||||
#endif
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
#define DRAGON_BOOSTER_ANGLE 45
|
BIN
addons/dragon/sounds/M47_1.wss
Normal file
BIN
addons/dragon/sounds/M47_1.wss
Normal file
Binary file not shown.
BIN
addons/dragon/sounds/M47_2.wss
Normal file
BIN
addons/dragon/sounds/M47_2.wss
Normal file
Binary file not shown.
BIN
addons/dragon/sounds/dry.wss
Normal file
BIN
addons/dragon/sounds/dry.wss
Normal file
Binary file not shown.
BIN
addons/dragon/sounds/rocket_fly.wss
Normal file
BIN
addons/dragon/sounds/rocket_fly.wss
Normal file
Binary file not shown.
BIN
addons/dragon/sounds/rocket_reload.wss
Normal file
BIN
addons/dragon/sounds/rocket_reload.wss
Normal file
Binary file not shown.
BIN
addons/dragon/sounds/service_charge.wss
Normal file
BIN
addons/dragon/sounds/service_charge.wss
Normal file
Binary file not shown.
29
addons/dragon/stringtable.xml
Normal file
29
addons/dragon/stringtable.xml
Normal file
@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project name="ACE">
|
||||
<Package name="dragon">
|
||||
<Key ID="STR_ACE_dragon_dragonName">
|
||||
<English>M47 Super-Dragon</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_dragon_dragonNoSight">
|
||||
<English>M47 Super-Dragon (No Sight)</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_dragon_dragonSight">
|
||||
<English>M47 Super-Dragon (With Sight)</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_dragon_attachSight">
|
||||
<English>Attach Sight</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_dragon_detachSight">
|
||||
<English>Detach Sight</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_dragon_sightName">
|
||||
<English>SU-36/P Daysight</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_dragon_sightDescription">
|
||||
<English>A light, cheap sight used for daytime operations. Contains the guidance computer for the whole system</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_dragon_dragonDescription">
|
||||
<English>A Wire-Guided SACLOS missile with a unique flight characteristic</English>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
@ -5,6 +5,7 @@ class EGVAR(missileguidance,AttackProfiles) {
|
||||
description = CSTRING(missileType_Description);
|
||||
|
||||
functionName = QFUNC(attackProfile_WIRE);
|
||||
onFired = QFUNC(wire_onFired);
|
||||
};
|
||||
};
|
||||
class EGVAR(missileguidance,SeekerTypes) {
|
||||
@ -14,6 +15,7 @@ class EGVAR(missileguidance,SeekerTypes) {
|
||||
description = CSTRING(SACLOS_Description);
|
||||
|
||||
functionName = QFUNC(seekerType_SACLOS);
|
||||
onFired = QFUNC(SACLOS_onFired);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -70,8 +70,6 @@ class CfgAmmo {
|
||||
defaultSeekerLockMode = "LOAL";
|
||||
seekerLockModes[] = { "LOAL", "LOBL" };
|
||||
|
||||
onFired = QFUNC(onFired);
|
||||
|
||||
seekLastTargetPos = 0; // seek last target position [if seeker loses LOS of target, continue to last known pos]
|
||||
seekerAngle = 30; // Angle from the shooter's view that can track the missile
|
||||
seekerAccuracy = 1; // seeker accuracy multiplier
|
||||
|
@ -1,4 +1,5 @@
|
||||
PREP(seekerType_SACLOS);
|
||||
PREP(attackProfile_WIRE);
|
||||
PREP(onFired);
|
||||
PREP(wire_onFired);
|
||||
PREP(SACLOS_onFired);
|
||||
|
||||
|
35
addons/hot/functions/fnc_SACLOS_onFired.sqf
Normal file
35
addons/hot/functions/fnc_SACLOS_onFired.sqf
Normal file
@ -0,0 +1,35 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Sets up SACLOS state arrays (called from missileGuidance's onFired).
|
||||
*
|
||||
* Arguments:
|
||||
* Guidance Arg Array <ARRAY>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_hot_fnc_SACLOS_onFired
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params ["_firedEH", "", "", "", "_stateParams"];
|
||||
_firedEH params ["_shooter","_weapon","","","","","_projectile"];
|
||||
_stateParams params ["", "_seekerStateParams"];
|
||||
|
||||
private _config = ([_projectile] call CBA_fnc_getObjectConfig) >> "ace_missileguidance";
|
||||
private _distanceAheadOfMissile = [_config >> "missileLeadDistance", "NUMBER", DEFAULT_LEAD_DISTANCE] call CBA_fnc_getConfigEntry;
|
||||
|
||||
if (_shooter isKindOf "Plane") then { WARNING("SACLOS fired from planes unsupported"); };
|
||||
|
||||
private _turretPath = [_shooter, _weapon] call CBA_fnc_turretPathWeapon;
|
||||
private _turretConfig = [_shooter, _turretPath] call CBA_fnc_getTurret;
|
||||
private _memoryPointGunnerOptics = getText(_turretConfig >> "memoryPointGunnerOptics");
|
||||
private _animationSourceBody = getText(_turretConfig >> "animationSourceBody");
|
||||
private _animationSourceGun = getText(_turretConfig >> "animationSourceGun");
|
||||
_seekerStateParams set [0, _memoryPointGunnerOptics];
|
||||
_seekerStateParams set [1, _animationSourceBody];
|
||||
_seekerStateParams set [2, _animationSourceGun];
|
||||
_seekerStateParams set [3, _distanceAheadOfMissile];
|
||||
|
@ -19,7 +19,7 @@
|
||||
params ["_seekerTargetPos", "_args", "_attackProfileStateParams"];
|
||||
_args params ["_firedEH"];
|
||||
_firedEH params ["_shooter","","","","","","_projectile"];
|
||||
_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "_wireCutSource"];
|
||||
_attackProfileStateParams params["_maxCorrectableDistance", "_wireCut", "_randomVector", "_crosshairOffset", "_seekerMaxRangeSqr", "", "_wireCutSource"];
|
||||
|
||||
private _projectilePos = getPosASL _projectile;
|
||||
|
||||
|
@ -25,7 +25,7 @@ _seekerStateParams params ["_memoryPointGunnerOptics", "_animationSourceBody", "
|
||||
private _shooterPos = AGLToASL (_shooter modelToWorld(_shooter selectionPosition _memoryPointGunnerOptics));
|
||||
private _projPos = getPosASL _projectile;
|
||||
|
||||
private _lookDirection = if !(_shooter isKindOf "CAManBase") then {
|
||||
private _lookDirection = if !(_shooter isKindOf "CAManBase" || {_shooter isKindOf "StaticWeapon"}) then {
|
||||
private _gBody = -deg(_shooter animationPhase _animationSourceBody);
|
||||
private _gGun = deg(_shooter animationPhase _animationSourceGun);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "script_component.hpp"
|
||||
/*
|
||||
* Author: Brandon (TCVM)
|
||||
* Sets up missile guidance state arrays (called from missileGuidance's onFired).
|
||||
* Sets up wireGuided state arrays (called from missileGuidance's onFired).
|
||||
*
|
||||
* Arguments:
|
||||
* Guidance Arg Array <ARRAY>
|
||||
@ -10,26 +10,26 @@
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_hot_fnc_onFired
|
||||
* [] call ace_hot_fnc_wire_onFired
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params ["_firedEH", "", "", "_seekerParams", "_stateParams"];
|
||||
_firedEH params ["_shooter","_weapon","","","","","_projectile", "_gunner"];
|
||||
_stateParams params ["", "_seekerStateParams", "_attackProfileStateParams"];
|
||||
_seekerParams params ["", "", "_seekerMaxRange"];
|
||||
_stateParams params ["", "", "_attackProfileStateParams"];
|
||||
_seekerParams params ["", "", "_seekerMaxRange", "_seekerMinRange"];
|
||||
|
||||
private _config = ([_projectile] call CBA_fnc_getObjectConfig) >> "ace_missileguidance";
|
||||
private _maxCorrectableDistance = [_config >> "correctionDistance", "NUMBER", DEFAULT_CORRECTION_DISTANCE] call CBA_fnc_getConfigEntry;
|
||||
private _crosshairOffset = [_config >> "offsetFromCrosshair", "ARRAY", [0, 0, 0]] call CBA_fnc_getConfigEntry;
|
||||
private _maxDistanceSqr = _seekerMaxRange * _seekerMaxRange;
|
||||
private _distanceAheadOfMissile = [_config >> "missileLeadDistance", "NUMBER", DEFAULT_LEAD_DISTANCE] call CBA_fnc_getConfigEntry;
|
||||
private _minDistanceSqr = _seekerMinRange * _seekerMinRange;
|
||||
|
||||
// AI don't know how to use the crosshair offset becauze they dum dum
|
||||
if ((_gunner != ACE_PLAYER) && {_gunner != (ACE_controlledUAV select 1)}) then {
|
||||
_crosshairOffset = [0, 0, 0];
|
||||
_crosshairOffset = if ((_gunner != ACE_PLAYER) && {_gunner != (ACE_controlledUAV select 1)}) then {
|
||||
[0, 0, 0];
|
||||
} else {
|
||||
[_config >> "offsetFromCrosshair", "ARRAY", [0, 0, 0]] call CBA_fnc_getConfigEntry
|
||||
};
|
||||
if (_shooter isKindOf "Plane") then {WARNING("SACLOS fired from planes unsupported");};
|
||||
|
||||
private _turretPath = [_shooter, _weapon] call CBA_fnc_turretPathWeapon;
|
||||
private _turretConfig = [_shooter, _turretPath] call CBA_fnc_getTurret;
|
||||
@ -41,13 +41,6 @@ _attackProfileStateParams set [1, false]; // _wireCut
|
||||
_attackProfileStateParams set [2, [0, 0, 0]]; // _randomVector
|
||||
_attackProfileStateParams set [3, _crosshairOffset]; // crosshair offset
|
||||
_attackProfileStateParams set [4, _maxDistanceSqr]; // max distance squared used for wire cut
|
||||
_attackProfileStateParams set [5, _wireCutSource];
|
||||
|
||||
private _memoryPointGunnerOptics = getText(_turretConfig >> "memoryPointGunnerOptics");
|
||||
private _animationSourceBody = getText(_turretConfig >> "animationSourceBody");
|
||||
private _animationSourceGun = getText(_turretConfig >> "animationSourceGun");
|
||||
_seekerStateParams set [0, _memoryPointGunnerOptics];
|
||||
_seekerStateParams set [1, _animationSourceBody];
|
||||
_seekerStateParams set [2, _animationSourceGun];
|
||||
_seekerStateParams set [3, _distanceAheadOfMissile];
|
||||
_attackProfileStateParams set [5, _minDistanceSqr];
|
||||
_attackProfileStateParams set [6, _wireCutSource];
|
||||
|
@ -55,7 +55,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 isEqualTo [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 isEqualTo [0,0,0])}) then {
|
||||
|
||||
private _targetVector = _projectilePos vectorFromTo _profileAdjustedTargetPos;
|
||||
private _adjustVector = _targetVector vectorDiff (vectorDir _projectile);
|
||||
|
@ -112,19 +112,30 @@ private _args = [_this,
|
||||
[
|
||||
getNumber ( _config >> "seekerAngle" ),
|
||||
getNumber ( _config >> "seekerAccuracy" ),
|
||||
getNumber ( _config >> "seekerMaxRange" )
|
||||
getNumber ( _config >> "seekerMaxRange" ),
|
||||
getNumber ( _config >> "seekerMinRange" )
|
||||
],
|
||||
[ diag_tickTime, [], [], _lastKnownPosState]
|
||||
];
|
||||
|
||||
|
||||
// Run the "onFired" function passing the full guidance args array
|
||||
private _onFiredFunc = getText (_config >> "onFired");
|
||||
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"];
|
||||
@ -134,24 +145,6 @@ if (_onFiredFunc != "") then {
|
||||
// _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"];
|
||||
// _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange"];
|
||||
|
||||
|
||||
// Hand off to the guiding unit. We just use local player so local PFH fires for now
|
||||
// Laser code needs to give us a shooter for LOBL, or the seeker unit needs to be able to shift locality
|
||||
// Based on its homing laser
|
||||
// Lasers need to be handled in a special LOAL/LOBL case
|
||||
|
||||
//if (isPlayer _shooter) then {
|
||||
// private _guidingUnit = ACE_player;
|
||||
//
|
||||
// if (local _guidingUnit) then {
|
||||
// [FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler;
|
||||
// } else {
|
||||
// [QGVAR(handoff), [_guidingUnit, _args] ] call FUNC(doHandoff);
|
||||
// };
|
||||
//} else {
|
||||
// [FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler;
|
||||
//};
|
||||
|
||||
[FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler;
|
||||
|
||||
|
||||
|
BIN
docs/img/wiki/feature/m47_flank.png
Normal file
BIN
docs/img/wiki/feature/m47_flank.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 475 KiB |
BIN
docs/img/wiki/feature/m47_fro_obl_fla.png
Normal file
BIN
docs/img/wiki/feature/m47_fro_obl_fla.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 MiB |
BIN
docs/img/wiki/feature/m47_frontal.png
Normal file
BIN
docs/img/wiki/feature/m47_frontal.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 414 KiB |
BIN
docs/img/wiki/feature/m47_oblique_45.png
Normal file
BIN
docs/img/wiki/feature/m47_oblique_45.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 346 KiB |
BIN
docs/img/wiki/feature/m47_oblique_60.png
Normal file
BIN
docs/img/wiki/feature/m47_oblique_60.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 431 KiB |
80
docs/wiki/feature/dragon.md
Normal file
80
docs/wiki/feature/dragon.md
Normal file
@ -0,0 +1,80 @@
|
||||
---
|
||||
layout: wiki
|
||||
title: M47 Dragon Missile
|
||||
description: M47 Dragon
|
||||
group: feature
|
||||
category: equipment
|
||||
parent: wiki
|
||||
mod: ace
|
||||
version:
|
||||
major: 3
|
||||
minor: 13
|
||||
patch: 0
|
||||
---
|
||||
|
||||
## 1. Overview
|
||||
|
||||
### 1.1 Guidance
|
||||
|
||||
The M47 Dragon is a wire-guided SACLOS missile with a unique manuever system. It has a series of charges along the missile that fire every third of a second to adjust the missile on course
|
||||
|
||||
### 1.2 Attack profiles
|
||||
|
||||
The missile requires line of sight to the target at all times. Keep your crosshair on the target as the missile cruises toward it until impact.
|
||||
If you lose line of sight the missile will stop tracking toward your crosshair and will fly on its current trajectory. You can regain control if the missile re-enters line of sight.
|
||||
If the missile exceeds its maximum range the wire will snap and it will fly off in a random direction.
|
||||
The missiles manuever system causes inaccuracy that cannot be corrected for by the gunner. This means that the risk of missing increases as range goes up
|
||||
|
||||
## 2. Usage
|
||||
|
||||
### 2.1 Placement
|
||||
|
||||
- Ensure that you have the M47 Super-Dragon launcher as well as the SU-36/P sighting unit
|
||||
- Use self interaction <kbd>Ctrl</kbd>+<kbd>⊞ Win</kbd> (ACE3 default key bind `Self Interaction Key`)
|
||||
- Select 'Place Tripod'
|
||||
- Interact with the missile <kbd>⊞ Win</kbd> (ACE3 default key bind `Interaction Key`)
|
||||
- Select 'Attach Sight'
|
||||
- Get into the launcher
|
||||
- Point at target
|
||||
- Fire
|
||||
|
||||
### 2.2 Tear Down
|
||||
- Interact with the missile <kbd>⊞ Win</kbd> (ACE3 default key bind `Interaction Key`)
|
||||
- Select 'Disassemble'
|
||||
- Look to the right of the launcher and pick up the sighting unit
|
||||
- Move on
|
||||
|
||||
## 3. Sight Ranging
|
||||
|
||||
The Dragon gunners use the stadia lines in the daysight to determine if a target falls within range. Moving and stationary vehicles may present flank, oblique, and frontal or rear targets (Figure 1).
|
||||
At maximum range (1,500 meters), a 7-meter (23-foot) long target completely fills the area between the stadia lines and exceeds the stadia lines at a closer range.
|
||||
|
||||
**Figure 1. Frontal, oblique, and flank targets**
|
||||
<img src="{{ site.baseurl }}/img/wiki/feature/m47_fro_obl_fla.png" width="1400" height="452" alt="Frontal, Oblique, and Flank targets" />
|
||||
|
||||
### 3.1 **Flanking Targets (Full Stadia)**
|
||||
|
||||
Adjust the sight picture by moving the launcher so the target centers between the stadia lines (Figure 2).
|
||||
|
||||
**Figure 2. Range determination for flank target.**
|
||||
<img src="{{ site.baseurl }}/img/wiki/feature/m47_flank.png" width="1400" height="331" alt="Frontal, Oblique, and Flank targets" />
|
||||
|
||||
### 3.2 **Oblique Targets**
|
||||
|
||||
If you can see more of the flank, use the full-stadia method (Figure 3.1). The vehicle should appear to fill the area between the stadia lines. If you see more of the front or rear, use the half-stadia method (Figure 3.2). The track of the vehicle should fit between one stadia line and the center.
|
||||
|
||||
**Figure 3.1. Range determination for oblique target, more flank visible**
|
||||
<img src="{{ site.baseurl }}/img/wiki/feature/m47_oblique_45.png" width="1400" height="408" alt="Frontal, Oblique, and Flank targets" />
|
||||
**Figure 3.2. Range determination for oblique target, more front or rear visible**
|
||||
<img src="{{ site.baseurl }}/img/wiki/feature/m47_oblique_60.png" width="1400" height="331" alt="Frontal, Oblique, and Flank targets" />
|
||||
|
||||
### 3.3 **Frontal (Head-On) or Rear (Going Away, Half-Stadia) Targets**
|
||||
|
||||
Adjust the sight picture by moving the launcher to align the vertical cross hair and one of the stadia lines on the target (Figure 4)
|
||||
|
||||
**Figure 4. Range determination for frontal or rear target.**
|
||||
<img src="{{ site.baseurl }}/img/wiki/feature/m47_frontal.png" width="1400" height="357" alt="Frontal, Oblique, and Flank targets" />
|
||||
|
||||
## 4. Dependencies
|
||||
|
||||
{% include dependencies_list.md component="dragon" %}
|
Loading…
Reference in New Issue
Block a user