leecarter
Member-
Content Count
9 -
Joined
-
Last visited
-
Medals
Everything posted by leecarter
-
Finally got Artillery working right!
leecarter posted a topic in ARMA 3 - MISSION EDITING & SCRIPTING
EDIT: More refined and smarter script 2 posts down. I looked high and low for a way to get Artillery to fire correctly but couldn't find it. Maybe this is somewhere else, but I don't know where. I wanted a script that: Allowed the artillery to fire on *any* enemy that strays into it's marked area of defense. Made the artillery piece re-adjust it's aim before every shot for moving targets. Was smart enough not to fire at aircraft. I tried the approach most people use with mortars, but it wasn't working with artillery pieces and the MLRS. It took me hours of trial and error, but I finally figured out you have to hold the artillery piece's hand and tell it to reload and then wait for it to finish reloading. When you run it, you'll see the piece fire, put it's cannon or MLRS launcher down while it's reloading (10 secs default), then put it back up again and fire - wash and repeat. The range has to be correct, if it's too far or too close it won't fire. You can cut the reload time down with the MLRS, but it seems to get a little buggy if you do. Actually, the MLRS just seems to be a little buggy period. It takes a while for the rounds to reach their targets, so if you have something trucking through the target area the shells are going to lag pretty far behind it, but they will follow the target. Here's the main script, I called it fireArty.sqf: _arty = _this select 0; _targetArray = _this select 1; _target = _targetArray select 0; _theAmmo = getArtilleryAmmo [_arty] select 0; _idx = 0; //10 seconds to reload is for the //longest reloading artillery piece. //MLRS can reload faster, but they get buggy. _reloadTime = 10; // The number of times you want the _arty to check for range // and fire (if in range). _shellCount = 10; _arty addMagazineTurret [_theAmmo, [0]]; sleep _reloadTime; // prevents firing at aircraft if(isTouchingGround _target ) then { while {(_idx < _shellCount)} do{ _tgtPos = position _target; _isInRange = _tgtPos inRangeOfArtillery [[_arty], _theAmmo ]; if (_isInRange) then { _arty doArtilleryFire [_tgtPos, _theAmmo, 1]; _arty addMagazineTurret [_theAmmo, [0]]; sleep _reloadTime; } else { //Try moving the target area marker hint "Too close or far for artillery"; _idx = _shellCount; }; _idx = _idx + 1; }; }; You can change the values at the top for whatever piece you're using if you wanted to. To set it up, make an artillery piece and name it whatever you want. In this example I used arty1. Then make a trigger that goes off repeatedly any time an enemy enters and put this in the on act section: script=[arty1, thislist] execVM "fireArty.sqf"; You can reuse this script with as many different artillery and MLRS pieces and as many different targets as you want, so: script=[arty1, thislist] execVM "fireArty.sqf"; script=[arty2, thislist] execVM "fireArty.sqf"; script=[arty3, thislist] execVM "fireArty.sqf"; Would all be valid as actions for targets assuming you created artillery pieces with those names. Enjoy! :) -
Haha that was me! Funny to find yourself quoted like that. Anyway, yeah the game is bad. Real bad.
-
Finally got Artillery working right!
leecarter replied to leecarter's topic in ARMA 3 - MISSION EDITING & SCRIPTING
Sure, you could attach a variable to the target called "currentlyTargeted" or something that the other arty pieces could do a check on in their scripts. There's lots of room for refinement and additions here (like any script), but this makes for a nice usable "core" artillery script. ---------- Post added at 00:16 ---------- Previous post was at 00:13 ---------- Sure, I'd pass your "spotter" soldier in as a parameter and then do a check that he's alive before targeting. I believe it keeps reloading forever, if you wanted to get fancy you could count the number of rounds and then stop after x amount and upon reloading set the variable back to 0. -
Finally got Artillery working right!
leecarter replied to leecarter's topic in ARMA 3 - MISSION EDITING & SCRIPTING
Here's a script for mortars since they behave a little differently. As it turns out, mortars aren't as predictable as artillery. Sometimes they just rattle off a bunch of rounds despite what the scripts tell them to do. But regardless of that, like the artillery script above, this script does a decent job of: Fire on any enemy ground unit (set in the trigger) that strays into it's target area. Re-adjust it's aim between (most) shots. Doesn't fire at aircraft. Acquires a new target if the current target is dead. Allows for shell transit time before checking if the target is still alive and re-adjusting aim (buggy). This also uses 2 scripts, so make sure you have the "findLiveGroundTarget.sqf"" script from the post above. Then the script I called "fireMortar.sqf" _mortar = _this select 0; _targetArray = _this select 1; _shellTravelTime = _this select 2; // _shellTravelTime is the third // param passed in. // This is how long you want the // mortar to wait between // checking for targets. The point is // to prevent wasting shots on dead targets. // This doesn't work 100% with mortars like // it does with artillery. Not sure why - might // be a tad bugged still. // Higher = slower rate of fire, more accurate // Lower = higher rate of fire, less accurate //This script call acquires the target _tgtScript = [_targetArray] execVM "findLiveGroundTarget.sqf"; waitUntil {scriptDone _tgtScript}; _target = liveGroundTarget; if (!isNull _target) then { _theAmmo = getArtilleryAmmo [_mortar] select 0; _idx = 0; // The number of times you want the mortar //to check for range and fire (if in range). _shellCount = 10; // The number of times you want the _mortar to check for range while {(_idx < _shellCount)} do{ _isAlive = alive _target; if(!_isAlive) then { //Target is dead, find another _idx = _shellCount; script = [_mortar, _targetArray, _shellTravelTime] execVM "fireMortar.sqf"; } else { _tgtPos = position _target; _isInRange = _tgtPos inRangeOfArtillery [[_mortar], _theAmmo ]; if (_isInRange) then { _mortar doArtilleryFire [_tgtPos, _theAmmo , 1 ]; //Reload time sleep 5; sleep _shellTravelTime; }else { //The target may have moved too //close or too far, or you might //try moving the target area marker. _idx = _shellCount; }; }; _idx = _idx + 1; }; }; Set it up just like the artillery script above, works exactly the same. Your target on act will look like: script=[mortar1, thislist, 10] execVM "fireMortar.sqf"; For each mortar/target area you wish to use. Enjoy! -
Finally got Artillery working right!
leecarter replied to leecarter's topic in ARMA 3 - MISSION EDITING & SCRIPTING
Yes, you'll get targeted like anything else. If there are multiple targets in the area you may not be the first target chosen though. A fun way to test it is sit on a hill and put a few enemy units down below in the target zone. It's cool to see the arty pause, then start dropping shells on another target after the first is dead. Also helps figure out your shell transit times, they can take quite awhile to get there if the target area is far away. The MLRS is pretty accurate, the big guns - not so much. :D -
Finally got Artillery working right!
leecarter replied to leecarter's topic in ARMA 3 - MISSION EDITING & SCRIPTING
The script would have to be rewritten for that. I just wanted it to fire at anything that came in it's "zone" as that seemed more realistic than "fire only at this guy". I've refined the script quite a bit and am about to post it below. ---------- Post added at 17:02 ---------- Previous post was at 16:46 ---------- The script for mortars is about four posts down. The original script above works fine, but I've refined it and made it a little "smarter". This script will: Fire on any enemy ground unit (set in the trigger) that strays into it's target area. Re-adjust it's aim before each shot. Doesn't fire at aircraft. Acquires a new target if the current target is dead. Allows for shell transit time before checking if the target is still alive and re-adjusting aim. This is a little more complicated than the one above, but it makes for smarter AI artillery. There is a new variable you'll pass in from the trigger for shell transit time. What this does is force the artillery piece to wait for the shell to arrive at the target before checking to see if it's still alive. You'll need to tinker around with this number to get it right for the range and artillery piece. Or just set it to one second and let it fire immediately after it reloads like before. This involves 2 scripts. I wanted to break the functionality for finding live ground targets into another script so it could be used for mortars (or anything else). This one I called "findLiveGroundTarget.sqf"" _targetArray = _this select 0; // Reset the global variable to null // to make sure we start fresh every check. liveGroundTarget = objNull; _idx = 0; _targetCount = count _targetArray; while {(_idx < _targetCount)} do{ _someTarget = _targetArray select _idx; _isAlive = alive _someTarget; if(isTouchingGround _someTarget && _isAlive ) then { //live ground target found, get out of the loop liveGroundTarget = _someTarget; _idx = _targetCount; }; _idx = _idx +1; }; And here is the updated "fireArty.sqf" script: _arty = _this select 0; _targetArray = _this select 1; _shellTravelTime = _this select 2; // _shellTravelTime is the third // param passed in. // This is how long you want the // artillery piece to wait between // checking for targets. The point is // to prevent wasting shots on dead targets. // This wait time increases the time // between shots in addition to the // _reloadTime variable below. // Higher = slower rate of fire, more accurate // Lower = higher rate of fire, less accurate //This script call acquires the target _tgtScript = [_targetArray] execVM "findLiveGroundTarget.sqf"; waitUntil {scriptDone _tgtScript}; _target = liveGroundTarget; if (!isNull _target) then { _theAmmo = getArtilleryAmmo [_arty] select 0; _idx = 0; // The number of times you want the artillery //to check for range and fire (if in range). _shellCount = 10; // 10 seconds to reload is for the // longest reloading artillery piece. // MLRS reloads faster, but it gets buggy // if you set this much lower. _reloadTime = 10; _arty addMagazineTurret [_theAmmo, [0]]; sleep _reloadTime; while {(_idx < _shellCount)} do{ _isAlive = alive _target; if(!_isAlive) then { //Target is dead, find another _idx = _shellCount; script = [_arty, _targetArray, _shellTravelTime] execVM "fireArty.sqf"; } else { _tgtPos = position _target; _isInRange = _tgtPos inRangeOfArtillery [[_arty], _theAmmo ]; if (_isInRange) then { _arty doArtilleryFire [_tgtPos, _theAmmo, 1]; _arty addMagazineTurret [_theAmmo, [0]]; sleep _reloadTime; sleep _shellTravelTime; } else { //The target may have moved too //close or too far, or you might //try moving the target area marker. _idx = _shellCount; }; }; _idx = _idx + 1; }; }; Just like above, create a named artillery piece, in this case "arty1". Then in your trigger's on act put this: script=[arty1, thislist, 10] execVM "fireArty.sqf"; That third parameter is the shell transit time mentioned above. In this example I used 10. And just like above, it's re-usable for as many target areas and artillery pieces you need: script=[arty1, thislist, 10] execVM "fireArty.sqf"; script=[arty2, thislist, 45] execVM "fireArty.sqf"; script=[arty3, thislist, 25] execVM "fireArty.sqf"; Would be for different arty pieces with different shell transit times. Thanks! -
Making the MLRS fire at single target on a trigger
leecarter replied to Yeti1's topic in ARMA 3 - MISSION EDITING & SCRIPTING
I was just working on this today and this solution may be what you're looking for. Works in my testing with the MLRS just fine. :) http://forums.bistudio.com/showthread.php?164194-Finally-got-Artillery-working-right! -
Enemy AI using artillery.
leecarter replied to Jayd33's topic in ARMA 3 - MISSION EDITING & SCRIPTING
I had to edit the script above to prevent the mortar from firing at aircraft, otherwise it seems to be testing out well. Now to figure out the deal with artillery... I've got the artillery working pretty well now, made a separate thread: http://forums.bistudio.com/showthread.php?164194-Finally-got-Artillery-working-right! I'll clean my mortar script up to work more like it sometime soon and post it here. -
Enemy AI using artillery.
leecarter replied to Jayd33's topic in ARMA 3 - MISSION EDITING & SCRIPTING
Hi all, Just thought I'd drop in and share how I managed to do this. First off, as of this post I can not get this to work with artillery units, only mortars. This is a script I wrote that allows the mortar to fire at any enemy land target that enters the target zone. Basically, the effect is that the mortar will "lock on" to any enemy that strays into the target zone(s) you set up for it and will re-adjust it's targeting as the enemy moves around. First, here's the script you'll need. _mortar = _this select 0; _targetArray = _this select 1; _target = _targetArray select 0; _theAmmo = getArtilleryAmmo [_mortar] select 0; _idx = 0; //-- prevents firing at aircraft if(isTouchingGround _target) then { //-- The number of times you want the _mortar to check for range while {(_idx < 10)} do{ _tgtPos = position _target; _isInRange = _tgtPos inRangeOfArtillery [[_mortar], _theAmmo ]; if (_isInRange) then { _mortar commandArtilleryFire [_tgtPos, _theAmmo , 1 ]; }; sleep 5; _idx = _idx + 1; }; }; Of course you can tinker with the values to suit your taste. Next, make a mortar and name it whatever you want. In this example I used mortar1. Then make a trigger that goes off repeatedly any time an enemy enters and put this in the on act section: script=[mortar1, thislist] execVM "fireMortar.sqf"; You can reuse this script with as many different mortars and as many different targets as you want, so: script=[mortar1, thislist] execVM "fireMortar.sqf"; script=[mortar2, thislist] execVM "fireMortar.sqf"; script=[mortar3, thislist] execVM "fireMortar.sqf"; Would all be valid as actions for targets assuming you created mortars with those names. I've only been tinkering around with the editor for a few days, but this is the first thing I wanted to script out and I thought I would share it. EDIT: Prevent firing at aircraft