Blitzen88 16 Posted June 14, 2020 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
Harzach 2505 Posted June 14, 2020 _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. 2 Share this post Link to post Share on other sites