Jump to content
Floof

[Release] C-RAM Script

Recommended Posts

Made a c-ram script for my mission and decided to post it here, feel free to use as you wish. (Wip)

 

Place into init.sqf:

call compile preprocessFileLineNumbers "scripts\C-RAM\C-RAM.sqf";
_null = execVM"scripts\C-RAM\cram_init.sqf";

 

scripts\C-RAM\C-RAM.sqf

if(isServer)then{

  FSG_fnc_addCram = {
    params["_cram","_range"];
    _null = [_cram,_range]spawn{
      private["_cram","_range","_incoming","_target","_targetTime"];
      _cram = _this select 0;
      _range = _this select 1;
      while{alive _cram}do{
        _incoming = _cram nearObjects["ShellBase",_range];
        _incoming = _incoming + (_cram nearObjects["MissileBase",_range]);
        _incoming = _incoming + (_cram nearObjects["RocketBase",_range]);

        if(count _incoming > 0)then{
          _target = _incoming select 0;
          _fromTarget = _target getDir _cram;
          _dirTarget = direction _target;
          if(_dirTarget < _fromTarget + 25 && _dirTarget > _fromTarget - 25 && ((getPos _target) select 2) > 20 && alive _target)then{
            _targetTime = time + 5;
            while{alive _cram && alive _target && _targetTime > time}do{
              _cram doWatch _target;
              if((_cram weaponDirection (currentWeapon _cram)) select 2 > 0.15)then{
                _cram fireAtTarget[_target,(currentWeapon _cram)];
              };
            };
          };
          if(alive _target && alive _cram && _target distance _cram < FSG_CRAMDIS && _target distance _cram > 40 && (getPos _target) select 2 > 20)then{
            _null = [_target,_cram]spawn{
              private["_target","_cram","_expPos","_exp"];
              _target = _this select 0;
              _cram = _this select 1;
              _expPos = getPos _target;
              deleteVehicle _target;
              sleep 1;
              _exp = "helicopterexplosmall" createVehicle _expPos;
            };
          };
        };
        if(count _incoming == 0)then{
          sleep 1;
        };
      };
    };
  };
};

scripts\C-RAM\cram_init.sqf

if(isServer)then{

FSG_DEBUG = TRUE; //Show debug info

FSG_CURATORS = []; //Add game masters here

FSG_CRAMDIS = 2000; //Distance to scan for projectiles

{
  if(_x isKindOf "B_AAA_System_01_F")then{
    if((side _x) == West)then{
      [_x,FSG_CRAMDIS]call FSG_fnc_addCram;
    };
  };
} forEach vehicles;

{
  _x addEventHandler["CuratorObjectPlaced",{
    _obj = _this select 1;
    if(_obj isKindOf "B_AAA_System_01_F")then{
      [_obj, FSG_CRAMDIS]call FSG_fnc_addCram;
    };
  }];
}forEach FSG_CURATORS;

};

 

SAMs (Mk21 Centurion) are not yet included.

  • Like 8
  • Thanks 3

Share this post


Link to post
Share on other sites

This is VERY useful ... would it be possible to make a little mod out of it so that it autoinits on every C-Ram and Praetorian ?

 

  • Like 1

Share this post


Link to post
Share on other sites

Should be pretty easy, first i'd like to make it so it doesn't shoot down your own missiles/mortars. And make the praetorian actually shoot down incoming rounds. After that why not, good idea.

  • Like 4

Share this post


Link to post
Share on other sites

Having PROPER antiaircraft AND anti-missile capabilities would just be awesome mate !

 

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

Fixed a bunch of minor bugs, it works like this now:

  • Main radar that scans the skies (optional)
  • Autoinit on every praetorian
  • Mk21 Centurion is very buggy and not included for the time being
  • About a 90% improvement in performance with multiple CRAMs
  • Now ready for mission implementation. (This means you can implement it now and update later without changing settings)

More to come soon, had to fix the broken mess here.

  • Like 2

Share this post


Link to post
Share on other sites

Back at it again trying to get the Mk21 Centurions to work, but for now this is happening:

  • Radar works properly now
  • Praetorians switch to using their own radar incase main is destroyed/not in use
  • Somewhat working target prioritization (Only when main radar is on)
  • Now doesn't drop down to 15 fps with multiple Praetorians on the map

Going to try and get the centurions working for the next update.

  • Thanks 2

Share this post


Link to post
Share on other sites

So, I tried your script and I don't seem to get it quite running.

 

I made a test mission in VR where I placed a Praetorian and a CSAT Mortar. After that I made a folder "scripts" in the mission folder and within that folder made a second folder called "cram". In there I put your two scripts and changed the variables in "init.sqf" as following:

//Edit these to your liking
FSG_DEBUG = FALSE; //Display some useful info
FSG_MAINRADAR = FALSE; //Use a single radar for all CRAMs
FSG_MAINRADAR_NAME = objNull; //Mainradar name, change to objNull if not using
FSG_MAINRADAR_DIS = 2000; //Mainradar scan range
FSG_PRAET_RADAR = TRUE; //Use CRAMs own radar (switches to this if main is destroyed/not in use)
FSG_PRAET_RADAR_RANGE = 2000; //CRAM scan range
FSG_PRAET_OFFSET = 50; //Cram offset
FSG_SAM_RADAR = TRUE; //Use SAMs own radar (switches to this if main is destroyed)
FSG_SAM_RADAR_RANGE = 2000; //SAM radar range
ALERT = FALSE; //This will toggle the alarm on, use if you wish

I then opened the mission in the editor again and played it. Fired one shell at the Praetorian with the mortar, an the Praetorian detected it and shot on it. But as soon as he started firing he started aiming to the ground and fired first into the ground and after that into the horizon at a flat angle. After about 3 seconds he stopped firing.

 

Do you know what went wrong? Or did I do something wrong?

Share this post


Link to post
Share on other sites

Just tested it myself and it does fire at the ground for some reason, even though it shouldn't be able to fire after the incoming round gets destroyed. Targeting part of the script is a mess anyways so i might as well rewrite it, shouldn't take long unless more stuff gets broken (like always).

  • Like 2

Share this post


Link to post
Share on other sites

Holy Flippers!!! Thank you so much for this! I owe you! Please do not let this die. I will spread to word of your great work. We at Tactical Terror are Very Excited to see the improvements to this script.

 

  • Like 1

Share this post


Link to post
Share on other sites

Don't worry it's not dying, just got done fixing the targeting for the moment. I'm still trying to get somewhat accurate target lead & zeroing to work properly. Here's how it looks now:

Gonna post an update later this evening. (It's 3 pm here)

edit: Script seems to be working pretty good now, if the cram shoots you, you are too close. Apparently the Praetorian engages hostile vehicles. (delete the part that enables auto-targeting if you don't want this)

  • Like 1

Share this post


Link to post
Share on other sites

Great work, thank you. Will test it later.

 

By the way, what is this setting for?

FSG_PRAET_OFFSET = 50; //Cram offset

 

Share this post


Link to post
Share on other sites

Was away for a while but FSG_PRAET_OFFSET is used as a detection cone basically, if you fire towards the praetorian and the missile is going towards the praet in a 50 degree radius it will be shot down. This is needed so the praets don't shoot down your own mortars etc. I made a picture so you understand:

580d72b910eb47a36ae4a1fb1d38cc6b.png

Updating the script this weekend.

  • Like 1

Share this post


Link to post
Share on other sites

Wait...that means if the praetorian gets attacked from behind its placement direction it will not shoot down the rounds?

Share this post


Link to post
Share on other sites

Sorry to resurrect this topic after 3 months of no reply, but I was wondering if there was some way to get this to work with Zeus spawned objects? I know Achilles has the ability to use init on objects, so just the script to use it would work.

Share this post


Link to post
Share on other sites

A few questions:

Why aren't you using doTarget for the round instead of the wonky createVehicle?
Why don't you use the normal turret and ammo for the vehicle? You could fetch them by weaponsTurret.
Why is the AI being disabled - the doWatch should override the the AI ability.
Why are you using fire instead of fireAtTarget (once again to avoid the wonkiness of creating the vehicle)?

Presumably, you have good answers for these, so now I'm going to ask about alternatives:
Instead of pulling the variables for leadPrediction out of a hat, why aren't you using the velocity function?
Why is there a sleep for blowing up the round? It takes too long for most missiles - you should sleep for the delete target instead and do that AFTER the round is deleted.
Why is there a chance variable? It doesn't even do anything.
Why didn't you create a fakeHelo target for the missiles part of CRAM script?

Sorry if I come across as really demanding - this is a brilliant script and I can see you've put a lot of work into it, I just wanted to offer some real criticism that you could use to improve it! Also, if I'm necroing this thread, sorry, but I will post a dump of my version soonTM

Thanks for the hard work Floof

Share this post


Link to post
Share on other sites

Didn't really work on this for a while, came up with a new version that works for now. I think this is how it should've looked like from the start, works better too. Last version was a bunch of ideas mashed into one script that barely worked. I have some free time now so i guess it would be a good idea to just finish this project. Also works with Zeus now, i'll try to get some ideas on how to improve performance with many C-RAMs in one area, maybe add some targeting system so all of them don't shoot at a single target. We'll see. And @kirumy half of the script didn't make sense anyways, better to rewrite it. Chance variable was supposed to be a ~0.001% chance to miss the target, wasn't implemented. Createvehicle for targeting was a bad idea from the start, i still have no idea how to get zeroing to work, suggestions welcome.

  • Like 3

Share this post


Link to post
Share on other sites

I think you're in good shape atm. I recommend looking at (pun not intended) this function https://community.bistudio.com/wiki/lookAt and example 3 on that function.

I gave making the mk21 sam version a go (it's not limited to the mk21, should work with any SAM, even Igla pods or static AA launchers), obviously you'd need to adjust the cram_init. Keep in mind I wrote this while at work and it's completely untested, though I see no reason why it shouldn't work (though it probably won't).

if(isServer)then{

  FSG_fnc_addCram = {
    params["_cram","_range"];
    _null = [_cram,_range]spawn{
      private["_cram","_range","_incoming","_target","_targetTime"];
      _cram = _this select 0;
      _range = _this select 1;
      while{alive _cram}do{
        _incoming = _cram nearObjects["ShellBase",_range];
        _incoming = _incoming + (_cram nearObjects["MissileBase",_range]);
        _incoming = _incoming + (_cram nearObjects["RocketBase",_range]);

        if(count _incoming > 0)then{
          _target = _incoming select 0;
          _fromTarget = _target getDir _cram;
          _dirTarget = direction _target;
          if(_dirTarget < _fromTarget + 25 && _dirTarget > _fromTarget - 25 && ((getPos _target) select 2) > 20 && alive _target)then{
            _targetTime = time + 5;
            while{alive _cram && alive _target && _targetTime > time}do{
              _cram doWatch _target;
              if((_cram weaponDirection (currentWeapon _cram)) select 2 > 0.15)then{
                _cram fireAtTarget[_target,(currentWeapon _cram)];
              };
            };
          };
          if(alive _target && alive _cram && _target distance _cram < FSG_CRAMDIS && _target distance _cram > 40 && (getPos _target) select 2 > 20)then{
            _null = [_target,_cram]spawn{
              private["_target","_cram","_expPos","_exp"];
              _target = _this select 0;
              _cram = _this select 1;
              _expPos = getPos _target;
              deleteVehicle _target;
              sleep 1;
              _exp = "helicopterexplosmall" createVehicle _expPos;
            };
          };
        };
        if(count _incoming == 0)then{
          sleep 1;
        };
      };
    };
  };
 
  FSG_fnc_addSam = {
	params["_sam", "_range"];
	_null = [_sam, _range]spawn{
		private ["_sam","_range", "_incoming","_target","_interceptor"];
		_sam = _this select 0;
		_range = _this select 1;
		_magazine = weaponState [_sam, [0]];
		_ammo = getText (configFile >> "CfgMagazines" >> magazines _sam select 0 >> "ammo");
		while {alive _sam}do{
			_incoming = _sam nearObjects ["ShellBase", _range]; 	//advisable to comment this one out, unless you're roleplaying the IDF
			_incoming = _incoming + (_sam nearObjects["MissileBase", _range]);
			_incoming = _incoming + (_sam nearObjects["RocketBase", _range]);
			hint format ["%1 incoming projectiles", _incoming];
			 if (count _incoming > 0) then{
				_missile = _incoming select 0;
				_fromTarget = _missile getDir _sam;
				_dirTarget = direction _missile;
				if(_dirTarget <_fromTarget + 25 &&_dirTarget >_fromTarget - 25 && alive _missile) then {
					_target = (position _missile) vectorAdd (velocity _missile vectorMultiply (_missile distance _sam)*0.0001); //this is our offset
					_unitVector = vectorNormalized (position _sam vectorDiff _target);											//I strongly advise
					_sam lookAt position _missile;																				//adjusting on a per rocket
					sleep 1; // let it swing the gun around																		basis
					[_sam, _magazine select 1] call BIS_fnc_fire;
					sleep 0.01;
					_interceptor = position _sam nearObjects [_ammo, 500] select 0;
					hint format ["%1 Launched!", _interceptor];
					sleep 0.09;
					while {alive _missile} do {
						_target = (position _missile) vectorAdd ((velocity _missile) vectorMultiply (_missile distance _interceptor)*0.0001); //re
						_unitVector = vectorNormalized (position _interceptor vectorDiff _target);
						_interceptor setVelocity (_unitVector vectorMultiply (vectorMagnitude velocity _missile));
						sleep 0; // adjust if laggy
						if (_interceptor distance _missile < 200) then {
							"HelicopterExploBig" createVehicle (getPos _missile);
							deleteVehicle _missile;
							deleteVehicle _interceptor;
						};
					};
				};
			};
			if (count _incoming == 0) then {
				sleep 1;
			};
			};
		};
	};		 
};


Init:

 

if(isServer)then{

FSG_DEBUG = TRUE; //Show debug info

FSG_CURATORS = []; //Add game masters here

FSG_CRAMDIS = 2000; //Distance to scan for projectiles

{
  if(_x isKindOf "B_AAA_System_01_F")then{
    if((side _x) == West)then{
      [_x,FSG_CRAMDIS]call FSG_fnc_addCram;
    };
  };
  if (_x isKindOf "B_SAM_System_02_F")then{	//you could also add B_SAM_System_01_F, B_SAM_System_03_F or anything you want, that's got a missile.
	if((side _x) == West)then{
	  [_x,8000]call FSG_fnc_addSam; // the cramdis doesn't even do anything lol
	};
  };
} forEach vehicles;

{
  _x addEventHandler["CuratorObjectPlaced",{
    _obj = _this select 1;
    if(_obj isKindOf "B_AAA_System_01_F")then{
      [_obj, FSG_CRAMDIS]call FSG_fnc_addCram;
    };
	if(_obj isKindOf "B_SAM_System_02_F")then{ // you know the drill
	  [_obj, 8000]call FSG_fnc_addSam;
	};
  }];
}forEach FSG_CURATORS; //could also do allCurators if you feel heckin' lazy

};

 

  • Like 2

Share this post


Link to post
Share on other sites

Debugging that's going to be a nightmare, I'll add a debugger version soonTM. I did the entire thing in regular notepad so the syntax is probably less than stellar.
of course, considering how well POOK's SAM pack works, this is might be rather redundant, though I still like the idea of getting this all to work vanilla. Maybe one day we'll be able to do hit-to-kill simulation.

ALSO, it'd be very neat if you could get the rounds to airburst near the object - even if you do something with smoke and mirrors (just spawning many small explosions to occur in a rough area with staggered detonations before deleting the shell or similar).

Alright, final edit: GOT IT WORKING YAY.

Apparently 20m was too small a margin of error and 50m was good. We could make our missile more manoeuvrable to compensate, but why waste the performance?

Share this post


Link to post
Share on other sites

Recommend increasing the offset angle from 25 to 55, this produces more realistic results without risking firing at outgoing ammo. Also, I'd spend some time testing this against the desired munition to triple check it doesn't do anything crazy.
 

 

  • Like 4

Share this post


Link to post
Share on other sites

I was bored at work and was trying to come up with possible improvements. A "centralised" targetting system would be good. If the missiles flew up to altitude before turning to face the incoming projectiles, it would look much more realistic: iron_dome_mortars_intercept_29052018.png

I will upload another version where the missiles "curve" (multiple stages of flight with multiple changes to the direction vector as well as the velocity vector (atm it's only velocity which is why it looks so jank). Might also attach some smoke grenades or something to give the missiles a nicer trail.

Share this post


Link to post
Share on other sites

This version now features boosting to the target + curving missiles + simulated guidance types. The "fuse" proximity has been dramatically lowered. Naturally, this is completely untested as I'm at work, though this time I am confident it will work out of the box (considering I ripped the last one to do it and Barbuse's lovely guided missile script).

Hey Floof, do you reckon it's possible to use a distance check to produce an anti-air site battery that "shares" data via global variables? We could also use those arrays to determine which missile/c-ram is engaging which target -> an array of batteries engages its corresponding missile number. So _incoming select 0 is engaged by _battery select 0 and so on. If we want, we can shuffle the order of the array by sending the most recently used battery to the back of the array.

Also, since we have a method to fetch the ammotypes of the batteries, we can also track outgoing/whitelisted projectiles to reduce clutter + use simulated proximity fuses on each of the projectiles to determine a hit as opposed to using randomization. This is the beautiful thing about this engine, even novices like me can create some heckin' detailed frameworks.

 

if(isServer)then{

  FSG_fnc_addCram = {
    params["_cram","_range"];
    _null = [_cram,_range]spawn{
      private["_cram","_range","_incoming","_target","_targetTime"];
      _cram = _this select 0;
      _range = _this select 1;
      while{alive _cram}do{
        _incoming = _cram nearObjects["ShellBase",_range];
        _incoming = _incoming + (_cram nearObjects["MissileBase",_range]);
        _incoming = _incoming + (_cram nearObjects["RocketBase",_range]);

        if(count _incoming > 0)then{
          _target = _incoming select 0;
          _fromTarget = _target getDir _cram;
          _dirTarget = direction _target;
          if(_dirTarget < _fromTarget + 25 && _dirTarget > _fromTarget - 25 && ((getPos _target) select 2) > 20 && alive _target)then{
            _targetTime = time + 5;
            while{alive _cram && alive _target && _targetTime > time}do{
              _cram doWatch _target;
              if((_cram weaponDirection (currentWeapon _cram)) select 2 > 0.15)then{
                _cram fireAtTarget[_target,(currentWeapon _cram)];
              };
            };
          };
          if(alive _target && alive _cram && _target distance _cram < FSG_CRAMDIS && _target distance _cram > 40 && (getPos _target) select 2 > 20)then{
            _null = [_target,_cram]spawn{
              private["_target","_cram","_expPos","_exp"];
              _target = _this select 0;
              _cram = _this select 1;
              _expPos = getPos _target;
              deleteVehicle _target;
              sleep 1;
              _exp = "helicopterexplosmall" createVehicle _expPos;
            };
          };
        };
        if(count _incoming == 0)then{
          sleep 1;
        };
      };
    };
  };
 
  FSG_fnc_addSam = {
	params["_sam", "_range"];
	_null = [_sam, _range]spawn{
		private ["_sam","_range", "_incoming","_target","_interceptor"];
		_sam = _this select 0;
		_range = _this select 1;
		_magazine = weaponState [_sam, [0]];
		_ammo = getText (configFile >> "CfgMagazines" >> magazines _sam select 0 >> "ammo");
		while {alive _sam}do{
			_incoming = _sam nearObjects ["ShellBase", _range]; 	//advisable to comment this one out, unless you're roleplaying the IDF
			_incoming = _incoming + (_sam nearObjects["MissileBase", _range]);
			_incoming = _incoming + (_sam nearObjects["RocketBase", _range]);
			hint format ["%1 incoming projectiles", count _incoming];
			 if (count _incoming > 0) then{
				_missile = selectRandom _incoming;
				_fromTarget = _missile getDir _sam;
				_dirTarget = direction _missile;
				_target = position _missile;
				_sam lookAt _target;
				sleep (random 4)+3;
				_engaged = _missile getVariable "engaged";
				if(_dirTarget <_fromTarget + 60 &&_dirTarget >_fromTarget - 60 && alive _missile && isNil "_engaged") then {
					_missile setVariable ["engaged", 123,true];
					[_sam, _magazine select 1] call BIS_fnc_fire;
					_interceptor = position _sam nearObjects [_ammo, 5] select 0;
					sleep 0.1; //moved to catch missile immediately.
					hint format ["%1 Launched!", _interceptor];
					_failCount = 0;
					_boostTimer = time + 1.5;
					_boostAngle = _interceptor call BIS_fnc_getPitchBank select 0;
					//sleep 0.09;   boost stage can now be used for guidance without breaking muh immersion
					while {alive _missile} do {
						_minDist = _missile distance _interceptor;
						drawIcon3D["", [1,0,0,1], ASLtoAGL getPosAsl _interceptor, 1,1,45,"Interceptor",1,0.05, "TahomaB"];
						drawIcon3D["", [1,0,0,1], ASLtoAGL getPosAsl _missile, 1,1,45,"Target",1,0.05,"TahomaB"];
						//_velocity = (velocityModelSpace _interceptor) vectorMultiply 1.00001;
						_velocity = (velocityModelSpace _interceptor) vectorMultiply 1.01;
						_velocityTrue = velocityModelSpace _interceptor;
						_dirHor = [_interceptor, _missile] call BIS_fnc_DirTo;
						_interceptor setDir _dirHor;
						_dirVer = acos ((_missile distance2D _interceptor) /(_missile distance _interceptor));
						hint format ["Direction: %1, distance2d: %2, Distance3d: %3", _dirVer, _missile distance2D _interceptor, _missile distance _interceptor];
						// idk?_dirVer = (_dirVer * -1);
						if (serverTime > _boostTimer) then {
							if (_boostAngle < 70) then {_boostAngle = _boostAngle+2.5};
							[_interceptor, _boostAngle, 0] call BIS_fnc_setPitchBank;
							_interceptor setVelocityModelSpace _velocityTrue;
						} else {
							[_interceptor, _dirVer, 0] call BIS_fnc_setPitchBank;
							_interceptor setVelocityModelSpace _velocity;
						};//boosts up for 3 seconds.
						sleep 0.002; // adjust if laggy
						if (_minDist < _missile distance _interceptor) then {
							_failCount = _failCount + 1;
							} else {_failCount = 0};
						if (_interceptor distance _missile < 60 or _failCount > 3) /* Cheat mode*/ then {
							"HelicopterExploBig" createVehicle (getPos _missile);
							deleteVehicle _missile;

						};
					};
					sleep 0.1;
					if (alive _interceptor) then {
						sleep 0.5;
						"HelicopterExploBig" createVehicle (getPos _interceptor);
						deleteVehicle _interceptor;
					};
				};
			};
			if (count _incoming == 0) then {
				sleep 0.5;
			};
			};
		};
	};		 
};


This one is EXTRAORDINARILY complicated, due to all the guidance simulation without actually introducing any new missiles! Frankly, it'll be a miracle if it works, but I secretly have really high hopes for this. One day, some day, we will be doing ship-to-ship combat and it'll be important.

Or you could just go download HAFM Navy, that works too.

Share this post


Link to post
Share on other sites

Sorry for taking a long time to respond. To answer your question i think we should use a global variable for incoming targets. However i have no idea how to seperate them. Say we have 3 C-RAMs in a triangle. How do they know which target to engage? You could store xyz positions of projectiles, but i think this would be slow. My idea was originally to scan for projectiles within range (say theres 5 crams in 1km, they all use the same central point for scanning). This would make the system more realistic by using a central point, a virtual "radar" (even though we have way higher transfer-speeds IRL), this would be great for MILSIMs due to seperate human operated groups, wouldn't work for AI as well. In my opinion it would be great to have radar groups to detect incoming missiles, almost like it works IRL (even tho irl they're more automated (and boring)). If you have other ideas let me know, and since you're clearly interested in this script idea feel free to add me on steam.

  • Like 1

Share this post


Link to post
Share on other sites
On 12/18/2018 at 7:09 AM, kirumy said:

 


if(isServer)then{

  FSG_fnc_addCram = {
    params["_cram","_range"];
    _null = [_cram,_range]spawn{
      private["_cram","_range","_incoming","_target","_targetTime"];
      _cram = _this select 0;
      _range = _this select 1;
      while{alive _cram}do{
        _incoming = _cram nearObjects["ShellBase",_range];
        _incoming = _incoming + (_cram nearObjects["MissileBase",_range]);
        _incoming = _incoming + (_cram nearObjects["RocketBase",_range]);

        if(count _incoming > 0)then{
          _target = _incoming select 0;
          _fromTarget = _target getDir _cram;
          _dirTarget = direction _target;
          if(_dirTarget < _fromTarget + 25 && _dirTarget > _fromTarget - 25 && ((getPos _target) select 2) > 20 && alive _target)then{
            _targetTime = time + 5;
            while{alive _cram && alive _target && _targetTime > time}do{
              _cram doWatch _target;
              if((_cram weaponDirection (currentWeapon _cram)) select 2 > 0.15)then{
                _cram fireAtTarget[_target,(currentWeapon _cram)];
              };
            };
          };
          if(alive _target && alive _cram && _target distance _cram < FSG_CRAMDIS && _target distance _cram > 40 && (getPos _target) select 2 > 20)then{
            _null = [_target,_cram]spawn{
              private["_target","_cram","_expPos","_exp"];
              _target = _this select 0;
              _cram = _this select 1;
              _expPos = getPos _target;
              deleteVehicle _target;
              sleep 1;
              _exp = "helicopterexplosmall" createVehicle _expPos;
            };
          };
        };
        if(count _incoming == 0)then{
          sleep 1;
        };
      };
    };
  };
 
  FSG_fnc_addSam = {
	params["_sam", "_range"];
	_null = [_sam, _range]spawn{
		private ["_sam","_range", "_incoming","_target","_interceptor"];
		_sam = _this select 0;
		_range = _this select 1;
		_magazine = weaponState [_sam, [0]];
		_ammo = getText (configFile >> "CfgMagazines" >> magazines _sam select 0 >> "ammo");
		while {alive _sam}do{
			_incoming = _sam nearObjects ["ShellBase", _range]; 	//advisable to comment this one out, unless you're roleplaying the IDF
			_incoming = _incoming + (_sam nearObjects["MissileBase", _range]);
			_incoming = _incoming + (_sam nearObjects["RocketBase", _range]);
			hint format ["%1 incoming projectiles", count _incoming];
			 if (count _incoming > 0) then{
				_missile = selectRandom _incoming;
				_fromTarget = _missile getDir _sam;
				_dirTarget = direction _missile;
				_target = position _missile;
				_sam lookAt _target;
				sleep (random 4)+3;
				_engaged = _missile getVariable "engaged";
				if(_dirTarget <_fromTarget + 60 &&_dirTarget >_fromTarget - 60 && alive _missile && isNil "_engaged") then {
					_missile setVariable ["engaged", 123,true];
					[_sam, _magazine select 1] call BIS_fnc_fire;
					_interceptor = position _sam nearObjects [_ammo, 5] select 0;
					sleep 0.1; //moved to catch missile immediately.
					hint format ["%1 Launched!", _interceptor];
					_failCount = 0;
					_boostTimer = time + 1.5;
					_boostAngle = _interceptor call BIS_fnc_getPitchBank select 0;
					//sleep 0.09;   boost stage can now be used for guidance without breaking muh immersion
					while {alive _missile} do {
						_minDist = _missile distance _interceptor;
						drawIcon3D["", [1,0,0,1], ASLtoAGL getPosAsl _interceptor, 1,1,45,"Interceptor",1,0.05, "TahomaB"];
						drawIcon3D["", [1,0,0,1], ASLtoAGL getPosAsl _missile, 1,1,45,"Target",1,0.05,"TahomaB"];
						//_velocity = (velocityModelSpace _interceptor) vectorMultiply 1.00001;
						_velocity = (velocityModelSpace _interceptor) vectorMultiply 1.01;
						_velocityTrue = velocityModelSpace _interceptor;
						_dirHor = [_interceptor, _missile] call BIS_fnc_DirTo;
						_interceptor setDir _dirHor;
						_dirVer = acos ((_missile distance2D _interceptor) /(_missile distance _interceptor));
						hint format ["Direction: %1, distance2d: %2, Distance3d: %3", _dirVer, _missile distance2D _interceptor, _missile distance _interceptor];
						// idk?_dirVer = (_dirVer * -1);
						if (serverTime > _boostTimer) then {
							if (_boostAngle < 70) then {_boostAngle = _boostAngle+2.5};
							[_interceptor, _boostAngle, 0] call BIS_fnc_setPitchBank;
							_interceptor setVelocityModelSpace _velocityTrue;
						} else {
							[_interceptor, _dirVer, 0] call BIS_fnc_setPitchBank;
							_interceptor setVelocityModelSpace _velocity;
						};//boosts up for 3 seconds.
						sleep 0.002; // adjust if laggy
						if (_minDist < _missile distance _interceptor) then {
							_failCount = _failCount + 1;
							} else {_failCount = 0};
						if (_interceptor distance _missile < 60 or _failCount > 3) /* Cheat mode*/ then {
							"HelicopterExploBig" createVehicle (getPos _missile);
							deleteVehicle _missile;

						};
					};
					sleep 0.1;
					if (alive _interceptor) then {
						sleep 0.5;
						"HelicopterExploBig" createVehicle (getPos _interceptor);
						deleteVehicle _interceptor;
					};
				};
			};
			if (count _incoming == 0) then {
				sleep 0.5;
			};
			};
		};
	};		 
};


 


Hey @kirumy I'm very interested in outcome of this. One thing i don't know is where exactly do I put this? "Init" part in init.sqf or weapon's init field? And where to put the main part with FSG_fnc_addCram and FSG_fnc_addSam?

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

×