Jump to content
JohnRayMitch

Help: Spawn AI Unit and Begin Patrolling

Recommended Posts

Hello! I'm new to Arma scripting but having a background in scripting for web apps and such I find this to be such a good hobby.

 

Anyways, I'm currently trying to spawn some opfor units on a specified location (Which I have done correctly or at least works).

After they all spawn I want them to start patrolling the area within a specified range from they're spawn location.

 

Now, I have looked at numerous youtube videos and found a couple of scripts on the internet that i could just copy and paste;

But I'm really trying to learn and not have to hack my way during every scenario. Could someone please review my code and point out 

what I'm doing wrong and correct it so I can try to learn the logic behind the corrections?

 

So far this is what I'm trying...

 

Spawn units on location (infSpawn) from designated list array (_opUnitList)

 

Use a selector variable to pick from list, then updating the selector to reflect the value of the next object in array.

 

After each unit spawns that unit is added to a second list of spawned units (_opUnitSpawned)

 

From the spawned list, use a forEach to cycle through and assign them the patrol task.

 

Everything is working besides the patrol task. I get the "Error Undefined variable in expression: _grp from SpawnGroups.sqf line 40"

 

_opUnitList = [

	"CUP_O_TK_INS_Soldier",
	"CUP_O_TK_INS_Mechanic", 
	"CUP_O_TK_INS_Soldier_FNFAL",
	"CUP_O_TK_INS_Bomber",
	"CUP_O_TK_INS_Soldier_MG",
	"CUP_O_TK_INS_Sniper",
	"CUP_O_TK_INS_Soldier_TL",
	"CUP_O_TK_INS_Commander",
	"CUP_O_TK_INS_Soldier_AT",
	"CUP_O_TK_INS_Guerilla_Medic"
	
];

_opUnitSpawned = [];

_total = (count _opUnitList);
_rnd = 0;


for [{_x = 1}, {_x <= 10}, {_x = _x + 1}] do {

	_pick = _opUnitList select _rnd;

	hint "Spawning Soldier";
	sleep 0.5;
	
	grp = createGroup east;
	
	_newSoldier = _pick createUnit[position infSpawn, grp];
	
	_opUnitSpawned = _opUnitSpawned + [_pick];
	
	_rnd = _rnd + 1;
	
};

{
	[group this, position infSpawn, 50] call bis_fnc_taskpatrol;
	
} forEach _opUnitSpawned;


hint "Done!";

 

 

Share this post


Link to post
Share on other sites
//fnc
private _fnc_arrRandSeq = {
	params [ ["_array",[],[[]]], ["_indexcnt",1,[0]]];
	private ["_return_array","_randindex"];
	if (_array isEqualTo []) exitWith {};
	_return_array = [];
	if (_indexcnt isEqualTo 0) then {_indexcnt = 1};
	if (_indexcnt > (count _array)) then {_indexcnt = count _array};
	if (_indexcnt isEqualTo (count _array)) exitWith {
		_return_array = _array call BIS_fnc_arrayShuffle;
		_return_array
	};
	for "_i" from 1 to _indexcnt do {
		_randindex = selectRandom _array;
		_return_array pushBack _randindex;
		_array = _array - [_randindex];
	};
	(_return_array)
};

private _fnc_getUnitsCnt = {
	private _players = [] call BIS_fnc_listPlayers;
	private _unitsCnt = ((count _players)*3);
	(_unitsCnt)
};

fnc_getRandomPos = {
	params [["_anchor",[],[[],objNull,""]]];
	private _direction = round (random 360);
	private _randomPos = [];
	if (_anchor isEqualType []) then {
		_randomPos  =  [_anchor, 150, _direction] call BIS_fnc_relPos;
	} else {
		if (_anchor isEqualType "") then {
			_randomPos =  [getMarkerPos _anchor, 150, _direction] call BIS_fnc_relPos;
		} else {
			_randomPos =  [getPos _anchor, 150, _direction] call BIS_fnc_relPos;
		};
	};
(_randomPos)
};

fnc_addNewWaypoint = {
	params [["_leader",objNull,[objNull]],["_anchor",[],[[],"",objNull]]];
	private _group = group _leader;

	private _wp01a = _group addWaypoint [[_anchor] call fnc_getRandomPos,10];
	_wp01a setWaypointType "SAD";
	_wp01a setWaypointBehaviour "SAFE";
	_wp01a setWaypointCombatMode "RED";
	_wp01a setWaypointSpeed "LIMITED";
	_wp01a setWaypointStatements ["true", "0 = [this,'Marker1'] spawn fnc_addNewWaypoint"];
};


//code
private _unitsCnt = [] call _fnc_getUnitsCnt;
_units = [
	"O_G_Soldier_F","O_G_Soldier_GL_F","O_G_medic_F","O_G_Soldier_SL_F","O_G_Soldier_AR_F","O_G_Soldier_TL_F","O_G_Soldier_F",
	"O_G_Soldier_GL_F","O_G_medic_F","O_G_Soldier_SL_F","O_G_Soldier_AR_F","O_G_Soldier_TL_F"
];
private _grp01= [getMarkerPos "Marker1", EAST, [_units, _unitsCnt] call _fnc_arrRandSeq] call BIS_fnc_spawnGroup; 


{_x setSkill ["AimingAccuracy",0.7]} forEach (units _grp01);
_grp01 allowFleeing 0;
_grp01 enableDynamicSimulation true;
_grp01 deleteGroupWhenEmpty true;
0 = [leader _grp01,"Marker1"] spawn fnc_addNewWaypoint;

 

  • Like 2

Share this post


Link to post
Share on other sites
50 minutes ago, davidoss said:

//fnc
private _fnc_arrRandSeq = {
	params [ ["_array",[],[[]]], ["_indexcnt",1,[0]]];
	private ["_return_array","_randindex"];
	if (_array isEqualTo []) exitWith {};
	_return_array = [];
	if (_indexcnt isEqualTo 0) then {_indexcnt = 1};
	if (_indexcnt > (count _array)) then {_indexcnt = count _array};
	if (_indexcnt isEqualTo (count _array)) exitWith {
		_return_array = _array call BIS_fnc_arrayShuffle;
		_return_array
	};
	for "_i" from 1 to _indexcnt do {
		_randindex = selectRandom _array;
		_return_array pushBack _randindex;
		_array = _array - [_randindex];
	};
	(_return_array)
};

private _fnc_getUnitsCnt = {
	private _players = [] call BIS_fnc_listPlayers;
	private _unitsCnt = ((count _players)*3);
	(_unitsCnt)
};

fnc_getRandomPos = {
	params [["_anchor",[],[[],objNull,""]]];
	private _direction = round (random 360);
	private _randomPos = [];
	if (_anchor isEqualType []) then {
		_randomPos  =  [_anchor, 150, _direction] call BIS_fnc_relPos;
	} else {
		if (_anchor isEqualType "") then {
			_randomPos =  [getMarkerPos _anchor, 150, _direction] call BIS_fnc_relPos;
		} else {
			_randomPos =  [getPos _anchor, 150, _direction] call BIS_fnc_relPos;
		};
	};
(_randomPos)
};

fnc_addNewWaypoint = {
	params [["_leader",objNull,[objNull]],["_anchor",[],[[],"",objNull]]];
	private _group = group _leader;

	private _wp01a = _group addWaypoint [[_anchor] call fnc_getRandomPos,10];
	_wp01a setWaypointType "SAD";
	_wp01a setWaypointBehaviour "SAFE";
	_wp01a setWaypointCombatMode "RED";
	_wp01a setWaypointSpeed "LIMITED";
	_wp01a setWaypointStatements ["true", "0 = [this,'Marker1'] spawn fnc_addNewWaypoint"];
};


//code
private _unitsCnt = [] call _fnc_getUnitsCnt;
_units = [
	"O_G_Soldier_F","O_G_Soldier_GL_F","O_G_medic_F","O_G_Soldier_SL_F","O_G_Soldier_AR_F","O_G_Soldier_TL_F","O_G_Soldier_F",
	"O_G_Soldier_GL_F","O_G_medic_F","O_G_Soldier_SL_F","O_G_Soldier_AR_F","O_G_Soldier_TL_F"
];
private _grp01= [getMarkerPos "Marker1", EAST, [_units, _unitsCnt] call _fnc_arrRandSeq] call BIS_fnc_spawnGroup; 


{_x setSkill ["AimingAccuracy",0.7]} forEach (units _grp01);
_grp01 allowFleeing 0;
_grp01 enableDynamicSimulation true;
_grp01 deleteGroupWhenEmpty true;
0 = [leader _grp01,"Marker1"] spawn fnc_addNewWaypoint;

 

That code is so pretty.

Works just right too.

.

Thank you!

Share this post


Link to post
Share on other sites

The error you're getting depends on what "this" is, first parameter you're passing to bis_fnc_taskPatrol.

 

Here's a barebones version that I enjoy using for simple unit spawning and sending them on patrol:

GOM_fnc_spawnPatrol = {
	params ["_pos","_units","_side","_size","_distance"];
	_grp = createGroup [_side,true];
	for "_i" from 0 to _size do {
		selectRandomWeighted _units createUnit [_pos, _grp];
	};
	while {{alive _x} count units _grp > 0} do {
		waitUntil {sleep (5 + random 20);unitReady leader _grp AND combatMode leader _grp != "COMBAT"};
		_grp move (_pos getPos [random _distance,random 360]);
	}
};
_units = [
	"O_G_Soldier_F",0.9,"O_G_Soldier_TL_F",0.1
];
_patrol = [getPos player,_units,east,10,50] spawn GOM_fnc_spawnPatrol;

Using selectRandomWeighted you can dictate the chance which unit class will be picked, in the above case 90% chance to spawn a rifleman, 10% chance to spawn a TL.

Can easily enhance this to add custom speedModes and combat modes upon spawning.

 

Cheers

  • Like 2

Share this post


Link to post
Share on other sites

Thanks guys for all your input! This has been the best community to be a part of. I ended up using a mixture of both techniques shared and it work just how i need it too. I plan on refining it more to allow for garrisoning the spawned troops but here is what I put together. 

fnc_SpawnOpUnits = {

	_opUnitList = [

	"CUP_O_TK_INS_Soldier",
	"CUP_O_TK_INS_Mechanic", 
	"CUP_O_TK_INS_Soldier_FNFAL",
	"CUP_O_TK_INS_Bomber",
	"CUP_O_TK_INS_Soldier_MG",
	"CUP_O_TK_INS_Sniper",
	"CUP_O_TK_INS_Soldier_TL",
	"CUP_O_TK_INS_Commander",
	"CUP_O_TK_INS_Soldier_AT",
	"CUP_O_TK_INS_Guerilla_Medic"
	
	];

	//hint "Spawning OpFor...";
	
	_amount = _this select 0;
	_location = _this select 1;
	
	_selector = 0;
	_pick = _opUnitList select _selector;
	
	for [{_x = 1}, {_x < _amount}, {_x = _x + 1}] do {
		
		_grp = createGroup [east, true];
		_grp allowFleeing 0;
		_grp enableDynamicSimulation true;
		
		_newOpUnit = _pick createUnit[(getMarkerPos _location), _grp];
		
		sleep 0.5;
		
		[_grp, (getMarkerPos _location), 60] call bis_fnc_taskPatrol;
		
		if(_selector <= 11) then {
			
			_selector = _selector + 1;
			
		} else {
			
			_selector = 0;
		};
	};
	
	//hint "Done";
	
};

 

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

×