Jump to content

Andre Aerial Patrol - [Coconut Release] - Any Map


Donnovan

Recommended Posts

// *********************************
// Airpatrol.sqf
// Author: Donnavan
// Creates Airbourne convoys
// Modifications:
// Random Weapon selection by Tang0 - redacted
// Random crew skins by Albertus Smythe - redacted
// Random convoy selection by Albertus Smythe
// Bigger spawn area radius by Albertus Smythe
// Below modifications are done by salival
// Full credit for the AI gear/pack/skin/weapon selection goes to WAI, I used this system because it works amazingly and it gives me a single configuration to make loot changes to. - salival
// Random gear selection (ai_gear_random from WAI - WAI MUST BE INSTALLED)
// Random weapon selection (ai_wep_random from WAI - WAI MUST BE INSTALLED)
// Random backpack selection (ai_packs from WAI - WAI MUST BE INSTALLED)
// Random skill selection (ai_skill_random from WAI - WAI MUST BE INSTALLED) 
// Random skin selection (variable: _aiskins contains arrays from WAI (ai_hero_skin,ai_bandit_skin) - WAI MUST BE INSTALLED)
// Enemy will now pull parachute 100% of the time to stop players from getting free loot. Make the buggers work for it!
// Enemies will now share information about players to other AI when a unit is killed (variable _aisharedistance)
// Humanity is now given/lost dependant on alignment, - humanity if player is bandit, + humanity if player is hero
// Chopper will now correctly spawn at the right height based on _spawn (setPosATL)
// Chopper will now fly at a height of (_fh_lower + random(_fh_random). 
// Chopper will randomly select a speed from _convoyspeeds. You can sway the chance of a particular speed being selected by upping the number in the second field. Make sure it all adds up to 100.
// *********************************

//diag_log format ["Heli Convoy: debug: %1 ",_debugvariable]; //place holder for debugging.


if (isServer) then {
	// Add 5min delay to alow DZAI etc to sort itself out otherwise 1st heli seems to be created without a pilot
	// so it immedietly crashes and then there are no waypoints set for the convoy so it just hovers above
	// the create point
	uiSleep (60*5);
	
	_convoyspeed = [];
	_flyspeed = "";
	
	_fh_random = 80; // This number here gets randomized and then added to the below number to form the _flyheight variable.
	_fh_lower = 70; // This is the lowest number that flyheight can be, the above number gets randomized and added to it to form the _flyheight variable.
	_aisharedistance = 600;
	_aiskins = ai_hero_skin + ai_bandit_skin;
	_spawn = [50,50,300]; // Spawn location of chopper, x, y and z for height.
	//_spawn = [100,1500,0]; //debug spawn location for testing

	_gridN = 15;
	_mapSize = 15360; //CHERNARUS

	// ["SPEED",% chance of picking this speed], Make sure the chances add up to 100 or it will not be an accurate percentage.
	_convoyspeeds			= [ 
	["LIMITED",10],
	["NORMAL",50],
	["FULL",40]
	];
	
	_heliFormation =[
	[5,0],
	[10,6],
	[4,3], 
	[0,4], 
	[8,1,7],
	[0], 
	[1],
	[2],  
	[3],
	[4],
	[5],
	[6],
	[7],
	[8], 
	[10]
	];
	
	// define a list of heli's to make up convoys from.
	// [ Vehicle_name,Passenger count,[ammo for each gunpoint],number of Loot points]
	// Passenger count is in addition to the pilot and gunners on the heli's gun points.
	// Empty ammo array means the Heli is unarmed and won't shoot but will land and disembark crew.
	donn_heliConvy = [
	/*0*/["UH1H_DZ",0,["100Rnd_762x51_M240","100Rnd_762x51_M240"],3],
	/*1*/["UH1H_DZ",4,[],4],
	/*2*/["Mi17_UN_CDF_EP1",5,["100Rnd_762x54_PK","100Rnd_762x54_PK"],5],
	/*3*/["CH_47F_EP1_DZE",6,["100Rnd_762x51_M240","4000Rnd_762x51_M134","4000Rnd_762x51_M134"],6],
	/*4*/["AH6J_EP1_DZ",1,[],2],        //ARMED (PILOT)
	/*5*/["UH60M_EP1_DZE",0,["2000Rnd_762x51_M134","2000Rnd_762x51_M134"],3],
	/*6*/["UH1Y_DZE",0,["2000Rnd_762x51_M134","2000Rnd_762x51_M134"],3],
	/*7*/["UH1H_TK_EP1",0,["100Rnd_762x51_M240","100Rnd_762x51_M240"],3],
	/*8*/["BAF_Merlin_DZE",4,[],4],
	/*9*/["pook_H13_amphib_CIV",1,[],1],
	/*10*/["pook_H13_transport_UNO",2,["100Rnd_762x51_M240"],2]
	];

	{
		for "_i" from 1 to (_x select 1) do {
			_convoyspeed set [count _convoyspeed, _x select 0];
		};
	} count _convoyspeeds;
	
	donn_hwps = [];

	for "_i" from 1 to (_gridN - 1) do {
		_wpx = (_i/_gridN)*_mapSize;
		for "_y" from 1 to (_gridN - 1) do {
			_wpy = (_y/_gridN)*_mapSize;
			if !(surfaceIsWater [_wpx,_wpy]) then {donn_hwps = donn_hwps + [[_wpx,_wpy,0]];};
		};
	};

	_heliGroupTot  = count _heliFormation;
	
	donn_heli_HD = {
		_heliHurt = _this select 0;
		_damage   = _this select 2;

		if !(canMove _heliHurt) then {
			if (_heliHurt getVariable "dncmv") then {
				_heliHurt setVariable ["dncmv",false,false];
				{ 
					_x action ["Eject",_heliHurt]; 
				} forEach crew _heliHurt;
			};
		};
		_damage
	};

	donn_heli_unit_HD = {
		// Put group into combat RED mode if heli damaged by player
		_hurtedOne = _this select 0;
		_damage    = _this select 2;
		_ofender   = _this select 3;
		_grp       = group _hurtedOne;

		if (combatMode _grp != "RED" && isPlayer _ofender) then {
			{_x enableAi "TARGET";} forEach units _grp;
			{_x enableAi "AUTOTARGET";} forEach units _grp;
			_grp reveal [_ofender,4];
			_grp setCombatMode "RED";_grp setBehaviour "COMBAT";
		};
		_damage
	};

	donn_heli_unitKill = {
		_unit = _this select 0;
		_player = _this select 1;
		_humanity = _player getVariable["humanity",0];  //Reads the player's current humanity count
		_gain = _unit getVariable ["humanity",50];  //Sets Humanity reward value. 50 humanity per AI kill.
		_role = assignedVehicleRole _unit;

		if ((assignedVehicleRole _unit) select 0 == "Driver") then {
			// If driver is killed eject the crew.
			_vehEject = assignedVehicle _unit;
			{ 
				_x action ["Eject",_vehEject]; 
			} forEach crew _vehEject;
		};

		if ({alive _x} count units group _unit == 0) then {donn_heliGrps = donn_heliGrps - [group _unit];};
		//coins reward
		//_unit setVariable ["cashMoney",12500 + (round random 5) * 1000,true];
		//Humanity Reward - this gives - humanity for bandit player and + humanity for hero player
		if (_humanity < 0) then { _player setVariable ["humanity",(_humanity - _gain),true]; } else { _player setVariable ["humanity",(_humanity + _gain),true]; }; 
		{
			if (((position _x) distance (position _unit)) <= _aisharedistance) then {
				_x reveal [_player, 4.0];
			}
		} forEach allUnits;
	};

	donn_makeAeroRoute = {
		// Set route for convoy
		_origin     = _this select 0;
		_heli_group = _this select 1;
		_speed      = _this select 2;
		_posBefore  = _origin;
		_posNow     = _origin;
		_wp         = _heli_group addWaypoint [_posNow,0,0];
		_wp setWaypointCompletionRadius 65;
		_wp setWaypointType "MOVE";
		_wp setWaypointSpeed _speed;
		_posNext = [0,0,0];

		for "_c" from 1 to 5 do {
			_distToBefore = 0;
			_distToNext   = 0;
			_found        = false;

			for "_x" from 1 to 200 do {
				_posNext        = donn_hwps call BIS_fnc_selectRandom;
				_distToNext     = _posNow distance _posNext;
				_distToBefore   = _posNext distance _posBefore;
				if (_distToNext > 3000 && _distToBefore > 4000) exitWith {};
				uiSleep 0.001;
			};

			if (!_found) then {_posNext = donn_hwps call BIS_fnc_selectRandom;};
			_wp = _heli_group addWaypoint [_posNext,0,_c];
			_wp setWaypointCompletionRadius 65;
			_wp setWaypointType "MOVE";
			_wp setWaypointSpeed _speed;
			_posNow = _posNext;
		};

		_wp = _heli_group addWaypoint [_origin,0,6];
		_wp setWaypointCompletionRadius 65;
		_wp setWaypointType "CYCLE";
		_wp setWaypointSpeed _speed;
	};

	donn_heliGrps = [];

	[] spawn {

		while {{!isNull _x} count donn_heliGrps > 0} do {
			{
				_grp     = _x;
				_forceIn = true;
				{if (_grp knowsAbout _x >= 1.5) then {_grp reveal [_x,4];_forceIn = false;};} forEach playableUnits;
				if (_forceIn) then {
					if (combatMode _grp != "BLUE") then {
						{_x disableAi "TARGET";uiSleep 0.001;} forEach units _grp;
						{_x disableAi "AUTOTARGET";uiSleep 0.001;} forEach units _grp;
						_grp setCombatMode "BLUE";_grp setBehaviour "CARELESS";
					};
					{if (vehicle _x == _x) then {[_x] orderGetIn true;uiSleep 0.001;};} forEach units _grp;
				};
			} forEach donn_heliGrps;
			uiSleep 10;
		};
		diag_log "[HELI CONVOY] Finished convoy rotation.";
	};

	while {1 == 1}  do {
		_cs = floor( random _heliGroupTot);
		diag_log ("[HELI CONVOY] Initialized Spawn! " + str _cs);
		_flyheight = round(_fh_lower + random(_fh_random)); 

		_heli_group     = createGroup EAST;
		donn_heliGrps   = donn_heliGrps + [_heli_group];
		_convoy         = _heliFormation select (_cs);
		_qtd            = count _convoy;
		_helis = [];

		{_helis = _helis + [donn_heliConvy select _x];} forEach _convoy;

		for "_n" from 1 to _qtd do {
			_heli       = _helis    select (_n-1);
			_motor      = createVehicle [_heli select 0,_spawn,[],150,"FLY"];
			_motor setPosATL _spawn;
			_crew       =[];

			_motor removeAllEventHandlers "handleDamage";
			_motor addEventHandler ["handleDamage",{_this call donn_heli_HD}];
			_motor setVariable ["dncmv",true,false];
			_motor setVariable ["dnishp",true,true];
			_motor setVariable ["dnishpq",_heli select 3,true];
			_motor setFuel 1;
			_motor setVehicleLock "LOCKED";
			_motor flyInHeight _flyHeight;

			_ammos = _heli select 2;
			{_ammo = _x;for "_a" from 1 to 8 do {_motor addMagazineTurret [_ammo,[_forEachIndex]];};} forEach _ammos;
			_driverCount    = 1;
			_turreterCount  = count _ammos;
			_cargorsCount   = _heli select 1;
			_crewCount      = _driverCount + _turreterCount + _cargorsCount;
			_gunnerPos      = 0;

			for "_y" from 1 to _crewCount do {
				private "_unit","_aiweapon","_weapon","_magazine","_aipack","_aigear","_gearmagazines","_geartools","aicskill","aiskin";
				_aiweapon 			= [];
				_aigear 			= [];
				_aipack 			= "";
				_aiskin 			= "";
				_aicskill 			= [];
				
				if (_y == 1) then {
					//Skin for pilot
					_aiskin = _aiskins 		call BIS_fnc_selectRandom;
					_unit = _heli_group createUnit [_aiskin,_spawn,[],50,"PRIVATE"];
				};

				if (_y > 1) then {
					// Selection of skins for other crew.
					_aiskin = _aiskins 		call BIS_fnc_selectRandom;
					_unit = _heli_group createUnit [_aiskin,_spawn,[],50,"PRIVATE"];
				};
				
				_unit removeAllEventHandlers "killed";
				_unit removeAllEventHandlers "handleDamage";
				_unit addEventHandler ["killed",{_this call donn_heli_unitKill;}];
				_unit addEventHandler ["handleDamage",{_this call donn_heli_unit_HD}];
				[_unit] joinSilent _heli_group;
				_unit setSkill 0.85;

				// remove default gear/weapons from crew man
				removeAllWeapons _unit;
				removeAllItems _unit;

				_aigear = ai_gear_random call BIS_fnc_selectRandom;
				_gearmagazines 	= _aigear select 0;
				_geartools 		= _aigear select 1;
				
				_aiweapon = ai_wep_random call BIS_fnc_selectRandom;
				_weapon 	= _aiweapon call BIS_fnc_selectRandom;
				_magazine 	= _weapon 	call find_suitable_ammunition;

				_aipack = ai_packs call BIS_fnc_selectRandom; 
				
				for "_i" from 1 to 4 do {
					_unit addMagazine _magazine;
				};
				
				_unit addweapon _weapon;
				_unit selectWeapon _weapon;
				_unit addBackpack _aipack;
				
				{
					_unit addMagazine _x
				} count _gearmagazines;

				{
					_unit addweapon _x
				} count _geartools;
				
				_crew set [_y-1,_unit];
			};
			
			{deleteVehicle _x;} forEach crew _motor;  // moved in order to delete any default crew immediatly before adding the new crew.

			for "_y" from 1 to _crewCount do {
				_unit = _crew select (_y-1);
				
				if (_y == 1) then {
					//First crewman is pilot
					_unit assignAsDriver _motor;
					_unit moveInDriver _motor;
					_aicskill = ai_skill_random call BIS_fnc_selectRandom;
					{
						_unit setSkill [(_x select 0),(_x select 1)]
					} count _aicskill;
				};

				if (_y > 1 && _y <= 1 + _turreterCount) then {
					// Assign a crewman to each turret.
					_unit assignAsGunner _motor;
					_unit moveInTurret [_motor,[_gunnerPos]];
					_gunnerPos = _gunnerPos + 1;
					_aicskill = ai_skill_random call BIS_fnc_selectRandom;
					{
						_unit setSkill [(_x select 0),(_x select 1)]
					} count _aicskill;
				};

				if (_y > 1 + _turreterCount) then {
					//Assign the rest of the crew as passengers
					_unit assignAsCargo _motor;
					_unit moveInCargo _motor;
					_aicskill = ai_skill_random call BIS_fnc_selectRandom;
					{
						_unit setSkill [(_x select 0),(_x select 1)]
					} count _aicskill;
				};
			};
			{_x disableAi "TARGET";uiSleep 0.001;} forEach units _heli_group;
			{_x disableAi "AUTOTARGET";uiSleep 0.001;} forEach units _heli_group;
			_heli_group setCombatMode "BLUE";_heli_group setBehaviour "CARELESS";
		};
		_flyspeed 			= _convoyspeed call BIS_fnc_selectRandom;
		[donn_hwps call BIS_fnc_selectRandom,_heli_group,_flyspeed] call donn_makeAeroRoute;
		
		uiSleep (60*15);
	};
};

 

Link to comment
Share on other sites

Like the changes you've made to the AI but I'm not so sure about using one height and speed for all the convoys, each to his own though.

I'm going to make the AI changes to my servers but personally I'm going to stick with the varied height/speed of the convoys (might even randomise them up a bit).

<THINKS> Wonder if this could be converted into a full WAI mission?</THINKS>

Link to comment
Share on other sites

7 hours ago, Albertus Smythe said:

Like the changes you've made to the AI but I'm not so sure about using one height and speed for all the convoys, each to his own though.

I'm going to make the AI changes to my servers but personally I'm going to stick with the varied height/speed of the convoys (might even randomise them up a bit).

<THINKS> Wonder if this could be converted into a full WAI mission?</THINKS>

To be honest the height/speed changes were just a temporary thing, It got annoying adding them for each convoy while I was debugging, I was also looking at randomizing that so the only heli related variable was the convoy array.

 

I'd be very interested to see what changes you suggest for my edits, they are just a stepping stone really.

Link to comment
Share on other sites

4 hours ago, salival said:

Hey,

 

I went back and updated the script based on Albertus's points, I have updated my previous post with the latest script that adds fly height and speed randomization.

Let me know what you guys think of it.

 

Cheers,

Scott

I've merged your script and mine, basically I've just kept my heli patrol arrays, coin reward and comments, it works well award yourself 2 house points.

2 things, you have the line

		if ({alive _x} count units group _unit == 0) then {donn_heliGrps = donn_heliGrps - [group _unit];};

  twice, any reason? and you can remove the line "_cs = _cs+1" and change any "_cs-1" to "_cs", this was just me trying to make fewe changes to original code in case I had to reverse things out.

Link to comment
Share on other sites

3 hours ago, Albertus Smythe said:

I've merged your script and mine, basically I've just kept my heli patrol arrays, coin reward and comments, it works well award yourself 2 house points.

2 things, you have the line


		if ({alive _x} count units group _unit == 0) then {donn_heliGrps = donn_heliGrps - [group _unit];};

  twice, any reason? and you can remove the line "_cs = _cs+1" and change any "_cs-1" to "_cs", this was just me trying to make fewe changes to original code in case I had to reverse things out.

Looking back in the thread it looks like the second one of those was introduced by Jyggs on page 4 when he showed how to do humanity. I took over the scripting on this server and looking at the original aerial.sqf it was there, too. I guess I always just glanced past it.

I have removed it and changed the _cs references!

 

Cheers,

Scott

Jyggs

Link to comment
Share on other sites

I've just been staring at the line

if ({alive _x} count units group _unit == 0) then {donn_heliGrps = donn_heliGrps - [group _unit];};

and realised it removes the group (and therefore the convoy) from the array donn_heliGrps if all the units (AI) in the convoy are dead.

As a new group is created and inserted into donn_heliGrps for each convoy, it seems to me that we could use count donn_heliGrps to limit the number of convoys active at any one time by surrounding everything between while (1 ==1)  do { and the bottom uisleep (40*15); inside an if (count donn_heliGrps) < _maxConvoys then {}; statement, then every 15 minutes it will only create a new convoy if there are less than _maxConvoys active.

 

 

Link to comment
Share on other sites

22 hours ago, Albertus Smythe said:

I've just been staring at the line


if ({alive _x} count units group _unit == 0) then {donn_heliGrps = donn_heliGrps - [group _unit];};

and realised it removes the group (and therefore the convoy) from the array donn_heliGrps if all the units (AI) in the convoy are dead.

As a new group is created and inserted into donn_heliGrps for each convoy, it seems to me that we could use count donn_heliGrps to limit the number of convoys active at any one time by surrounding everything between while (1 ==1)  do { and the bottom uisleep (40*15); inside an if (count donn_heliGrps) < _maxConvoys then {}; statement, then every 15 minutes it will only create a new convoy if there are less than _maxConvoys active.

 

 

That sounds like a really good idea. I think 3-4 would be the most you would want up at any one point.

 

I have also converted this script over to use fn_selfactions.sqf instead of the way Donnavan had it checking the cursor target, when I work out all the bugs and test it some more i'll also release that and to make a loot crate when you check the chopper for loot, I always found it was hard to find the weapons/items and they were really hard to get the loot right. I would often get 40 motors and 80 bandages and no useful guns. Once again, I've used the WAI weapon/crate spawning logic (I have all my loot in WAI as like a master list)

Cheers,

Scott

Link to comment
Share on other sites

Here's my changes to make this script use fn_selfActions.sqf instead of the default setup. This is the better way to do it. I'm basically assuming you have a custom fn_selfActions.sqf and a custom variables.sqf, if you don't then... you probably should.

 

in your fn_selfActions.sqf Search for: //Repairing Vehicles

Paste the following above it:

_donn_cursorTarget = cursorTarget;
_objVar = _donn_cursorTarget getVariable ["dnishpq",0];

if  ((player distance _donn_cursorTarget < ((sizeOf typeOf _donn_cursorTarget)/2 + 4)) && (!isNil "_objVar") && _objVar > 0) then {
	if (s_collect_heli < 0) then {
		_heliTxt = "Search wreckage for loot";
		if (alive _donn_cursorTarget) then {_heliTxt = "Search helicopter for loot";};
		s_collect_heli = player addaction[("<t color=""#0096ff"">" + _heliTxt + "</t>"),"scripts\andre_heliConvoy_items.sqf",_donn_cursorTarget,5,false,true,"",""];
	};
} else {
	player removeAction s_collect_heli;
	s_collect_heli = -1;
};

Scroll down to the bottom and find:

	// vault
	player removeAction s_player_unlockvault;
	s_player_unlockvault = -1;

Paste this above it:

	player removeAction s_collect_heli;
	s_collect_heli = -1;	

So it looks like:

	player removeAction s_collect_heli;
	s_collect_heli = -1;		
	// vault
	player removeAction s_player_unlockvault;
	s_player_unlockvault = -1;

In your variables.sqf find the section called: dayz_resetSelfActions and find s_player_lockUnlock_crtl inside it (probably towards the end) and add this under it: 	s_collect_heli = -1;
It should now look like this:
	
	s_player_lockUnlock_crtl = -1;
	s_collect_heli = -1;
};


You can now delete the file: heliconvoy_loadout.sqf and remove the line from your init.sqf that loads it. (example: [] execVM "scripts\heliconvoy_loadout.sqf";)
Make sure you change the scripts\andre_heliConvoy_items.sqf to where ever you put it, i.e custom\ or fixes\ etc.

This completes the section for fn_selfActions.sqf

 

Link to comment
Share on other sites

This is my replacement andre_heliConvoy_items.sqf.

 

You need to make sure whatever crate you have (_crate) that it is whitelisted in your battleeye filters, it will kick you otherwise. You can do so by adding !="USOrdnanceBox" to a line that starts with 5. i.e 5 !="USOrdnanceBox" in your battleye/createvehicle.txt

 

Copy paste the following code block into andre_heliConvoy_items.sqf and you're done (as long as you have this mod installed obviously)

 

//Original by Donnavan
//Modified by salival for better loot control
//find_suitable_ammunition from WAI, uses the same variables (but in this file instead since these are clientside)
//Edit the variables to suit your needs, the crate will spawn behind the player.

find_suitable_ammunition = {

	private["_weapon","_result","_ammoArray"];

	_result 	= false;
	_weapon 	= _this;
	_ammoArray 	= getArray (configFile >> "cfgWeapons" >> _weapon >> "magazines");

	if (count _ammoArray > 0) then {
		_result = _ammoArray select 0;
		call {
			if(_result == "20Rnd_556x45_Stanag") 	exitWith { _result = "30Rnd_556x45_Stanag"; };
			if(_result == "30Rnd_556x45_G36") 		exitWith { _result = "30Rnd_556x45_Stanag"; };
			if(_result == "30Rnd_556x45_G36SD") 	exitWith { _result = "30Rnd_556x45_StanagSD"; };
		};
	};
	_result
};

private ["_crate_type","_crate","_num_weapons","_weapon","_ammo"];

//Edit the variables below to suit your needs
_crate_type 	= "USOrdnanceBox"; //this needs to be whitelisted in your battleye filters (createvehicle.txt) - you can do so by adding !="USOrdnanceBox" to a line that starts with 5. i.e 5 !="USOrdnanceBox"
_crate_items					= ["FoodNutmix","FoodPistachio","FoodMRE","ItemSodaOrangeSherbet","ItemSodaRbull","ItemSodaR4z0r","ItemSodaMdew","ItemSodaPepsi","ItemBandage","ItemSodaCoke","FoodbaconCooked","FoodCanBakedBeans","FoodCanFrankBeans","FoodCanPasta","FoodCanSardines","FoodchickenCooked","FoodmuttonCooked","FoodrabbitCooked","ItemTroutCooked","ItemTunaCooked","ItemSeaBassCooked","ItemAntibiotic","ItemBloodbag","ItemEpinephrine","ItemHeatPack","ItemMorphine","ItemGoldBar","ItemGoldBar10oz","CinderBlocks","ItemCanvas","ItemComboLock","ItemLightBulb","ItemLockbox","ItemSandbag","ItemTankTrap","ItemWire","MortarBucket","PartEngine","PartFueltank","PartGeneric","PartGlass","PartPlankPack","PartVRotor","PartWheel","PartWoodPile","ItemBriefcase100oz","ItemBriefcase100oz","ItemBriefcase100oz","ItemBriefcase100oz"];

_ai_wep_assault				= ["M16A4_ACG","Sa58V_RCO_EP1","SCAR_L_STD_Mk4CQT","M8_sharpshooter","M4A1_HWS_GL_camo","SCAR_L_STD_HOLO","M4A3_CCO_EP1","M4A3_CCO_EP1","M4A1_AIM_SD_camo","M16A4","m8_carbine","BAF_L85A2_RIS_Holo","Sa58V_CCO_EP1"];	// Assault
_ai_wep_machine				= ["MK_48_DZ","M249_EP1_DZ","Pecheneg_DZ","M240_DZ"];	// Light machine guns
_ai_wep_sniper				= ["M14_EP1","HUNTINGRIFLE","M4SPR","M24","M24_DES_EP1","SCAR_H_LNG_Sniper_SD","M110_NVG_EP1","SVD_CAMO","VSS_Vintorez","DMR_DZ","M40A3","KSVK_DZE","BAF_LRR_SCOPED"];	// Sniper rifles
_ai_wep_random				= _ai_wep_assault + _ai_wep_assault + _ai_wep_sniper + _ai_wep_machine;	

_motor = _this select 3;

player playActionNow "Medic";
uisleep 10;

_position = [(position player select 0) - (sin(getdir player)*2), (position player select 1) - (cos(getdir player)*2), (position player select 2)];
_dir = getDir player;

_crate 			= createVehicle [_crate_type,_position,[],0,"CAN_COLLIDE"];

_crate setVariable ["ObjectID","1",true];
_crate setVariable ["permaLoot",true];

_num_weapons	= 6;
_num_items	= 14;
_item_array	= _crate_items;

PVDZE_serverObjectMonitor set [count PVDZE_serverObjectMonitor,_crate];

clearWeaponCargoGlobal _crate;
clearMagazineCargoGlobal _crate;

if(_num_weapons > 0) then {

	_num_weapons = (ceil((_num_weapons) / 2) + floor(random (_num_weapons / 2)));

	for "_i" from 1 to _num_weapons do {
		_weapon = _ai_wep_random call BIS_fnc_selectRandom;
		_ammo = _weapon call find_suitable_ammunition;
		_crate addWeaponCargoGlobal [_weapon,1];
		_crate addMagazineCargoGlobal [_ammo, (1 + floor(random 5))];
	};
};

if(_num_items > 0) then {
	_num_items	= (ceil((_num_items) / 2) + floor(random (_num_items / 2)));
	for "_i" from 1 to _num_items do {
		_item = _item_array call BIS_fnc_selectRandom;
		if(typeName (_item) == "ARRAY") then {
			_crate addMagazineCargoGlobal [_item select 0,_item select 1];
		} else {
			_crate addMagazineCargoGlobal [_item,1];
		};
	};
};

_motor setVariable ["dnishpq",0,true];

if (alive _motor) then { systemChat "You manage to find a loot crate in the cargo hold";
} else { 
	systemChat "You manage to find a loot crate in the wreckage of the chopper"; 
};

 

Link to comment
Share on other sites

On 12/05/2016 at 0:08 AM, Albertus Smythe said:

I've just been staring at the line


if ({alive _x} count units group _unit == 0) then {donn_heliGrps = donn_heliGrps - [group _unit];};

and realised it removes the group (and therefore the convoy) from the array donn_heliGrps if all the units (AI) in the convoy are dead.

As a new group is created and inserted into donn_heliGrps for each convoy, it seems to me that we could use count donn_heliGrps to limit the number of convoys active at any one time by surrounding everything between while (1 ==1)  do { and the bottom uisleep (60*15); inside an if (count donn_heliGrps) < _maxConvoys then {}; statement, then every 15 minutes it will only create a new convoy if there are less than _maxConvoys active.

 

 

I can confirm that

_maxConvoys = 3
...
...
while {true} do {
   	diag_log format["[HELI CONVOY] Currently %1 of %2 active convoys", count donn_heliGrps, _maxConvoys];
    
    if (count donn_heliGrps < _maxConvoys) then {
		...
        ...
    };
	...
	...
};

Works just fine and dandy. No new convoys are created when count donn_HeliGrps  reaches _maxConvoys unless  all the crew in a convoy is killed causing count donn_HeliGrps to drop by one.

 

Albertus

Link to comment
Share on other sites

  • 2 weeks later...

How's this mod going for you now Albertus? My users love that the choppers are now worth killing, especially since they get a crate and not 500 engines.

I still notice occasional AI in the sea, but it's only 1-5 not too many. I added a delay between spawning inside the loop too, to try and make sure that choppers didn't crash into each other

Link to comment
Share on other sites

On 28/05/2016 at 1:50 AM, salival said:

How's this mod going for you now Albertus? My users love that the choppers are now worth killing, especially since they get a crate and not 500 engines.

I still notice occasional AI in the sea, but it's only 1-5 not too many. I added a delay between spawning inside the loop too, to try and make sure that choppers didn't crash into each other

Hi, I have yet to see any crashes at spawn time since I made the changes I suggested, however they still fly into mountains on mountainous maps like Panthera and Napf, which makes it too easy because you just have to wait !. However locating  AI that have been wandering for an hour is fun.

I've also added a random addition to the time between spawns ((30 * 60)+ (60*(random 15))) and a 30% chance that a convoy won't spawn this time anyway just to make them a little less predictable and less common.

 

Link to comment
Share on other sites

There are a number of variables that never change their values so we ought to define them as static, this saves the memory and time overheads associated with variables.

//===== Define static variables
//Maximun convoys active at one time.
#define MAXCONVOYS 3 
// Define the helis in each of the convoys
#define HELIFORMATION  [[0,0,2],[2,2],[4,4,4],[3,3,3],[3],[1,1],[7,7,8],[5,5],[9,13,9,9],[11,11,10],[12],[6,6]] 
// ["SPEED",% chance of picking this speed], Make sure the chances add up to 100 or it will not be an accurate percentage.
#define CONVOYSPEEDS [["LIMITED",10],["NORMAL",50],["FULL",40]]
//CHERNARUS
#define GRIDN 15
#define MAPSIZE 15360 
// This number here gets randomized and then added to the below number to form the _flyheight variable.
#define FH_RANDOM 80
// This is the lowest number that flyheight can be, the above number gets randomized and added to it to form the 
#define FH_LOWER 70
#define AISHAREDISTANCE	600
// Spawn location of chopper, x, y and z for height.
#define SPAWNCOORD [50,50,300]
//===== End of static defines

Also change setPos & getPos to setPosATL & getPosATL as they're 2x to 3x quicker according to bohimia's code optimisation wiki page (https://community.bistudio.com/wiki/Code_Optimisation)

Link to comment
Share on other sites

  • 2 months later...

 

 

On 13/08/2016 at 9:07 PM, Thug said:

Hello, has this script been updated since dec 2015?:blink:

The original post is still the original however Salival and I (mostly Salival) have worked to make sensible changes to this script, which are mostly listed on pages 4 & 5, so you'll have to read through them to get the files you need.

 

Here's my live code;

Airpatrol.sqf & andre_heliConvoy_items.sqf

Spoiler

// *********************************
// Airpatrol.sqf
// Author: Donnavan
// Creates Airbourne convoys
// Modifications:
// Random Weapon selection by Tang0 - redacted
// Random crew skins by Albertus Smythe - redacted
// Random convoy selection by Albertus Smythe
// Bigger spawn area radius by Albertus Smythe
// Below modifications are done by salival
// Full credit for the AI gear/pack/skin/weapon selection goes to WAI, I used this system because it works amazingly and it gives me a single configuration to make loot changes to. - salival
// Random gear selection (ai_gear_random from WAI - WAI MUST BE INSTALLED)
// Random weapon selection (ai_wep_random from WAI - WAI MUST BE INSTALLED)
// Random backpack selection (ai_packs from WAI - WAI MUST BE INSTALLED)
// Random skill selection (ai_skill_random from WAI - WAI MUST BE INSTALLED)
// Random skin selection (variable: _aiskins contains arrays from WAI (ai_hero_skin,ai_bandit_skin) - WAI MUST BE INSTALLED)
// Enemy will now pull parachute 100% of the time to stop players from getting free loot. Make the buggers work for it!
// Enemies will now share information about players to other AI when a unit is killed (variable AISHAREDISTANCE	)
// Humanity is now given/lost dependant on alignment, - humanity if player is bandit, + humanity if player is hero
// Chopper will now correctly spawn at the right height based on SPAWNCOORD (setPosATL)
// Chopper will now fly at a height of FH_LOWER + random(FH_RANDOM).
// Chopper will randomly select a speed from CONVOYSPEEDS. You can sway the chance of a particular speed being selected by upping the number in the second field. Make sure it all adds up to 100.
// *********************************

//diag_log format ["Heli Convoy: debug: %1 ",_debugvariable]; //place holder for debugging.

//===== Define static variables
// Maximun convoys active at one time.
#define MAXCONVOYS 3 
// Define the helis in each of the convoys
#define HELIFORMATION  [[0,0,2],[2,2],[4,4,4],[3,3,3],[3],[1,1],[7,7,8],[5,5],[9,13,9,9],[11,11,10],[12],[6,6]] 
// ["SPEED",% chance of picking this speed], Make sure the chances add up to 100 or it will not be an accurate percentage.
#define CONVOYSPEEDS [["LIMITED",10],["NORMAL",50],["FULL",40]]
//CHERNARUS
#define GRIDN 15
#define MAPSIZE 15360 
// This number here gets randomized and then added to the below number to form the _flyheight variable.
#define FH_RANDOM 80
// This is the lowest number that flyheight can be, the above number gets randomized and added to it to form the 
#define FH_LOWER 70
#define AISHAREDISTANCE	600
// Spawn location of chopper, x, y and z for height.
#define SPAWNCOORD [50,50,300]
//===== End of static defines


if (isServer) then {
    // Add 5min delay to alow DZAI etc to sort itself out otherwise 1st heli seems to be created without a pilot
    // so it immedietly crashes and then there are no waypoints set for the convoy so it just hovers above
    // the create point
    uiSleep (60*5);
    
    _convoyspeed =[];
    
	_aiskins = ai_hero_skin + ai_bandit_skin;
    _convoyspeeds = [["LIMITED",10],["NORMAL",50],["FULL",40]];
    // define a list of heli's to make up convoys from.
    // [ Vehicle_name,Passenger count,[ammo for each gunpoint],number of Loot points]
    // Passenger count is in addition to the pilot and gunners on the heli's gun points.
    // Empty ammo array means the Heli is unarmed and won't shoot but will land and disembark crew.
    donn_heliConvy = [
        /* 0*/["UH1H_DZ",0,["100Rnd_762x51_M240","100Rnd_762x51_M240"],3],
        /* 1*/["UH1H_DZ",4,[],4],
        /* 2*/["Mi17_UN_CDF_EP1",5,["100Rnd_762x54_PK","100Rnd_762x54_PK"],5],
        /* 3*/["CH_47F_EP1_DZE",6,["100Rnd_762x51_M240","4000Rnd_762x51_M134","4000Rnd_762x51_M134"],6],
        /* 4*/["AH6J_EP1_DZ",1,[],2],        //ARMED (PILOT)
        /* 5*/["UH60M_EP1_DZE",0,["2000Rnd_762x51_M134","2000Rnd_762x51_M134"],3],
        /* 6*/["UH1Y_DZE",0,["2000Rnd_762x51_M134","2000Rnd_762x51_M134"],3],
        /* 7*/["UH1H_TK_EP1",0,["100Rnd_762x51_M240","100Rnd_762x51_M240"],3],
        /* 8*/["BAF_Merlin_DZE",4,[],4],
        /* 9*/["Mi24_V",4,[],4],        //ARMED (PILOT)
        /*10*/["pook_H13_amphib_CIV",1,[],1],
        /*11*/["pook_H13_transport_UNO",2,["100Rnd_762x51_M240"],2],
        /*12*/["AH64D",1,[],1],        //ARMED (PILOT)
        /*13*/["Mi17_rockets_RU",5,["100Rnd_762x54_PK","100Rnd_762x54_PK","100Rnd_762x54_PK"],5]
    ];

	{
		for "_i" from 1 to (_x select 1) do {
			_convoyspeed set [count _convoyspeed, _x select 0];
		};
	} count _convoyspeeds;
    
    donn_hwps = [];

    for "_i" from 1 to (GRIDN - 1) do {
        _wpx = (_i/GRIDN)*MAPSIZE;

        for "_y" from 1 to (GRIDN - 1) do {
            _wpy = (_y/GRIDN)*MAPSIZE;
            if !(surfaceIsWater [_wpx,_wpy]) then {donn_hwps = donn_hwps + [[_wpx,_wpy,0]];};
        };

    };
    _heliGroupTot  = count HELIFORMATION;
    donn_heli_HD = {
        _heliHurt = _this select 0;
        _damage   = _this select 2;

        if !(canMove _heliHurt) then {

            if (_heliHurt getVariable "dncmv") then {
                _heliHurt setVariable ["dncmv",false,false];
                {if (random 100 > 50) then {_x action ["Eject",_heliHurt];} else {_x setPosATL getPosATL _heliHurt;};} forEach crew _heliHurt;
            };

        };

        _damage
    };

    donn_heli_unit_HD = {
        // Put group into combat RED mode if heli damaged by player
        _hurtedOne = _this select 0;
        _damage    = _this select 2;
        _ofender   = _this select 3;
        _grp       = group _hurtedOne;

        if (combatMode _grp != "RED" && isPlayer _ofender) then {
            {_x enableAi "TARGET";} forEach units _grp;
            {_x enableAi "AUTOTARGET";} forEach units _grp;
            _grp reveal [_ofender,3];
            _grp setCombatMode "RED";_grp setBehaviour "COMBAT";
        };
       _damage
    };

    donn_heli_unitKill = {
        _unit = _this select 0;
		_player = _this select 1;
		_humanity = _player getVariable["humanity",0];  //Reads the player's current humanity count
		_gain = _unit getVariable ["humanity",50];  //Sets Humanity reward value. 50 humanity per AI kill.
        _role = assignedVehicleRole _unit;

        if ((assignedVehicleRole _unit) select 0 == "Driver") then {
            // If driver is killed eject the crew.
            _vehEject = assignedVehicle _unit;
            {if (random 100 > 40) then {_x action ["Eject",_vehEject];} else {_x setPosATL getPosATL _vehEject};} forEach crew _vehEject;
        };

        if ({alive _x} count units group _unit == 0) then {donn_heliGrps = donn_heliGrps - [group _unit];};
        //coins reward
        _unit setVariable ["cashMoney",12500 + (round random 5) * 1000,true];
        //Humanity Reward - this gives - humanity for bandit player and + humanity for hero player
        if (_humanity < 0) then { _player setVariable ["humanity",(_humanity - _gain),true]; } else { _player setVariable ["humanity",(_humanity + _gain),true]; };
        {
            if (((position _x) distance (position _unit)) <= AISHAREDISTANCE	) then {
            _x reveal [_player, 3];
            }
        } forEach allUnits;
    };

    donn_makeAeroRoute = {
        // Set route for convoy
        _origin     = _this select 0;
        _heli_group = _this select 1;
        _speed      = _this select 2;
        _posBefore  = _origin;
        _posNow     = _origin;
        _wp         = _heli_group addWaypoint [_posNow,0,0];
        _wp setWaypointCompletionRadius 65;
        _wp setWaypointType "MOVE";
        _wp setWaypointSpeed _speed;
        _posNext = [0,0,0];

        for "_c" from 1 to 5 do {
            _distToBefore = 0;
            _distToNext   = 0;
            _found        = false;

            for "_x" from 1 to 200 do {
                _posNext        = donn_hwps call BIS_fnc_selectRandom;
                _distToNext     = _posNow distance _posNext;
                _distToBefore   = _posNext distance _posBefore;
                if (_distToNext > 3000 && _distToBefore > 4000) exitWith {};
                uiSleep 0.001;
            };

            if (!_found) then {_posNext = donn_hwps call BIS_fnc_selectRandom;};
            _wp = _heli_group addWaypoint [_posNext,0,_c];
            _wp setWaypointCompletionRadius 65;
            _wp setWaypointType "MOVE";
            _wp setWaypointSpeed _speed;
            _posNow = _posNext;
        };

        _wp = _heli_group addWaypoint [_origin,0,6];
        _wp setWaypointCompletionRadius 65;
        _wp setWaypointType "CYCLE";
        _wp setWaypointSpeed _speed;
    };

    donn_heliGrps = [];

    [] spawn {

        while {{!isNull _x} count donn_heliGrps > 0} do {

            {
                _grp     = _x;
                _forceIn = true;
                {if (_grp knowsAbout _x >= 1.5) then {_grp reveal [_x,4];_forceIn = false;};} forEach playableUnits;

                if (_forceIn) then {

                    if (combatMode _grp != "BLUE") then {
                        {_x disableAi "TARGET";uiSleep 0.001;} forEach units _grp;
                        {_x disableAi "AUTOTARGET";uiSleep 0.001;} forEach units _grp;
                        _grp setCombatMode "BLUE";_grp setBehaviour "CARELESS";
                    };

                    {if (vehicle _x == _x) then {[_x] orderGetIn true;uiSleep 0.001;};} forEach units _grp;
                };
            } forEach donn_heliGrps;

            uiSleep 10;
        };

		diag_log "[HELI CONVOY] Finished convoy rotation.";
    };

    while {true} do {
    	diag_log format["[HELI CONVOY] Currently %1 of %2 active convoys", count donn_heliGrps, MAXCONVOYS];

        if ((count donn_heliGrps < MAXCONVOYS) && (random 10 <= 7 )) then {
            _cs = floor( random _heliGroupTot);
            diag_log ("[HELI CONVOY] Initialized Spawn! Formation " + str _cs);
            _flyheight      = round(FH_LOWER + random(FH_RANDOM));
            _heli_group     = createGroup EAST;
            donn_heliGrps   = donn_heliGrps + [_heli_group];
            _convoy         = HELIFORMATION select (_cs);
            _qtd            = count _convoy;
            _helis          = [];

            {_helis = _helis + [donn_heliConvy select _x];} forEach _convoy;

            for "_n" from 1 to _qtd do {
                _heli       = _helis    select (_n-1);
                _motor      = createVehicle [_heli select 0,SPAWNCOORD,[],150,"FLY"];
                _motor setPosATL SPAWNCOORD;
                _crew       =[];

                _motor removeAllEventHandlers "handleDamage";
                _motor addEventHandler ["handleDamage",{_this call donn_heli_HD}];
                _motor setVariable ["dncmv",true,false];
                _motor setVariable ["dnishp",true,true];
                _motor setVariable ["dnishpq",_heli select 3,true];
                _motor setFuel 1;
                _motor setVehicleLock "LOCKED";
                _motor flyInHeight _flyHeight;

                _ammos = _heli select 2;
                {_ammo = _x;for "_a" from 1 to 8 do {_motor addMagazineTurret [_ammo,[_forEachIndex]];};} forEach _ammos;
                _driverCount    = 1;
                _turreterCount  = count _ammos;
                _cargorsCount   = _heli select 1;
                _crewCount      = _driverCount + _turreterCount + _cargorsCount;
                _gunnerPos      = 0;

                // Originally the default crew were deleted then our crew were created, modified and added him to the helicopter one at a time.
                // This led to there, occasionally being enough of a delay between deleting the pilot and inserting the new one for the helicopter
                // to fall to the ground and crash then all the crew were spawned on the ground as they couldn't get into a crashed vehicle.
                // Now we're creating all our crew into an array before deleting the default crew then adding our crew from the array, this should
                // minimise the time the helicopter is without crew, although the overall time may be slightly longer as we're looping through the crew twice.
                for "_y" from 1 to _crewCount do {
                    // Finally figured it out !!, you have to declare _unit as private here. otherwise it is created inside the If{} statement
                    // as private to the if{} structure and therefore not visible outside of it, so although the crew member is created
                    // the line '_unit removeAllEventHandlers "killed";' creates a new variable called _unit because it effectively doesn't
                    // know about the original _unit variable. Everything errors from then on becouse the visible _unit it isn't the crewman object.
                    private "_unit","_aiweapon","_weapon","_magazine","_aipack","_aigear","_gearmagazines","_geartools","aicskill","aiskin";

                    _aiweapon 			= [];
                    _aigear 			= [];
                    _aipack 			= "";
                    _aiskin 			= "";
                    _aicskill 			= [];

                    if (_y == 1) then {
                        //Skin for pilot
                        _aiskin = ["TK_Soldier_Pilot_EP1","US_Soldier_Pilot_EP1","Soldier_Pilot_PMC","Pilot_EP1"] call BIS_fnc_selectRandom;
                        _unit = _heli_group createUnit [_aiskin,SPAWNCOORD,[],50,"PRIVATE"];
                    };

                    if (_y > 1) then {
                        // Selection of skins for other crew.
                        _aiskin = _aiskins 		call BIS_fnc_selectRandom;
                        _unit = _heli_group createUnit [_aiskin,SPAWNCOORD,[],50,"PRIVATE"];
                    };

                    _unit removeAllEventHandlers "killed";
                    _unit removeAllEventHandlers "handleDamage";
                    _unit addEventHandler ["killed",{_this call donn_heli_unitKill;}];
                    _unit addEventHandler ["handleDamage",{_this call donn_heli_unit_HD}];
                    [_unit] joinSilent _heli_group;
                    _unit setSkill 0.85;

                    // remove default gear/weapons from crew man
                    removeAllWeapons _unit;
                    removeAllItems _unit;

                    _aigear         = ai_gear_random call BIS_fnc_selectRandom;
                    _gearmagazines 	= _aigear select 0;
                    _geartools 		= _aigear select 1;

                    _aiweapon       = ai_wep_random call BIS_fnc_selectRandom;
                    _weapon 	    = _aiweapon call BIS_fnc_selectRandom;
                    _magazine 	    = _weapon 	call find_suitable_ammunition;

                    _aipack = ai_packs call BIS_fnc_selectRandom;

                    for "_i" from 1 to 4 do {
                        _unit addMagazine _magazine;
                    };

                    _unit addweapon _weapon;
                    _unit selectWeapon _weapon;
                    _unit addBackpack _aipack;

                    {_unit addMagazine _x} count _gearmagazines;
                    {_unit addweapon _x} count _geartools;

                    _crew set [_y-1,_unit];
                };

                {deleteVehicle _x;} forEach crew _motor;  // moved in order to delete any default crew immediatly before adding the new crew.

                for "_y" from 1 to _crewCount do {
                    _unit = _crew select (_y-1);

                    if (_y == 1) then {
                        //First crewman is pilot
                        _unit assignAsDriver _motor;
                        _unit moveInDriver _motor;
                        _aicskill = ai_skill_random call BIS_fnc_selectRandom;
                        {_unit setSkill [(_x select 0),(_x select 1)]} count _aicskill;
                    };

                    if (_y > 1 && _y <= 1 + _turreterCount) then {
                        // Assign a crewman to each turret.
                        _unit assignAsGunner _motor;
                        _unit moveInTurret [_motor,[_gunnerPos]];
                        _gunnerPos = _gunnerPos + 1;
                        _aicskill = ai_skill_random call BIS_fnc_selectRandom;
                        {_unit setSkill [(_x select 0),(_x select 1)]} count _aicskill;
                    };

                    if (_y > 1 + _turreterCount) then {
                        //Assign the rest of the crew as passengers
                        _unit assignAsCargo _motor;
                        _unit moveInCargo _motor;
                        _aicskill = ai_skill_random call BIS_fnc_selectRandom;
                        {_unit setSkill [(_x select 0),(_x select 1)]} count _aicskill;
                    };

                };

                {_x disableAi "TARGET";uiSleep 0.001;} forEach units _heli_group;
                {_x disableAi "AUTOTARGET";uiSleep 0.001;} forEach units _heli_group;
                _heli_group setCombatMode "BLUE";_heli_group setBehaviour "CARELESS";
                // Uncomment next two lines if you want a red shere attached to your convoy's helicopters
                // _sphere = createVehicle ["Sign_sphere100cm_EP1",[0,0,0],[],0,"CAN_COLLIDE"];
                // _sphere attachTo [_motor,[0,0,3]];
            };

            _flyspeed = _convoyspeed call BIS_fnc_selectRandom;
            [donn_hwps call BIS_fnc_selectRandom,_heli_group,_flyspeed] call donn_makeAeroRoute;
        };

        uiSleep ((60*30)+(60*(random 15)));
    };

};

 

Spoiler


// andre_heliConvoy_items.sqf
//Original by Donnavan
//Modified by salival for better loot control
//find_suitable_ammunition from WAI, uses the same variables (but in this file instead since these are clientside)
//Edit the variables to suit your needs, the crate will spawn behind the player.

find_suitable_ammunition = {

	private["_weapon","_result","_ammoArray"];

	_result 	= false;
	_weapon 	= _this;
	_ammoArray 	= getArray (configFile >> "cfgWeapons" >> _weapon >> "magazines");

	if (count _ammoArray > 0) then {
		_result = _ammoArray select 0;
		call {
			if(_result == "20Rnd_556x45_Stanag") 	exitWith { _result = "30Rnd_556x45_Stanag"; };
			if(_result == "30Rnd_556x45_G36") 		exitWith { _result = "30Rnd_556x45_Stanag"; };
			if(_result == "30Rnd_556x45_G36SD") 	exitWith { _result = "30Rnd_556x45_StanagSD"; };
		};
	};
	_result
};

private ["_crate_type","_crate","_num_weapons","_weapon","_ammo"];

//Edit the variables below to suit your needs
_crate_type     = "USOrdnanceBox"; //this needs to be whitelisted in your battleye filters (createvehicle.txt) - you can do so by adding !="USOrdnanceBox" to a line that starts with 5. i.e 5 !="USOrdnanceBox"
_crate_items	= ["FoodNutmix","FoodPistachio","FoodMRE","ItemSodaOrangeSherbet","ItemSodaRbull","ItemSodaR4z0r","ItemSodaMdew","ItemSodaPepsi","ItemBandage","ItemSodaCoke","FoodbaconCooked","FoodCanBakedBeans","FoodCanFrankBeans","FoodCanPasta","FoodCanSardines","FoodchickenCooked","FoodmuttonCooked","FoodrabbitCooked","ItemTroutCooked","ItemTunaCooked","ItemSeaBassCooked","ItemAntibiotic","ItemBloodbag","ItemEpinephrine","ItemHeatPack","ItemMorphine","ItemGoldBar","ItemGoldBar10oz","CinderBlocks","ItemCanvas","ItemComboLock","ItemLightBulb","ItemLockbox","ItemSandbag","ItemTankTrap","ItemWire","MortarBucket","PartEngine","PartFueltank","PartGeneric","PartGlass","PartPlankPack","PartVRotor","PartWheel","PartWoodPile","ItemBriefcase100oz","ItemBriefcase100oz","ItemBriefcase100oz","ItemBriefcase100oz"];

_ai_wep_assault	= ["M16A4_ACG","Sa58V_RCO_EP1","SCAR_L_STD_Mk4CQT","M8_sharpshooter","M4A1_HWS_GL_camo","SCAR_L_STD_HOLO","M4A3_CCO_EP1","M4A3_CCO_EP1","M4A1_AIM_SD_camo","M16A4","m8_carbine","BAF_L85A2_RIS_Holo","Sa58V_CCO_EP1","SCAR_L_STD_EGLM_TWS"];	// Assault
_ai_wep_machine	= ["MK_48_DZ","M249_EP1_DZ","Pecheneg_DZ","M240_DZ"];	// Light machine guns
_ai_wep_sniper	= ["M14_EP1","HUNTINGRIFLE","M4SPR","M24","M24_DES_EP1","SCAR_H_LNG_Sniper_SD","M110_NVG_EP1","SVD_CAMO","VSS_Vintorez","DMR_DZ","M40A3","KSVK_DZE","BAF_LRR_SCOPED","BAF_AS50_scoped"];	// Sniper rifles
_ai_wep_random	= _ai_wep_assault + _ai_wep_assault + _ai_wep_sniper + _ai_wep_machine;	

_motor          = _this select 3;

player playActionNow "Medic";
uisleep 10;

_position       = [(position player select 0) - (sin(getdir player)*2), (position player select 1) - (cos(getdir player)*2), (position player select 2)];
_dir            = getDir player;

_crate 			= createVehicle [_crate_type,_position,[],0,"CAN_COLLIDE"];

_crate setVariable ["ObjectID","1",true];
_crate setVariable ["permaLoot",true];

_num_weapons	= 6;
_num_items	    = 14;
_item_array	    = _crate_items;

PVDZE_serverObjectMonitor set [count PVDZE_serverObjectMonitor,_crate];

clearWeaponCargoGlobal _crate;
clearMagazineCargoGlobal _crate;

if(_num_weapons > 0) then {
	_num_weapons = (ceil((_num_weapons) / 2) + floor(random (_num_weapons / 2)));

	for "_i" from 1 to _num_weapons do {
		_weapon = _ai_wep_random call BIS_fnc_selectRandom;
		_ammo   = _weapon call find_suitable_ammunition;
		_crate addWeaponCargoGlobal [_weapon,1];
		_crate addMagazineCargoGlobal [_ammo, (1 + floor(random 5))];
	};
};

if(_num_items > 0) then {
	_num_items	= (ceil((_num_items) / 2) + floor(random (_num_items / 2)));
	
    for "_i" from 1 to _num_items do {
		_item = _item_array call BIS_fnc_selectRandom;
	
        if(typeName (_item) == "ARRAY") then {
			_crate addMagazineCargoGlobal [_item select 0,_item select 1];
		} else {
			_crate addMagazineCargoGlobal [_item,1];
		};
	};
};

_motor setVariable ["dnishpq",0,true];

if (alive _motor) then { systemChat "You manage to find a loot crate in the cargo hold";
} else { 
	systemChat "You manage to find a loot crate in the wreckage of the chopper"; 
};

 

Changes to FN_selfActions.sqf

Spoiler

Here's my changes to make this script use fn_selfActions.sqf instead of the default setup. This is the better way to do it. I'm basically assuming you have a custom fn_selfActions.sqf and a custom variables.sqf, if you don't then... you probably should.

 


in your fn_selfActions.sqf Search for: //Repairing Vehicles

Paste the following above it:

_donn_cursorTarget = cursorTarget;
_objVar = _donn_cursorTarget getVariable ["dnishpq",0];

if  ((player distance _donn_cursorTarget < ((sizeOf typeOf _donn_cursorTarget)/2 + 4)) && (!isNil "_objVar") && _objVar > 0) then {
	if (s_collect_heli < 0) then {
		_heliTxt = "Search wreckage for loot";
		if (alive _donn_cursorTarget) then {_heliTxt = "Search helicopter for loot";};
		s_collect_heli = player addaction[("<t color=""#0096ff"">" + _heliTxt + "</t>"),"scripts\andre_heliConvoy_items.sqf",_donn_cursorTarget,5,false,true,"",""];
	};
} else {
	player removeAction s_collect_heli;
	s_collect_heli = -1;
};

Scroll down to the bottom and find:

	// vault
	player removeAction s_player_unlockvault;
	s_player_unlockvault = -1;

Paste this above it:

	player removeAction s_collect_heli;
	s_collect_heli = -1;	

So it looks like:

	player removeAction s_collect_heli;
	s_collect_heli = -1;		
	// vault
	player removeAction s_player_unlockvault;
	s_player_unlockvault = -1;

In your variables.sqf find the section called: dayz_resetSelfActions and find s_player_lockUnlock_crtl inside it (probably towards the end) and add this under it: 	s_collect_heli = -1;
It should now look like this:
	
	s_player_lockUnlock_crtl = -1;
	s_collect_heli = -1;
};


You can now delete the file: heliconvoy_loadout.sqf and remove the line from your init.sqf that loads it. (example: [] execVM "scripts\heliconvoy_loadout.sqf";)
Make sure you change the scripts\andre_heliConvoy_items.sqf to where ever you put it, i.e custom\ or fixes\ etc.

This completes the section for fn_selfActions.sqf

 

Edited by Albertus Smythe
Albertus' live code added
Link to comment
Share on other sites

4 hours ago, Albertus Smythe said:

 

 

The original post is still the original however Salival and I (mostly Salival) have worked to make sensible changes to this script, which are mostly listed on pages 4 & 5, so you'll have to read through them to get the files you need.

 

Here's my live code;

Airpatrol.sqf & andre_heliConvoy_items.sqf

  Reveal hidden contents


// *********************************
// Airpatrol.sqf
// Author: Donnavan
// Creates Airbourne convoys
// Modifications:
// Random Weapon selection by Tang0 - redacted
// Random crew skins by Albertus Smythe - redacted
// Random convoy selection by Albertus Smythe
// Bigger spawn area radius by Albertus Smythe
// Below modifications are done by salival
// Full credit for the AI gear/pack/skin/weapon selection goes to WAI, I used this system because it works amazingly and it gives me a single configuration to make loot changes to. - salival
// Random gear selection (ai_gear_random from WAI - WAI MUST BE INSTALLED)
// Random weapon selection (ai_wep_random from WAI - WAI MUST BE INSTALLED)
// Random backpack selection (ai_packs from WAI - WAI MUST BE INSTALLED)
// Random skill selection (ai_skill_random from WAI - WAI MUST BE INSTALLED)
// Random skin selection (variable: _aiskins contains arrays from WAI (ai_hero_skin,ai_bandit_skin) - WAI MUST BE INSTALLED)
// Enemy will now pull parachute 100% of the time to stop players from getting free loot. Make the buggers work for it!
// Enemies will now share information about players to other AI when a unit is killed (variable AISHAREDISTANCE	)
// Humanity is now given/lost dependant on alignment, - humanity if player is bandit, + humanity if player is hero
// Chopper will now correctly spawn at the right height based on SPAWNCOORD (setPosATL)
// Chopper will now fly at a height of FH_LOWER + random(FH_RANDOM).
// Chopper will randomly select a speed from CONVOYSPEEDS. You can sway the chance of a particular speed being selected by upping the number in the second field. Make sure it all adds up to 100.
// *********************************

//diag_log format ["Heli Convoy: debug: %1 ",_debugvariable]; //place holder for debugging.

//===== Define static variables
// Maximun convoys active at one time.
#define MAXCONVOYS 3 
// Define the helis in each of the convoys
#define HELIFORMATION  [[0,0,2],[2,2],[4,4,4],[3,3,3],[3],[1,1],[7,7,8],[5,5],[9,13,9,9],[11,11,10],[12],[6,6]] 
// ["SPEED",% chance of picking this speed], Make sure the chances add up to 100 or it will not be an accurate percentage.
#define CONVOYSPEEDS [["LIMITED",10],["NORMAL",50],["FULL",40]]
//CHERNARUS
#define GRIDN 15
#define MAPSIZE 15360 
// This number here gets randomized and then added to the below number to form the _flyheight variable.
#define FH_RANDOM 80
// This is the lowest number that flyheight can be, the above number gets randomized and added to it to form the 
#define FH_LOWER 70
#define AISHAREDISTANCE	600
// Spawn location of chopper, x, y and z for height.
#define SPAWNCOORD [50,50,300]
//===== End of static defines


if (isServer) then {
    // Add 5min delay to alow DZAI etc to sort itself out otherwise 1st heli seems to be created without a pilot
    // so it immedietly crashes and then there are no waypoints set for the convoy so it just hovers above
    // the create point
    uiSleep (60*5);
    
    _convoyspeed =[];
    
	_aiskins = ai_hero_skin + ai_bandit_skin;
    _convoyspeeds = [["LIMITED",10],["NORMAL",50],["FULL",40]];
    // define a list of heli's to make up convoys from.
    // [ Vehicle_name,Passenger count,[ammo for each gunpoint],number of Loot points]
    // Passenger count is in addition to the pilot and gunners on the heli's gun points.
    // Empty ammo array means the Heli is unarmed and won't shoot but will land and disembark crew.
    donn_heliConvy = [
        /* 0*/["UH1H_DZ",0,["100Rnd_762x51_M240","100Rnd_762x51_M240"],3],
        /* 1*/["UH1H_DZ",4,[],4],
        /* 2*/["Mi17_UN_CDF_EP1",5,["100Rnd_762x54_PK","100Rnd_762x54_PK"],5],
        /* 3*/["CH_47F_EP1_DZE",6,["100Rnd_762x51_M240","4000Rnd_762x51_M134","4000Rnd_762x51_M134"],6],
        /* 4*/["AH6J_EP1_DZ",1,[],2],        //ARMED (PILOT)
        /* 5*/["UH60M_EP1_DZE",0,["2000Rnd_762x51_M134","2000Rnd_762x51_M134"],3],
        /* 6*/["UH1Y_DZE",0,["2000Rnd_762x51_M134","2000Rnd_762x51_M134"],3],
        /* 7*/["UH1H_TK_EP1",0,["100Rnd_762x51_M240","100Rnd_762x51_M240"],3],
        /* 8*/["BAF_Merlin_DZE",4,[],4],
        /* 9*/["Mi24_V",4,[],4],        //ARMED (PILOT)
        /*10*/["pook_H13_amphib_CIV",1,[],1],
        /*11*/["pook_H13_transport_UNO",2,["100Rnd_762x51_M240"],2],
        /*12*/["AH64D",1,[],1],        //ARMED (PILOT)
        /*13*/["Mi17_rockets_RU",5,["100Rnd_762x54_PK","100Rnd_762x54_PK","100Rnd_762x54_PK"],5]
    ];

	{
		for "_i" from 1 to (_x select 1) do {
			_convoyspeed set [count _convoyspeed, _x select 0];
		};
	} count _convoyspeeds;
    
    donn_hwps = [];

    for "_i" from 1 to (GRIDN - 1) do {
        _wpx = (_i/GRIDN)*MAPSIZE;

        for "_y" from 1 to (GRIDN - 1) do {
            _wpy = (_y/GRIDN)*MAPSIZE;
            if !(surfaceIsWater [_wpx,_wpy]) then {donn_hwps = donn_hwps + [[_wpx,_wpy,0]];};
        };

    };
    _heliGroupTot  = count HELIFORMATION;
    donn_heli_HD = {
        _heliHurt = _this select 0;
        _damage   = _this select 2;

        if !(canMove _heliHurt) then {

            if (_heliHurt getVariable "dncmv") then {
                _heliHurt setVariable ["dncmv",false,false];
                {if (random 100 > 50) then {_x action ["Eject",_heliHurt];} else {_x setPosATL getPosATL _heliHurt;};} forEach crew _heliHurt;
            };

        };

        _damage
    };

    donn_heli_unit_HD = {
        // Put group into combat RED mode if heli damaged by player
        _hurtedOne = _this select 0;
        _damage    = _this select 2;
        _ofender   = _this select 3;
        _grp       = group _hurtedOne;

        if (combatMode _grp != "RED" && isPlayer _ofender) then {
            {_x enableAi "TARGET";} forEach units _grp;
            {_x enableAi "AUTOTARGET";} forEach units _grp;
            _grp reveal [_ofender,3];
            _grp setCombatMode "RED";_grp setBehaviour "COMBAT";
        };
       _damage
    };

    donn_heli_unitKill = {
        _unit = _this select 0;
		_player = _this select 1;
		_humanity = _player getVariable["humanity",0];  //Reads the player's current humanity count
		_gain = _unit getVariable ["humanity",50];  //Sets Humanity reward value. 50 humanity per AI kill.
        _role = assignedVehicleRole _unit;

        if ((assignedVehicleRole _unit) select 0 == "Driver") then {
            // If driver is killed eject the crew.
            _vehEject = assignedVehicle _unit;
            {if (random 100 > 40) then {_x action ["Eject",_vehEject];} else {_x setPosATL getPosATL _vehEject};} forEach crew _vehEject;
        };

        if ({alive _x} count units group _unit == 0) then {donn_heliGrps = donn_heliGrps - [group _unit];};
        //coins reward
        _unit setVariable ["cashMoney",12500 + (round random 5) * 1000,true];
        //Humanity Reward - this gives - humanity for bandit player and + humanity for hero player
        if (_humanity < 0) then { _player setVariable ["humanity",(_humanity - _gain),true]; } else { _player setVariable ["humanity",(_humanity + _gain),true]; };
        {
            if (((position _x) distance (position _unit)) <= AISHAREDISTANCE	) then {
            _x reveal [_player, 3];
            }
        } forEach allUnits;
    };

    donn_makeAeroRoute = {
        // Set route for convoy
        _origin     = _this select 0;
        _heli_group = _this select 1;
        _speed      = _this select 2;
        _posBefore  = _origin;
        _posNow     = _origin;
        _wp         = _heli_group addWaypoint [_posNow,0,0];
        _wp setWaypointCompletionRadius 65;
        _wp setWaypointType "MOVE";
        _wp setWaypointSpeed _speed;
        _posNext = [0,0,0];

        for "_c" from 1 to 5 do {
            _distToBefore = 0;
            _distToNext   = 0;
            _found        = false;

            for "_x" from 1 to 200 do {
                _posNext        = donn_hwps call BIS_fnc_selectRandom;
                _distToNext     = _posNow distance _posNext;
                _distToBefore   = _posNext distance _posBefore;
                if (_distToNext > 3000 && _distToBefore > 4000) exitWith {};
                uiSleep 0.001;
            };

            if (!_found) then {_posNext = donn_hwps call BIS_fnc_selectRandom;};
            _wp = _heli_group addWaypoint [_posNext,0,_c];
            _wp setWaypointCompletionRadius 65;
            _wp setWaypointType "MOVE";
            _wp setWaypointSpeed _speed;
            _posNow = _posNext;
        };

        _wp = _heli_group addWaypoint [_origin,0,6];
        _wp setWaypointCompletionRadius 65;
        _wp setWaypointType "CYCLE";
        _wp setWaypointSpeed _speed;
    };

    donn_heliGrps = [];

    [] spawn {

        while {{!isNull _x} count donn_heliGrps > 0} do {

            {
                _grp     = _x;
                _forceIn = true;
                {if (_grp knowsAbout _x >= 1.5) then {_grp reveal [_x,4];_forceIn = false;};} forEach playableUnits;

                if (_forceIn) then {

                    if (combatMode _grp != "BLUE") then {
                        {_x disableAi "TARGET";uiSleep 0.001;} forEach units _grp;
                        {_x disableAi "AUTOTARGET";uiSleep 0.001;} forEach units _grp;
                        _grp setCombatMode "BLUE";_grp setBehaviour "CARELESS";
                    };

                    {if (vehicle _x == _x) then {[_x] orderGetIn true;uiSleep 0.001;};} forEach units _grp;
                };
            } forEach donn_heliGrps;

            uiSleep 10;
        };

		diag_log "[HELI CONVOY] Finished convoy rotation.";
    };

    while {true} do {
    	diag_log format["[HELI CONVOY] Currently %1 of %2 active convoys", count donn_heliGrps, MAXCONVOYS];

        if ((count donn_heliGrps < MAXCONVOYS) && (random 10 <= 7 )) then {
            _cs = floor( random _heliGroupTot);
            diag_log ("[HELI CONVOY] Initialized Spawn! Formation " + str _cs);
            _flyheight      = round(FH_LOWER + random(FH_RANDOM));
            _heli_group     = createGroup EAST;
            donn_heliGrps   = donn_heliGrps + [_heli_group];
            _convoy         = HELIFORMATION select (_cs);
            _qtd            = count _convoy;
            _helis          = [];

            {_helis = _helis + [donn_heliConvy select _x];} forEach _convoy;

            for "_n" from 1 to _qtd do {
                _heli       = _helis    select (_n-1);
                _motor      = createVehicle [_heli select 0,SPAWNCOORD,[],150,"FLY"];
                _motor setPosATL SPAWNCOORD;
                _crew       =[];

                _motor removeAllEventHandlers "handleDamage";
                _motor addEventHandler ["handleDamage",{_this call donn_heli_HD}];
                _motor setVariable ["dncmv",true,false];
                _motor setVariable ["dnishp",true,true];
                _motor setVariable ["dnishpq",_heli select 3,true];
                _motor setFuel 1;
                _motor setVehicleLock "LOCKED";
                _motor flyInHeight _flyHeight;

                _ammos = _heli select 2;
                {_ammo = _x;for "_a" from 1 to 8 do {_motor addMagazineTurret [_ammo,[_forEachIndex]];};} forEach _ammos;
                _driverCount    = 1;
                _turreterCount  = count _ammos;
                _cargorsCount   = _heli select 1;
                _crewCount      = _driverCount + _turreterCount + _cargorsCount;
                _gunnerPos      = 0;

                // Originally the default crew were deleted then our crew were created, modified and added him to the helicopter one at a time.
                // This led to there, occasionally being enough of a delay between deleting the pilot and inserting the new one for the helicopter
                // to fall to the ground and crash then all the crew were spawned on the ground as they couldn't get into a crashed vehicle.
                // Now we're creating all our crew into an array before deleting the default crew then adding our crew from the array, this should
                // minimise the time the helicopter is without crew, although the overall time may be slightly longer as we're looping through the crew twice.
                for "_y" from 1 to _crewCount do {
                    // Finally figured it out !!, you have to declare _unit as private here. otherwise it is created inside the If{} statement
                    // as private to the if{} structure and therefore not visible outside of it, so although the crew member is created
                    // the line '_unit removeAllEventHandlers "killed";' creates a new variable called _unit because it effectively doesn't
                    // know about the original _unit variable. Everything errors from then on becouse the visible _unit it isn't the crewman object.
                    private "_unit","_aiweapon","_weapon","_magazine","_aipack","_aigear","_gearmagazines","_geartools","aicskill","aiskin";

                    _aiweapon 			= [];
                    _aigear 			= [];
                    _aipack 			= "";
                    _aiskin 			= "";
                    _aicskill 			= [];

                    if (_y == 1) then {
                        //Skin for pilot
                        _aiskin = ["TK_Soldier_Pilot_EP1","US_Soldier_Pilot_EP1","Soldier_Pilot_PMC","Pilot_EP1"] call BIS_fnc_selectRandom;
                        _unit = _heli_group createUnit [_aiskin,SPAWNCOORD,[],50,"PRIVATE"];
                    };

                    if (_y > 1) then {
                        // Selection of skins for other crew.
                        _aiskin = _aiskins 		call BIS_fnc_selectRandom;
                        _unit = _heli_group createUnit [_aiskin,SPAWNCOORD,[],50,"PRIVATE"];
                    };

                    _unit removeAllEventHandlers "killed";
                    _unit removeAllEventHandlers "handleDamage";
                    _unit addEventHandler ["killed",{_this call donn_heli_unitKill;}];
                    _unit addEventHandler ["handleDamage",{_this call donn_heli_unit_HD}];
                    [_unit] joinSilent _heli_group;
                    _unit setSkill 0.85;

                    // remove default gear/weapons from crew man
                    removeAllWeapons _unit;
                    removeAllItems _unit;

                    _aigear         = ai_gear_random call BIS_fnc_selectRandom;
                    _gearmagazines 	= _aigear select 0;
                    _geartools 		= _aigear select 1;

                    _aiweapon       = ai_wep_random call BIS_fnc_selectRandom;
                    _weapon 	    = _aiweapon call BIS_fnc_selectRandom;
                    _magazine 	    = _weapon 	call find_suitable_ammunition;

                    _aipack = ai_packs call BIS_fnc_selectRandom;

                    for "_i" from 1 to 4 do {
                        _unit addMagazine _magazine;
                    };

                    _unit addweapon _weapon;
                    _unit selectWeapon _weapon;
                    _unit addBackpack _aipack;

                    {_unit addMagazine _x} count _gearmagazines;
                    {_unit addweapon _x} count _geartools;

                    _crew set [_y-1,_unit];
                };

                {deleteVehicle _x;} forEach crew _motor;  // moved in order to delete any default crew immediatly before adding the new crew.

                for "_y" from 1 to _crewCount do {
                    _unit = _crew select (_y-1);

                    if (_y == 1) then {
                        //First crewman is pilot
                        _unit assignAsDriver _motor;
                        _unit moveInDriver _motor;
                        _aicskill = ai_skill_random call BIS_fnc_selectRandom;
                        {_unit setSkill [(_x select 0),(_x select 1)]} count _aicskill;
                    };

                    if (_y > 1 && _y <= 1 + _turreterCount) then {
                        // Assign a crewman to each turret.
                        _unit assignAsGunner _motor;
                        _unit moveInTurret [_motor,[_gunnerPos]];
                        _gunnerPos = _gunnerPos + 1;
                        _aicskill = ai_skill_random call BIS_fnc_selectRandom;
                        {_unit setSkill [(_x select 0),(_x select 1)]} count _aicskill;
                    };

                    if (_y > 1 + _turreterCount) then {
                        //Assign the rest of the crew as passengers
                        _unit assignAsCargo _motor;
                        _unit moveInCargo _motor;
                        _aicskill = ai_skill_random call BIS_fnc_selectRandom;
                        {_unit setSkill [(_x select 0),(_x select 1)]} count _aicskill;
                    };

                };

                {_x disableAi "TARGET";uiSleep 0.001;} forEach units _heli_group;
                {_x disableAi "AUTOTARGET";uiSleep 0.001;} forEach units _heli_group;
                _heli_group setCombatMode "BLUE";_heli_group setBehaviour "CARELESS";
                // Uncomment next two lines if you want a red shere attached to your convoy's helicopters
                // _sphere = createVehicle ["Sign_sphere100cm_EP1",[0,0,0],[],0,"CAN_COLLIDE"];
                // _sphere attachTo [_motor,[0,0,3]];
            };

            _flyspeed = _convoyspeed call BIS_fnc_selectRandom;
            [donn_hwps call BIS_fnc_selectRandom,_heli_group,_flyspeed] call donn_makeAeroRoute;
        };

        uiSleep ((60*30)+(60*(random 15)));
    };

};

 

  Reveal hidden contents



// andre_heliConvoy_items.sqf
//Original by Donnavan
//Modified by salival for better loot control
//find_suitable_ammunition from WAI, uses the same variables (but in this file instead since these are clientside)
//Edit the variables to suit your needs, the crate will spawn behind the player.

find_suitable_ammunition = {

	private["_weapon","_result","_ammoArray"];

	_result 	= false;
	_weapon 	= _this;
	_ammoArray 	= getArray (configFile >> "cfgWeapons" >> _weapon >> "magazines");

	if (count _ammoArray > 0) then {
		_result = _ammoArray select 0;
		call {
			if(_result == "20Rnd_556x45_Stanag") 	exitWith { _result = "30Rnd_556x45_Stanag"; };
			if(_result == "30Rnd_556x45_G36") 		exitWith { _result = "30Rnd_556x45_Stanag"; };
			if(_result == "30Rnd_556x45_G36SD") 	exitWith { _result = "30Rnd_556x45_StanagSD"; };
		};
	};
	_result
};

private ["_crate_type","_crate","_num_weapons","_weapon","_ammo"];

//Edit the variables below to suit your needs
_crate_type     = "USOrdnanceBox"; //this needs to be whitelisted in your battleye filters (createvehicle.txt) - you can do so by adding !="USOrdnanceBox" to a line that starts with 5. i.e 5 !="USOrdnanceBox"
_crate_items	= ["FoodNutmix","FoodPistachio","FoodMRE","ItemSodaOrangeSherbet","ItemSodaRbull","ItemSodaR4z0r","ItemSodaMdew","ItemSodaPepsi","ItemBandage","ItemSodaCoke","FoodbaconCooked","FoodCanBakedBeans","FoodCanFrankBeans","FoodCanPasta","FoodCanSardines","FoodchickenCooked","FoodmuttonCooked","FoodrabbitCooked","ItemTroutCooked","ItemTunaCooked","ItemSeaBassCooked","ItemAntibiotic","ItemBloodbag","ItemEpinephrine","ItemHeatPack","ItemMorphine","ItemGoldBar","ItemGoldBar10oz","CinderBlocks","ItemCanvas","ItemComboLock","ItemLightBulb","ItemLockbox","ItemSandbag","ItemTankTrap","ItemWire","MortarBucket","PartEngine","PartFueltank","PartGeneric","PartGlass","PartPlankPack","PartVRotor","PartWheel","PartWoodPile","ItemBriefcase100oz","ItemBriefcase100oz","ItemBriefcase100oz","ItemBriefcase100oz"];

_ai_wep_assault	= ["M16A4_ACG","Sa58V_RCO_EP1","SCAR_L_STD_Mk4CQT","M8_sharpshooter","M4A1_HWS_GL_camo","SCAR_L_STD_HOLO","M4A3_CCO_EP1","M4A3_CCO_EP1","M4A1_AIM_SD_camo","M16A4","m8_carbine","BAF_L85A2_RIS_Holo","Sa58V_CCO_EP1","SCAR_L_STD_EGLM_TWS"];	// Assault
_ai_wep_machine	= ["MK_48_DZ","M249_EP1_DZ","Pecheneg_DZ","M240_DZ"];	// Light machine guns
_ai_wep_sniper	= ["M14_EP1","HUNTINGRIFLE","M4SPR","M24","M24_DES_EP1","SCAR_H_LNG_Sniper_SD","M110_NVG_EP1","SVD_CAMO","VSS_Vintorez","DMR_DZ","M40A3","KSVK_DZE","BAF_LRR_SCOPED","BAF_AS50_scoped"];	// Sniper rifles
_ai_wep_random	= _ai_wep_assault + _ai_wep_assault + _ai_wep_sniper + _ai_wep_machine;	

_motor          = _this select 3;

player playActionNow "Medic";
uisleep 10;

_position       = [(position player select 0) - (sin(getdir player)*2), (position player select 1) - (cos(getdir player)*2), (position player select 2)];
_dir            = getDir player;

_crate 			= createVehicle [_crate_type,_position,[],0,"CAN_COLLIDE"];

_crate setVariable ["ObjectID","1",true];
_crate setVariable ["permaLoot",true];

_num_weapons	= 6;
_num_items	    = 14;
_item_array	    = _crate_items;

PVDZE_serverObjectMonitor set [count PVDZE_serverObjectMonitor,_crate];

clearWeaponCargoGlobal _crate;
clearMagazineCargoGlobal _crate;

if(_num_weapons > 0) then {
	_num_weapons = (ceil((_num_weapons) / 2) + floor(random (_num_weapons / 2)));

	for "_i" from 1 to _num_weapons do {
		_weapon = _ai_wep_random call BIS_fnc_selectRandom;
		_ammo   = _weapon call find_suitable_ammunition;
		_crate addWeaponCargoGlobal [_weapon,1];
		_crate addMagazineCargoGlobal [_ammo, (1 + floor(random 5))];
	};
};

if(_num_items > 0) then {
	_num_items	= (ceil((_num_items) / 2) + floor(random (_num_items / 2)));
	
    for "_i" from 1 to _num_items do {
		_item = _item_array call BIS_fnc_selectRandom;
	
        if(typeName (_item) == "ARRAY") then {
			_crate addMagazineCargoGlobal [_item select 0,_item select 1];
		} else {
			_crate addMagazineCargoGlobal [_item,1];
		};
	};
};

_motor setVariable ["dnishpq",0,true];

if (alive _motor) then { systemChat "You manage to find a loot crate in the cargo hold";
} else { 
	systemChat "You manage to find a loot crate in the wreckage of the chopper"; 
};

 

Changes to FN_selfActions.sqf

  Reveal hidden contents

Here's my changes to make this script use fn_selfActions.sqf instead of the default setup. This is the better way to do it. I'm basically assuming you have a custom fn_selfActions.sqf and a custom variables.sqf, if you don't then... you probably should.

 



in your fn_selfActions.sqf Search for: //Repairing Vehicles

Paste the following above it:

_donn_cursorTarget = cursorTarget;
_objVar = _donn_cursorTarget getVariable ["dnishpq",0];

if  ((player distance _donn_cursorTarget < ((sizeOf typeOf _donn_cursorTarget)/2 + 4)) && (!isNil "_objVar") && _objVar > 0) then {
	if (s_collect_heli < 0) then {
		_heliTxt = "Search wreckage for loot";
		if (alive _donn_cursorTarget) then {_heliTxt = "Search helicopter for loot";};
		s_collect_heli = player addaction[("<t color=""#0096ff"">" + _heliTxt + "</t>"),"scripts\andre_heliConvoy_items.sqf",_donn_cursorTarget,5,false,true,"",""];
	};
} else {
	player removeAction s_collect_heli;
	s_collect_heli = -1;
};

Scroll down to the bottom and find:

	// vault
	player removeAction s_player_unlockvault;
	s_player_unlockvault = -1;

Paste this above it:

	player removeAction s_collect_heli;
	s_collect_heli = -1;	

So it looks like:

	player removeAction s_collect_heli;
	s_collect_heli = -1;		
	// vault
	player removeAction s_player_unlockvault;
	s_player_unlockvault = -1;

In your variables.sqf find the section called: dayz_resetSelfActions and find s_player_lockUnlock_crtl inside it (probably towards the end) and add this under it: 	s_collect_heli = -1;
It should now look like this:
	
	s_player_lockUnlock_crtl = -1;
	s_collect_heli = -1;
};


You can now delete the file: heliconvoy_loadout.sqf and remove the line from your init.sqf that loads it. (example: [] execVM "scripts\heliconvoy_loadout.sqf";)
Make sure you change the scripts\andre_heliConvoy_items.sqf to where ever you put it, i.e custom\ or fixes\ etc.

This completes the section for fn_selfActions.sqf

 

Thank you, will try it out.

What you have here is the whole script or part? Does all go on client side? Thank you in advance for all your help.

Link to comment
Share on other sites

45 minutes ago, Thug said:

Thank you, will try it out.

What you have here is the whole script or part? Does all go on client side? Thank you in advance for all your help.

Airpatrol goes server side, I have mine in a folder called custom, call it from server_monitor.sqf just under the WAI call

Quote

    // WAI missions
    [] ExecVM "\z\addons\dayz_server\WAI\init.sqf";
    // EMS missions
    //  [] ExecVM "\z\addons\dayz_server\EMS\DZMSInit.sqf";
        
    call compile preprocessFileLineNumbers "\z\addons\dayz_server\DZAI\init\dzai_initserver.sqf";
        
    // DZMS missions
    //[] ExecVM "\z\addons\dayz_server\DZMS\DZMSInit.sqf";
    
    //Andre's Air Convoy
    [] ExecVM "\z\addons\dayz_server\custom\airpatrol.sqf";

 

 

Put andre_heliConvoy_items.sqf client side in your custom script directory.

Change your custom fn_selfActions.sqf as detailed.

 

 

Link to comment
Share on other sites

6 minutes ago, Albertus Smythe said:

Airpatrol goes server side, I have mine in a folder called custom, call it from server_monitor.sqf just under the WAI call

 

Put andre_heliConvoy_items.sqf client side in your custom script directory.

Change your custom fn_selfActions.sqf as detailed.

 

 

Thank you for the reply and installing now. Well give feedback on it. Andre does such a great job. Hope to see more from you guys, doing a great job also. Ever come into game on one of my servers. I will buy you guys a beer. btw on my Chernarus server all the soda mechines sell beer.  lol

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...