mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge branch 'master' of github.com:KoffeinFlummi/ACE3
This commit is contained in:
commit
dec5aa3ec5
@ -62,6 +62,7 @@ Raspu86
|
||||
Riccardo Petricca <petriccarcc@gmail.com>
|
||||
Robert Boklahánics <bokirobi@gmail.com>
|
||||
simon84
|
||||
Sniperwolf572 <tenga6@gmail.com>
|
||||
Tonic
|
||||
Tourorist <tourorist@gmail.com>
|
||||
Valentin Torikian <valentin.torikian@gmail.com>
|
||||
|
@ -1,9 +1,7 @@
|
||||
|
||||
class CfgAmmo {
|
||||
class BulletBase;
|
||||
class B_20mm;
|
||||
|
||||
class ACE_20mm_HEDP : B_20mm {
|
||||
class B_20mm : BulletBase {
|
||||
hit = 80;
|
||||
indirectHit = 12;
|
||||
indirectHitRange = 2; //2;
|
||||
@ -11,8 +9,22 @@ class CfgAmmo {
|
||||
tracerStartTime = 0.02;
|
||||
timeToLive = 40;
|
||||
explosive = 1.8;
|
||||
tracersEvery = 3;
|
||||
tracerEndTime = 3.5;
|
||||
|
||||
CraterEffects = "ExploAmmoCrater";
|
||||
explosionEffects = "ExploAmmoExplosion";
|
||||
model = "\A3\Weapons_f\Data\bullettracer\tracer_red";
|
||||
};
|
||||
class ACE_20mm_HEDP : B_20mm {};
|
||||
class ACE_20mm_AP : B_20mm {
|
||||
hit = 50;
|
||||
indirectHit = 12;
|
||||
indirectHitRange = 0.3; //2;
|
||||
explosive = 0;
|
||||
CraterEffects = "";
|
||||
explosionEffects = "";
|
||||
};
|
||||
|
||||
|
||||
// adjust minigun caliber and deflection to other ammo
|
||||
class SubmunitionBullet;
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
units[] = {};
|
||||
units[] = {"ACE_Comanche_Test"};
|
||||
weapons[] = {};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ace_common"};
|
||||
|
@ -15,7 +15,7 @@ class CfgWeapons {
|
||||
class ACE_FakePrimaryWeapon: Rifle_Base_F {
|
||||
scope = 2;
|
||||
displayName = "";
|
||||
model = "";
|
||||
model = "\A3\Weapons_f\empty";
|
||||
picture = "";
|
||||
magazines[] = {"ACE_FakeMagazine"};
|
||||
discreteDistance[] = {};
|
||||
|
@ -107,6 +107,7 @@ PREP(isAutoWind);
|
||||
PREP(isAwake);
|
||||
PREP(isEngineer);
|
||||
PREP(isEOD);
|
||||
PREP(isFeatureCameraActive);
|
||||
PREP(isInBuilding);
|
||||
PREP(isModLoaded);
|
||||
PREP(isPlayer);
|
||||
@ -177,6 +178,9 @@ PREP(useItem);
|
||||
PREP(useMagazine);
|
||||
PREP(waitAndExecute);
|
||||
|
||||
PREP(translateToWeaponSpace);
|
||||
PREP(translateToModelSpace);
|
||||
|
||||
// config items
|
||||
PREP(getConfigType);
|
||||
PREP(getItemType);
|
||||
|
@ -1,23 +1,37 @@
|
||||
/**
|
||||
* fn_disableAI_f.sqf
|
||||
* @Descr: N/A
|
||||
* @Author: Glowbal
|
||||
/*
|
||||
* Author: Glowbal, KoffeinFlummi
|
||||
* Disables/Enables AI
|
||||
*
|
||||
* @Arguments: []
|
||||
* @Return:
|
||||
* @PublicAPI: false
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Disable AI <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [bob, true] call ace_common_fnc_disableAI;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
private ["_unit","_disable"];
|
||||
_unit = [_this, 0,ObjNull,[ObjNull]] call BIS_fnc_Param;
|
||||
_disable = [_this, 1,false,[false]] call BIS_fnc_Param;
|
||||
|
||||
if (local _unit && !(IsPlayer _unit)) then {
|
||||
PARAMS_2(_unit,_disable);
|
||||
|
||||
if ((local _unit) && {!([_unit] call EFUNC(common,isPlayer))}) then {
|
||||
if (_disable) then {
|
||||
_unit disableAI "Move";
|
||||
_unit disableAI "MOVE";
|
||||
_unit disableAI "TARGET";
|
||||
_unit disableAI "AUTOTARGET";
|
||||
_unit disableAI "FSM";
|
||||
_unit disableConversation true;
|
||||
} else {
|
||||
_unit enableAI "Move";
|
||||
//Sanity check to make sure we don't enable unconsious AI
|
||||
if (_unit getVariable ["ace_isunconscious", false]) exitWith {ERROR("Enabling AI for unconsious unit");};
|
||||
_unit enableAI "MOVE";
|
||||
_unit enableAI "TARGET";
|
||||
_unit enableAI "AUTOTARGET";
|
||||
_unit enableAI "FSM";
|
||||
_unit disableConversation false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
31
addons/common/functions/fnc_isFeatureCameraActive.sqf
Normal file
31
addons/common/functions/fnc_isFeatureCameraActive.sqf
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Author: Sniperwolf572
|
||||
*
|
||||
* Checks if one of the following BI feature cameras are active:
|
||||
*
|
||||
* - Classic camera (BIS_fnc_cameraOld)
|
||||
* - Splendid camera (BIS_fnc_camera)
|
||||
* - Arsenal camera (BIS_fnc_arsenal)
|
||||
* - Animation viewer (BIS_fnc_animViewer)
|
||||
* - Establishing shot (BIS_fnc_establishingShot)
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return value:
|
||||
* Is BI feature camera active (bool)
|
||||
*
|
||||
* Example:
|
||||
* call ace_common_fnc_isFeatureCameraActive;
|
||||
*
|
||||
*/
|
||||
|
||||
#include "script_component.hpp"
|
||||
|
||||
(
|
||||
!isNull (missionNamespace getVariable ["BIS_DEBUG_CAM", objNull]) || // Classic camera
|
||||
{!isNull (missionNamespace getVariable ["BIS_fnc_camera_cam", objNull])} || // Splendid camera
|
||||
{!isNull (uiNamespace getVariable ["BIS_fnc_arsenal_cam", objNull])} || // Arsenal camera
|
||||
{!isNull (uiNamespace getVariable ["BIS_fnc_animViewer_cam", objNull])} || // Animation viewer camera
|
||||
{!isNull (missionNamespace getVariable ["BIS_fnc_establishingShot_fakeUAV", objNull])} // Establishing shot camera
|
||||
)
|
@ -16,4 +16,5 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (GVAR(showInThirdPerson)) exitWith { false };
|
||||
(cameraView == "External")
|
||||
|
||||
(cameraView in ["EXTERNAL", "GROUP"] || {call EFUNC(common,isFeatureCameraActive)})
|
||||
|
@ -9,3 +9,11 @@ class Extended_PostInit_EventHandlers {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_post_init));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_Init_EventHandlers {
|
||||
class LaserTargetBase {
|
||||
class ADDON {
|
||||
init = QUOTE(_this call DFUNC(laser_init));
|
||||
};
|
||||
};
|
||||
};
|
@ -14,13 +14,7 @@ PREP(translateToWeaponSpace);
|
||||
|
||||
PREP(laser_init);
|
||||
|
||||
GVAR(laser) = nil; // a single hud draws 1 laser at a time
|
||||
|
||||
PREP(laserTargetPFH);
|
||||
|
||||
ACE_LASERS = [];
|
||||
|
||||
ACE_DEFAULT_LASER_CODE = 1000;
|
||||
ACE_DEFAULT_FIRE_SELECTION = [FIREMODE_DIRECT_LOAL, ACE_DEFAULT_LASER_CODE];
|
||||
|
||||
FUNC(getPosASL) = {visiblePositionASL (_this select 0)};
|
||||
ACE_DEFAULT_LASER_CODE = 1001;
|
@ -1,17 +1,21 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_missile", "_headingPitch", "_found", "_vectorTo", "_polarTo", "_dir", "_vertOk", "_horzOk", "_fov",
|
||||
private ["_seeker", "_headingPitch", "_found", "_vectorTo", "_polarTo", "_dir", "_vertOk", "_horzOk", "_fov",
|
||||
"_closestDistance", "_pos1", "_pos2", "_disCheck", "_currentTarget", "_potentialTargets", "_offset", "_vector"];
|
||||
_missile = _this select 0;
|
||||
|
||||
_seeker = _this select 0;
|
||||
_laserCode = _this select 1;
|
||||
_fov = if (count _this > 2) then {_this select 2} else {75};
|
||||
_vector = if (count _this > 3) then {_this select 3} else {vectorDir _missile};
|
||||
_vector = if (count _this > 3) then {_this select 3} else {vectorDir _seeker};
|
||||
_offset = if (count _this > 4) then {_this select 4} else {[0,0,0]};
|
||||
|
||||
_headingPitch = _vector call CBA_fnc_vect2polar;
|
||||
_currentTarget = nil;
|
||||
_found = false;
|
||||
|
||||
_getPosASL = {visiblePositionASL (_this select 0)};
|
||||
|
||||
LOG("Searching lasers");
|
||||
if(!(isNil "ACE_LASERS")) then {
|
||||
_potentialTargets = [];
|
||||
@ -19,8 +23,8 @@ if(!(isNil "ACE_LASERS")) then {
|
||||
|
||||
{
|
||||
if(!(isNull _x)) then {
|
||||
_sensorPos = ATLtoASL(_missile modelToWorldVisual _offset);
|
||||
_vectorTo = [_sensorPos, ([_x] call FUNC(getPosASL))] call BIS_fnc_vectorFromXToY;
|
||||
_sensorPos = ATLtoASL(_seeker modelToWorldVisual _offset);
|
||||
_vectorTo = [_sensorPos, ([_x] call _getPosASL)] call BIS_fnc_vectorFromXToY;
|
||||
_polarTo = _vectorTo call CBA_fnc_vect2polar;
|
||||
_dir = _polarTo select 1;
|
||||
_dir = _dir - (_headingPitch select 1);
|
||||
@ -42,7 +46,7 @@ if(!(isNil "ACE_LASERS")) then {
|
||||
|
||||
if(_vertOk && {_horzOk}) then {
|
||||
// Does the laser currently have our current code, if we have one?
|
||||
_targetCode = _x getVariable ["ACE_LASERTARGET_CODE", ACE_DEFAULT_LASER_CODE];
|
||||
_targetCode = _x getVariable ["ACE_LASER_CODE", ACE_DEFAULT_LASER_CODE];
|
||||
TRACE_1("Target in sight, checking code", _targetCode, _laserCode);
|
||||
if(_targetCode == _laserCode) then {
|
||||
_potentialTargets set[(count _potentialTargets), _x];
|
||||
@ -56,11 +60,11 @@ if(!(isNil "ACE_LASERS")) then {
|
||||
|
||||
_closestDistance = 100000;
|
||||
{
|
||||
_pos1 = (getPosASL _missile);
|
||||
_pos2 = ([_x] call FUNC(getPosASL));
|
||||
_pos1 = (getPosASL _seeker);
|
||||
_pos2 = ([_x] call _getPosASL);
|
||||
_disCheck = _pos1 distance _pos2;
|
||||
// shouldn't this bail out when a valid target is found instead of iterating over all potential targets ?
|
||||
if(_disCheck < _closestDistance && {[_pos1, _pos2, _x, _missile] call FUNC(checkLos)}) then {
|
||||
if(_disCheck < _closestDistance && {[_pos1, _pos2, _x, _seeker] call FUNC(checkLos)}) then {
|
||||
_found = true;
|
||||
_currentTarget = _x;
|
||||
_closestDistance = _disCheck;
|
||||
|
@ -9,16 +9,16 @@ TRACE_1("enter", _this);
|
||||
// Add the laser localized to the laser array, and give it the default localized code
|
||||
PUSH(ACE_LASERS, _laserTarget);
|
||||
// Check the vehicle, otherwise use the default
|
||||
_laserTarget setVariable ["ACE_LASERTARGET_CODE", ACE_DEFAULT_LASER_CODE, false];
|
||||
_laserTarget setVariable ["ACE_LASER_CODE", ACE_DEFAULT_LASER_CODE, false];
|
||||
// Clean the lasers of any null objects while we are here
|
||||
REM(ACE_LASERS, objNull);
|
||||
|
||||
if(!(local _laserTarget)) exitWith { };
|
||||
// The target is local, so its on this client
|
||||
if(!isDedicated) then {
|
||||
_laserTarget setVariable ["ACE_LASERTARGET_SHOOTER", player, true];
|
||||
_laserTarget setVariable ["ACE_LASERTARGET_SHOOTER", ACE_player, true];
|
||||
|
||||
[FUNC(laserTargetPFH), 0, [_laserTarget, player]] call cba_fnc_addPerFrameHandler;
|
||||
[FUNC(laserTargetPFH), 0, [_laserTarget, ACE_player]] call cba_fnc_addPerFrameHandler;
|
||||
} else {
|
||||
// server side ownership of laser
|
||||
//_laserTarget setVariable ["ACE_LASERTARGET_SHOOTER", nil, false];
|
||||
|
@ -6,6 +6,6 @@ PREP(laserHudDesignateOff);
|
||||
PREP(unitTurretHasDesignator);
|
||||
|
||||
GVAR(laser) = nil;
|
||||
GVAR(laserActive) = false;
|
||||
GVAR(active) = false;
|
||||
|
||||
FUNC(getPosASL) = {visiblePositionASL (_this select 0)};
|
||||
|
@ -28,7 +28,7 @@ GVAR(initializedClasses) = _initializedClasses;
|
||||
|
||||
if (getNumber (_turretConfig >> QGVAR(Enabled)) == 1) exitWith {
|
||||
// @todo: Add the state variables to the vehicle, instead of to the client
|
||||
// e.g.: _vehicle setVariable [format ["%1_%2", QGVAR(laserActive), _x], false];
|
||||
// e.g.: _vehicle setVariable [format ["%1_%2", QGVAR(active), _x], false];
|
||||
|
||||
// Add actions
|
||||
_onAction = [QGVAR(LaserOn), localize "STR_ACE_Laser_SelfDesignate_DesignatorOn", "",
|
||||
@ -38,7 +38,7 @@ GVAR(initializedClasses) = _initializedClasses;
|
||||
},
|
||||
{
|
||||
// Condition
|
||||
!GVAR(laserActive) && {[ACE_player] call FUNC(unitTurretHasDesignator)}
|
||||
!GVAR(active) && {[ACE_player] call FUNC(unitTurretHasDesignator)}
|
||||
}] call EFUNC(interact_menu,createAction);
|
||||
|
||||
_offAction = [QGVAR(LaserOff), localize "STR_ACE_Laser_SelfDesignate_DesignatorOff", "",
|
||||
@ -48,7 +48,7 @@ GVAR(initializedClasses) = _initializedClasses;
|
||||
},
|
||||
{
|
||||
// Condition
|
||||
GVAR(laserActive) && {[ACE_player] call FUNC(unitTurretHasDesignator)}
|
||||
GVAR(active) && {[ACE_player] call FUNC(unitTurretHasDesignator)}
|
||||
}] call EFUNC(interact_menu,createAction);
|
||||
|
||||
[_type, 1, ["ACE_SelfActions"], _onAction] call EFUNC(interact_menu,addActionToClass);
|
||||
|
@ -1,5 +1,11 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
if( (count _this) > 2) then {
|
||||
EXPLODE_3_PVT(_this,_vehicle,_shooter,_laserTarget);
|
||||
// We got the optional vehicle list, clear the parameters
|
||||
_vehicle setVariable[QGVAR(currentTarget), [], true];
|
||||
};
|
||||
|
||||
if(isNil QGVAR(laser)) exitWith {
|
||||
false
|
||||
};
|
||||
@ -15,6 +21,8 @@ if(!isNil "_handle") then {
|
||||
REM(ACE_LASERS, GVAR(laser));
|
||||
deleteVehicle GVAR(laser);
|
||||
GVAR(laser) = nil;
|
||||
GVAR(laserActive) = false;
|
||||
GVAR(active) = false;
|
||||
|
||||
|
||||
|
||||
true
|
@ -5,25 +5,21 @@ TRACE_1("enter", _this);
|
||||
|
||||
#define FCS_UPDATE_DELAY 1
|
||||
|
||||
FUNC(magnitude) = {
|
||||
_this distance [0, 0, 0]
|
||||
};
|
||||
|
||||
FUNC(mat_normalize3d) = {
|
||||
private ["_mag"];
|
||||
PARAMS_3(_vx,_vy,_vz);
|
||||
|
||||
_mag = _this call FUNC(magnitude);
|
||||
if (_mag == 0) then {_mag = 1};
|
||||
[(_vx/_mag), (_vy/_mag), (_vz/_mag)]
|
||||
};
|
||||
|
||||
FUNC(laserHudDesignatePFH) = {
|
||||
private["_args", "_laserTarget", "_shooter", "_vehicle", "_weapon", "_gunnerInfo", "_turret", "_pov", "_gunBeg", "_gunEnd", "_povPos", "_povDir", "_result", "_resultPositions", "_firstResult", "_forceUpdateTime"];
|
||||
private["_strongestResultPos", "_args", "_laserTarget", "_shooter", "_vehicle", "_weapon", "_gunnerInfo", "_turret", "_pov", "_gunBeg", "_gunEnd", "_povPos", "_povDir", "_result", "_resultPositions", "_firstResult", "_forceUpdateTime"];
|
||||
_args = _this select 0;
|
||||
_laserTarget = _args select 0;
|
||||
_shooter = _args select 1;
|
||||
|
||||
TRACE_1("", _args, (_laserTarget getVariable["ACE_LASER_CODE"]));
|
||||
|
||||
if((vehicle ACE_player) != _shooter || !alive _shooter || isNull _vehicle || isNull _laserTarget || !GVAR(active) ) exitWith {
|
||||
[_vehicle, _shooter, _laserTarget] call FUNC(laserHudDesignateOff);
|
||||
};
|
||||
if(!([_shooter] call FUNC(unitTurretHasDesignator)) ) exitWith {
|
||||
[_vehicle, _shooter, _laserTarget] call FUNC(laserHudDesignateOff);
|
||||
};
|
||||
|
||||
if( (count _args) < 3) then {
|
||||
_args set[2, diag_tickTime + FCS_UPDATE_DELAY];
|
||||
};
|
||||
@ -32,21 +28,23 @@ FUNC(laserHudDesignatePFH) = {
|
||||
_vehicle = vehicle _shooter;
|
||||
_weapon = currentWeapon _vehicle;
|
||||
|
||||
TRACE_1("", _args);
|
||||
|
||||
if(!alive _shooter || isNull _vehicle || isNull _laserTarget || !GVAR(laserActive) ) exitWith {
|
||||
[] call FUNC(laserHudDesignateOff);
|
||||
};
|
||||
if(!([ACE_player] call FUNC(unitTurretHasDesignator)) ) exitWith {
|
||||
[] call FUNC(laserHudDesignateOff);
|
||||
};
|
||||
|
||||
// Retrieve the gunner and turret memory point information
|
||||
_gunnerInfo = [_vehicle, _weapon] call CBA_fnc_getFirer;
|
||||
_turretInfo = [_vehicle, _gunnerInfo select 1] call EFUNC(common,getTurretDirection);
|
||||
_povPos = _turretInfo select 0;
|
||||
_povDir = _turretInfo select 1;
|
||||
|
||||
_targetInfo = _vehicle getVariable[QGVAR(currentTarget), [] ];
|
||||
if( (count _targetInfo) > 0) then {
|
||||
if(_laserTarget != (_targetInfo select 0) ) then {
|
||||
_targetInfo = []
|
||||
};
|
||||
};
|
||||
if( (count _targetInfo) < 1) then {
|
||||
_targetInfo = [_laserTarget, 1001]; // TODO: set laser code
|
||||
_vehicle setVariable[QGVAR(currentTarget), _targetInfo, true];
|
||||
_laserTarget setVariable[QGVAR(owner), _vehicle, true];
|
||||
};
|
||||
|
||||
|
||||
_result = [_povPos, _povDir] call EFUNC(laser,shootCone);
|
||||
@ -54,24 +52,23 @@ FUNC(laserHudDesignatePFH) = {
|
||||
_resultPositions = _result select 2;
|
||||
|
||||
if((count _resultPositions) > 0) then {
|
||||
_firstResult = _resultPositions select 0;
|
||||
_pos = _firstResult select 0;
|
||||
_strongestResultPos = [_resultPositions, _povPos] call EFUNC(laser,findStrongestRay);
|
||||
|
||||
// If the laser has moved less than a half meter, then dont move it.
|
||||
// Just regular use of lasers will commonly make them move this much,
|
||||
// but not across multiple close frames.
|
||||
// This loses accuracy a little, but saves position updates per frame.
|
||||
TRACE_5("", diag_tickTime, _forceUpdateTime, getPosASL _laserTarget, _pos, ((getPosASL _laserTarget) distance _pos));
|
||||
TRACE_5("", diag_tickTime, _forceUpdateTime, getPosASL _laserTarget, _strongestResultPos, ((getPosASL _laserTarget) distance _pos));
|
||||
|
||||
if(diag_tickTime > _forceUpdateTime) then {
|
||||
TRACE_1("FCS Update", "");
|
||||
["ace_fcs_forceUpdate", []] call ace_common_fnc_localEvent;
|
||||
};
|
||||
|
||||
if( (_laserTarget distance _pos) > 0.1) then {
|
||||
//if( (_laserTarget distance _strongestResultPos) > 0.1) then {
|
||||
TRACE_1("LaserPos Update", "");
|
||||
_laserTarget setPosATL (ASLToATL _pos);
|
||||
};
|
||||
_laserTarget setPosATL (ASLToATL _strongestResultPos);
|
||||
//};
|
||||
|
||||
if(diag_tickTime > _forceUpdateTime) then {
|
||||
_args set[2, diag_tickTime + FCS_UPDATE_DELAY];
|
||||
@ -91,18 +88,19 @@ FUNC(laserHudDesignatePFH) = {
|
||||
_this set[0, _args];
|
||||
};
|
||||
|
||||
private "_laserTarget";
|
||||
private "_handle";
|
||||
private ["_laserTarget", "_handle", "_vehicle"];
|
||||
|
||||
if(isNil QGVAR(laser)) then {
|
||||
_laserTarget = "LaserTargetW" createVehicle (getpos ACE_player);
|
||||
|
||||
_laserTarget = "LaserTargetW" createVehicle (getpos player);
|
||||
GVAR(active) = true;
|
||||
|
||||
GVAR(laserActive) = true;
|
||||
|
||||
_handle = [FUNC(laserHudDesignatePFH), 0.1, [_laserTarget, player]] call cba_fnc_addPerFrameHandler;
|
||||
_handle = [FUNC(laserHudDesignatePFH), 0.1, [_laserTarget, ACE_player]] call cba_fnc_addPerFrameHandler;
|
||||
_laserTarget setVariable ["ACE_PFH_HANDLE", _handle, false];
|
||||
|
||||
// Clear the vehicle parameters
|
||||
_vehicle setVariable[QGVAR(currentTarget), [], true];
|
||||
|
||||
GVAR(laser) = _laserTarget;
|
||||
} else {
|
||||
[] call FUNC(laserHudDesignateOff);
|
||||
|
@ -116,7 +116,7 @@ _startingTime = time;
|
||||
// Swhich the unit back to its original group
|
||||
[_unit, false, "ACE_isUnconscious", side group _unit] call EFUNC(common,switchToGroupSide);
|
||||
|
||||
[_unit, false] call EFUNC(common,disableAI_F);
|
||||
[_unit, false] call EFUNC(common,disableAI);
|
||||
_unit setUnitPos _originalPos; // This is not position but stance (DOWN, MIDDLE, UP)
|
||||
|
||||
_unit setUnconscious false;
|
||||
|
61
addons/missileguidance/ACE_GuidanceConfig.hpp
Normal file
61
addons/missileguidance/ACE_GuidanceConfig.hpp
Normal file
@ -0,0 +1,61 @@
|
||||
class GVAR(AttackProfiles) {
|
||||
class LIN {
|
||||
name = "";
|
||||
visualName = "";
|
||||
description = "";
|
||||
|
||||
functionName = QFUNC(attackProfile_LIN);
|
||||
};
|
||||
class DIR {
|
||||
name = "";
|
||||
visualName = "";
|
||||
description = "";
|
||||
|
||||
functionName = QFUNC(attackProfile_DIR);
|
||||
};
|
||||
class MID {
|
||||
name = "";
|
||||
visualName = "";
|
||||
description = "";
|
||||
|
||||
functionName = QFUNC(attackProfile_MID);
|
||||
};
|
||||
class HI {
|
||||
name = "";
|
||||
visualName = "";
|
||||
description = "";
|
||||
|
||||
functionName = QFUNC(attackProfile_HI);
|
||||
};
|
||||
class TOP {
|
||||
name = "";
|
||||
visualName = "";
|
||||
description = "";
|
||||
|
||||
functionName = QFUNC(attackProfile_TOP);
|
||||
};
|
||||
class PYM {
|
||||
name = "";
|
||||
visualName = "";
|
||||
description = "";
|
||||
|
||||
functionName = QFUNC(attackProfile_PYM);
|
||||
};
|
||||
};
|
||||
|
||||
class GVAR(SeekerTypes) {
|
||||
class SALH {
|
||||
name = "";
|
||||
visualName = "";
|
||||
description = "";
|
||||
|
||||
functionName = QFUNC(seekerType_SALH);
|
||||
};
|
||||
class Optic {
|
||||
name = "";
|
||||
visualName = "";
|
||||
description = "";
|
||||
|
||||
functionName = QFUNC(seekerType_Optic);
|
||||
};
|
||||
};
|
9
addons/missileguidance/ACE_Settings.hpp
Normal file
9
addons/missileguidance/ACE_Settings.hpp
Normal file
@ -0,0 +1,9 @@
|
||||
class ACE_Settings {
|
||||
class GVAR(enabled) {
|
||||
value = 1;
|
||||
typeName = "BOOL";
|
||||
isClientSetable = 1;
|
||||
displayName = "$STR_ACE_MissileGuidance";
|
||||
description = "$STR_ACE_MissileGuidance_Desc";
|
||||
};
|
||||
};
|
@ -1,10 +1,141 @@
|
||||
enum {
|
||||
ACE_LOBL = 1,
|
||||
ACE_LOAL = 2
|
||||
};
|
||||
|
||||
class CfgAmmo {
|
||||
class MissileBase;
|
||||
|
||||
class M_PG_AT : MissileBase {
|
||||
model = "\A3\Weapons_F\Ammo\Rocket_01_fly_F";
|
||||
proxyShape = "\A3\Weapons_F\Ammo\Rocket_01_F";
|
||||
|
||||
irLock = 0;
|
||||
laserLock = 0;
|
||||
airLock = 0;
|
||||
laserLock = 0;
|
||||
airLock = 0;
|
||||
weaponLockSystem = "2 + 16";
|
||||
|
||||
maxSpeed = 720;
|
||||
maxControlRange = 5000;
|
||||
maneuvrability = 8;
|
||||
timeToLive = 60;
|
||||
simulationStep = 0.01;
|
||||
airFriction = 0.1;
|
||||
sideAirFriction = 0.16;
|
||||
initTime = 0.002;
|
||||
thrustTime = 1.07;
|
||||
thrust = 530;
|
||||
fuseDistance = 2;
|
||||
|
||||
effectsMissileInit = "MissileDAR1";
|
||||
effectsMissile = "missile2";
|
||||
whistleDist = 4;
|
||||
muzzleEffect = "";
|
||||
|
||||
// Turn off arma crosshair-guidance
|
||||
manualControl = 0;
|
||||
|
||||
// ACE uses these values
|
||||
trackOversteer = 1;
|
||||
trackLead = 0;
|
||||
|
||||
// Begin ACE guidance Configs
|
||||
class ACE_MissileGuidance {
|
||||
enabled = 1;
|
||||
|
||||
minDeflection = 0.005; // Minium flap deflection for guidance
|
||||
maxDeflection = 0.025; // Maximum flap deflection for guidance
|
||||
incDeflection = 0.005; // The incrmeent in which deflection adjusts.
|
||||
//minDeflection = 0.005;
|
||||
//maxDeflection = 0.5;
|
||||
//incDeflection = 0.005;
|
||||
|
||||
// Guidance type for munitions
|
||||
defaultSeekerType = "SALH";
|
||||
seekerTypes[] = { "SALH", "LIDAR", "SARH", "Optic", "Thermal", "GPS", "SACLOS", "MCLOS" };
|
||||
|
||||
defaultSeekerLockMode = "LOAL";
|
||||
seekerLockModes[] = { "LOAL", "LOBL" };
|
||||
|
||||
seekerAngle = 90; // Angle in front of the missile which can be searched
|
||||
seekerAccuracy = 1; // seeker accuracy multiplier
|
||||
|
||||
seekerMinRange = 1;
|
||||
seekerMaxRange = 2500; // Range from the missile which the seeker can visually search
|
||||
|
||||
// Attack profile type selection
|
||||
defaultAttackProfile = "LIN";
|
||||
attackProfiles[] = { "LIN", "DIR", "MID", "HI", "TOP", "PYM" };
|
||||
};
|
||||
};
|
||||
|
||||
class ACE_Hydra70_DAGR : M_PG_AT {
|
||||
displayName = "$STR_ACE_Hydra70_DAGR";
|
||||
displayNameShort = "$STR_ACE_Hydra70_DAGR_Short";
|
||||
|
||||
description = "$STR_ACE_Hydra70_DAGR";
|
||||
descriptionShort = "$STR_ACE_Hydra70_DAGR_Desc";
|
||||
};
|
||||
|
||||
class ACE_Hellfire_AGM114K : ACE_Hydra70_DAGR {
|
||||
displayName = "$STR_ACE_Hellfire_AGM114K";
|
||||
displayNameShort = "$STR_ACE_Hellfire_AGM114K_Short";
|
||||
|
||||
description = "$STR_ACE_Hellfire_AGM114K_desc";
|
||||
descriptionShort = "$STR_ACE_Hellfire_AGM114K_desc";
|
||||
|
||||
// @TODO: placeholder model to at least make it look different
|
||||
model = "\A3\Weapons_F\Ammo\Missile_AT_03_fly_F";
|
||||
proxyShape = "\A3\Weapons_F\Ammo\Missile_AT_03_F";
|
||||
|
||||
hit = 1400;
|
||||
indirectHit = 71;
|
||||
indirectHitRange = 4.5;
|
||||
effectsMissile = "missile2";
|
||||
};
|
||||
|
||||
// Titan
|
||||
class M_Titan_AT : MissileBase {
|
||||
irLock = 0;
|
||||
laserLock = 0;
|
||||
airLock = 0;
|
||||
|
||||
// Turn off arma crosshair-guidance
|
||||
manualControl = 0;
|
||||
|
||||
hit = 1400;
|
||||
|
||||
// ACE uses these values
|
||||
//trackOversteer = 1;
|
||||
//trackLead = 0;
|
||||
|
||||
// Begin ACE guidance Configs
|
||||
class ACE_MissileGuidance {
|
||||
enabled = 1;
|
||||
|
||||
minDeflection = 0.005; // Minium flap deflection for guidance
|
||||
maxDeflection = 0.25; // Maximum flap deflection for guidance
|
||||
incDeflection = 0.005; // The incrmeent in which deflection adjusts.
|
||||
//minDeflection = 0.005;
|
||||
//maxDeflection = 0.5;
|
||||
//incDeflection = 0.005;
|
||||
|
||||
// Guidance type for munitions
|
||||
defaultSeekerType = "Optic";
|
||||
seekerTypes[] = { "Optic" };
|
||||
|
||||
defaultSeekerLockMode = "LOBL";
|
||||
seekerLockModes[] = { "LOBL" };
|
||||
|
||||
seekerAngle = 90; // Angle in front of the missile which can be searched
|
||||
seekerAccuracy = 1; // seeker accuracy multiplier
|
||||
|
||||
seekerMinRange = 1;
|
||||
seekerMaxRange = 2500; // Range from the missile which the seeker can visually search
|
||||
|
||||
// Attack profile type selection
|
||||
defaultAttackProfile = "LIN";
|
||||
attackProfiles[] = { "TOP", "LIN" };
|
||||
};
|
||||
};
|
||||
};
|
@ -5,13 +5,13 @@ class Extended_PreInit_EventHandlers {
|
||||
};
|
||||
|
||||
class Extended_PostInit_EventHandlers {
|
||||
class ADDON {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_post_init));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_FiredBIS_EventHandlers {
|
||||
class AllVehicles {
|
||||
class All {
|
||||
ADDON = QUOTE(_this call FUNC(fired));
|
||||
};
|
||||
};
|
53
addons/missileguidance/CfgMagazines.hpp
Normal file
53
addons/missileguidance/CfgMagazines.hpp
Normal file
@ -0,0 +1,53 @@
|
||||
class CfgMagazines {
|
||||
class 12Rnd_PG_missiles;
|
||||
|
||||
class 6Rnd_ACE_Hydra70_DAGR : 12Rnd_PG_missiles {
|
||||
ammo = "ACE_Hydra70_DAGR";
|
||||
count = 12;
|
||||
displayName = "6 Round DAGR";
|
||||
displayNameShort = "6 Round DAGR";
|
||||
descriptionShort = "6 Round DAGR";
|
||||
weight = 36;
|
||||
|
||||
};
|
||||
class 12Rnd_ACE_Hydra70_DAGR : 6Rnd_ACE_Hydra70_DAGR {
|
||||
count = 12;
|
||||
displayName = "16 Round DAGR";
|
||||
displayNameShort = "16 Round DAGR";
|
||||
descriptionShort = "16 Round DAGR";
|
||||
weight = 72;
|
||||
};
|
||||
class 24Rnd_ACE_Hydra70_DAGR : 6Rnd_ACE_Hydra70_DAGR {
|
||||
count = 24;
|
||||
displayName = "24 Round DAGR";
|
||||
displayNameShort = "24 Round DAGR";
|
||||
descriptionShort = "24 Round DAGR";
|
||||
weight = 72;
|
||||
};
|
||||
|
||||
// Hellfires
|
||||
class 6Rnd_ACE_Hellfire_AGM114K : 12Rnd_PG_missiles {
|
||||
count = 12;
|
||||
ammo = "ACE_Hellfire_AGM114K";
|
||||
displayName = "6Rnd_ACE_Hellfire_AGM114K";
|
||||
displayNameShort = "6Rnd_ACE_Hellfire_AGM114K";
|
||||
descriptionShort = "6Rnd_ACE_Hellfire_AGM114K";
|
||||
weight = 36;
|
||||
|
||||
};
|
||||
class 12Rnd_ACE_Hellfire_AGM114K : 6Rnd_ACE_Hydra70_DAGR {
|
||||
count = 12;
|
||||
displayName = "12Rnd_ACE_Hellfire_AGM114K";
|
||||
displayNameShort = "12Rnd_ACE_Hellfire_AGM114K";
|
||||
descriptionShort = "12Rnd_ACE_Hellfire_AGM114K";
|
||||
weight = 72;
|
||||
};
|
||||
class 24Rnd_ACE_Hellfire_AGM114K : 6Rnd_ACE_Hydra70_DAGR {
|
||||
count = 24;
|
||||
displayName = "24Rnd_ACE_Hellfire_AGM114K";
|
||||
displayNameShort = "24Rnd_ACE_Hellfire_AGM114K";
|
||||
descriptionShort = "24Rnd_ACE_Hellfire_AGM114K";
|
||||
weight = 72;
|
||||
};
|
||||
|
||||
};
|
24
addons/missileguidance/CfgVehicles.hpp
Normal file
24
addons/missileguidance/CfgVehicles.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
class CfgVehicles {
|
||||
class Heli_Attack_01_base_F;
|
||||
|
||||
class B_Heli_Attack_01_F : Heli_Attack_01_base_F {
|
||||
class Turrets {
|
||||
class MainTurret;
|
||||
};
|
||||
}
|
||||
|
||||
class ACE_Comanche_Test : B_Heli_Attack_01_F {
|
||||
displayName = "ACE_Comanche_Test";
|
||||
author = "ACE Team";
|
||||
class Library
|
||||
{
|
||||
libTextDesc = "ACE_Comanche_Test";
|
||||
};
|
||||
class Turrets: Turrets {
|
||||
class MainTurret: MainTurret {
|
||||
magazines[] = {"ACE_500Rnd_20mm_shells_Comanche", "24Rnd_ACE_Hellfire_AGM114K"};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -6,29 +6,8 @@ class CfgWeapons {
|
||||
class RocketPods: LauncherCore {
|
||||
canLock = 1;
|
||||
};
|
||||
class missiles_DAGR: RocketPods {
|
||||
class missiles_DAGR : RocketPods {
|
||||
canLock = 1;
|
||||
magazines[] += {"24Rnd_ACE_Hydra70_DAGR", "12Rnd_ACE_Hydra70_DAGR", "6Rnd_ACE_Hydra70_DAGR", "24Rnd_ACE_Hellfire_AGM114K", "12Rnd_ACE_Hellfire_AGM114K", "6Rnd_ACE_Hellfire_AGM114K" };
|
||||
};
|
||||
/*
|
||||
class autocannon_Base_F: CannonCore {
|
||||
canLock = 1;
|
||||
};
|
||||
class cannon_120mm: CannonCore {
|
||||
canLock = 1;
|
||||
|
||||
class player : Mode_SemiAuto {
|
||||
canLock = 1;
|
||||
};
|
||||
};
|
||||
class gatling_25mm: CannonCore {
|
||||
canLock = 1;
|
||||
};
|
||||
class autocannon_35mm: CannonCore {
|
||||
canLock = 1;
|
||||
};
|
||||
|
||||
class launch_NLAW_F: Launcher_Base_F
|
||||
{
|
||||
canLock = 1;
|
||||
};*/
|
||||
};
|
65
addons/missileguidance/Example_ACE_MissileGuidance.hpp
Normal file
65
addons/missileguidance/Example_ACE_MissileGuidance.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
THIS IS A WIP FUNCTIONALITY, DUE TO CHANGE
|
||||
|
||||
|
||||
class M_PG_AT : MissileBase {
|
||||
model = "\A3\Weapons_F\Ammo\Rocket_01_fly_F";
|
||||
proxyShape = "\A3\Weapons_F\Ammo\Rocket_01_F";
|
||||
|
||||
irLock = 0;
|
||||
laserLock = 0;
|
||||
airLock = 0;
|
||||
weaponLockSystem = "2 + 16";
|
||||
|
||||
maxSpeed = 720;
|
||||
maxControlRange = 5000;
|
||||
maneuvrability = 8;
|
||||
timeToLive = 60;
|
||||
simulationStep = 0.01;
|
||||
airFriction = 0.1;
|
||||
sideAirFriction = 0.16;
|
||||
initTime = 0.002;
|
||||
thrustTime = 1.07;
|
||||
thrust = 530;
|
||||
fuseDistance = 2;
|
||||
|
||||
effectsMissileInit = "MissileDAR1";
|
||||
effectsMissile = "missile2";
|
||||
whistleDist = 4;
|
||||
muzzleEffect = "";
|
||||
|
||||
// Turn off arma crosshair-guidance
|
||||
manualControl = 0;
|
||||
|
||||
// ACE uses these values
|
||||
trackOversteer = 1;
|
||||
trackLead = 0;
|
||||
|
||||
// Begin ACE guidance Configs
|
||||
class ACE_MissileGuidance {
|
||||
enabled = 1;
|
||||
|
||||
minDeflection = 0.005; // Minium flap deflection for guidance
|
||||
maxDeflection = 0.025; // Maximum flap deflection for guidance
|
||||
incDeflection = 0.005; // The incrmeent in which deflection adjusts.
|
||||
//minDeflection = 0.005;
|
||||
//maxDeflection = 0.5;
|
||||
//incDeflection = 0.005;
|
||||
|
||||
// Guidance type for munitions
|
||||
defaultSeekerType = "SALH";
|
||||
seekerTypes[] = { "SALH", "LIDAR", "SARH", "Optic", "Thermal", "GPS", "SACLOS", "MCLOS" };
|
||||
|
||||
defaultSeekerLockMode = "LOAL";
|
||||
seekerLockModes[] = { "LOAL", "LOBL" };
|
||||
|
||||
seekerAngle = 90; // Angle in front of the missile which can be searched
|
||||
seekerAccuracy = 1; // seeker accuracy multiplier
|
||||
|
||||
seekerMinRange = 1;
|
||||
seekerMaxRange = 2500; // Range from the missile which the seeker can visually search
|
||||
|
||||
// Attack profile type selection
|
||||
defaultAttackProfile = "LIN";
|
||||
attackProfiles[] = { "LIN", "DIR", "MID", "HI", "TOP", "PYM" };
|
||||
};
|
||||
};
|
@ -1,3 +1,2 @@
|
||||
#include "script_component.hpp"
|
||||
NO_DEDICATED;
|
||||
|
||||
|
@ -3,12 +3,21 @@
|
||||
PREP(rotateVectLineGetMap);
|
||||
PREP(rotateVectLine);
|
||||
|
||||
PREP(translateToModelSpace);
|
||||
PREP(translateToWeaponSpace);
|
||||
|
||||
PREP(fired);
|
||||
|
||||
PREP(guidance_DAGR);
|
||||
PREP(guidance_LGB);
|
||||
PREP(guidance_HellfireII);
|
||||
FUNC(getPosASL) = {visiblePositionASL (_this select 0)};
|
||||
PREP(guidancePFH);
|
||||
PREP(doAttackProfile);
|
||||
PREP(doSeekerSearch);
|
||||
|
||||
// Attack Profiles
|
||||
PREP(attackProfile_LIN);
|
||||
PREP(attackProfile_DIR);
|
||||
PREP(attackProfile_MID);
|
||||
PREP(attackProfile_HI);
|
||||
PREP(attackProfile_TOP);
|
||||
PREP(attackprofile_PYM);
|
||||
PREP(attackProfile_AIR);
|
||||
|
||||
// Seeker search functions
|
||||
PREP(seekerType_SALH);
|
||||
PREP(seekerType_Optic);
|
@ -10,6 +10,11 @@ class CfgPatches {
|
||||
};
|
||||
};
|
||||
|
||||
#include "ACE_GuidanceConfig.hpp"
|
||||
#include "ACE_Settings.hpp"
|
||||
|
||||
#include "CfgEventhandlers.hpp"
|
||||
#include "CfgAmmo.hpp"
|
||||
#include "CfgWeapons.hpp"
|
||||
#include "CfgMagazines.hpp"
|
||||
#include "CfgWeapons.hpp"
|
||||
#include "CfgVehicles.hpp"
|
||||
|
54
addons/missileguidance/functions/fnc_attackProfile_AIR.sqf
Normal file
54
addons/missileguidance/functions/fnc_attackProfile_AIR.sqf
Normal file
@ -0,0 +1,54 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
private["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"];
|
||||
private["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos"];
|
||||
_seekerTargetPos = _this select 0;
|
||||
_launchParams = _this select 1;
|
||||
|
||||
_target = _launchParams select 0;
|
||||
_targetLaunchParams = _launchParams select 1;
|
||||
|
||||
_shooterPos = getPosASL _shooter;
|
||||
_projectilePos = getPosASL _projectile;
|
||||
|
||||
_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos;
|
||||
_distanceToShooter = _projectilePos vectorDistance _shooterPos;
|
||||
|
||||
TRACE_2("", _distanceToTarget, _distanceToShooter);
|
||||
|
||||
// Add height depending on distance for compensate
|
||||
_addHeight = [0,0,0];
|
||||
|
||||
// Always climb an arc on initial launch if we are close to the round
|
||||
if( ((ASLtoATL _projectilePos) select 2) < 5 && _distanceToShooter < 15) then {
|
||||
_addHeight = _addHeight vectorAdd [0,0,_distanceToTarget];
|
||||
} else {
|
||||
// If we are below the target, increase the climbing arc
|
||||
if((_projectilePos select 2) < (_seekerTargetPos select 2) && _distanceToTarget > 100) then {
|
||||
_addHeight = _addHeight vectorAdd [0,0, ((_seekerTargetPos select 2) - (_projectilePos select 2))];
|
||||
};
|
||||
};
|
||||
|
||||
// Handle arcing terminal low for high decent
|
||||
if( (_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget < 100) then {
|
||||
_addHeight = _addHeight vectorDiff [0,0, ((_projectilePos select 2) - (_seekerTargetPos select 2))];
|
||||
} else {
|
||||
if((_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget > 100) then {
|
||||
_addHeight = _addHeight vectorAdd [0,0, _distanceToTarget];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
TRACE_3("", _distanceToTarget,_distanceToShooter,_addHeight);
|
||||
|
||||
_returnTargetPos = _seekerTargetPos vectorAdd _addHeight;
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawLine3D [(ASLtoATL _returnTargetPos) vectorAdd _addHeight, ASLtoATL _returnTargetPos, [0,1,0,1]];
|
||||
#endif
|
||||
|
||||
TRACE_1("Adjusted target position", _returnTargetPos);
|
||||
_returnTargetPos;
|
@ -0,0 +1,4 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
_this call FUNC(attackProfile_LIN);
|
@ -0,0 +1,4 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
_this call FUNC(attackProfile_LIN);
|
54
addons/missileguidance/functions/fnc_attackProfile_LIN.sqf
Normal file
54
addons/missileguidance/functions/fnc_attackProfile_LIN.sqf
Normal file
@ -0,0 +1,54 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
private["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"];
|
||||
private["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos"];
|
||||
_seekerTargetPos = _this select 0;
|
||||
_launchParams = _this select 1;
|
||||
|
||||
_target = _launchParams select 0;
|
||||
_targetLaunchParams = _launchParams select 1;
|
||||
|
||||
_shooterPos = getPosASL _shooter;
|
||||
_projectilePos = getPosASL _projectile;
|
||||
|
||||
_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos;
|
||||
_distanceToShooter = _projectilePos vectorDistance _shooterPos;
|
||||
|
||||
TRACE_2("", _distanceToTarget, _distanceToShooter);
|
||||
|
||||
// Add height depending on distance for compensate
|
||||
_addHeight = [0,0,0];
|
||||
|
||||
// Always climb an arc on initial launch if we are close to the round
|
||||
if( ((ASLtoATL _projectilePos) select 2) < 5 && _distanceToShooter < 15) then {
|
||||
_addHeight = _addHeight vectorAdd [0,0,_distanceToTarget];
|
||||
} else {
|
||||
// If we are below the target, increase the climbing arc
|
||||
if((_projectilePos select 2) < (_seekerTargetPos select 2) && _distanceToTarget > 100) then {
|
||||
_addHeight = _addHeight vectorAdd [0,0, ((_seekerTargetPos select 2) - (_projectilePos select 2))];
|
||||
};
|
||||
};
|
||||
|
||||
// Handle arcing terminal low for high decent
|
||||
if( (_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget < 100) then {
|
||||
_addHeight = _addHeight vectorDiff [0,0, ((_projectilePos select 2) - (_seekerTargetPos select 2)) * 0.5];
|
||||
} else {
|
||||
if((_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget > 100) then {
|
||||
_addHeight = _addHeight vectorAdd [0,0, _distanceToTarget*0.02];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
TRACE_3("", _distanceToTarget,_distanceToShooter,_addHeight);
|
||||
|
||||
_returnTargetPos = _seekerTargetPos vectorAdd _addHeight;
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawLine3D [(ASLtoATL _returnTargetPos) vectorAdd _addHeight, ASLtoATL _returnTargetPos, [0,1,0,1]];
|
||||
#endif
|
||||
|
||||
TRACE_1("Adjusted target position", _returnTargetPos);
|
||||
_returnTargetPos;
|
@ -0,0 +1,4 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
_this call FUNC(attackProfile_LIN);
|
@ -0,0 +1,4 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
_this call FUNC(attackProfile_LIN);
|
52
addons/missileguidance/functions/fnc_attackProfile_TOP.sqf
Normal file
52
addons/missileguidance/functions/fnc_attackProfile_TOP.sqf
Normal file
@ -0,0 +1,52 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
private["_targetPos", "_projectilePos", "_target", "_seekerTargetPos", "_launchParams", "_targetLaunchParams"];
|
||||
private["_distanceToTarget", "_distanceToShooter", "_addHeight", "_returnTargetPos"];
|
||||
_seekerTargetPos = _this select 0;
|
||||
_launchParams = _this select 1;
|
||||
|
||||
_target = _launchParams select 0;
|
||||
_targetLaunchParams = _launchParams select 1;
|
||||
|
||||
_shooterPos = getPosASL _shooter;
|
||||
_projectilePos = getPosASL _projectile;
|
||||
|
||||
_distanceToTarget = _projectilePos vectorDistance _seekerTargetPos;
|
||||
_distanceToShooter = _projectilePos vectorDistance _shooterPos;
|
||||
|
||||
TRACE_2("", _distanceToTarget, _distanceToShooter);
|
||||
|
||||
// Add height depending on distance for compensate
|
||||
_addHeight = [0,0,0];
|
||||
|
||||
// Always climb an arc on initial launch if we are close to the round
|
||||
if( ((ASLtoATL _projectilePos) select 2) < 140 && _distanceToShooter < 50) then {
|
||||
_addHeight = _addHeight vectorAdd [0,0,_distanceToTarget];
|
||||
} else {
|
||||
// If we are below the target, increase the climbing arc
|
||||
if((_projectilePos select 2) < (_seekerTargetPos select 2) + 140 && _distanceToTarget > 100) then {
|
||||
_addHeight = _addHeight vectorAdd [0,0, ((_seekerTargetPos select 2) - (_projectilePos select 2))+50];
|
||||
};
|
||||
};
|
||||
|
||||
// Handle arcing terminal low for high decent
|
||||
if( (_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget < 140) then {
|
||||
_addHeight = _addHeight vectorDiff [0,0, ((_projectilePos select 2) - (_seekerTargetPos select 2)) * 0.5];
|
||||
} else {
|
||||
if((_projectilePos select 2) > (_seekerTargetPos select 2) && _distanceToTarget > 140) then {
|
||||
_addHeight = _addHeight vectorAdd [0,0, ((_projectilePos select 2) - (_seekerTargetPos select 2)) * 0.02];
|
||||
};
|
||||
};
|
||||
|
||||
TRACE_3("", _distanceToTarget,_distanceToShooter,_addHeight);
|
||||
|
||||
_returnTargetPos = _seekerTargetPos vectorAdd _addHeight;
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawLine3D [(ASLtoATL _returnTargetPos) vectorAdd _addHeight, ASLtoATL _returnTargetPos, [0,1,0,1]];
|
||||
#endif
|
||||
|
||||
TRACE_1("Adjusted target position", _returnTargetPos);
|
||||
_returnTargetPos;
|
30
addons/missileguidance/functions/fnc_doAttackProfile.sqf
Normal file
30
addons/missileguidance/functions/fnc_doAttackProfile.sqf
Normal file
@ -0,0 +1,30 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
private["_attackProfilePos"];
|
||||
|
||||
_launchParams = ((_this select 1) select 1);
|
||||
_attackProfileName = _launchParams select 3;
|
||||
|
||||
TRACE_1("Attacking profile", _attackProfileName);
|
||||
|
||||
_attackProfilesCfg = ( configFile >> QGVAR(AttackProfiles) );
|
||||
|
||||
_attackProfile = nil;
|
||||
for [{_i=0}, {_i< (count _attackProfilesCfg) }, {_i=_i+1}] do {
|
||||
_testProfile = _attackProfilesCfg select _i;
|
||||
_testName = configName _testProfile;
|
||||
TRACE_3("", _testName, _testProfile, _attackProfilesCfg);
|
||||
|
||||
if( _testName == _attackProfileName) exitWith {
|
||||
_attackProfile = _attackProfilesCfg select _i;
|
||||
};
|
||||
};
|
||||
|
||||
_attackProfilePos = [0,0,0];
|
||||
if(!isNil "_attackProfile") then {
|
||||
_attackProfilePos = _this call (missionNamespace getVariable (getText (_attackProfile >> "functionName")));
|
||||
};
|
||||
|
||||
_attackProfilePos;
|
30
addons/missileguidance/functions/fnc_doSeekerSearch.sqf
Normal file
30
addons/missileguidance/functions/fnc_doSeekerSearch.sqf
Normal file
@ -0,0 +1,30 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
private["_seekerProfilePos"];
|
||||
|
||||
_launchParams = ((_this select 1) select 1);
|
||||
_seekerTypeName = _launchParams select 2;
|
||||
|
||||
TRACE_1("Seeker type", _seekerTypeName);
|
||||
|
||||
_seekerTypesCfg = ( configFile >> QGVAR(SeekerTypes) );
|
||||
|
||||
_seekerType = nil;
|
||||
for [{_i=0}, {_i< (count _seekerTypesCfg) }, {_i=_i+1}] do {
|
||||
_testProfile = _seekerTypesCfg select _i;
|
||||
_testName = configName _testProfile;
|
||||
TRACE_3("", _testName, _testProfile, _seekerTypesCfg);
|
||||
|
||||
if( _testName == _seekerTypeName) exitWith {
|
||||
_seekerType = _seekerTypesCfg select _i;
|
||||
};
|
||||
};
|
||||
|
||||
_seekerProfilePos = [0,0,0];
|
||||
if(!isNil "_seekerType") then {
|
||||
_seekerProfilePos = _this call (missionNamespace getVariable (getText (_seekerType >> "functionName")));
|
||||
};
|
||||
|
||||
_seekerProfilePos;
|
@ -1,18 +1,80 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
//_this=[TEST_AI_HELICOPTER,"missiles_DAGR","missiles_DAGR","Far_AI","M_PG_AT","24Rnd_PG_missiles",163988: rocket_01_fly_f.p3d]
|
||||
TRACE_1("enter", _this);
|
||||
|
||||
// Bail if guidance is disabled
|
||||
if(!GVAR(enabled)) exitWith { false };
|
||||
|
||||
// Bail on locality of the projectile, it should be local to us
|
||||
if(!local _projectile) exitWith { false };
|
||||
|
||||
private["_config", "_enabled", "_target", "_seekerType", "_attackProfile"];
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
|
||||
if(!local _shooter) exitWith { false };
|
||||
// Bail on not missile
|
||||
if(! (_ammo isKindOf "MissileBase") ) exitWith { false };
|
||||
|
||||
switch _weapon do {
|
||||
case "missiles_DAGR": {
|
||||
_this call FUNC(guidance_DAGR);
|
||||
};
|
||||
case "GBU12BombLauncher": {
|
||||
_this call FUNC(guidance_LGB);
|
||||
_config = configFile >> "CfgAmmo" >> _ammo >> "ACE_MissileGuidance";
|
||||
_enabled = getNumber ( _config >> "enabled");
|
||||
|
||||
// Bail if guidance is not enabled
|
||||
if(isNil "_enabled" || {_enabled != 1}) exitWith { false };
|
||||
|
||||
_target = (vehicle _shooter) getVariable [QGVAR(target), nil];
|
||||
_seekerType = (vehicle _shooter) getVariable [QGVAR(seekerType), nil];
|
||||
_attackProfile = (vehicle _shooter) getVariable [QGVAR(attackProfile), nil];
|
||||
_lockMode = (vehicle _shooter) getVariable [QGVAR(lockMode), nil];
|
||||
|
||||
TRACE_3("Begin guidance", _target, _seekerType, _attackProfile);
|
||||
|
||||
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 {
|
||||
_canUseLock = getNumber (_config >> "canVanillaLock");
|
||||
if(_canUseLock > 0) then {
|
||||
// @TODO: Get vanilla target
|
||||
_vanillaTarget = cursorTarget;
|
||||
|
||||
TRACE_1("Using Vanilla Locking", _vanillaTarget);
|
||||
if(!isNil "_vanillaTarget") then {
|
||||
_target = _vanillaTarget;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
//_this call FUNC(guidance_HellfireII);
|
||||
TRACE_4("Beginning ACE guidance system",_target,_ammo,_seekerType,_attackProfile);
|
||||
[FUNC(guidancePFH), 0, [_this,
|
||||
[ACE_player,
|
||||
[_target, _targetPos, _launchPos],
|
||||
_seekerType,
|
||||
_attackProfile,
|
||||
_lockMode
|
||||
],
|
||||
[
|
||||
getNumber ( _config >> "minDeflection" ),
|
||||
getNumber ( _config >> "maxDeflection" ),
|
||||
getNumber ( _config >> "incDeflection" )
|
||||
],
|
||||
[
|
||||
getNumber ( _config >> "seekerAngle" ),
|
||||
getNumber ( _config >> "seekerAccuracy" ),
|
||||
getNumber ( _config >> "seekerMaxRange" )
|
||||
],
|
||||
[ diag_tickTime ]
|
||||
]
|
||||
] call cba_fnc_addPerFrameHandler;
|
||||
|
||||
/* Clears locking settings
|
||||
(vehicle _shooter) setVariable [QGVAR(target), nil];
|
||||
(vehicle _shooter) setVariable [QGVAR(seekerType), nil];
|
||||
(vehicle _shooter) setVariable [QGVAR(attackProfile), nil];
|
||||
(vehicle _shooter) setVariable [QGVAR(lockMode), nil];
|
||||
*/
|
97
addons/missileguidance/functions/fnc_guidancePFH.sqf
Normal file
97
addons/missileguidance/functions/fnc_guidancePFH.sqf
Normal file
@ -0,0 +1,97 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
#define TIMESTEP_FACTOR 0.01
|
||||
|
||||
private["_args", "_stateParams", "_launchParams", "_targetLaunchParams", "_config", "_flightParams", "_seekerParams", "_seekerTargetPos"];
|
||||
private["_lastRunTime", "_runtimeDelta", "_profileAdjustedTargetPos", "_targetVectorSeeker", "_targetVector"];
|
||||
private["_minDeflection", "_maxDeflection", "_incDeflection"];
|
||||
private["_yVec", "_zVec", "_xVec"];
|
||||
|
||||
_args = _this select 0;
|
||||
EXPLODE_7_PVT((_args select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
|
||||
_launchParams = _args select 1;
|
||||
_targetLaunchParams = _launchParams select 1;
|
||||
_flightParams = _args select 2;
|
||||
_seekerParams = _args select 3;
|
||||
|
||||
_stateParams = _args select 4;
|
||||
|
||||
_lastRunTime = _stateParams select 0;
|
||||
_runtimeDelta = diag_tickTime - _lastRunTime;
|
||||
|
||||
_config = configFile >> "CfgAmmo" >> _ammo >> "ACE_MissileGuidance";
|
||||
|
||||
if(!alive _projectile || isNull _projectile || isNull _shooter) exitWith {
|
||||
[(_this select 1)] call cba_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
// TODO: placeholder for "last seek target position"
|
||||
_seekerTargetPos = [ [0,0,0], _args] call FUNC(doSeekerSearch);
|
||||
if(!isNil "_seekerTargetPos") then {
|
||||
|
||||
_profileAdjustedTargetPos = [_seekerTargetPos,_args] call FUNC(doAttackProfile);
|
||||
|
||||
_minDeflection = _flightParams select 0;
|
||||
_maxDeflection = _flightParams select 1;
|
||||
_incDeflection = _flightParams select 2;
|
||||
|
||||
_yVec = vectorDir _projectile;
|
||||
_zVec = vectorUp _projectile;
|
||||
_xVec = vectorNormalized (_yVec vectorCrossProduct _zVec);
|
||||
|
||||
_projectilePos = getPosASL _projectile;
|
||||
|
||||
_targetVectorSeeker = [_projectile, [_xVec, _yVec, _zVec], _profileAdjustedTargetPos] call EFUNC(common,translateToWeaponSpace);
|
||||
_targetVector = [0,0,0] vectorFromTo _targetVectorSeeker;
|
||||
TRACE_1("", _targetVectorSeeker, _targetVector);
|
||||
|
||||
private["_yaw", "_pitch"];
|
||||
_yaw = 0;
|
||||
_pitch = 0;
|
||||
|
||||
if((_targetVectorSeeker select 0) < 0) then {
|
||||
_yaw = - ( (_minDeflection max (abs(_targetVector select 0) min _maxDeflection) ) );
|
||||
} else {
|
||||
if((_targetVectorSeeker select 0) > 0) then {
|
||||
_yaw = ( (_minDeflection max ((_targetVector select 0) min _maxDeflection) ) );
|
||||
};
|
||||
};
|
||||
if((_targetVectorSeeker select 2) < 0) then {
|
||||
_pitch = - ( (_minDeflection max (abs(_targetVector select 2) min _maxDeflection) ) );
|
||||
} else {
|
||||
if((_targetVectorSeeker select 2) > 0) then {
|
||||
_pitch = ( (_minDeflection max ((_targetVector select 2) min _maxDeflection) ) );
|
||||
};
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoATL _projectilePos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"];
|
||||
drawLine3D [ASLtoATL _projectilePos, ASLtoATL _profileAdjustedTargetPos, [1,0,0,1]];
|
||||
#endif
|
||||
|
||||
if(accTime > 0) then {
|
||||
private["_adjustTime", "_outVector", "_vectorTo"];
|
||||
_adjustTime = 1/accTime;
|
||||
_adjustTime = _adjustTime * (_runtimeDelta / TIMESTEP_FACTOR);
|
||||
TRACE_4("Adjust timing", 1/accTime, _adjustTime, _runtimeDelta, (_runtimeDelta / TIMESTEP_FACTOR) );
|
||||
|
||||
// @TODO: Apply velocity multiplier to yaw/pitch. Basically, it can adjust faster at lower speeds
|
||||
//_adjustDeflection = (vectorMagnitude velocity _projectile);
|
||||
|
||||
_outVector = [_projectile, [_xVec, _yVec, _zVec], [_yaw, _adjustTime, _pitch]] call EFUNC(common,translateToModelSpace);
|
||||
_vectorTo = _projectilePos vectorFromTo _outVector;
|
||||
|
||||
_projectile setVectorDirAndUp [_vectorTo, vectorUp _projectile];
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
hintSilent format["d: %1", _distanceToTarget];
|
||||
#endif
|
||||
};
|
||||
|
||||
_stateParams set[0, diag_tickTime];
|
||||
|
||||
_args set[4, _stateParams];
|
||||
_this set[0, _args];
|
@ -1,120 +0,0 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
FUNC(guidance_DIRECT_LOAL_PFH) = {
|
||||
//TRACE_1("enter", _this);
|
||||
private["_args", "_shooter", "_dagr", "_curVelocity", "_targets", "_target", "_yVec", "_xVec", "_zVec", "_dagrPos", "_shooterPos", "_distanceToTarget", "_distanceToShooter", "_def"];
|
||||
_args = _this select 0;
|
||||
//PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
_shooter = _args select 0;
|
||||
_dagr = _args select 6;
|
||||
_curVelocity = velocity _dagr;
|
||||
|
||||
if(!alive _dagr || isNull _dagr || isNull _shooter) exitWith {
|
||||
[(_this select 1)] call cba_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
_targets = [_dagr, ACE_DEFAULT_LASER_CODE, 70, _curVelocity] call ace_laser_fnc_findLaserDesignator;
|
||||
TRACE_2("Targets", _target, _targets);
|
||||
|
||||
if((_targets select 0)) then {
|
||||
_target = _targets select 1;
|
||||
|
||||
// player sideChat "FUCK!";
|
||||
// drop ["\a3\data_f\Cl_basic","","Billboard",1,20,(getPos _dagr),[0,0,0],1,1.275,1.0,0.0,[5],[[1,0,0,1]],[0],0.0,2.0,"","",""];
|
||||
|
||||
|
||||
_yVec = vectorDir _dagr;
|
||||
_zVec = vectorUp _dagr;
|
||||
_xVec = vectorNormalized (_yVec vectorCrossProduct _zVec);
|
||||
|
||||
_dagrPos = getPosASL _dagr;
|
||||
// player sideChat "G!";
|
||||
_targetPos = getPosASL _target;
|
||||
_shooterPos = getPosASL _shooter;
|
||||
|
||||
if((count _targetPos) > 0) then {
|
||||
_distanceToTarget = _dagrPos vectorDistance _targetPos;
|
||||
_distanceToShooter = _dagrPos vectorDistance _shooterPos;
|
||||
|
||||
_addHeight = [0,0,(_dagrPos distance _targetPos)*0.02];
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawLine3D [(ASLtoATL _targetPos) vectorAdd _addHeight, ASLtoATL _targetPos, [0,1,0,1]];
|
||||
#endif
|
||||
|
||||
_targetPos = _targetPos vectorAdd _addHeight;
|
||||
|
||||
_def = 0.0040;
|
||||
if(_distanceToShooter > 100) then {
|
||||
_def = 0.0025;
|
||||
};
|
||||
|
||||
_targetVectorSeeker = [_dagr, [_xVec, _yVec, _zVec], _targetPos] call FUNC(translateToWeaponSpace);
|
||||
// _targetVectorSeeker = _dagr worldToModel (ASLtoATL _targetPos);
|
||||
// _targetVectorSeeker = [0,0,0] vectorFromTo _targetVectorSeeker;
|
||||
_yaw = 0.0;
|
||||
if((_targetVectorSeeker select 0) < 0) then {
|
||||
_yaw = -_def;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 0) > 0) then {
|
||||
_yaw = _def;
|
||||
};
|
||||
};
|
||||
|
||||
_pitch = 0.0;
|
||||
if((_targetVectorSeeker select 2) < 0) then {
|
||||
_pitch = -_def;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 2) > 0) then {
|
||||
_pitch = _def;
|
||||
};
|
||||
};
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoATL _dagrPos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"];
|
||||
drawLine3D [ASLtoATL _dagrPos, ASLtoATL _targetPos, [1,0,0,1]];
|
||||
|
||||
_distance = ([getPos startPos, _dagrPos] call BIS_fnc_distance2D);
|
||||
_marker = createMarkerLocal [format["m%1", MARKERCOUNT], [_distance, _dagrPos select 2]];
|
||||
_marker setMarkerTypeLocal "mil_dot";
|
||||
_marker setMarkerColorLocal "ColorRed";
|
||||
|
||||
MARKERCOUNT = MARKERCOUNT + 1;
|
||||
#endif
|
||||
|
||||
if(accTime > 0) then {
|
||||
_outVector = [_dagr, [_xVec, _yVec, _zVec], [_yaw, 1/accTime, _pitch]] call FUNC(translateToModelSpace);
|
||||
// _outVector = _dagr modelToWorldVisual [_yaw, 1, _pitch];
|
||||
// _outVector = ATLtoASL _outVector;
|
||||
_vectorTo = _dagrPos vectorFromTo _outVector;
|
||||
|
||||
// hintSilent format["v: %1", _vectorTo];
|
||||
|
||||
// _dagr setVectorDir _vectorTo;
|
||||
_dagr setVectorDirAndUp [_vectorTo, vectorUp _dagr];
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
hintSilent format["d: %1", _distanceToTarget];
|
||||
#endif
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
FUNC(guidance_DAGR_DIRECT_LOAL) = {
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
|
||||
GVAR(lastTime) = time;
|
||||
[FUNC(guidance_DIRECT_LOAL_PFH), 0, _this] call cba_fnc_addPerFrameHandler;
|
||||
};
|
||||
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
_fireMode = _shooter getVariable ["ACE_FIRE_SELECTION", ACE_DEFAULT_FIRE_SELECTION];
|
||||
|
||||
switch (_fireMode select 0) do {
|
||||
// Default to FIREMODE_DIRECT_LOAL
|
||||
// FIREMODE_DIRECT_LOAL
|
||||
default {
|
||||
LOG("Initiating DAGR FIREMODE_DIRECT_LOAL");
|
||||
_this call FUNC(guidance_DAGR_DIRECT_LOAL);
|
||||
};
|
||||
};
|
@ -1,249 +0,0 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
FUNC(guidance_Hellfire_LOAL_HI_PFH) = {
|
||||
//TRACE_1("enter", _this);
|
||||
_args = _this select 0;
|
||||
//PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
_shooter = _args select 0;
|
||||
_missile = _args select 6;
|
||||
_curVelocity = velocity _missile;
|
||||
|
||||
if(!alive _missile || isNull _missile || isNull _shooter) exitWith {
|
||||
[(_this select 1)] call cba_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
_launchPos = _shooter getVariable [QGVAR(launchPos), nil];
|
||||
if(isNil "_launchPos") then {
|
||||
TRACE_1("Setting launch parameters", "");
|
||||
_launchPos = getPosASL _shooter;
|
||||
_shooter setVariable [QGVAR(launchPos), _launchPos, false];
|
||||
_shooter setVariable [QGVAR(launchTime), diag_tickTime, false];
|
||||
};
|
||||
|
||||
_targets = [_missile, ACE_DEFAULT_LASER_CODE, 70, _curVelocity] call ace_laser_fnc_findLaserDesignator;
|
||||
_addHeight = [0,0,0];
|
||||
if((_targets select 0)) then {
|
||||
_target = _targets select 1;
|
||||
TRACE_2("Targets", _target, _targets);
|
||||
|
||||
_yVec = vectorDir _missile;
|
||||
_zVec = vectorUp _missile;
|
||||
_xVec = vectorNormalized (_yVec vectorCrossProduct _zVec);
|
||||
|
||||
_missilePos = getPosASL _missile;
|
||||
// player sideChat "G!";
|
||||
_targetPos = getPosASL _target;
|
||||
TRACE_4("Phase Check", _launchPos, _missilePos, _targetPos, (_missilePos distance _targetPos));
|
||||
if((count _targetPos) > 0) then {
|
||||
_distanceToTarget = _missilePos vectorDistance _targetPos;
|
||||
|
||||
_defPitch = 0.05;
|
||||
|
||||
if((_launchPos distance _missilePos) < 400 && (_targetPos distance _missilePos) > 400) then {
|
||||
_addHeight = [0,0,(_targetPos select 2) + ((_launchPos distance _targetPos)*2)];
|
||||
TRACE_1("Climb phase", _addHeight);
|
||||
//_defPitch = 0.1;
|
||||
} else {
|
||||
// Covered half the distance, go terminal
|
||||
if((_missilePos distance _targetPos) < (_launchPos distance _targetPos) / 2) then {
|
||||
TRACE_1("TERMINAL", "");
|
||||
} else {
|
||||
if((_missilePos select 2) > (_targetPos select 2)) then {
|
||||
_heightDiff = (_missilePos select 2) - (_targetPos select 2);
|
||||
TRACE_1("Coasting", _heightDiff);
|
||||
_addHeight = [0,0, _heightDiff];
|
||||
};
|
||||
};
|
||||
};
|
||||
_targetPos = _targetPos vectorAdd _addHeight;
|
||||
|
||||
_defYaw = 0.0035;
|
||||
|
||||
|
||||
_targetVectorSeeker = [_missile, [_xVec, _yVec, _zVec], _targetPos] call FUNC(translateToWeaponSpace);
|
||||
_yaw = 0.0;
|
||||
if((_targetVectorSeeker select 0) < 0) then {
|
||||
_yaw = -_defYaw;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 0) > 0) then {
|
||||
_yaw = _defYaw;
|
||||
};
|
||||
};
|
||||
|
||||
_pitch = 0.0;
|
||||
if((_targetVectorSeeker select 2) < 0) then {
|
||||
_pitch = -_defPitch;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 2) > 0) then {
|
||||
_pitch = _defPitch;
|
||||
};
|
||||
};
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawLine3D [(ASLtoATL _targetPos) vectorAdd _addHeight, ASLtoATL _targetPos, [0,1,0,1]];
|
||||
|
||||
_light = "#lightpoint" createVehicleLocal (getPos _missile);
|
||||
_light setLightBrightness 1.0;
|
||||
_light setLightAmbient [1.0, 0.0, 0.0];
|
||||
_light setLightColor [1.0, 0.0, 0.0];
|
||||
|
||||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoATL _missilePos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"];
|
||||
drawLine3D [ASLtoATL _missilePos, ASLtoATL _targetPos, [1,0,0,1]];
|
||||
|
||||
_distance = ([getPos startPos, _missilePos] call BIS_fnc_distance2D);
|
||||
_marker = createMarkerLocal [format["m%1", MARKERCOUNT], [_distance, _missilePos select 2]];
|
||||
_marker setMarkerTypeLocal "mil_dot";
|
||||
_marker setMarkerColorLocal "ColorRed";
|
||||
|
||||
MARKERCOUNT = MARKERCOUNT + 1;
|
||||
#endif
|
||||
|
||||
if(accTime > 0) then {
|
||||
_outVector = [_missile, [_xVec, _yVec, _zVec], [_yaw, 1/accTime, _pitch]] call FUNC(translateToModelSpace);
|
||||
|
||||
_vectorTo = _missilePos vectorFromTo _outVector;
|
||||
_missile setVectorDirAndUp [_vectorTo, vectorUp _missile];
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
hintSilent format["d: %1", _distanceToTarget];
|
||||
#endif
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
FUNC(guidance_Hellfire_LOAL_DIR_PFH) = {
|
||||
//TRACE_1("enter", _this);
|
||||
_args = _this select 0;
|
||||
//PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
_shooter = _args select 0;
|
||||
_missile = _args select 6;
|
||||
_curVelocity = velocity _missile;
|
||||
|
||||
if(!alive _missile || isNull _missile || isNull _shooter) exitWith {
|
||||
[(_this select 1)] call cba_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
_launchPos = _shooter getVariable [QGVAR(launchPos), nil];
|
||||
if(isNil "_launchPos") then {
|
||||
TRACE_1("Setting launch parameters", "");
|
||||
_launchPos = getPosASL _shooter;
|
||||
_shooter setVariable [QGVAR(launchPos), _launchPos, false];
|
||||
_shooter setVariable [QGVAR(launchTime), diag_tickTime, false];
|
||||
};
|
||||
|
||||
_targets = [_missile, ACE_DEFAULT_LASER_CODE, 70, _curVelocity] call ace__laser_fnc_findLaserDesignator;
|
||||
_addHeight = [0,0,0];
|
||||
if((_targets select 0)) then {
|
||||
_target = _targets select 1;
|
||||
TRACE_2("Targets", _target, _targets);
|
||||
|
||||
_yVec = vectorDir _missile;
|
||||
_zVec = vectorUp _missile;
|
||||
_xVec = vectorNormalized (_yVec vectorCrossProduct _zVec);
|
||||
|
||||
_missilePos = getPosASL _missile;
|
||||
// player sideChat "G!";
|
||||
_targetPos = getPosASL _target;
|
||||
TRACE_4("Phase Check", _launchPos, _missilePos, _targetPos, (_missilePos distance _targetPos));
|
||||
if((count _targetPos) > 0) then {
|
||||
_distanceToTarget = _missilePos vectorDistance _targetPos;
|
||||
|
||||
if((_launchPos distance _missilePos) < 400 && (_targetPos distance _missilePos) > 400) then {
|
||||
_addHeight = [0,0,(_targetPos select 2) + (_missilePos distance _targetPos)*0.5];
|
||||
TRACE_1("Climb phase", _addHeight);
|
||||
} else {
|
||||
// Covered half the distance, go terminal
|
||||
if((_missilePos distance _targetPos) < (_launchPos distance _targetPos) / 2) then {
|
||||
TRACE_1("TERMINAL", "");
|
||||
} else {
|
||||
if((_missilePos select 2) > (_targetPos select 2)) then {
|
||||
_heightDiff = (_missilePos select 2) - (_targetPos select 2);
|
||||
TRACE_1("Coasting", _heightDiff);
|
||||
_addHeight = [0,0, _heightDiff];
|
||||
};
|
||||
};
|
||||
};
|
||||
_targetPos = _targetPos vectorAdd _addHeight;
|
||||
|
||||
_defYaw = 0.0035;
|
||||
_defPitch = 0.0075;
|
||||
|
||||
_targetVectorSeeker = [_missile, [_xVec, _yVec, _zVec], _targetPos] call FUNC(translateToWeaponSpace);
|
||||
_yaw = 0.0;
|
||||
if((_targetVectorSeeker select 0) < 0) then {
|
||||
_yaw = -_defYaw;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 0) > 0) then {
|
||||
_yaw = _defYaw;
|
||||
};
|
||||
};
|
||||
|
||||
_pitch = 0.0;
|
||||
if((_targetVectorSeeker select 2) < 0) then {
|
||||
_pitch = -_defPitch;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 2) > 0) then {
|
||||
_pitch = _defPitch;
|
||||
};
|
||||
};
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawLine3D [(ASLtoATL _targetPos) vectorAdd _addHeight, ASLtoATL _targetPos, [0,1,0,1]];
|
||||
|
||||
_light = "#lightpoint" createVehicleLocal (getPos _missile);
|
||||
_light setLightBrightness 1.0;
|
||||
_light setLightAmbient [1.0, 0.0, 0.0];
|
||||
_light setLightColor [1.0, 0.0, 0.0];
|
||||
|
||||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoATL _missilePos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"];
|
||||
drawLine3D [ASLtoATL _missilePos, ASLtoATL _targetPos, [1,0,0,1]];
|
||||
|
||||
_distance = ([getPos startPos, _missilePos] call BIS_fnc_distance2D);
|
||||
_marker = createMarkerLocal [format["m%1", MARKERCOUNT], [_distance, _missilePos select 2]];
|
||||
_marker setMarkerTypeLocal "mil_dot";
|
||||
_marker setMarkerColorLocal "ColorRed";
|
||||
|
||||
MARKERCOUNT = MARKERCOUNT + 1;
|
||||
#endif
|
||||
|
||||
if(accTime > 0) then {
|
||||
_outVector = [_missile, [_xVec, _yVec, _zVec], [_yaw, 1/accTime, _pitch]] call FUNC(translateToModelSpace);
|
||||
|
||||
_vectorTo = _missilePos vectorFromTo _outVector;
|
||||
_missile setVectorDirAndUp [_vectorTo, vectorUp _missile];
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
hintSilent format["d: %1", _distanceToTarget];
|
||||
#endif
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
FUNC(guidance_Hellfire_LOAL_HI) = {
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
|
||||
GVAR(lastTime) = time;
|
||||
[FUNC(guidance_Hellfire_LOAL_HI_PFH), 0, _this] call cba_fnc_addPerFrameHandler;
|
||||
};
|
||||
|
||||
|
||||
FUNC(guidance_Hellfire_LOAL_DIR) = {
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
|
||||
GVAR(lastTime) = time;
|
||||
[FUNC(guidance_Hellfire_LOAL_DIR_PFH), 0, _this] call cba_fnc_addPerFrameHandler;
|
||||
};
|
||||
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
_fireMode = _shooter getVariable ["ACE_FIRE_SELECTION", ACE_DEFAULT_FIRE_SELECTION];
|
||||
|
||||
switch (_fireMode select 0) do {
|
||||
// Default to FIREMODE_DIRECT_LOAL
|
||||
// FIREMODE_DIRECT_LOAL
|
||||
default {
|
||||
LOG("Initiating Hellfire II FIREMODE_LOAL_DIR");
|
||||
_this call FUNC(guidance_Hellfire_LOAL_HI);
|
||||
};
|
||||
};
|
@ -1,109 +0,0 @@
|
||||
#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
FUNC(guidance_LGB_LOAL_PFH) = {
|
||||
//TRACE_1("enter", _this);
|
||||
_args = _this select 0;
|
||||
//PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
_lgb = _args select 6;
|
||||
_curVelocity = velocity _lgb;
|
||||
|
||||
if(!alive _lgb) exitWith {
|
||||
[(_this select 1)] call cba_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
_targets = [_lgb, ACE_DEFAULT_LASER_CODE, 70, _curVelocity] call uo_laser_fnc_findLaserDesignator;
|
||||
//TRACE_2("Targets", _target, _targets);
|
||||
|
||||
if((_targets select 0)) then {
|
||||
_target = _targets select 1;
|
||||
|
||||
// player sideChat "FUCK!";
|
||||
// drop ["\a3\data_f\Cl_basic","","Billboard",1,20,(getPos _lgb),[0,0,0],1,1.275,1.0,0.0,[5],[[1,0,0,1]],[0],0.0,2.0,"","",""];
|
||||
|
||||
|
||||
_yVec = vectorDir _lgb;
|
||||
_zVec = vectorUp _lgb;
|
||||
_xVec = vectorNormalized (_yVec vectorCrossProduct _zVec);
|
||||
|
||||
_lgbPos = getPosASL _lgb;
|
||||
// player sideChat "G!";
|
||||
_targetPos = getPosASL _target;
|
||||
if((count _targetPos) > 0) then {
|
||||
// player sideChat format["f: %1", _targetPos];
|
||||
_addHeight = [0,0,(_lgbPos distance _targetPos)*0.06];
|
||||
// drawLine3D [(ASLtoATL _targetPos) vectorAdd _addHeight, ASLtoATL _targetPos, [0,1,0,1]];
|
||||
_targetPos = _targetPos vectorAdd _addHeight;
|
||||
|
||||
|
||||
|
||||
_def = 0.0025;
|
||||
|
||||
_targetVectorSeeker = [_lgb, [_xVec, _yVec, _zVec], _targetPos] call FUNC(translateToWeaponSpace);
|
||||
// _targetVectorSeeker = _lgb worldToModel (ASLtoATL _targetPos);
|
||||
// _targetVectorSeeker = [0,0,0] vectorFromTo _targetVectorSeeker;
|
||||
_yaw = 0.0;
|
||||
if((_targetVectorSeeker select 0) < 0) then {
|
||||
_yaw = -_def;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 0) > 0) then {
|
||||
_yaw = _def;
|
||||
};
|
||||
};
|
||||
|
||||
_pitch = 0.0;
|
||||
if((_targetVectorSeeker select 2) < 0) then {
|
||||
_pitch = -_def;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 2) > 0) then {
|
||||
_pitch = _def;
|
||||
};
|
||||
};
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoATL _lgbPos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"];
|
||||
drawLine3D [ASLtoATL _lgbPos, ASLtoATL _targetPos, [1,0,0,1]];
|
||||
|
||||
_distance = ([getPos startPos, _lgbPos] call BIS_fnc_distance2D);
|
||||
_marker = createMarkerLocal [format["m%1", MARKERCOUNT], [_distance, _lgbPos select 2]];
|
||||
_marker setMarkerTypeLocal "mil_dot";
|
||||
_marker setMarkerColorLocal "ColorRed";
|
||||
|
||||
MARKERCOUNT = MARKERCOUNT + 1;
|
||||
#endif
|
||||
|
||||
if(accTime > 0) then {
|
||||
_outVector = [_lgb, [_xVec, _yVec, _zVec], [_yaw, 1/accTime, _pitch]] call FUNC(translateToModelSpace);
|
||||
// _outVector = _lgb modelToWorldVisual [_yaw, 1, _pitch];
|
||||
// _outVector = ATLtoASL _outVector;
|
||||
_vectorTo = _lgbPos vectorFromTo _outVector;
|
||||
|
||||
// hintSilent format["v: %1", _vectorTo];
|
||||
|
||||
// _lgb setVectorDir _vectorTo;
|
||||
_lgb setVectorDirAndUp [_vectorTo, vectorUp _lgb];
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
hintSilent format["d: %1", _lgbPos vectorDistance _targetPos];
|
||||
#endif
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
FUNC(guidance_LGB_LOAL) = {
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
|
||||
[FUNC(guidance_LGB_LOAL_PFH), 0, _this] call cba_fnc_addPerFrameHandler;
|
||||
};
|
||||
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
_fireMode = _shooter getVariable ["ACE_FIRE_SELECTION", ACE_DEFAULT_FIRE_SELECTION];
|
||||
|
||||
switch (_fireMode select 0) do {
|
||||
// Default to FIREMODE_DIRECT_LOAL
|
||||
// FIREMODE_DIRECT_LOAL
|
||||
default {
|
||||
LOG("Initiating FIREMODE_DIRECT_LOAL");
|
||||
_this call FUNC(guidance_LGB_LOAL);
|
||||
};
|
||||
};
|
32
addons/missileguidance/functions/fnc_seekerType_Optic.sqf
Normal file
32
addons/missileguidance/functions/fnc_seekerType_Optic.sqf
Normal file
@ -0,0 +1,32 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
private["_targets", "_foundTargetPos", "_launchParams", "_seekerParams", "_targetLaunchParams"];
|
||||
|
||||
_seekerTargetPos = _this select 0;
|
||||
|
||||
_launchParams = _this select 1;
|
||||
_target = (((_launchParams select 1) select 1) select 0);
|
||||
_seekerParams = _launchParams select 3;
|
||||
|
||||
TRACE_1("", _this);
|
||||
TRACE_1("", _launchParams);
|
||||
|
||||
// TODO:: Make sure the missile maintains LOS
|
||||
_foundTargetPos = [0,0,0];
|
||||
if(!isNil "_target") then {
|
||||
_foundTargetPos = getPosASL _target;
|
||||
};
|
||||
|
||||
TRACE_2("", _target, _foundTargetPos);
|
||||
|
||||
_projectileSpeed = (vectorMagnitude velocity _projectile);
|
||||
_distanceToTarget = (getPosASL _projectile) vectorDistance _foundTargetPos;
|
||||
|
||||
_eta = _distanceToTarget / _projectileSpeed;
|
||||
|
||||
_adjustVelocity = (velocity _target) vectorMultiply _eta;
|
||||
_foundTargetPos = _foundTargetPos vectorAdd _adjustVelocity;
|
||||
|
||||
_foundTargetPos;
|
17
addons/missileguidance/functions/fnc_seekerType_SALH.sqf
Normal file
17
addons/missileguidance/functions/fnc_seekerType_SALH.sqf
Normal file
@ -0,0 +1,17 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
EXPLODE_7_PVT(((_this select 1) select 0),_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
private["_targets", "_foundTargetPos", "_launchParams", "_seekerParams", "_targetLaunchParams"];
|
||||
|
||||
_seekerTargetPos = _this select 0;
|
||||
|
||||
_launchParams = _this select 1;
|
||||
_seekerParams = _launchParams select 3;
|
||||
|
||||
// TODO: this needs to be shootCone/findStrongestRay after testing
|
||||
_targets = [_projectile, ACE_DEFAULT_LASER_CODE, (_seekerParams select 0)] call ace_laser_fnc_findLaserDesignator;
|
||||
_foundTargetPos = getPosASL (_targets select 1);
|
||||
|
||||
TRACE_1("Seeker return target pos", _foundTargetPos);
|
||||
_foundTargetPos;
|
107
addons/missileguidance/stringtable.xml
Normal file
107
addons/missileguidance/stringtable.xml
Normal file
@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Edited with tabler - 2014-12-22 -->
|
||||
<Project name="ACE">
|
||||
<Package name="missileguidance">
|
||||
<Key ID="STR_ACE_MissileGuidance">
|
||||
<English>Advanced Missile Guidance</English>
|
||||
<Spanish>Avanzada Misiles Orientación</Spanish>
|
||||
<French>Avancée Missile orientation</French>
|
||||
<Polish>Asystent Missile</Polish>
|
||||
<German>Erweiterte Missile Guidance</German>
|
||||
<Czech>Advanced Missile Guidance</Czech>
|
||||
<Italian>Avanzato Missile Guidance</Italian>
|
||||
<Portuguese>Avançado Missile Guidance</Portuguese>
|
||||
<Hungarian>Részletes rakéta irányító</Hungarian>
|
||||
<Russian>Расширенный ракетой</Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_MissileGuidance_Desc">
|
||||
<English>Enables advanced guidance mechanics and selection for different missiles and fire modes.</English>
|
||||
<Spanish></Spanish>
|
||||
<French></French>
|
||||
<Polish></Polish>
|
||||
<German></German>
|
||||
<Czech></Czech>
|
||||
<Italian></Italian>
|
||||
<Portuguese></Portuguese>
|
||||
<Hungarian></Hungarian>
|
||||
<Russian></Russian>
|
||||
</Key>
|
||||
|
||||
/* Weapons */
|
||||
<Key ID="STR_ACE_Hydra70_DAGR">
|
||||
<English>Hydra-70 DAGR Missile</English>
|
||||
<Spanish></Spanish>
|
||||
<French></French>
|
||||
<Polish></Polish>
|
||||
<German></German>
|
||||
<Czech></Czech>
|
||||
<Italian></Italian>
|
||||
<Portuguese></Portuguese>
|
||||
<Hungarian></Hungarian>
|
||||
<Russian></Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Hydra70_DAGR_Short">
|
||||
<English>DAGR</English>
|
||||
<Spanish></Spanish>
|
||||
<French></French>
|
||||
<Polish></Polish>
|
||||
<German></German>
|
||||
<Czech></Czech>
|
||||
<Italian></Italian>
|
||||
<Portuguese></Portuguese>
|
||||
<Hungarian></Hungarian>
|
||||
<Russian></Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Hydra70_DAGR_Desc">
|
||||
<English>Hydra-70 DAGR Laser Guided Missile</English>
|
||||
<Spanish></Spanish>
|
||||
<French></French>
|
||||
<Polish></Polish>
|
||||
<German></German>
|
||||
<Czech></Czech>
|
||||
<Italian></Italian>
|
||||
<Portuguese></Portuguese>
|
||||
<Hungarian></Hungarian>
|
||||
<Russian></Russian>
|
||||
</Key>
|
||||
|
||||
/* Weapons */
|
||||
<Key ID="STR_ACE_Hellfire_AGM114K">
|
||||
<English>Hellfire II AGM-114K Missile</English>
|
||||
<Spanish></Spanish>
|
||||
<French></French>
|
||||
<Polish></Polish>
|
||||
<German></German>
|
||||
<Czech></Czech>
|
||||
<Italian></Italian>
|
||||
<Portuguese></Portuguese>
|
||||
<Hungarian></Hungarian>
|
||||
<Russian></Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Hellfire_AGM114K_Short">
|
||||
<English>AGM-114K</English>
|
||||
<Spanish></Spanish>
|
||||
<French></French>
|
||||
<Polish></Polish>
|
||||
<German></German>
|
||||
<Czech></Czech>
|
||||
<Italian></Italian>
|
||||
<Portuguese></Portuguese>
|
||||
<Hungarian></Hungarian>
|
||||
<Russian></Russian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Hellfire_AGM114K_desc">
|
||||
<English>Hellfire II AGM-114K Laser Guided Missile</English>
|
||||
<Spanish></Spanish>
|
||||
<French></French>
|
||||
<Polish></Polish>
|
||||
<German></German>
|
||||
<Czech></Czech>
|
||||
<Italian></Italian>
|
||||
<Portuguese></Portuguese>
|
||||
<Hungarian></Hungarian>
|
||||
<Russian></Russian>
|
||||
</Key>
|
||||
|
||||
</Package>
|
||||
</Project>
|
@ -230,6 +230,7 @@ class CfgWeapons {
|
||||
class Snip: Snip {
|
||||
modelOptics[] = {QUOTE(PATHTOF(models\ace_optics_pip.p3d)),QUOTE(PATHTOF(models\ace_optics_pip.p3d))};
|
||||
};
|
||||
class Iron: Iron {};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -9,10 +9,4 @@ class Extended_PostInit_EventHandlers {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_post_init));
|
||||
clientInit = QUOTE(call COMPILE_FILE(XEH_clientInit));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_FiredBIS_EventHandlers {
|
||||
class CAManBase {
|
||||
ADDON = QUOTE(_this call FUNC(fired));
|
||||
};
|
||||
};
|
@ -1,13 +1,13 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
PREP(fired);
|
||||
|
||||
PREP(translateToWeaponSpace);
|
||||
PREP(translateToModelSpace);
|
||||
|
||||
PREP(lockKeyDown);
|
||||
PREP(lockKeyUp);
|
||||
|
||||
PREP(cycleFireMode);
|
||||
PREP(showFireMode);
|
||||
|
||||
PREP(onOpticLoad);
|
||||
PREP(onOpticDraw);
|
||||
|
@ -5,7 +5,7 @@ class CfgPatches {
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ace_laser"};
|
||||
requiredAddons[] = { "ace_main", "ace_common", "ace_missileguidance" };
|
||||
VERSION_CONFIG;
|
||||
};
|
||||
};
|
||||
|
@ -1,19 +1,13 @@
|
||||
#define DEBUG_MODE_FULL
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
TRACE_1("enter", _this);
|
||||
|
||||
private["_player", "_currentFireMode"];
|
||||
|
||||
_currentFireMode = ACE_player getVariable["ACE_FIRE_SELECTION", ACE_JAV_FIREMODE_TOP];
|
||||
if(_currentFireMode == ACE_JAV_FIREMODE_DIR) then {
|
||||
_currentFireMode = ACE_JAV_FIREMODE_TOP;
|
||||
|
||||
__JavelinIGUITop ctrlSetTextColor __ColorGreen;
|
||||
__JavelinIGUIDir ctrlSetTextColor __ColorGray;
|
||||
_currentFireMode = ACE_player getVariable["ace_missileguidance_attackProfile", "TOP"];
|
||||
if(_currentFireMode == "LIN") then {
|
||||
_currentFireMode = "TOP";
|
||||
} else {
|
||||
_currentFireMode = ACE_JAV_FIREMODE_DIR;
|
||||
|
||||
__JavelinIGUITop ctrlSetTextColor __ColorGray;
|
||||
__JavelinIGUIDir ctrlSetTextColor __ColorGreen;
|
||||
_currentFireMode = "LIN";
|
||||
};
|
||||
ACE_player setVariable["ACE_FIRE_SELECTION", _currentFireMode, false];
|
||||
ACE_player setVariable["ace_missileguidance_attackProfile", _currentFireMode, false];
|
||||
|
@ -1,285 +0,0 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
//_this=[TEST_AI_HELICOPTER,"missiles_DAGR","missiles_DAGR","Far_AI","M_PG_AT","24Rnd_PG_missiles",163988: rocket_01_fly_f.p3d]
|
||||
TRACE_1("Launch", _this);
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
|
||||
FUNC(guidance_Javelin_LOBL_DIR_PFH) = {
|
||||
TRACE_1("enter", _this);
|
||||
private["_pitch", "_yaw", "_wentTerminal", "_target", "_targetPos", "_curVelocity", "_missile",
|
||||
"_launchPos", "_targetStartPos", "_defPitch", "_defYaw"];
|
||||
_args = _this select 0;
|
||||
//PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
_shooter = _args select 0;
|
||||
_missile = _args select 6;
|
||||
|
||||
if((count _args) > 7) then {
|
||||
_saveArgs = _args select 7;
|
||||
_target = _saveArgs select 0;
|
||||
_targetStartPos = _saveArgs select 1;
|
||||
_launchPos = _saveArgs select 2;
|
||||
_wentTerminal = _saveArgs select 3;
|
||||
} else {
|
||||
_wentTerminal = false;
|
||||
_launchPos = getPosASL _shooter;
|
||||
_target = ACE_player getVariable[QGVAR(currentTarget), objNull];
|
||||
_targetStartPos = ACE_player getVariable[QGVAR(currentTargetPos), [0,0,0]];
|
||||
};
|
||||
|
||||
if(!alive _missile || isNull _missile || isNull _target) exitWith {
|
||||
[(_this select 1)] call cba_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
_targetPos = getPosASL _target;
|
||||
_curVelocity = velocity _missile;
|
||||
|
||||
TRACE_4("", _target, _targetPos, _launchPos, _targetStartPos);
|
||||
|
||||
_addHeight = [0,0,0];
|
||||
if(!isNil "_target") then {
|
||||
|
||||
_yVec = vectorDir _missile;
|
||||
_zVec = vectorUp _missile;
|
||||
_xVec = vectorNormalized (_yVec vectorCrossProduct _zVec);
|
||||
|
||||
_missilePos = getPosASL _missile;
|
||||
// player sideChat "G!";
|
||||
|
||||
TRACE_4("Phase Check", _launchPos, _missilePos, _targetPos, (_missilePos distance _targetPos));
|
||||
if((count _targetPos) > 0) then {
|
||||
_distanceToTarget = [(_missilePos select 0), (_missilePos select 1), (_targetPos select 2)] vectorDistance _targetPos;
|
||||
|
||||
if( (_missilePos select 2) < (_targetPos select 2) + 60 && !_wentTerminal) then {
|
||||
_addHeight = [0,0,(_targetPos select 2) + 120];
|
||||
|
||||
_defPitch = 0.15;
|
||||
_defYaw = 0.035;
|
||||
|
||||
TRACE_1("Climb phase", _addHeight);
|
||||
} else {
|
||||
_wentTerminal = true;
|
||||
_this set[2, _wentTerminal];
|
||||
|
||||
_defPitch = 0.15;
|
||||
_defYaw = 0.035;
|
||||
|
||||
TRACE_1("TERMINAL", "");
|
||||
};
|
||||
_targetPos = _targetPos vectorAdd _addHeight;
|
||||
|
||||
_targetVectorSeeker = [_missile, [_xVec, _yVec, _zVec], _targetPos] call FUNC(translateToWeaponSpace);
|
||||
TRACE_5("", _missile, _xVec, _yVec, _zVec, _targetPos);
|
||||
|
||||
_yaw = 0.0;
|
||||
_pitch = 0.0;
|
||||
|
||||
if((_targetVectorSeeker select 0) < 0) then {
|
||||
_yaw = -_defYaw;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 0) > 0) then {
|
||||
_yaw = _defYaw;
|
||||
};
|
||||
};
|
||||
|
||||
if((_targetVectorSeeker select 2) < 0) then {
|
||||
_pitch = -_defPitch;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 2) > 0) then {
|
||||
_pitch = _defPitch;
|
||||
};
|
||||
};
|
||||
|
||||
TRACE_3("", _targetVectorSeeker, _pitch, _yaw);
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawLine3D [(ASLtoATL _targetPos) vectorAdd _addHeight, ASLtoATL _targetPos, [0,1,0,1]];
|
||||
|
||||
_light = "#lightpoint" createVehicleLocal (getPos _missile);
|
||||
_light setLightBrightness 1.0;
|
||||
_light setLightAmbient [1.0, 0.0, 0.0];
|
||||
_light setLightColor [1.0, 0.0, 0.0];
|
||||
|
||||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoATL _missilePos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"];
|
||||
drawLine3D [ASLtoATL _missilePos, ASLtoATL _targetPos, [1,0,0,1]];
|
||||
|
||||
MARKERCOUNT = MARKERCOUNT + 1;
|
||||
#endif
|
||||
|
||||
if(accTime > 0) then {
|
||||
TRACE_5("", _xVec, _yVec, _zVec, _yaw, _pitch);
|
||||
_outVector = [_missile, [_xVec, _yVec, _zVec], [_yaw, 1/accTime, _pitch]] call FUNC(translateToModelSpace);
|
||||
|
||||
_vectorTo = _missilePos vectorFromTo _outVector;
|
||||
TRACE_3("", _missile, _outVector, _vectorTo);
|
||||
_missile setVectorDirAndUp [_vectorTo, vectorUp _missile];
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
hintSilent format["d: %1", _distanceToTarget];
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
_saveArgs = [_target,_targetStartPos, _launchPos, _wentTerminal];
|
||||
_args set[7, _saveArgs ];
|
||||
_this set[0, _args];
|
||||
};
|
||||
|
||||
FUNC(guidance_Javelin_LOBL_TOP_PFH) = {
|
||||
TRACE_1("enter", _this);
|
||||
private["_pitch", "_yaw", "_wentTerminal", "_target", "_targetPos", "_curVelocity", "_missile",
|
||||
"_launchPos", "_targetStartPos", "_defPitch", "_defYaw"];
|
||||
_args = _this select 0;
|
||||
//PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
_shooter = _args select 0;
|
||||
_missile = _args select 6;
|
||||
|
||||
if((count _args) > 7) then {
|
||||
_saveArgs = _args select 7;
|
||||
_target = _saveArgs select 0;
|
||||
_targetStartPos = _saveArgs select 1;
|
||||
_launchPos = _saveArgs select 2;
|
||||
_wentTerminal = _saveArgs select 3;
|
||||
} else {
|
||||
_wentTerminal = false;
|
||||
_launchPos = getPosASL _shooter;
|
||||
_target = ACE_player getVariable[QGVAR(currentTarget), objNull];
|
||||
_targetStartPos = ACE_player getVariable[QGVAR(currentTargetPos), [0,0,0]];
|
||||
};
|
||||
|
||||
if(!alive _missile || isNull _missile || isNull _target) exitWith {
|
||||
[(_this select 1)] call cba_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
_targetPos = getPosASL _target;
|
||||
_curVelocity = velocity _missile;
|
||||
|
||||
TRACE_4("", _target, _targetPos, _launchPos, _targetStartPos);
|
||||
|
||||
_addHeight = [0,0,0];
|
||||
if(!isNil "_target") then {
|
||||
|
||||
_yVec = vectorDir _missile;
|
||||
_zVec = vectorUp _missile;
|
||||
_xVec = vectorNormalized (_yVec vectorCrossProduct _zVec);
|
||||
|
||||
_missilePos = getPosASL _missile;
|
||||
// player sideChat "G!";
|
||||
|
||||
TRACE_4("Phase Check", _launchPos, _missilePos, _targetPos, (_missilePos distance _targetPos));
|
||||
if((count _targetPos) > 0) then {
|
||||
_distanceToTarget = [(_missilePos select 0), (_missilePos select 1), (_targetPos select 2)] vectorDistance _targetPos;
|
||||
|
||||
if( (_missilePos select 2) < (_targetPos select 2) + 200 && !_wentTerminal) then {
|
||||
_addHeight = [0,0, ( (_distanceToTarget * 2) + 400)];
|
||||
|
||||
_defPitch = 0.25;
|
||||
_defYaw = 0.035;
|
||||
|
||||
TRACE_1("Climb phase", _addHeight);
|
||||
} else {
|
||||
_wentTerminal = true;
|
||||
_this set[2, _wentTerminal];
|
||||
|
||||
_defPitch = 0.25;
|
||||
_defYaw = 0.25;
|
||||
|
||||
TRACE_1("TERMINAL", "");
|
||||
};
|
||||
_targetPos = _targetPos vectorAdd _addHeight;
|
||||
|
||||
_targetVectorSeeker = [_missile, [_xVec, _yVec, _zVec], _targetPos] call FUNC(translateToWeaponSpace);
|
||||
TRACE_5("", _missile, _xVec, _yVec, _zVec, _targetPos);
|
||||
|
||||
_yaw = 0.0;
|
||||
_pitch = 0.0;
|
||||
|
||||
// Stop jinking on terminal final decent
|
||||
if((_missilePos distance _targetPos) < 150) then {
|
||||
_defPitch = 0.0015;
|
||||
_defYaw = 0.0015;
|
||||
};
|
||||
|
||||
if((_targetVectorSeeker select 0) < 0) then {
|
||||
_yaw = -_defYaw;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 0) > 0) then {
|
||||
_yaw = _defYaw;
|
||||
};
|
||||
};
|
||||
|
||||
if((_targetVectorSeeker select 2) < 0) then {
|
||||
_pitch = -_defPitch;
|
||||
} else {
|
||||
if((_targetVectorSeeker select 2) > 0) then {
|
||||
_pitch = _defPitch;
|
||||
};
|
||||
};
|
||||
|
||||
TRACE_3("", _targetVectorSeeker, _pitch, _yaw);
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
drawLine3D [(ASLtoATL _targetPos) vectorAdd _addHeight, ASLtoATL _targetPos, [0,1,0,1]];
|
||||
|
||||
_light = "#lightpoint" createVehicleLocal (getPos _missile);
|
||||
_light setLightBrightness 1.0;
|
||||
_light setLightAmbient [1.0, 0.0, 0.0];
|
||||
_light setLightColor [1.0, 0.0, 0.0];
|
||||
|
||||
drawIcon3D ["\a3\ui_f\data\IGUI\Cfg\Cursors\selectover_ca.paa", [1,1,1,1], ASLtoATL _missilePos, 0.75, 0.75, 0, str _vectorTo, 1, 0.025, "TahomaB"];
|
||||
drawLine3D [ASLtoATL _missilePos, ASLtoATL _targetPos, [1,0,0,1]];
|
||||
|
||||
MARKERCOUNT = MARKERCOUNT + 1;
|
||||
#endif
|
||||
|
||||
if(accTime > 0) then {
|
||||
TRACE_5("", _xVec, _yVec, _zVec, _yaw, _pitch);
|
||||
_outVector = [_missile, [_xVec, _yVec, _zVec], [_yaw, 1/accTime, _pitch]] call FUNC(translateToModelSpace);
|
||||
|
||||
_vectorTo = _missilePos vectorFromTo _outVector;
|
||||
TRACE_3("", _missile, _outVector, _vectorTo);
|
||||
_missile setVectorDirAndUp [_vectorTo, vectorUp _missile];
|
||||
};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
hintSilent format["d: %1", _distanceToTarget];
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
_saveArgs = [_target,_targetStartPos, _launchPos, _wentTerminal];
|
||||
_args set[7, _saveArgs ];
|
||||
_this set[0, _args];
|
||||
};
|
||||
|
||||
FUNC(guidance_Javelin_LOBL_TOP) = {
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
|
||||
GVAR(lastTime) = time;
|
||||
[FUNC(guidance_Javelin_LOBL_TOP_PFH), 0, _this] call cba_fnc_addPerFrameHandler;
|
||||
};
|
||||
|
||||
FUNC(guidance_Javelin_LOBL_DIR) = {
|
||||
PARAMS_7(_shooter,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile);
|
||||
|
||||
GVAR(lastTime) = time;
|
||||
[FUNC(guidance_Javelin_LOBL_DIR_PFH), 0, _this] call cba_fnc_addPerFrameHandler;
|
||||
};
|
||||
|
||||
if(!local _shooter) exitWith { false };
|
||||
if(_ammo == "M_Titan_AT") then {
|
||||
_fireMode = _shooter getVariable ["ACE_FIRE_SELECTION", ACE_JAV_FIREMODE_TOP];
|
||||
|
||||
switch (_fireMode) do {
|
||||
// Default to FIREMODE_DIRECT_LOAL
|
||||
// FIREMODE_DIRECT_LOAL
|
||||
case ACE_JAV_FIREMODE_DIR: {
|
||||
LOG("Initiating Javelin FIREMODE_LOBL_DIR");
|
||||
_this call FUNC(guidance_Javelin_LOBL_DIR);
|
||||
};
|
||||
default {
|
||||
LOG("Initiating Javelin FIREMODE_LOBL_TOP");
|
||||
_this call FUNC(guidance_Javelin_LOBL_TOP);
|
||||
};
|
||||
};
|
||||
};
|
@ -1,3 +1,3 @@
|
||||
#define DEBUG_MODE_FULL
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
TRACE_1("enter", _this);
|
@ -1,3 +1,3 @@
|
||||
#define DEBUG_MODE_FULL
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
TRACE_1("enter", _this);
|
@ -7,15 +7,6 @@
|
||||
#define __LOCKONTIMERANDOM 0.3 // Deviation in lock on time
|
||||
#define __SENSORSQUARE 1 // Locking on sensor square side in angles
|
||||
|
||||
#define __ConstraintTop (((ctrlPosition __JavelinIGUITargetingConstrainTop) select 1) + ((ctrlPosition (__JavelinIGUITargetingConstrainTop)) select 3))
|
||||
#define __ConstraintBottom ((ctrlPosition __JavelinIGUITargetingConstrainBottom) select 1)
|
||||
#define __ConstraintLeft (((ctrlPosition __JavelinIGUITargetingConstrainLeft) select 0) + ((ctrlPosition (__JavelinIGUITargetingConstrainLeft)) select 2))
|
||||
#define __ConstraintRight ((ctrlPosition __JavelinIGUITargetingConstrainRight) select 0)
|
||||
|
||||
#define __OffsetX ((ctrlPosition __JavelinIGUITargetingLineV) select 0) - 0.5
|
||||
#define __OffsetY ((ctrlPosition __JavelinIGUITargetingLineH) select 1) - 0.5
|
||||
|
||||
|
||||
private["_args", "_lastTick", "_runTime", "_soundTime", "_lockTime", "_newTarget", "_currentTarget", "_range", "_pos", "_targetArray"];
|
||||
|
||||
// Reset arguments if we havnt rendered in over a second
|
||||
@ -41,6 +32,9 @@ if ((velocity ACE_player) distance [0,0,0] > 0.5 && {cameraView == "GUNNER"} &&
|
||||
ACE_player switchCamera "INTERNAL";
|
||||
};
|
||||
|
||||
// Refresh the firemode
|
||||
[] call FUNC(showFireMode);
|
||||
|
||||
// Only start locking on holding tab
|
||||
if(!GVAR(isLockKeyDown)) exitWith { false };
|
||||
|
||||
@ -68,7 +62,7 @@ if (isNull _newTarget) then {
|
||||
__JavelinIGUITargetingGate ctrlShow false;
|
||||
__JavelinIGUITargetingLines ctrlShow false;
|
||||
|
||||
ACE_player setVariable [QGVAR(currentTarget),nil, false];
|
||||
ACE_player setVariable ["ace_missileguidance_target",nil, false];
|
||||
|
||||
// Disallow fire
|
||||
//if (ACE_player ammo "Javelin" > 0 || {ACE_player ammo "ACE_Javelin_Direct" > 0}) then {ACE_player setWeaponReloadingTime //[player, "Javelin", 0.2];};
|
||||
@ -91,8 +85,7 @@ if (isNull _newTarget) then {
|
||||
__JavelinIGUINFOV ctrlSetTextColor __ColorNull;
|
||||
__JavelinIGUITargetingConstrains ctrlShow true;
|
||||
|
||||
ACE_player setVariable[QGVAR(currentTarget), _currentTarget, false];
|
||||
ACE_player setVariable[QGVAR(currentTargetPos), getPosASL _currentTarget, false];
|
||||
ACE_player setVariable["ace_missileguidance_target", _currentTarget, false];
|
||||
|
||||
if(diag_tickTime > _soundTime) then {
|
||||
playSound "ACE_Javelin_Locked";
|
||||
@ -115,7 +108,7 @@ if (isNull _newTarget) then {
|
||||
__JavelinIGUITargetingGate ctrlShow false;
|
||||
__JavelinIGUITargetingLines ctrlShow false;
|
||||
|
||||
ACE_player setVariable [QGVAR(currentTarget),nil, false];
|
||||
ACE_player setVariable ["ace_missileguidance_target",nil, false];
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -6,6 +6,11 @@ if((count _this) > 0) then {
|
||||
uiNameSpace setVariable ['ACE_RscOptics_javelin',_this select 0];
|
||||
};
|
||||
|
||||
ACE_player setVariable ["ace_missileguidance_target",nil, false];
|
||||
|
||||
__JavelinIGUISeek ctrlSetTextColor __ColorGray;
|
||||
__JavelinIGUINFOV ctrlSetTextColor __ColorGray;
|
||||
|
||||
uiNameSpace setVariable [QGVAR(arguments),
|
||||
[
|
||||
0, // Last runtime
|
||||
|
14
addons/wep_javelin/functions/fnc_showFireMode.sqf
Normal file
14
addons/wep_javelin/functions/fnc_showFireMode.sqf
Normal file
@ -0,0 +1,14 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
TRACE_1("enter", _this);
|
||||
|
||||
private["_player", "_currentFireMode"];
|
||||
|
||||
_currentFireMode = ACE_player getVariable["ace_missileguidance_attackProfile", "TOP"];
|
||||
if(_currentFireMode == "TOP") then {
|
||||
__JavelinIGUITop ctrlSetTextColor __ColorGreen;
|
||||
__JavelinIGUIDir ctrlSetTextColor __ColorGray;
|
||||
} else {
|
||||
__JavelinIGUITop ctrlSetTextColor __ColorGray;
|
||||
__JavelinIGUIDir ctrlSetTextColor __ColorGreen;
|
||||
};
|
@ -46,6 +46,15 @@
|
||||
#define __JavelinIGUITargetingLineH (__JavelinIGUI displayCtrl 699301)
|
||||
#define __JavelinIGUITargetingLineV (__JavelinIGUI displayCtrl 699302)
|
||||
|
||||
#define __ConstraintTop (((ctrlPosition __JavelinIGUITargetingConstrainTop) select 1) + ((ctrlPosition (__JavelinIGUITargetingConstrainTop)) select 3))
|
||||
#define __ConstraintBottom ((ctrlPosition __JavelinIGUITargetingConstrainBottom) select 1)
|
||||
#define __ConstraintLeft (((ctrlPosition __JavelinIGUITargetingConstrainLeft) select 0) + ((ctrlPosition (__JavelinIGUITargetingConstrainLeft)) select 2))
|
||||
#define __ConstraintRight ((ctrlPosition __JavelinIGUITargetingConstrainRight) select 0)
|
||||
|
||||
#define __OffsetX ((ctrlPosition __JavelinIGUITargetingLineV) select 0) - 0.5
|
||||
#define __OffsetY ((ctrlPosition __JavelinIGUITargetingLineH) select 1) - 0.5
|
||||
|
||||
|
||||
// Colors for controls
|
||||
#define __ColorOrange [0.9255,0.5216,0.1216,1]
|
||||
#define __ColorGreen [0.2941,0.8745,0.2157,1]
|
||||
|
828
tools/make64.py
Normal file
828
tools/make64.py
Normal file
@ -0,0 +1,828 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: set fileencoding=utf-8 :
|
||||
|
||||
# make.py
|
||||
# An Arma 3 addon build system
|
||||
|
||||
###############################################################################
|
||||
|
||||
# The MIT License (MIT)
|
||||
|
||||
# Copyright (c) 2013-2014 Ryan Schultz
|
||||
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
###############################################################################
|
||||
|
||||
__version__ = "0.3dev"
|
||||
|
||||
import sys
|
||||
|
||||
if sys.version_info[0] == 2:
|
||||
print("Python 3 is required.")
|
||||
sys.exit(1)
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import shutil
|
||||
import platform
|
||||
import glob
|
||||
import subprocess
|
||||
import hashlib
|
||||
import configparser
|
||||
import json
|
||||
import traceback
|
||||
import time
|
||||
import re
|
||||
|
||||
if sys.platform == "win32":
|
||||
import winreg
|
||||
|
||||
###############################################################################
|
||||
# http://akiscode.com/articles/sha-1directoryhash.shtml
|
||||
# Copyright (c) 2009 Stephen Akiki
|
||||
# MIT License (Means you can do whatever you want with this)
|
||||
# See http://www.opensource.org/licenses/mit-license.php
|
||||
# Error Codes:
|
||||
# -1 -> Directory does not exist
|
||||
# -2 -> General error (see stack traceback)
|
||||
def get_directory_hash(directory):
|
||||
directory_hash = hashlib.sha1()
|
||||
if not os.path.exists (directory):
|
||||
return -1
|
||||
|
||||
try:
|
||||
for root, dirs, files in os.walk(directory):
|
||||
for names in files:
|
||||
path = os.path.join(root, names)
|
||||
try:
|
||||
f = open(path, 'rb')
|
||||
except:
|
||||
# You can't open the file for some reason
|
||||
f.close()
|
||||
continue
|
||||
|
||||
while 1:
|
||||
# Read file in as little chunks
|
||||
buf = f.read(4096)
|
||||
if not buf: break
|
||||
new = hashlib.sha1(buf)
|
||||
directory_hash.update(new.digest())
|
||||
f.close()
|
||||
|
||||
except:
|
||||
# Print the stack traceback
|
||||
traceback.print_exc()
|
||||
return -2
|
||||
|
||||
return directory_hash.hexdigest()
|
||||
|
||||
# Copyright (c) André Burgaud
|
||||
# http://www.burgaud.com/bring-colors-to-the-windows-console-with-python/
|
||||
if sys.platform == "win32":
|
||||
from ctypes import windll, Structure, c_short, c_ushort, byref
|
||||
|
||||
SHORT = c_short
|
||||
WORD = c_ushort
|
||||
|
||||
class COORD(Structure):
|
||||
"""struct in wincon.h."""
|
||||
_fields_ = [
|
||||
("X", SHORT),
|
||||
("Y", SHORT)]
|
||||
|
||||
class SMALL_RECT(Structure):
|
||||
"""struct in wincon.h."""
|
||||
_fields_ = [
|
||||
("Left", SHORT),
|
||||
("Top", SHORT),
|
||||
("Right", SHORT),
|
||||
("Bottom", SHORT)]
|
||||
|
||||
class CONSOLE_SCREEN_BUFFER_INFO(Structure):
|
||||
"""struct in wincon.h."""
|
||||
_fields_ = [
|
||||
("dwSize", COORD),
|
||||
("dwCursorPosition", COORD),
|
||||
("wAttributes", WORD),
|
||||
("srWindow", SMALL_RECT),
|
||||
("dwMaximumWindowSize", COORD)]
|
||||
|
||||
# winbase.h
|
||||
STD_INPUT_HANDLE = -10
|
||||
STD_OUTPUT_HANDLE = -11
|
||||
STD_ERROR_HANDLE = -12
|
||||
|
||||
# wincon.h
|
||||
FOREGROUND_BLACK = 0x0000
|
||||
FOREGROUND_BLUE = 0x0001
|
||||
FOREGROUND_GREEN = 0x0002
|
||||
FOREGROUND_CYAN = 0x0003
|
||||
FOREGROUND_RED = 0x0004
|
||||
FOREGROUND_MAGENTA = 0x0005
|
||||
FOREGROUND_YELLOW = 0x0006
|
||||
FOREGROUND_GREY = 0x0007
|
||||
FOREGROUND_INTENSITY = 0x0008 # foreground color is intensified.
|
||||
|
||||
BACKGROUND_BLACK = 0x0000
|
||||
BACKGROUND_BLUE = 0x0010
|
||||
BACKGROUND_GREEN = 0x0020
|
||||
BACKGROUND_CYAN = 0x0030
|
||||
BACKGROUND_RED = 0x0040
|
||||
BACKGROUND_MAGENTA = 0x0050
|
||||
BACKGROUND_YELLOW = 0x0060
|
||||
BACKGROUND_GREY = 0x0070
|
||||
BACKGROUND_INTENSITY = 0x0080 # background color is intensified.
|
||||
|
||||
stdout_handle = windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
|
||||
SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute
|
||||
GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo
|
||||
|
||||
def get_text_attr():
|
||||
"""Returns the character attributes (colors) of the console screen
|
||||
buffer."""
|
||||
csbi = CONSOLE_SCREEN_BUFFER_INFO()
|
||||
GetConsoleScreenBufferInfo(stdout_handle, byref(csbi))
|
||||
return csbi.wAttributes
|
||||
|
||||
def set_text_attr(color):
|
||||
"""Sets the character attributes (colors) of the console screen
|
||||
buffer. Color is a combination of foreground and background color,
|
||||
foreground and background intensity."""
|
||||
SetConsoleTextAttribute(stdout_handle, color)
|
||||
###############################################################################
|
||||
|
||||
def find_bi_tools(work_drive):
|
||||
"""Find BI tools."""
|
||||
|
||||
reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
|
||||
try:
|
||||
k = winreg.OpenKey(reg, r"Software\bohemia interactive\arma 3 tools")
|
||||
arma3tools_path = winreg.QueryValueEx(k, "path")[0]
|
||||
winreg.CloseKey(k)
|
||||
except:
|
||||
raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.")
|
||||
|
||||
addonbuilder_path = os.path.join(arma3tools_path, "AddonBuilder", "AddonBuilder.exe")
|
||||
dssignfile_path = os.path.join(arma3tools_path, "DSSignFile", "DSSignFile.exe")
|
||||
dscreatekey_path = os.path.join(arma3tools_path, "DSSignFile", "DSCreateKey.exe")
|
||||
cfgconvert_path = os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe")
|
||||
|
||||
if os.path.isfile(addonbuilder_path) and os.path.isfile(dssignfile_path) and os.path.isfile(dscreatekey_path) and os.path.isfile(cfgconvert_path):
|
||||
return [addonbuilder_path, dssignfile_path, dscreatekey_path, cfgconvert_path]
|
||||
else:
|
||||
raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.")
|
||||
|
||||
def find_depbo_tools(regKey):
|
||||
"""Use registry entries to find DePBO-based tools."""
|
||||
stop = False
|
||||
|
||||
if regKey == "HKCU":
|
||||
reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
|
||||
stop = True
|
||||
else:
|
||||
reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
||||
|
||||
try:
|
||||
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\pboProject")
|
||||
try:
|
||||
pboproject_path = winreg.QueryValueEx(k, "exe")[0]
|
||||
winreg.CloseKey(k)
|
||||
print("Found pboproject.")
|
||||
except:
|
||||
print_error("ERROR: Could not find pboProject.")
|
||||
|
||||
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\rapify")
|
||||
try:
|
||||
rapify_path = winreg.QueryValueEx(k, "exe")[0]
|
||||
winreg.CloseKey(k)
|
||||
print("Found rapify.")
|
||||
except:
|
||||
print_error("Could not find rapify.")
|
||||
|
||||
k = winreg.OpenKey(reg, r"Software\Wow6432Node\Mikero\MakePbo")
|
||||
try:
|
||||
makepbo_path = winreg.QueryValueEx(k, "exe")[0]
|
||||
winreg.CloseKey(k)
|
||||
print("Found makepbo.")
|
||||
except:
|
||||
print_error("Could not find makepbo.")
|
||||
except:
|
||||
if stop == True:
|
||||
raise Exception("BadDePBO", "DePBO tools not installed correctly")
|
||||
return -1
|
||||
|
||||
|
||||
#Strip any quotations from the path due to a MikeRo tool bug which leaves a trailing space in some of its registry paths.
|
||||
return [pboproject_path.strip('"'),rapify_path.strip('"'),makepbo_path.strip('"')]
|
||||
|
||||
def color(color):
|
||||
"""Set the color. Works on Win32 and normal terminals."""
|
||||
if sys.platform == "win32":
|
||||
if color == "green":
|
||||
set_text_attr(FOREGROUND_GREEN | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY)
|
||||
elif color == "red":
|
||||
set_text_attr(FOREGROUND_RED | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY)
|
||||
elif color == "blue":
|
||||
set_text_attr(FOREGROUND_BLUE | get_text_attr() & 0x0070 | FOREGROUND_INTENSITY)
|
||||
elif color == "reset":
|
||||
set_text_attr(FOREGROUND_GREY | get_text_attr() & 0x0070)
|
||||
elif color == "grey":
|
||||
set_text_attr(FOREGROUND_GREY | get_text_attr() & 0x0070)
|
||||
else :
|
||||
if color == "green":
|
||||
sys.stdout.write('\033[92m')
|
||||
elif color == "red":
|
||||
sys.stdout.write('\033[91m')
|
||||
elif color == "blue":
|
||||
sys.stdout.write('\033[94m')
|
||||
elif color == "reset":
|
||||
sys.stdout.write('\033[0m')
|
||||
|
||||
def print_error(msg):
|
||||
color("red")
|
||||
print ("ERROR: " + msg)
|
||||
color("reset")
|
||||
|
||||
def print_green(msg):
|
||||
color("green")
|
||||
print(msg)
|
||||
color("reset")
|
||||
|
||||
def print_blue(msg):
|
||||
color("blue")
|
||||
print(msg)
|
||||
color("reset")
|
||||
|
||||
def print_yellow(msg):
|
||||
color("yellow")
|
||||
print(msg)
|
||||
color("reset")
|
||||
|
||||
###############################################################################
|
||||
|
||||
def main(argv):
|
||||
"""Build an Arma addon suite in a directory from rules in a make.cfg file."""
|
||||
print_blue(("\nmake.py for Arma, v" + __version__))
|
||||
|
||||
if sys.platform != "win32":
|
||||
print_error("Non-Windows platform (Cygwin?). Please re-run from cmd.")
|
||||
sys.exit(1)
|
||||
|
||||
reg = winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER)
|
||||
try:
|
||||
k = winreg.OpenKey(reg, r"Software\bohemia interactive\arma 3 tools")
|
||||
arma3tools_path = winreg.QueryValueEx(k, "path")[0]
|
||||
winreg.CloseKey(k)
|
||||
except:
|
||||
raise Exception("BadTools","Arma 3 Tools are not installed correctly or the P: drive needs to be created.")
|
||||
|
||||
# Default behaviors
|
||||
test = False # Copy to Arma 3 directory?
|
||||
arg_modules = False # Only build modules on command line?
|
||||
make_release = False # Make zip file from the release?
|
||||
release_version = 0 # Version of release
|
||||
use_pboproject = True # Default to pboProject build tool
|
||||
make_target = "DEFAULT" # Which section in make.cfg to use for the build
|
||||
new_key = False # Make a new key and use it to sign?
|
||||
quiet = False # Suppress output from build tool?
|
||||
|
||||
# Parse arguments
|
||||
if "help" in argv or "-h" in argv or "--help" in argv:
|
||||
print ("""
|
||||
make.py [help] [test] [force] [key <name>] [target <name>] [release <version>]
|
||||
[module name] [module name] [...]
|
||||
|
||||
test -- Copy result to Arma 3.
|
||||
release <version> -- Make archive with <version>.
|
||||
force -- Ignore cache and build all.
|
||||
target <name> -- Use rules in make.cfg under heading [<name>] rather than
|
||||
default [Make]
|
||||
key <name> -- Use key in working directory with <name> to sign. If it does not
|
||||
exist, create key.
|
||||
quiet -- Suppress command line output from build tool.
|
||||
|
||||
If module names are specified, only those modules will be built.
|
||||
|
||||
Examples:
|
||||
make.py force test
|
||||
Build all modules (ignoring cache) and copy the mod folder to the Arma 3
|
||||
directory.
|
||||
make.py mymodule_gun
|
||||
Only build the module named 'mymodule_gun'.
|
||||
make.py force key MyNewKey release 1.0
|
||||
Build all modules (ignoring cache), sign them with NewKey, and pack them
|
||||
into a zip file for release with version 1.0.
|
||||
|
||||
|
||||
If a file called $NOBIN$ is found in the module directory, that module will not be binarized.
|
||||
|
||||
See the make.cfg file for additional build options.
|
||||
""")
|
||||
sys.exit(0)
|
||||
|
||||
if "force" in argv:
|
||||
argv.remove("force")
|
||||
force_build = True
|
||||
else:
|
||||
force_build = False
|
||||
|
||||
if "test" in argv:
|
||||
test = True
|
||||
argv.remove("test")
|
||||
|
||||
if "release" in argv:
|
||||
make_release = True
|
||||
release_version = argv[argv.index("release") + 1]
|
||||
argv.remove(release_version)
|
||||
argv.remove("release")
|
||||
|
||||
if "target" in argv:
|
||||
make_target = argv[argv.index("target") + 1]
|
||||
argv.remove("target")
|
||||
argv.remove(make_target)
|
||||
force_build = True
|
||||
|
||||
if "key" in argv:
|
||||
new_key = True
|
||||
key_name = argv[argv.index("key") + 1]
|
||||
argv.remove("key")
|
||||
argv.remove(key_name)
|
||||
|
||||
if "quiet" in argv:
|
||||
quiet = True
|
||||
argv.remove("quiet")
|
||||
|
||||
# Get the directory the make script is in.
|
||||
make_root = os.path.dirname(os.path.realpath(__file__))
|
||||
make_root_parent = os.path.abspath(os.path.join(os.getcwd(), os.pardir))
|
||||
os.chdir(make_root)
|
||||
|
||||
# Get latest commit ID
|
||||
try:
|
||||
gitpath = os.path.join(os.path.dirname(make_root), ".git")
|
||||
assert os.path.exists(gitpath)
|
||||
|
||||
commit_id = subprocess.check_output(["git", "rev-parse", "HEAD"])
|
||||
commit_id = str(commit_id, "utf-8")[:8]
|
||||
except:
|
||||
print_error("FAILED TO DETERMINE COMMIT ID.")
|
||||
commit_id = "NOGIT"
|
||||
|
||||
cfg = configparser.ConfigParser();
|
||||
try:
|
||||
cfg.read(os.path.join(make_root, "make.cfg"))
|
||||
|
||||
# Project name (with @ symbol)
|
||||
project = cfg.get(make_target, "project", fallback="@"+os.path.basename(os.getcwd()))
|
||||
|
||||
# Private key path
|
||||
key = cfg.get(make_target, "key", fallback=None)
|
||||
|
||||
# Project prefix (folder path)
|
||||
prefix = cfg.get(make_target, "prefix", fallback="")
|
||||
|
||||
# Should we autodetect modules on a complete build?
|
||||
module_autodetect = cfg.getboolean(make_target, "module_autodetect", fallback=True)
|
||||
|
||||
# Manual list of modules to build for a complete build
|
||||
modules = cfg.get(make_target, "modules", fallback=None)
|
||||
# Parse it out
|
||||
if modules:
|
||||
modules = [x.strip() for x in modules.split(',')]
|
||||
else:
|
||||
modules = []
|
||||
|
||||
# List of directories to ignore when detecting
|
||||
ignore = [x.strip() for x in cfg.get(make_target, "ignore", fallback="release").split(',')]
|
||||
|
||||
# BI Tools work drive on Windows
|
||||
work_drive = cfg.get(make_target, "work_drive", fallback="P:\\")
|
||||
|
||||
# Which build tool should we use?
|
||||
build_tool = cfg.get(make_target, "build_tool", fallback="addonbuilder").lower()
|
||||
|
||||
# Release/build directory, relative to script dir
|
||||
release_dir = cfg.get(make_target, "release_dir", fallback="release")
|
||||
|
||||
# Project PBO file prefix (files are renamed to prefix_name.pbo)
|
||||
pbo_name_prefix = cfg.get(make_target, "pbo_name_prefix", fallback=None)
|
||||
|
||||
# Project module Root
|
||||
module_root_parent = os.path.abspath(os.path.join(os.path.join(work_drive, prefix), os.pardir))
|
||||
module_root = cfg.get(make_target, "module_root", fallback=os.path.join(make_root_parent, "addons"))
|
||||
print_green ("module_root: " + module_root)
|
||||
if (os.path.isdir(module_root)):
|
||||
os.chdir(module_root)
|
||||
else:
|
||||
print_error ("Directory " + module_root + " does not exist.")
|
||||
sys.exit()
|
||||
|
||||
except:
|
||||
raise
|
||||
print_error("Could not parse make.cfg.")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
||||
# See if we have been given specific modules to build from command line.
|
||||
if len(argv) > 1 and not make_release:
|
||||
arg_modules = True
|
||||
modules = argv[1:]
|
||||
|
||||
# Find the tools we need.
|
||||
try:
|
||||
tools = find_bi_tools(work_drive)
|
||||
addonbuilder = tools[0]
|
||||
dssignfile = tools[1]
|
||||
dscreatekey = tools[2]
|
||||
cfgconvert = tools[3]
|
||||
|
||||
except:
|
||||
print_error("Arma 3 Tools are not installed correctly or the P: drive has not been created.")
|
||||
sys.exit(1)
|
||||
|
||||
if build_tool == "pboproject":
|
||||
try:
|
||||
depbo_tools = find_depbo_tools("HKLM")
|
||||
if depbo_tools == -1:
|
||||
depbo_tools = find_depbo_tools("HKCU")
|
||||
pboproject = depbo_tools[0]
|
||||
rapifyTool = depbo_tools[1]
|
||||
makepboTool = depbo_tools[2]
|
||||
except:
|
||||
raise
|
||||
print_error("Could not find dePBO tools. Download the needed tools from: https://dev.withsix.com/projects/mikero-pbodll/files")
|
||||
sys.exit(1)
|
||||
|
||||
# Try to open and deserialize build cache file.
|
||||
try:
|
||||
cache = {}
|
||||
with open(os.path.join(make_root, "make.cache"), 'r') as f:
|
||||
cache_raw = f.read()
|
||||
|
||||
cache = json.loads(cache_raw)
|
||||
|
||||
except:
|
||||
print ("No cache found.")
|
||||
cache = {}
|
||||
|
||||
# Get list of subdirs in make root.
|
||||
dirs = next(os.walk(module_root))[1]
|
||||
|
||||
# Autodetect what directories to build.
|
||||
if module_autodetect and not arg_modules:
|
||||
modules = []
|
||||
for path in dirs:
|
||||
# Any dir that has a config.cpp in its root is an addon to build.
|
||||
config_path = os.path.join(path, 'config.cpp')
|
||||
if os.path.isfile(config_path) and not path in ignore:
|
||||
modules.append(path)
|
||||
|
||||
# Make the key specified from command line if necessary.
|
||||
if new_key:
|
||||
if not os.path.isfile(os.path.join(module_root, key_name + ".biprivatekey")):
|
||||
print_green("\nRequested key does not exist.")
|
||||
ret = subprocess.call([dscreatekey, key_name]) # Created in make_root
|
||||
if ret == 0:
|
||||
print_blue("Created: " + os.path.join(module_root, key_name + ".biprivatekey"))
|
||||
else:
|
||||
print_error("Failed to create key!")
|
||||
|
||||
try:
|
||||
print_blue("Copying public key to release directory.")
|
||||
|
||||
try:
|
||||
os.makedirs(os.path.join(module_root, release_dir, "Keys"))
|
||||
except:
|
||||
pass
|
||||
|
||||
shutil.copyfile(os.path.join(module_root, key_name + ".bikey"), os.path.join(module_root, release_dir, "Keys", key_name + ".bikey"))
|
||||
|
||||
except:
|
||||
raise
|
||||
print_error("Could not copy key to release directory.")
|
||||
|
||||
else:
|
||||
print_green("\nNOTE: Using key " + os.path.join(module_root, key_name + ".biprivatekey"))
|
||||
|
||||
key = os.path.join(module_root, key_name + ".biprivatekey")
|
||||
|
||||
|
||||
# For each module, prep files and then build.
|
||||
for module in modules:
|
||||
print_green("\nMaking " + module + "-"*max(1, (60-len(module))))
|
||||
|
||||
# Cache check
|
||||
if module in cache:
|
||||
old_sha = cache[module]
|
||||
else:
|
||||
old_sha = ""
|
||||
|
||||
# Hash the module
|
||||
new_sha = get_directory_hash(os.path.join(module_root, module))
|
||||
|
||||
# Check if it needs rebuilt
|
||||
# print ("Hash:", new_sha)
|
||||
if old_sha == new_sha:
|
||||
if not force_build:
|
||||
print("Module has not changed.")
|
||||
# Skip everything else
|
||||
continue
|
||||
|
||||
# Only do this if the project isn't stored directly on the work drive.
|
||||
# Split the path at the drive name and see if they are on the same drive (usually P:)
|
||||
if os.path.splitdrive(module_root)[0] != os.path.splitdrive(work_drive)[0]:
|
||||
try:
|
||||
# Remove old work drive version (ignore errors)
|
||||
shutil.rmtree(os.path.join(work_drive, prefix, module), True)
|
||||
|
||||
# Copy module to the work drive
|
||||
shutil.copytree(module, os.path.join(work_drive, prefix, module))
|
||||
|
||||
except:
|
||||
raise
|
||||
print_error("ERROR: Could not copy module to work drive. Does the module exist?")
|
||||
input("Press Enter to continue...")
|
||||
print("Resuming build...")
|
||||
continue
|
||||
#else:
|
||||
#print("WARNING: Module is stored on work drive (" + work_drive + ").")
|
||||
|
||||
try:
|
||||
# Remove the old pbo, key, and log
|
||||
old = os.path.join(module_root, release_dir, project, "Addons", module) + "*"
|
||||
files = glob.glob(old)
|
||||
for f in files:
|
||||
os.remove(f)
|
||||
|
||||
if pbo_name_prefix:
|
||||
old = os.path.join(module_root, release_dir, project, "Addons", pbo_name_prefix+module) + "*"
|
||||
files = glob.glob(old)
|
||||
for f in files:
|
||||
os.remove(f)
|
||||
except:
|
||||
raise
|
||||
print_error("ERROR: Could not copy module to work drive. Does the module exist?")
|
||||
input("Press Enter to continue...")
|
||||
print("Resuming build...")
|
||||
continue
|
||||
|
||||
# Build the module into a pbo
|
||||
print_blue("Building: " + os.path.join(work_drive, prefix, module))
|
||||
print_blue("Destination: " + os.path.join(module_root, release_dir, project, "Addons"))
|
||||
|
||||
# Make destination folder (if needed)
|
||||
try:
|
||||
os.makedirs(os.path.join(module_root, release_dir, project, "Addons"))
|
||||
except:
|
||||
pass
|
||||
|
||||
# Run build tool
|
||||
build_successful = False
|
||||
if build_tool == "pboproject":
|
||||
try:
|
||||
#PABST: Convert config (run the macro'd config.cpp through CfgConvert twice to produce a de-macro'd cpp that pboProject can read without fucking up:
|
||||
shutil.copyfile(os.path.join(work_drive, prefix, module, "config.cpp"), os.path.join(work_drive, prefix, module, "config.backup"))
|
||||
|
||||
os.chdir("P:\\")
|
||||
|
||||
cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-bin", "-dst", os.path.join(work_drive, prefix, module, "config.bin"), os.path.join(work_drive, prefix, module, "config.cpp")]
|
||||
ret = subprocess.call(cmd)
|
||||
if ret != 0:
|
||||
print_error("CfgConvert -bin return code == " + str(ret))
|
||||
input("Press Enter to continue...")
|
||||
|
||||
cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-txt", "-dst", os.path.join(work_drive, prefix, module, "config.cpp"), os.path.join(work_drive, prefix, module, "config.bin")]
|
||||
ret = subprocess.call(cmd)
|
||||
if ret != 0:
|
||||
print_error("CfgConvert -txt) return code == " + str(ret))
|
||||
input("Press Enter to continue...")
|
||||
|
||||
# Include build number
|
||||
try:
|
||||
configpath = os.path.join(work_drive, prefix, module, "config.cpp")
|
||||
f = open(configpath, "r")
|
||||
configtext = f.read()
|
||||
f.close()
|
||||
|
||||
patchestext = re.search(r"class CfgPatches\n\{(.*?)\n\}", configtext, re.DOTALL).group(1)
|
||||
patchestext = re.sub(r'version(.*?)="(.*?)"', r'version\1="\2-{}"'.format(commit_id), patchestext)
|
||||
configtext = re.sub(r"class CfgPatches\n\{(.*?)\n\}", "class CfgPatches\n{"+patchestext+"\n}", configtext, flags=re.DOTALL)
|
||||
|
||||
f = open(configpath, "w")
|
||||
f.write(configtext)
|
||||
f.close()
|
||||
except:
|
||||
raise
|
||||
print_error("Failed to include build number")
|
||||
continue
|
||||
|
||||
if os.path.isfile(os.path.join(work_drive, prefix, module, "$NOBIN$")):
|
||||
print_green("$NOBIN$ Found. Proceeding with non-binarizing!")
|
||||
cmd = [makepboTool, "-P","-A","-L","-N","-G", os.path.join(work_drive, prefix, module),os.path.join(module_root, release_dir, project,"Addons")]
|
||||
|
||||
else:
|
||||
cmd = [pboproject, "-P", os.path.join(work_drive, prefix, module), "+Engine=Arma3", "-S","+Noisy", "+X", "+Clean", "+Mod="+os.path.join(module_root, release_dir, project), "-Key"]
|
||||
|
||||
color("grey")
|
||||
if quiet:
|
||||
devnull = open(os.devnull, 'w')
|
||||
ret = subprocess.call(cmd, stdout=devnull)
|
||||
devnull.close()
|
||||
else:
|
||||
ret = subprocess.call(cmd)
|
||||
color("reset")
|
||||
|
||||
if ret == 0:
|
||||
print_green("pboProject return code == " + str(ret))
|
||||
# Prettyprefix rename the PBO if requested.
|
||||
if pbo_name_prefix:
|
||||
try:
|
||||
os.rename(os.path.join(module_root, release_dir, project, "Addons", module+".pbo"), os.path.join(module_root, release_dir, project, "Addons", pbo_name_prefix+module+".pbo"))
|
||||
except:
|
||||
raise
|
||||
print_error("Could not rename built PBO with prefix.")
|
||||
# Sign result
|
||||
if key:
|
||||
print("Signing with " + key + ".")
|
||||
if pbo_name_prefix:
|
||||
ret = subprocess.call([dssignfile, key, os.path.join(module_root, release_dir, project, "Addons", pbo_name_prefix + module + ".pbo")])
|
||||
else:
|
||||
ret = subprocess.call([dssignfile, key, os.path.join(module_root, release_dir, project, "Addons", module + ".pbo")])
|
||||
|
||||
if ret == 0:
|
||||
build_successful = True
|
||||
else:
|
||||
build_successful = True
|
||||
|
||||
if not build_successful:
|
||||
print_error("pboProject return code == " + str(ret))
|
||||
print_error("Module not successfully built/signed.")
|
||||
input("Press Enter to continue...")
|
||||
print ("Resuming build...")
|
||||
continue
|
||||
|
||||
#PABST: cleanup config BS (you could comment this out to see the "de-macroed" cpp
|
||||
#print_green("\Pabst (restoring): " + os.path.join(work_drive, prefix, module, "config.cpp"))
|
||||
os.remove(os.path.join(work_drive, prefix, module, "config.cpp"))
|
||||
os.remove(os.path.join(work_drive, prefix, module, "config.bin"))
|
||||
os.rename(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp"))
|
||||
|
||||
# Back to the root
|
||||
os.chdir(module_root)
|
||||
|
||||
except:
|
||||
raise
|
||||
print_error("Could not run Addon Builder.")
|
||||
input("Press Enter to continue...")
|
||||
print ("Resuming build...")
|
||||
continue
|
||||
|
||||
elif build_tool== "addonbuilder":
|
||||
# Detect $NOBIN$ and do not binarize if found.
|
||||
if os.path.isfile(os.path.join(work_drive, prefix, module, "$NOBIN$")):
|
||||
do_binarize = False
|
||||
print("$NOBIN$ file found in module, packing only.")
|
||||
else:
|
||||
do_binarize = True
|
||||
try:
|
||||
# Call AddonBuilder
|
||||
os.chdir("P:\\")
|
||||
|
||||
cmd = [addonbuilder, os.path.join(work_drive, prefix, module), os.path.join(make_root, release_dir, project, "Addons"), "-clear", "-project="+work_drive]
|
||||
if not do_binarize:
|
||||
cmd.append("-packonly")
|
||||
|
||||
if quiet:
|
||||
previousDirectory = os.getcwd()
|
||||
os.chdir(arma3tools_path)
|
||||
devnull = open(os.devnull, 'w')
|
||||
ret = subprocess.call(cmd, stdout=devnull)
|
||||
devnull.close()
|
||||
os.chdir(previousDirectory)
|
||||
else:
|
||||
previousDirectory = os.getcwd()
|
||||
os.chdir(arma3tools_path)
|
||||
print_error("Current directory - " + os.getcwd())
|
||||
ret = subprocess.call(cmd)
|
||||
os.chdir(previousDirectory)
|
||||
print_error("Current directory - " + os.getcwd())
|
||||
color("reset")
|
||||
print_green("completed")
|
||||
# Prettyprefix rename the PBO if requested.
|
||||
if pbo_name_prefix:
|
||||
try:
|
||||
os.rename(os.path.join(make_root, release_dir, project, "Addons", module+".pbo"), os.path.join(make_root, release_dir, project, "Addons", pbo_name_prefix+module+".pbo"))
|
||||
except:
|
||||
raise
|
||||
print_error("Could not rename built PBO with prefix.")
|
||||
|
||||
if ret == 0:
|
||||
# Sign result
|
||||
if key:
|
||||
print("Signing with " + key + ".")
|
||||
if pbo_name_prefix:
|
||||
ret = subprocess.call([dssignfile, key, os.path.join(make_root, release_dir, project, "Addons", pbo_name_prefix + module + ".pbo")])
|
||||
else:
|
||||
ret = subprocess.call([dssignfile, key, os.path.join(make_root, release_dir, project, "Addons", module + ".pbo")])
|
||||
|
||||
if ret == 0:
|
||||
build_successful = True
|
||||
else:
|
||||
build_successful = True
|
||||
|
||||
if not build_successful:
|
||||
print_error("Module not successfully built.")
|
||||
|
||||
# Back to the root
|
||||
os.chdir(make_root)
|
||||
|
||||
except:
|
||||
raise
|
||||
print_error("Could not run Addon Builder.")
|
||||
input("Press Enter to continue...")
|
||||
print ("Resuming build...")
|
||||
continue
|
||||
|
||||
else:
|
||||
print_error("Unknown build_tool " + build_tool + "!")
|
||||
|
||||
# Update the hash for a successfully built module
|
||||
if build_successful:
|
||||
cache[module] = new_sha
|
||||
|
||||
# Done building all modules!
|
||||
|
||||
# Write out the cache state
|
||||
cache_out = json.dumps(cache)
|
||||
with open(os.path.join(make_root, "make.cache"), 'w') as f:
|
||||
f.write(cache_out)
|
||||
|
||||
# Delete the pboproject temp files if building a release.
|
||||
if make_release and build_tool == "pboproject":
|
||||
try:
|
||||
shutil.rmtree(os.path.join(module_root, release_dir, project, "temp"), True)
|
||||
except:
|
||||
print_error("ERROR: Could not delete pboProject temp files.")
|
||||
|
||||
print_green("\nDone.")
|
||||
|
||||
# Make release
|
||||
if make_release:
|
||||
print_blue("\nMaking release: " + project + "-" + release_version + ".zip")
|
||||
|
||||
try:
|
||||
# Delete all log files
|
||||
for root, dirs, files in os.walk(os.path.join(module_root, release_dir, project, "Addons")):
|
||||
for currentFile in files:
|
||||
if currentFile.lower().endswith("log"):
|
||||
os.remove(os.path.join(root, currentFile))
|
||||
|
||||
# Create a zip with the contents of release/ in it
|
||||
shutil.make_archive(project + "-" + release_version, "zip", os.path.join(module_root, release_dir))
|
||||
except:
|
||||
raise
|
||||
print_error("Could not make release.")
|
||||
|
||||
# Copy to Arma 3 folder for testing
|
||||
if test:
|
||||
print_blue("\nCopying to Arma 3.")
|
||||
|
||||
if sys.platform == "win32":
|
||||
reg = winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE)
|
||||
try:
|
||||
k = winreg.OpenKey(reg, r"SOFTWARE\Wow6432Node\Bohemia Interactive\Arma 3")
|
||||
a3_path = winreg.EnumValue(k, 1)[1]
|
||||
winreg.CloseKey(k)
|
||||
except:
|
||||
print_error("Could not find Arma 3's directory in the registry.")
|
||||
else:
|
||||
a3_path = cygwin_a3path
|
||||
|
||||
if os.path.exists(a3_path):
|
||||
try:
|
||||
shutil.rmtree(os.path.join(a3_path, project), True)
|
||||
shutil.copytree(os.path.join(module_root, release_dir, project), os.path.join(a3_path, project))
|
||||
except:
|
||||
print_error("Could not copy files. Is Arma 3 running?")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
input("Press Enter to continue...")
|
Loading…
Reference in New Issue
Block a user