Ambient artillery scripts

Party-approved future science plus handbooks for the revolution
Post Reply
User avatar
SuicideKing
Host
Posts: 311
Joined: Wed Nov 27, 2013 1:29 pm
Location: India/US West
Contact:

Ambient artillery scripts

Post by SuicideKing »

Hey ho, I put together some ambient artillery scripts that folks might find useful for missions.

The first is supposed to be a purely ambient script, where shells fall outside a safezone. the other has a shrinking safezone which can be non-ambient if you so choose. These are not on github yet because i don't remember how that works anymore :P

can spawn these scripts anywhere really, but probably best to do it from a trigger or something. can use smoke rounds as well.

Code: Select all

//ambient artillery script
if (!isServer) exitWith {};

/*
_centre = centre position of the target zone. Object or position. BIS_fnc_fireSupportVirtual will track a moving object, so the centre can move. 
If null, default centre will be assigned later in the script.
_radius = number. radius within which bombardment takes place. 300m is good for a small village.
_bufferzone = number. BIS_fnc_fireSupportVirtual uses a safe zone set to 0m by default. _bufferzone is used to calc the safe zone (but is not the same).
_unitList = array of units around which artillery should fall. If left empty, defaults will be assigned later in the script.
_ammo = string. ammo class used for bombardment.
_rounds = number. how many rounds to fire?
_delay = exact number or [min,max]. if the latter is used, random time within given range will be used by BIS_fnc_fireSupportVirtual.
*/

params
[
	["_centre", objNull, [objNull, []]],
	["_radius", 300,[999]],
	["_bufferzone", 100, [999]],
	["_unitList", [], [[]]],
	["_ammo", "Sh_82mm_AMOS",[""]],
	["_rounds", 8, [999]],
	["_delay",[10,20],[999,[]]]
];

//last three BIS_fnc_fireSupportVirtual params. These are calibrated to allow the shells to be heard up to 66m away from the impact point.
//The funciton uses say3D with default parameters, i.e. audible up to 100m. It is remote executed so it's MP safe.
//If you change these then test if the shells can still be heard.
_alt = 75; //altitude
_speed = 25; //slow down for flares
_sounds = ["mortar1", "mortar2"]; //CfgSounds classnames for incoming1.wss and incoming2.wss included in game.
//------------------------------------------------------------------------

/*if _unitList is not provided, then use playableUnits in multiplayer, or use all blufor uits in singleplayer. Change these defaults as per requirement.
final list of targets needs to be global scope otherwise BIS_fnc_fireSupportVirtual's condition can't use it.
sk_targetUnits is therefore global.*/
if (count _unitList == 0) then {
		if (isMultiplayer) then {sk_targetUnits = playableUnits}
			else {sk_targetUnits = allUnits select {side _x == blufor}};
	} 
		else {sk_targetUnits = _unitList
	};
systemChat str (sk_targetUnits);

//set random target unit as centre if no centre position or object is specified. 
if (isNull _centre) then {_centre = selectRandom sk_targetUnits};

//find the distances of all the units from the specified centre position or object.
_targetUnitsDistFromCentre = sk_targetUnits apply {_centre distance2D _x};
systemChat str (_targetUnitsDistFromCentre);

//calc safezone by finding the farthest unit from the centre, then adding the buffer distance. (Recommended to set a bigger buffer for larger calibre shells).
_safezone = (selectMax _targetUnitsDistFromCentre) + _bufferzone ;
systemChat format ["safeZone radius based on units = %1", _safezone];

//we might end up in a situation where the safezone is bigger than the total bombardment zone radius. In such a case, radius is increased.
if (_safezone >= _radius) then 
	{
		_radius = _safezone + _bufferzone;
		systemChat format ["safezone larger than radius, setting new radius to %1", _radius];
	};

//set failsafe condition. IF some unit strays out of the safezone radius, abort shelling.
//alternative way might be through trigger areas.
_conditionEnd = compileFinal "'check who is still alive';
							_aliveUnits = sk_targetUnits select {alive _x};
							
							'returns true if any unit strays outside of safezone and aborts fire support. _position and _safeZone are available in BIS_fnc_fireSupportVirtual';
							if( ({(_position distance2D _x) > _safeZone} count _aliveUnits) > 0 ) then
							{
								'Some units have left safezone, aborting bombardment';
								true
							} else 
							{
								'Units within safezone, continuing...';
								false
							};
					";

// spawn fire support function
systemChat "Spawning fire support function with set parameters";
[_centre, _ammo , _radius, _rounds, _delay, _conditionEnd, _safezone, _alt, _speed, _sounds] spawn BIS_fnc_fireSupportVirtual;

Code: Select all

// dynamic arty
if (!isServer) exitWith {};

/*
_centre = centre position of the target zone. Object, pos, or marker. Required. If moving object, BIS_fnc_fireSupportVirtual will track.
_cycleinterval = number. time to wait between fire support missions (and consequent safezone shrinkage)
_ncycles = number of cycles of fire support missions. Default of 999 means it goes on forever, effectively.
_radius = number. radius from centre within which bombardment takes place. 300m is good for a small village.
_safezone = number. safezone from centre in which no rounds will fall.
_minsafezone = number. safe zone will not reduce below this number.
_shrinkby = number. number of meters to shrink the safe zone by after each cycle. if negative, will be auto-calculated.
_ammo = string. ammo class used for bombardment, default mortars. for good smoke use ammo_ShipCannon_120mm_smoke. careful with larger HE rounds.
_rounds = number. rounds to fire in each fire support mission.
_splashdelay = time between round impacts. exact number or [min,max]. if the latter is used, random time within given range will be used by BIS_fnc_fireSupportVirtual.
*/

params
[
	["_centre", objNull, [objNull,[],""]],
	["_cycleinterval", 60, [999]],
	["_ncycles", 999, [999]],
	["_radius", 400, [999]],
	["_safezone", 200, [999]],
	["_minsafezone",0,[999]],
	["_shrinkby", -1, [999]],
	["_ammo", "Sh_82mm_AMOS", [""]],
	["_rounds", 8, [999]],
	["_splashdelay",[10,20], [999,[]]]
];

//last three BIS_fnc_fireSupportVirtual params. These are calibrated to allow the shells to be heard up to 66m away from the impact point.
//The funciton uses say3D with default parameters, i.e. audible up to 100m. It is remote executed so it's MP safe.
//If you change these then test if the shells can still be heard.
_alt = 75; //altitude
_speed = 25; //slow down for flares
_sounds = ["mortar1", "mortar2"]; //CfgSounds classnames for incoming1.wss and incoming2.wss included in game.

//---------------------------------
//check if centre has been provided
if (isNull _centre) exitWith {systemChat "WARNING: center position not provided, aborting script"};

//validate other variables
if (_cycleinterval < 0) then {_cycleinterval = 0};
if (_ncycles < 0) then {_ncycles = 0};
if (_minsafezone < 0) then {_minsafezone = 0};
if (_safezone < _minsafezone) then {_safezone = _minsafezone};
if (_radius < _safezone) then {_radius = _safezone + 100}; //set arbitary _radius

//calculate the safezone reduction per cycle automatically if input param set to a negative number.
//also guard against possible divide by zero
if (_shrinkby < 0) then 
{
	if (_safezone > 0) then {_shrinkby = ceil (_safezone/_ncycles)} 
		else {_shrinkby = 0};
};

//DEBUG
systemChat format ["centre = %1 | cycleinterval = %2 | radius = %3", _centre, _cycleinterval, _radius];

/*
start script loop.
the way it's set up right now, you should always be left with _safezone == _shrinkby (approx) if _shrinkby is auto calculated and _shrinkby > _minsafezone.
to get _safezone = _minsafezone, set _ncycles >= 0 in the while loop condition, but loop will run (_ncycles+1) times.
*/
while {_ncycles > 0} do 
{
	//DEBUG
	systemChat format ["ncycles = %1 | safezone = %2 | minsafezone = %3 | shrinkby = %4", _ncycles, _safezone, _minsafezone, _shrinkby];
	
	// spawn fire support function and wait until it is done (to avoid multiple fire support scripts running together if _cycleinterval is too small)
	_handler = [_centre, _ammo , _radius, _rounds, _splashdelay, {false}, _safezone, _alt, _speed, _sounds] spawn BIS_fnc_fireSupportVirtual;
	waitUntil {scriptDone _handler};
	systemChat "fire support complete";

	//reduce safe zone as long as it's bigger than the minimum allowed
	private _newsafezone = _safezone - _shrinkby;
	if (_newsafezone >= _minsafezone) then {_safezone = _newsafezone} 
		else {_safezone = _minsafezone;};
	
	//decrease cycle count by 1
	_ncycles = _ncycles - 1;

	//wait for the next cycle to start
	sleep (_cycleinterval);
};
let me know if there are any bugs and stuff or better ways of doing things. probably going to be easier to do that whenever i get around to uploading it to github. but yeah feel free to use it however.

Next project will be to make a non-virtual artillery-counter-artillery system with safe zones :science101:
themiddlevoid.wordpress.com

Post Reply