Jump to content
mike123hh

artillery barrage script

Recommended Posts

im trying to write a script to tell my artillery gun "art1" to fire near the soldier "s1" 10 times

using the below the gun only fires once it seems it gets stuck after one loop

 

 

for "_i" from 1 to 10 do {
_ammo = getArtilleryAmmo [art1] select 4;  
_dir = round random 360;  
_dis = 50 + round random 100;  
_tgt = s1 getRelPos [_dis,_dir];  
art1 doArtilleryFire[_tgt,_ammo,1]};

Share this post


Link to post
Share on other sites

try putting some sleep after the doArtilleryFire command. like sleep 3 to wait the arty is ready to fire another

Share this post


Link to post
Share on other sites

hi thanks for suggestion but still only fires once with the below

(its a sochor gun so has more than 1 round)

 

for "_i" from 1 to 10 do { 
_ammo = getArtilleryAmmo [art1] select 4;   
_dir = round random 360;   
_dis = 50 + round random 100;   
_tgt = s1 getRelPos [_dis,_dir];   
art1 doArtilleryFire[_tgt,_ammo,1];
sleep 20};

 

it says that there is an generic expression error somewhere when i start playing

Share this post


Link to post
Share on other sites
1 hour ago, mike123hh said:

hi thanks for suggestion but still only fires once with the below

(its a sochor gun so has more than 1 round)

 

for "_i" from 1 to 10 do { 
_ammo = getArtilleryAmmo [art1] select 4;   
_dir = round random 360;   
_dis = 50 + round random 100;   
_tgt = s1 getRelPos [_dis,_dir];   
art1 doArtilleryFire[_tgt,_ammo,1];
sleep 20};

 

it says that there is an generic expression error somewhere when i start playing

 

actually my advice wasn't the best. What you gotta do instead is to get rid of the loop and put at the third parameter of doArtilleryFire the number of rounds to fire

 

something like:

 

_ammo = getArtilleryAmmo [art1] select 4;   
_dir = round random 360;   
_dis = 50 + round random 100;   
_tgt = s1 getRelPos [_dis,_dir];   
art1 doArtilleryFire [_tgt,_ammo,10]; // Fire 10 times

 

hope that works

  • Like 2

Share this post


Link to post
Share on other sites

This Script Mike needed help with I have a question about a few of the entries

 

_ammo = getArtilleryAmmo [art1] select 4;   

_dir = round random 360;              **360**     ?

_dis = 50 + round random 100;      **50+ and 100**      ?

_tgt = s1 getRelPos [_dis,_dir];   

art1 doArtilleryFire [_tgt,_ammo,10]; // Fire 10 times

 

 

I'm trying to have the rounds land a little closer to the target, any suggestions.

Thanks

Share this post


Link to post
Share on other sites
14 minutes ago, fawlty said:

This Script Mike needed help with I have a question about a few of the entries

 

_ammo = getArtilleryAmmo [art1] select 4;   

_dir = round random 360;              **360**     ?

_dis = 50 + round random 100;      **50+ and 100**      ?

_tgt = s1 getRelPos [_dis,_dir];   

art1 doArtilleryFire [_tgt,_ammo,10]; // Fire 10 times

 

 

I'm trying to have the rounds land a little closer to the target, any suggestions.

Thanks

Cut out the random dir/dist lines, which increase inaccuracy:
 

_ammo = getArtilleryAmmo [art1] select 4;   
art1 doArtilleryFire [s1,_ammo,10]; 

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

It throws an error " Indefined Variable at line 6 _ammo " ...  
 

Update: 
Got it working with 
 

_ammo = getArtilleryAmmo [art1] select 0;

Strange, it should have at least four ammo types (vanilla 2S9 Sochor).
If someone makes this script to work with position instead of object it will be really awesome. 
 

Share this post


Link to post
Share on other sites
2 hours ago, kibaBG said:

Strange, it should have at least four ammo types (vanilla 2S9 Sochor).

"getArtilleryAmmo [art1]" returns an array of all artillery ammo types available to art1.

The "select 0" then takes the first element of said list and that is put into your _ammo variable. So yes _ammo will in your code only ever contain one ammo type.

 

2 hours ago, kibaBG said:

If someone makes this script to work with position instead of object it will be really awesome

You need some way to define where to hit, an object is just a easy way to get a position but the position can just as easily come from a marker or click on the map.

 

Assuming your target is stored as a valid position in _pos the call becomes:

art1 doArtilleryFire [_pos,_ammo,10]; 

 

So you just need to define _pos and watch the rain go boom. As for how you define your position well that's up to you and what you want to achieve.

 

  • Like 2

Share this post


Link to post
Share on other sites

This  script does call a custom function to find a random location near a position, you can write you own to randomize the X and Y location a bit.

 

/*

Order Artillery unit or units to fire on a position.
	
Declare function:  fnc_AI_Artillery = compileFinal preprocessFileLineNumbers "scripts\fnc_AI_Artillery.sqf";

Call function:  0 = [_arrayOrObject,_targetObj or _targetPos,_min_rounds,_max_rounds,_min_salvos,_max_salvos,_min_delay,_max_delay,_spread] call fnc_AI_Artillery;

Ex args:
_arty = Mortar_1
_arrayOrObject = (getMarkerPos "Mk_Booms")
_min_rounds = 2
_max_rounds = 10
_min_salvos = 1
_max_salvos = 5
_min_delay = 3
_max_delay = 20
_spread = 150


*/



private ["_arrayOrObject","_arty","_boomer", "_target","_min_delay","_max_delay","_min_rounds","_max_rounds","_min_salvos","_max_salvos","_salvos", "_delay", "_rounds", "_ammo"];

_arrayOrObject = _this select 0;
_arty = [];
_boomer = objNull;

_target = _this select 1;
_targetPos = [];

_min_rounds = _this select 2;
_max_rounds = _this select 3;

_min_salvos = _this select 4;
_max_salvos = _this select 5;

_min_delay = _this select 6;
_max_delay = _this select 7;

_spread = _this select 8;

if ((typeName _arrayOrObject) == "ARRAY") then 
{
	_arty = _arrayOrObject;
};

if ((typeName _arrayOrObject) == "OBJECT") then 
{
	_arty = [_arrayOrObject];
};


if ((typeName _target) == "ARRAY") then 
{
	_targetPos = _target;
};

if ((typeName _target) == "OBJECT") then 
{
	_targetPos = getpos _target;
};

_salvos = round (_min_salvos + random (_max_salvos - _min_salvos));

{
	_boomer = _x;
	
	// DEBUG STUFF
	/*
	 _txt = str(getArtilleryAmmo [_boomer]);
	 systemChat _txt;
	
	if ( ([[_boomer], (getArtilleryAmmo [_boomer] select 0)]) isEqualTo []) exitWith 
	{
		_txt = "Error in Arty unit " + (typeOf _boomer) + ".  No ammo type found.";
		systemChat _txt;
	};
	*/
	
	
	_isInRange = _targetPos inRangeOfArtillery [[_boomer], (getArtilleryAmmo [_boomer] select 0)];
	
	if (_isInRange) then
	{
	
		0 = [_boomer, _targetPos, _min_delay, _max_delay, _min_rounds, _max_rounds, _salvos, _spread] spawn
		{
			_unit = _this select 0;
			_tgt = _this select 1;
			_minDelay = _this select 2;
			_maxDelay = _this select 3;
			_minRounds = _this select 4;
			_maxRounds = _this select 5;
			_salvos2 = _this select 6;
			_artySpread = _this select 7;
			
			_randomPos = [];
			
			
			// DEBUG STUFF
			/*
			_txt = "Salvos: "+ str(_salvos2);
			systemChat _txt;
			*/
			
			_ammo = getArtilleryAmmo [_unit] select 0; 

			for "_i" from 1 to _salvos2 do 
			{
				_delay = _minDelay + random (_maxDelay - _minDelay);
				_rounds = round (_minRounds + random (_maxRounds - _minRounds));
				
				_mag = _unit ammo (currentMuzzle (gunner _unit));
			
				// DEBUG STUFF
				/*
				_txt = "Rounds in mag: " + str(_mag);
				systemChat _txt;
				*/
				
				if (_mag < _rounds) then
				{
					_rounds = _mag;
				};
				
				if (_mag isEqualTo 0) then
				{
					_unit addMagazine _ammo;
				};
				
				// DEBUG STUFF
				/*
				_txt = "Barrage count: " + str(_rounds);
				systemChat _txt;
				*/
				
				_randomPos = [_tgt,0,_artySpread] call fnc_FindPositionOnLand;

				_unit doArtilleryFire [_randomPos, _ammo, _rounds];

				sleep _delay;
			};
		};
	}
	else
	{
		_txt = "Target Location of Arty unit " + (typeOf _boomer) + " is out of range.";
		diag_log _txt;
		//systemChat _txt;
	};
} forEach _arty;

 

  • Like 1

Share this post


Link to post
Share on other sites

Cool!

3 hours ago, accuracythruvolume said:

This  script does call a custom function to find a random location near a position

I was reading through the script. It calls-

fnc_FindPositionOnLand

But there's no entry on the BIKI for it. Where did you find this function and how does it work 😄? Why this instead of BIS_fnc_findSafePos ?

Share this post


Link to post
Share on other sites

I think he's saying that the script calls that custom function, so you will need to write your own function or use another method to find a position.

Share this post


Link to post
Share on other sites

By the way, some time ago I discovered that the doArtilleryFire creates an invisible unknown enemy in place of the position and shoots at it in fact.
I discovered this when I added an "EnemyDetected" event handler to the artillery group.

Share this post


Link to post
Share on other sites

For  Random position you could do something like this, say you want a spread of 200 meters (100 meters in any direction):

 

_minX = 0;

_maxX = 200

 

_rndX = ((floor(random _maxX )) + _minX ) - (_maxX / 2);

 

_minY = 0;

_maxY = 200

 

_rndY = ((floor(random _maxY )) + _minY )  - (_maxY / 2);

 

_randomPos = [((_tgt select 0) + _rndX) ,  ((_tgt select 1) + _rndY), 0];

 

 

Also since spread is already in the full script I posted earlier, you can just use that.

 

Therefore, just replace the line:

 

_randomPos = [_tgt,0,_artySpread] call fnc_FindPositionOnLand;

 

 

with:

 

_minX = 0;

_maxX = _artySpread

 

_rndX = ((floor(random _maxX )) + _minX ) - (_maxX / 2);

 

_minY = 0;

_maxY = _artySpread

 

_rndY = ((floor(random _maxY )) + _minY )  - (_maxY / 2);

 

_randomPos = [((_tgt select 0) + _rndX) ,  ((_tgt select 1) + _rndY), 0];

 

 

 

 

 

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

×