Jump to content
Grumpy Old Man

[Release] GOM - Ambient AA V1.2.1

Recommended Posts

GOM - Ambient AA V1.2.1

 

 


Purpose of this script:

 

Gives mission makers access to simple and versatile ambient AA fire.

 

 

 

Features:

  • Takes pre placed vehicles and uses their main guns to engage AA fire at simulated targets for the given duration.
  • Works fine with static MG turrets (raised) and multiple third party vehicles.
  • It's also possible to immediately stop the script and free up all units to fire on actual threats.
  • For the duration of the ambient AA vehicles will check for a clean line of sight, so they don't mindlessly fire into terrain/objects.
  • If more than half of the assigned vehicles have no line of sight to the simulated target they'll simply pick another one.
  • You can also add and array of positions (ASL) to make the guns fire at them randomly.

 

How to use this script:
At first copy the spoiler contents into a file inside your mission folder and name it accordingly.

 

scripts\GOM\ambient\GOM_fnc_ambientAA.sqf:

 

//V1.2.1

GOM_fnc_ambientAA = {
params [["_battery",""],["_duration",1],["_customRounds",[0,0,0]],["_positions",[]],["_spread",150]];

_debug = false;

GOM_fnc_abortAA = false;
publicVariable "GOM_fnc_abortAA";

GOM_fnc_abortAmbientAA = {

    GOM_fnc_abortAA = true;
    publicVariable "GOM_fnc_abortAA";
    true

};

_getmode = [0,1,2,3];
_denial = [false,false,false,true];
if (_battery isEqualTo "") exitwith {systemchat "You need to specify AA battery in function params."};

_guns = vehicles select {_x getVariable ["GOM_fnc_ambientAABatteryID",""] isEqualTo _battery};

if (_guns isEqualTo []) exitwith {systemchat "You need to specify AA guns through the object init field."};
if (_positions isEqualTo []) then {_positions = [(_guns select 0) getrelpos [random [250,500,1000], random 360]]};

_text = format ["Starting AA fire for %1 minutes.",_duration];
if (_debug) then {systemchat _text;systemchat str _this};


sleep 2;
_fireAtPosition = {

    params ["_gun","_guns","_position","_speed","_movedir","_inittime","_mode","_denial","_overridePos","_spread","_customrounds","_debug"];
    _position params ["","","_alt"];
    if (assignedvehiclerole gunner _gun isEqualTo []) exitWith {true};
    _rndsleep = random [2,4,6];
    _weapon = (_gun weaponsTurret [0] select 0);
    _watchpos = _position;



    _shotsleepsArray = [0.3,-1,-1,0.7];
    _salvoSleepsArray = [ [5,6,7], [2,4,5], [1,1.5,2],[2,3,4]];
    _roundsArray = [[8,10,12],[5,10,20],[10,15,20],[2,3,6]];
    _salvoesArray = [3,round random [3,4,6],round random [5,10,20],4];

    _rounds = _roundsArray select _mode;
    _salvoSleep = _salvoSleepsArray select _mode;
    _salvoes = _salvoesArray select _mode;
    _shotsleep = _shotsleepsArray select _mode;

    if !(_customrounds isEqualTo [0,0,0]) then {_rounds = random _customrounds};

    _gun setvariable ["GOM_fnc_AAnoLoS",false];

    if (_shotsleep isequalto -1) then {
        _weapon = _gun currentweaponturret (assignedvehiclerole gunner _gun select 1);
        _shotsleep = getNumber (configfile >> "CfgWeapons" >> _weapon >> "reloadTime");
        if (_shotsleep >= 0.5) then {_shotsleep = 0.15};

    };

    _timer = time - _inittime + _rndsleep;
    _distance = _speed * _timer;

    if !(_overridePos) then {

        _watchpos = [_position,_distance,_movedir] call BIS_fnc_relPos;
        _watchpos params ["_wX","_wY"];
        _watchpos = [_wX,_wY,_alt];

    };

    if (_denial) then {

        _watchpos = _position;
        _watchpos = _watchpos vectoradd [random 250,random 250,random 250];

    };


    if (_overridePos) then {

        _watchpos = _position;
        _watchpos = _watchpos vectoradd [random [0,_spread,_spread * 2],random [0,_spread,_spread * 2],random [0,_spread,_spread * 2]];

    };

    gunner _gun dowatch _watchpos;
    _resync = time;
    _count = 0;
    waituntil {
        _olddir = gunner _gun weapondirection currentweapon gunner _gun;
        if ((gunner _gun weapondirection currentweapon gunner _gun) isequalto _olddir) then {

            _count = _count + 1;

        };
        _count >= 5;//should check for at least 5 frames to make sure turret is aimed

    };

    _gunGunEnd = getText (configfile >> "CfgVehicles" >> (typeOf _gun) >> "Turrets" >> "MainTurret" >> "gunEnd");

    sleep _rndsleep;

    _nolos = false;

    for "_s" from 1 to _salvoes do {

    if (!alive _gun or !canFire _gun) exitWith {true};

    if (GOM_fnc_abortAA) exitWith {if (_debug) then {systemchat "Aborting AA!";true}};

    if ({_x getvariable ["GOM_fnc_AAnoLoS",false]} count _guns > count _guns / 2) exitWith {
        if (_debug) then {systemchat "More than half of AA battery have no LoS, aborting."};
        true};

        _gunpos     = ATLtoASL (_gun modeltoworld (_gun selectionposition _gunGunEnd));

        _gun setVehicleAmmo 1;


        _intersect = lineIntersectsSurfaces [_gunpos, ATLtoASL _watchpos,_gun];
        _nointersect = _intersect isequalto [];
        if (!_nointersect) exitwith {if (_debug) then {gunner _gun sidechat "Can't fire, no line of sight!"};_nolos =true};

            for "_r" from 1 to round random _rounds do {

            if (!alive _gun or !canFire _gun) exitWith {true};
            if (assignedvehiclerole gunner _gun isEqualTo []) exitWith {true};

            if (GOM_fnc_abortAA) exitWith {if (_debug) then {systemchat "Aborting AA!";true}};



            _timer = time - _inittime + _shotsleep;
            _distance = _speed * _timer;

            if !(_denial) then {

                _watchpos = [_position,_distance,_movedir] call BIS_fnc_relPos;
                _watchpos params ["_wX","_wY"];
                _watchpos = [_wX,_wY,_alt];

            };

            if (_overridePos) then {

                _watchpos = _position;

            };

            //make sure weapon is of projectile type
            _weapons = weapons _gun;
            _projectileIndex = _weapons findIf {

                _mag = getArray (configfile >> "CfgWeapons" >> _x >> "magazines") select 0;
                _ammo = getText (configfile >> "CfgMagazines" >> _mag >> "ammo");
                _ammo isKindOf "BulletCore" AND toUpper _ammo find "SMOKE" isequalto -1;

            };

            if (_projectileIndex isEqualTo -1) exitWith {systemchat "Gun has no viable weapons"};

            gunner _gun dowatch _watchpos;
            _gun setvariable ["GOM_fnc_ambientAAtarget",_watchpos];

            _gunpos     = ATLtoASL (_gun modeltoworld (_gun selectionposition _gunGunEnd));
            _intersect = lineIntersectsSurfaces [_gunpos, ATLtoASL _watchpos,_gun];
            _nointersect = _intersect isequalto [];
            sleep _shotsleep;



                if (_nointersect) then {
                    _gun fire (_gun weaponsTurret [0] select _projectileIndex);
                };

            };

            _sleep = random _salvoSleep;
            _timer = time - _inittime + _sleep;
            _distance = _speed * _timer;

            if !(_denial) then {

                _watchpos = [_position,_distance,_movedir] call BIS_fnc_relPos;
                _watchpos params ["_wX","_wY"];
                _watchpos = [_wX,_wY,_alt];

            } else {

                _watchpos = _position;
               _watchpos =  _watchpos vectoradd [random 250,random 250,random 250];

            };

    if (_overridePos) then {

        _watchpos = _position;
        _watchpos = _watchpos vectoradd [random [0,_spread,_spread * 2],random [0,_spread,_spread * 2],random [0,_spread,_spread * 2]];

    };

            gunner _gun dowatch _watchpos;
            sleep random _sleep;
            _watchpos = _position;

    };

    if (_nolos) exitwith {_gun setvariable ["GOM_fnc_AAnoLoS",true];true};
    if (GOM_fnc_abortAA) exitWith {if (_debug) then {systemchat "Aborting AA!";true}};

    true

};

_sync = time;
_timeout = time + (_duration * 60);

_loopNum = 0;
_break = 0;
while {time < _timeout} do {


    if (GOM_fnc_abortAA) exitWith {if (_debug) then {systemchat "Aborting AA!";true}};

    _loopNum = _loopNum + 1;
    _break = _break + 1;

    _dir = random 360;
    _alt = random [1500,1800,3000] + (getposasl (selectrandom _guns) select 2);
    _dist = random [500,600,1500];

    _position = selectRandom _positions;

    if !(typeName _position isEqualTo "ARRAY") exitWith {systemchat "Positions has to be an array containing positions (ASL)!"};

    if ((ASLToATL _position) select 2 < 50) then {

        _position = _position vectorAdd [0,0,250];

    };

    _getposition = (selectrandom _guns getPos [_dist,_dir]);
    _getposition params ["_pX","_pY"];

    _overridePos = false;
    _getdenial = selectRandom _denial;

    if (_position isEqualTo [0,0,0]) then {

        if (_debug) then {systemchat "Firing at random position.";true};
        _position = [_px,_py,_alt];

    } else {

        _overridePos = true;
        if (_debug) then {systemchat format ["Firing at specfied position: %1 with an average spread of: %2m.",_position,_spread];sleep 3;};
        _getdenial = false;
    };

    _movedir = random 360;
    _speed = round ((random [200,500,800]) / 3.6);
    _mode = selectRandom _getmode;

    _blamblamblam = [];

    {

        _blam = [_x,_guns,_position,_speed,_movedir,_sync,_mode,_getdenial,_overridePos,_spread,_customrounds,_debug] spawn _fireAtPosition;
        _blamblamblam pushback _blam;

    } foreach _guns;
        _modedescr = ["Medium RoF","Fast RoF - Short bursts","Fast RoF - Long bursts","Low RoF - Few rounds"];

        if (_debug) then {

            systemchat format ["Starting loop %1:",_loopNum];
            systemchat format ["Mode %1:",_loopNum];
            systemchat format ["%1.",_modedescr select _mode];

            if (_getdenial) then {systemchat "Aerial Denial."} else {

                if !(_overridePos) then {

                systemchat "Moving target:";
                systemchat format ["Dir: %1 Dist: %2m AGL: %3m.",round _dir,round _dist,round _alt];
                systemchat format ["Target speed: %1km/h - Target heading: %2",round (_speed * 3.6),round _movedir];
            } else {

            systemchat format ["Firing at specified position:%1 Random spread: %2m",_position,_spread];

            };

            };

        };

    waituntil {{scriptdone _x} count _blamblamblam isEqualTo count _blamblamblam};

        if (_debug) then {systemchat format ["Ending loop %1.",_loopNum,_mode]};

            if (_break isequalto 3 AND _duration >= 10) then {
                _rndBreak = round random [10,20,30];
                if (_debug) then {systemchat format ["Break: No fire for %1s.",_rndBreak]};
                sleep _rndBreak;
                _break = 0;
            };

    sleep random [1,2,3];

};

_turretIdles = [];
if (GOM_fnc_abortAA) exitWith {if (_debug) then {systemchat "Aborting AA!";true}};

{

    _idle = [_x] spawn {

        params ["_gun"];
        sleep random [2,4,8];
        gunner _gun dowatch objnull;
        waituntil {_olddir = gunner _gun weapondirection currentweapon gunner _gun;sleep 0.1; gunner _gun weapondirection currentweapon gunner _gun isequalto _olddir;};
        _gun setvariable ["GOM_fnc_AAnoLoS",false];
        true
    };

    _turretIdles pushback _idle;

} foreach _guns;

if (_debug) then {systemchat "Turrets to idle position."};
waituntil {{scriptdone _x} count _turretIdles isEqualTo count _turretIdles};
if (_debug) then {systemchat "Ambient AA fire finished."};
true
};

 

 

init.sqf:

call compile preprocessFileLineNumbers "scripts\GOM\ambient\GOM_fnc_ambientAA.sqf";

 

In the editor:

  1. Place few grouped or ungrouped AA units or armed vehicles
  2. In their init fields put: this setVariable ["GOM_fnc_ambientAABatteryID","AABattery01",true]//where "AABattery01" can be any name
  3. spawn the script:
  4. _battery = "AABattery01";//which battery will do the firing
    _duration = 5;//duration in minutes for the ambient fire to take place
    _AA = [_battery,_duration] spawn GOM_fnc_ambientAA;

     

This will make AABattery01 commence AA fire for 5 minutes.

 

You can also use a custom amount of rounds fired per salvo:

_battery = "AABattery01";//which battery will do the firing
_duration = 2;//duration in minutes for the ambient fire to take place
_rounds = [20,50,50];//(OPTIONAL) will fire at most 50 rounds per salvo
_AA = [_battery,_duration,_rounds] spawn GOM_fnc_ambientAA;

 

To abort the script simply call GOM_fnc_abortAmbientAA to true wherever you like.

_abort = [] call GOM_fnc_abortAmbientAA;

By executing the script again guns will fire as usual.

 

 

Demo Mission 1.2.1

Armaholic 1.2

 

Known Issues:

None so far.

 

Changelog:

 

V1.2.1

  • Fixed: Vehicles that had missiles selected as default would not fire

 

V1.2

  • fixed weird bug that stopped the guns from firing since tanks DLC (had to remove a sleep at the beginning(!) of a waituntil, go figure)
  • added parameter to allow a custom amount of rounds to be fired each salvo
  • fixed error when crew bails out (thanks @Zer0cool and @AZCoder)

Previous changes:

Spoiler

 

V1.1.3

  • Picking random position to shoot at, if no position has been declared

 

V1.1.2:

  • Fixed positions params default value

 

V1.1.1:

  • Fixed wrong _debug value

 

V1.1:

  • Added parameters to make the guns fire at predefined positions
  • Fixed some vectorAdd mishaps

 

 

 

 

Enjoy!

  • Like 13

Share this post


Link to post
Share on other sites

Hey GOM, that is great.  You've made it very simple for adding ambient combat to missions and went the extra mile so these units can engage actual threats they perceive.  Well done.

  • Like 1

Share this post


Link to post
Share on other sites

wow, this looks awesome, thx GOM

 

do they randomly aim or can I actually have them fire at a specific location or a series of locations? 

Share this post


Link to post
Share on other sites

They usually fire at simulated moving targets,

another random fire mode is making them shoot at random static positions roughly above them.

 

I'll add an option to make them fire at a reference point with definable random distance and add further customization.

 

Cheers

Share this post


Link to post
Share on other sites

have them fire at a specific location or a series of locations

Updated to V1.1 and added this to the script.

 

Cheers

Share this post


Link to post
Share on other sites

Hey Grumpy!

 

After testing this I only got "Aborting AA!" when executing the script.

I switched true and false between lines 19 and 24 and then stuff works as it should. I really like the script tho, cool way to add some ambiance. Good job!

  • Like 1

Share this post


Link to post
Share on other sites

Weird, for some reason I forgot to set those variables back to the intended values...

Thanks for spotting that!

Updated the script.

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

Hello, have you tested this script on a dedicated server?

 

I'm making a mission where a signal intelligence team has to spoof a radar transmission to "bait" an AA gun into firing and revealing its position, clearing it for an arty strike.

 

I have your script attached to one Tigris named "AA1"

 

and a satellite phone named "hack" with an addaction code

spoof = [[hack,["Spoof Radar Transmission","scripts\spoof.sqf"]],"addAction",true] call BIS_fnc_MP;

that activates a script called "spoof.sqf" with your code in it and another line of code to show a hint

_AA = [[aa1],1] execVM "GOM_fnc_ambientAA.sqf";
["False Radar Transmission deployed","hint",true,true] call BIS_fnc_MP;

it works fine in the editor and when I host my own MP server off my machine, but when I test it on our groups dedicated server the hint displays without the gun firing. would you happen to have any idea whats causing this?

Share this post


Link to post
Share on other sites

I've tested and used it on dedicated several times by calling it exactly like the first post and it works well (with the modifications as of v1.1.1)

  • Like 1

Share this post


Link to post
Share on other sites

screenshot_232.png

 

 

I was trying to test out the script but it seems that the vehicles and turrets are not firing. The debug mode shows that the script is working but nothing is happening. Is there a long delay before they fire?

Share this post


Link to post
Share on other sites

How are you calling the script?

If you specify custom positions (guessing from the screenshot) to fire at, make sure they're ASL, it looks like you used getposATL instead.

 

Cheers

Share this post


Link to post
Share on other sites

How are you calling the script?

If you specify custom positions (guessing from the screenshot) to fire at, make sure they're ASL, it looks like you used getposATL instead.

 

Cheers

screenshot_233.png

 

 

I do not believe I am specifying a target right now, I copied the code from the example given and just removed the extra items. 

 

 

EDIT:

 

 

I tried again this time I did put in coordinates instead of leaving the item blank and it is firing. How do I get it to fire without having Positions?

 

screenshot_234.png

Share this post


Link to post
Share on other sites

I do not believe I am specifying a target right now, I copied the code from the example given and just removed the extra items. 

 

 

EDIT:

 

 

I tried again this time I did put in coordinates instead of leaving the item blank and it is firing. How do I get it to fire without having Positions?

 

There was an error with the _positions params, a leftover from testing.

Script updated, should be working now.

 

Cheers

Share this post


Link to post
Share on other sites

There was an error with the _positions params, a leftover from testing.

Script updated, should be working now.

 

Cheers

Thanks! I'll try it out asap!

  • Like 1

Share this post


Link to post
Share on other sites

Seems your AA gun doesn't have a gunner in it.

What kind of vehicle is it?

 

Cheers

It is a half track with a mounted AA gun on the back. Its from IFA3. 

 

screenshot_243.png

Share this post


Link to post
Share on other sites

I see, the vehicle has no gunner position, that's what's breaking the script.

Will look into it.

 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×