Jump to content
Blitzen88

Adding Randomization to Artillery Strike

Recommended Posts

I've been tweaking with an AI Artillery script that I cobbled together.  It is intended to be used in a sector control type of mission.  The script selects the closest enemy or neutral sector, scans for targets, and then, if enemys are within range, fires at them.  Although artillery units already have a degree of randomness in their salvo, is there a way to increase the randomness a bit?  I would like to add a bit of randomness to the actual target position.

 

Here is what I got:

 

/*==========================================================================================

				Arma III AI Artillery

===========================================================================================

* Parameters:
    
	- Unit: Unit which will act as Artillery.
   
	- Side: Side of the Artillery Unit
   
 	- Invincible: Whether the Artilley Unit should be invincible or not (True for Invincible)
  
	- Round Count: How many rounds will be fire per volley
  
 	- Scan Distance: Distance from the selected sector that the Artillery Unit will scan for targets
   
 	- Minimum Sleep Time: Minimum amount of time the Artillery Unit will wait before it scans again for targets

	- Maximum Sleep Time: Maximum amount of time the Artillery Unit will wait before it scans again for targets

* Call with: [This, WEST, True, 10, 1000, 300, 600] execVM "Scripts\AI_Artillery.sqf"

===========================================================================================*/

//Define Variables
_ArtilleryUnit = _this select 0;

_Side = _this select 1;

_Invincible = _this select 2;

_NumberofRounds = _this select 3;

_ScanDistance = _this select 4;

_SleepMin = _this select 5;

_SleepMax = _this select 6;

//Need to have a sleep command to give the sectors a moment to initialize
Sleep 5;

//Need to make the Artillery Unit Invincible (based off of input)
if (_Invincible) then {

_ArtilleryUnit allowDamage false;

} else {

_ArtilleryUnit allowDamage true;

};

//Make sure the ArtilleryUnit has ammo
_ArtilleryUnit setVehicleAmmo 1;

//Stop the ArtilleryUnit and empty its fuel so the ArtilleryUnit does not try to immediately move again after stopping
_ArtilleryUnit setVelocity [0, 0, 0];

_ArtilleryUnit setfuel 0;

Switch (_Side) do {
    	
//West Artillery Unit
//----------------------------------------------------
	case WEST : {

	EnemySide1 = East;			// Have to use a Global Variable (I dont know why)

	EnemySide2 = East;			// Have to use a Global Variable (I dont know why)

	FriendlySide = West;			// Have to use a Global Variable (I dont know why)

	};
	
//East Artillery Unit
//----------------------------------------------------
	case EAST : {
	
	EnemySide1 = West;			// Have to use a Global Variable (I dont know why)

	EnemySide2 = Resistance;		// Have to use a Global Variable (I dont know why)

	FriendlySide = East;			// Have to use a Global Variable (I dont know why)

	};
	

//Resistance Artillery Unit
//----------------------------------------------------
	case RESISTANCE : {

	EnemySide1 = East;			// Have to use a Global Variable (I dont know why)

	EnemySide2 = East;			// Have to use a Global Variable (I dont know why)

	FriendlySide = Resistance;		// Have to use a Global Variable (I dont know why)

	};
};


//Find the Closest Neutral or Enemy Sector
_sectors = +BIS_fnc_moduleSector_sectors apply{ [ _x distanceSqr _ArtilleryUnit, _x ] };
_sectors sort true;	
_index = _sectors findIf {
	_x params[ "", "_sector" ];
	
	_sectorOwner = _sector getVariable [ "owner", sideUnknown ];
	_sectorOwner isEqualTo sideUnknown || _sectorOwner isEqualTo EnemySide1 || _sectorOwner isEqualTo EnemySide1					
};

//If the Artillery Unit's side controls all the sectors at once then _index will return as -1.  Need to account for that in the script
if (_index < 0) then {
	
	_Sectors sort false;								// Sort in descending order (farthest sector to closest sector)
	
	_index = _sectors findIf 
		{
		_x params[ "", "_sector" ];
	
		_sectorOwner = _sector getVariable[ "owner", sideUnknown ];		// Include Friendly sectors in the sort since the Artillery Unit's side owns them all
		_sectorOwner isEqualTo FriendlySide
		};

	TargetedSector = getPos ( _sectors select _index select 1 );			// Have to use a Global Variable (I dont know why)


} else {

	TargetedSector = getpos ( _sectors select _index select 1 );			// If the Artillery Unit' side does not own all of the sectors then target the closest neutral/Enemy sector

};

//Save the Targeted Sector to avoid errors with the point changing mid target/scan
_SavedTargetedSector = TargetedSector;

//Scan for infantry groups near the targeted sector
_nearestEnemies = [];

_nearestMen = nearestObjects [_SavedTargetedSector, ["Man"], _ScanDistance];

	{
		    if ( (side _x getFriend (side _ArtilleryUnit)) < 0.6 && {side _x != CIVILIAN} ) then {

			_nearestEnemies = _nearestEnemies + [_x];
			
			};
			
	} forEach _nearestMen;
		

//If a target is found then open fire.  If a target is not found then loop through the script
if (count _nearestEnemies > 0) then {

_Enemy = _nearestEnemies call bis_fnc_selectRandom;

_ArtilleryAmmo = getArtilleryAmmo [_ArtilleryUnit] select 0;

_ArtilleryETA = _ArtilleryUnit getArtilleryETA [getPosATL _Enemy, _ArtilleryAmmo];

_InRange = (getPosATL _Enemy) inRangeOfArtillery [[_ArtilleryUnit], _ArtilleryAmmo];

	if (_ArtilleryETA > 0 AND _InRange) then {

	_ArtilleryUnit commandArtilleryFire [getPosATL _Enemy, _ArtilleryAmmo, _NumberofRounds];		// How can I add a bit of randomness (ie 25 meters left/right of the intended target)

	};

//Give the Artillery Unit Fuel since it is done firing
_ArtilleryUnit setfuel 1;

//Start the Cycle
Sleep _SleepMin + (random _SleepMax);

[_ArtilleryUnit, _Side, _Invincible, _NumberofRounds, _ScanDistance, _SleepMin, _SleepMax] execVM "Scripts\AI_Artillery.sqf";

} else {

//Give the Artillery Unit Fuel since there are no targets in range
_ArtilleryUnit setfuel 1;

//Start the Cycle
Sleep _SleepMin + (random _SleepMax);

[_ArtilleryUnit, _Side, _Invincible, _NumberofRounds, _ScanDistance, _SleepMin, _SleepMax] execVM "Scripts\AI_Artillery.sqf";

};
		

This is the actual fire command:  _ArtilleryUnit commandArtilleryFire [getPosATL _Enemy, _ArtilleryAmmo, _NumberofRounds];

 

How can I add a bit of randomness (ie 10-25 meters to the left/right/front/back) to the target position?

Share this post


Link to post
Share on other sites
_ArtilleryUnit commandArtilleryFire [(getPosATL _Enemy) getPos [random 25 * sqrt random 1, random 360], _ArtilleryAmmo, _NumberofRounds];

This should drop the shell inside of a circle with a radius of 25 meters. The "random 25" determines the actual distance from the center of the enemy position.

Tested with markers, but not with arty.

  • Like 2

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

×