Jump to content
Sign in to follow this  
Lucky44

Random spawn positions for AI???

Recommended Posts

I know how to use a finite set of markers to create a random spawn location (at one of the markers, chosen randomly), and I know how to use the "Placement Radius" boxes, but I don't know how to make an AI unit/vehicle spawn randomly within an area / trigger range.

I saw something like this talked about, but nothing was clear. Is it possible? If so, what are the key pieces of syntax?

Thanks in advance!

Edited by Lucky44

Share this post


Link to post
Share on other sites

well if the units are spawned via a script then the following would work

just make sure your arguments for calling the script have the preplaced marker and radius nul = [200,"spawnmarker"] execvm "yourscript.sqf";

_rad1 = _this select 0;
_spawn = _this select 1;

_eGrp = createGroup EAST;
_marker =  [(getMarkerPos _spawn select 0)-_rad1*sin(random 359),(getMarkerPos _spawn select 1)-_rad1*cos(random 359)];

_ldr = _egrp createUnit ["RU_Soldier_SL",_marker, [], 0, "NONE"];

what that does is spawn a unit at _marker which is a random position up to 200 from spawnmarker

Share this post


Link to post
Share on other sites

Heya lucky, maybe take a look at these scripts they do what you ask but spawn entire groups of units or vehicles at random locations. You can open them up and have a look to see how it was acheived, or use the included readme to help implement them into your own mission. hope it helps.

http://creobellum.org/node/24

Share this post


Link to post
Share on other sites

Use "placement radius" in the editor to get an infinite amount of options. The disadvantage of using that though is that nothing guarantees that your unit will spawn in a viable location, such as on top of an inaccessible roof or clipping through a wall. A possible workaround is to place them always at one spot (or 1 of a few viable spots) and give them a waypoint with placement radius, that way in most cases they will at least get close to it if it gets spawned in an inappropriate location (though in some cases you will still have a problem, such as if it turns out to be in water or certain areas on certain islands).

Share this post


Link to post
Share on other sites

"I know how to use a finite set of markers to create a random spawn location (at one of the markers, chosen randomly)"

Well, I don't, unfortunatelly. Could you be please kind enough to explain it to the newbee I am?

Share this post


Link to post
Share on other sites
"I know how to use a finite set of markers to create a random spawn location (at one of the markers, chosen randomly)"

Well, I don't, unfortunatelly. Could you be please kind enough to explain it to the newbee I am?

Sure. Here ya go:

I do it by building a script around the "random" function. That generates a random number from 0-1. Then, if you want, you can manipulate that into a finite set of whole numbers.

The code below generates a squad of 4 Guerrillas in 1 of 6 locations. To use it, you just need to put down 6 markers with the names "marker1", "marker2", etc. (You'll want to leave them with "empty" icons so they're invisible, probably.)

/////////////////////////////////////////////////////////
// Randomize placement of a group within 6 spots
/////////////////////////////////////////////////////////

if (! isServer) exitwith {}; // NOTE: in multiplayer, only server should create random numbers.


// Create Group for units to be spawned into; must have group created BEFORE spawning units in.
groupPrimo = createGroup RESISTANCE;


// Pick Location ///////////////////////////////////////////////////////////////////////
n1 = round ((random 6) + 0.5); // generates random number from 1 to 6

if (n1 == 1) then 
{
	G1 = "GUE_Soldier_CO" createunit [getMarkerPos "marker1", groupPrimo];
	G1 setdir 180;
	G2 = "GUE_Soldier_MG" createunit [getMarkerPos "marker1", groupPrimo];
	G2 setdir 180;
	G3 = "GUE_Soldier_GL" createunit [getMarkerPos "marker1", groupPrimo];
	G3 setdir 180;
	G3 = "GUE_Soldier_AT" createunit [getMarkerPos "marker1", groupPrimo];
	G3 setdir 180;
};

if (n1 == 2) then 
{
	G1 = "GUE_Soldier_CO" createunit [getMarkerPos "marker2", groupPrimo];
	G1 setdir 180;
	G2 = "GUE_Soldier_MG" createunit [getMarkerPos "marker2", groupPrimo];
	G2 setdir 180;
	G3 = "GUE_Soldier_GL" createunit [getMarkerPos "marker2", groupPrimo];
	G3 setdir 180;
	G3 = "GUE_Soldier_AT" createunit [getMarkerPos "marker2", groupPrimo];
	G3 setdir 180;
};

if (n1 == 3) then 
{
	G1 = "GUE_Soldier_CO" createunit [getMarkerPos "marker3", groupPrimo];
	G1 setdir 180;
	G2 = "GUE_Soldier_MG" createunit [getMarkerPos "marker3", groupPrimo];
	G2 setdir 180;
	G3 = "GUE_Soldier_GL" createunit [getMarkerPos "marker3", groupPrimo];
	G3 setdir 180;		
	G3 = "GUE_Soldier_AT" createunit [getMarkerPos "marker3", groupPrimo];
	G3 setdir 180;
};

if (n1 == 4) then 
{
	G1 = "GUE_Soldier_CO" createunit [getMarkerPos "marker4", groupPrimo];
	G1 setdir 180;
	G2 = "GUE_Soldier_MG" createunit [getMarkerPos "marker4", groupPrimo];
	G2 setdir 180;
	G3 = "GUE_Soldier_GL" createunit [getMarkerPos "marker4", groupPrimo];
	G3 setdir 180;
	G3 = "GUE_Soldier_AT" createunit [getMarkerPos "marker4", groupPrimo];
	G3 setdir 180;
};
if (n1 == 5) then 
{
	G1 = "GUE_Soldier_CO" createunit [getMarkerPos "marker5", groupPrimo];
	G1 setdir 180;
	G2 = "GUE_Soldier_MG" createunit [getMarkerPos "marker5", groupPrimo];
	G2 setdir 180;
	G3 = "GUE_Soldier_GL" createunit [getMarkerPos "marker5", groupPrimo];
	G3 setdir 180;
	G3 = "GUE_Soldier_AT" createunit [getMarkerPos "marker5", groupPrimo];
	G3 setdir 180;
};	

if (n1 == 6) then 
{
	G1 = "GUE_Soldier_CO" createunit [getMarkerPos "marker6", groupPrimo];
	G1 setdir 180;
	G2 = "GUE_Soldier_MG" createunit [getMarkerPos "marker6", groupPrimo];
	G2 setdir 180;
	G3 = "GUE_Soldier_GL" createunit [getMarkerPos "marker6", groupPrimo];
	G3 setdir 180;
	G3 = "GUE_Soldier_AT" createunit [getMarkerPos "marker6", groupPrimo];
	G3 setdir 180;
};

I have the lines "G1 setdir 180;" in there to set the facing of the units after they spawn. You can use them (and set them from 1-360 (or 0-359)), or you can leave them all out and the units will face north, to start.

I got the names of units to spawn from the Armaholic library, here: http://www.armatechsquad.com/ArmA2Class/Units/Guerillas/ , by the way.

This code goes into a file with an SQF extension (e.g., "gue_random6.sqf"). Then you need to have an "init.sqf" file with the line:

execVM "gue_random6.sqf";

And both the init.sqf and the gue_random6.sqf files get placed in your mission's folder.

Hope that helps!

Edited by Lucky44

Share this post


Link to post
Share on other sites

I would recommend condensing that script so you don't have to write so many duplicate lines...

Something like

/////////////////////////////////////////////////////////
// Randomize placement of a group within 6 spots
/////////////////////////////////////////////////////////

if (! isServer) exitwith {}; // NOTE: in multiplayer, only server should create random numbers.

// Create Group for units to be spawned into; must have group created BEFORE spawning units in.
groupPrimo = createGroup RESISTANCE;

// Pick Location ///////////////////////////////////////////////////////////////////////
n1 = round ((random 6) + 0.5); // generates random number from 1 to 6

switch (n1) do
{
   case 1: {_markerPos = getMarkerPos "marker1"};    
   case 2: {_markerPos = getMarkerPos "marker2"};

   //etc...
};

G1 = "GUE_Soldier_CO" createunit [_markerPos, groupPrimo];
G1 setdir 180;
G2 = "GUE_Soldier_MG" createunit [_markerPos, groupPrimo];
G2 setdir 180;
G3 = "GUE_Soldier_GL" createunit [_markerPos, groupPrimo];
G3 setdir 180;
G3 = "GUE_Soldier_AT" createunit [_markerPos, groupPrimo];

Share this post


Link to post
Share on other sites

Alright I hate to bump an old ass thread, but I've been trying the scripting given in this thread.

The problem being the script by Lucky44 works just fine, but is inefficient from a coders point of view.

The script given xPaveway for some reason doesn't work, and for the life of me I can't figure out why.

I'm guessing it has something to do with _markerPos = getMarkerPos "marker1" etc, but I can't figure out what is wrong in the syntax to fix it.

I've even tried my own combination of the 2 scripts to no avail and could really use some help.

/////////////////////////////////////////////////////////
// Randomize placement of a group within 6 spots
// gue_random6.sqf
/////////////////////////////////////////////////////////

if (! isServer) exitwith {}; // NOTE: in multiplayer, only server should create random numbers.

// Create Group for units to be spawned into; must have group created BEFORE spawning units in.
groupAlpha = createGroup RESISTANCE;

// Pick Location ///////////////////////////////////////////////////////////////////////
n1 = round ((random 6) + 0.5); // generates random number from 1 to 6

if (n1 == 1) then
{
	hint "1";
	_markerPos = getMarkerPos "markerA1";
};

if (n1 == 2) then
{
	hint "2";
	_markerPos = getMarkerPos "markerA2";
};

if (n1 == 3) then
{
	hint "3";
	_markerPos = getMarkerPos "markerA3";
};

if (n1 == 4) then
{
	hint "4";
	_markerPos = getMarkerPos "markerA4";
};

if (n1 == 5) then
{
	hint "5";
	_markerPos = getMarkerPos "markerA5";
};

if (n1 == 6) then
{
	hint "6";
	_markerPos = getMarkerPos "markerA6";
};

G1 = "GUE_Soldier_CO" createunit [_markerPos, groupAlpha];
G1 setdir 180;
G2 = "GUE_Soldier_MG" createunit [_markerPos, groupAlpha];
G2 setdir 180;
G3 = "GUE_Soldier_GL" createunit [_markerPos, groupAlpha];
G3 setdir 180;
G3 = "GUE_Soldier_AT" createunit [_markerPos, groupAlpha];
G3 setdir 180;

Share this post


Link to post
Share on other sites

Here it is... a little shorter. Tested and working.

if (! isServer) exitwith {}; // NOTE: in multiplayer, only server should create random numbers.

// Create Group for units to be spawned into; must have group created BEFORE spawning units in.
groupAlpha = createGroup RESISTANCE;

//random markerpos
_markerPos = getMarkerPos format ["markerA%1",ceil (random 6)];

//array of soldier typs
_typs = ["GUE_Soldier_CO","GUE_Soldier_MG","GUE_Soldier_GL","GUE_Soldier_AT"];

//create the units...set their direction
{_unit = groupAlpha createUnit [_x, _markerPos, [], 0, "NONE"];_unit setdir 180} foreach _typs;

You don't end up with unit names.... but you may not need the units to have individual names if they are just cannon fodder?!

Edited by twirly
Shortened code

Share this post


Link to post
Share on other sites

Thanks for the the responses, going to take a look at DAC in the morning.

I guess one of the things I want to know is why xPaveway's script doesn't run properly.

I've been banging my head against my keyboard and checking the syntax for all the bits in it to no avail, it seems like it's all properly formatted and should run just fine.

---------- Post added at 08:02 ---------- Previous post was at 08:01 ----------

Here it is... a little shorter. Tested and working.

if (! isServer) exitwith {}; // NOTE: in multiplayer, only server should create random numbers.

// Create Group for units to be spawned into; must have group created BEFORE spawning units in.
groupAlpha = createGroup RESISTANCE;

//random markerpos
_markerPos = getMarkerPos format ["markerA%1",ceil (random 6)];

//array of soldier typs
_typs = ["GUE_Soldier_CO","GUE_Soldier_MG","GUE_Soldier_GL","GUE_Soldier_AT"];

//create the units...set their direction
{_unit = groupAlpha createUnit [_x, _markerPos, [], 0, "NONE"];_unit setdir 180} foreach _typs;

You don't end up with unit names.... but you may not need the units to have individual names if they are just cannon fodder?!

Unfortunately I do need them to have names for the mission I'm working on.

Share this post


Link to post
Share on other sites

If that other script isn't working... make sure you have at least one INDEPENDANT placed on the map or they won't spawn.

Share this post


Link to post
Share on other sites
If that other script isn't working... make sure you have at least one INDEPENDANT placed on the map or they won't spawn.

Ok maybe you or someone else can indulge my curiosity. Your script line of:

_markerPos = getMarkerPos format ["markerA%1",ceil (random 6)];

works perfectly fine

While :

n1 = round ((random 6) + 0.5); // generates random number from 1 to 6

switch (n1) do
{
   case 1: {_markerPos = getMarkerPos "marker1"};    
   case 2: {_markerPos = getMarkerPos "marker2"};

   //etc...
};

doesn't seem to work besides the random number generation and case calls (tested that by using hint calls for each case instead of the _markerPos calls)

While I'm grateful as hell for the solution you presented, I have to to know (sorry I'm a programmer by trade) what's wrong with the example that doesn't work to help me learn more and hopefully avoid mistakes in the future.

Also what would be the correct format for displaying a variable as a hint?

Would it be:

hint format ["Position %1", _markerPos];

Share this post


Link to post
Share on other sites

If you don't have an independent placed on the map already they will still spawn. However, you will have to use the createCenter command for their AI to work.

Share this post


Link to post
Share on other sites

I'm not so sure about that, using the following script to generate all my enemies with just 6 markers and setting Independents to hostile in the actual mission editor has them engage me when I approach and normal behavior

/////////////////////////////////////////////////////////
// Randomize placement of a group within 6 spots
// gue_random6.sqf
/////////////////////////////////////////////////////////

if (! isServer) exitwith {}; // NOTE: in multiplayer, only server should create random numbers.

// Create Group for units to be spawned into; must have group created BEFORE spawning units in.
groupAlpha = createGroup RESISTANCE;

// Pick Location ///////////////////////////////////////////////////////////////////////
_markerPos = getMarkerPos format ["markerA%1",round ((random 6) + 0.5)];

// Show Enemy Spawn Location as a GPS Coord in Hint
_gridPos = mapGridPosition _markerPos;

hint format ["Position %1", _gridPos];

//Generate Soldiers
G1 = "GUE_Soldier_CO" createunit [_markerPos, groupAlpha];
G1 setdir 360;
G2 = "GUE_Soldier_MG" createunit [_markerPos, groupAlpha];
G2 setdir 90;
G3 = "GUE_Soldier_GL" createunit [_markerPos, groupAlpha];
G3 setdir 180;
G4 = "GUE_Soldier_AT" createunit [_markerPos, groupAlpha];
G4 setdir 270;

Share this post


Link to post
Share on other sites

n1 = round ((random 6) + 0.5); // generates random number from 1 to 6

switch (n1) do
{
   case 1: {_markerPos = getMarkerPos "marker[color="#FF0000"]A[/color]1"};    
   case 2: {_markerPos = getMarkerPos "marker[color="#FF0000"]A[/color]2"};

   //etc...
};

doesn't seem to work besides the random number generation and case calls (tested that by using hint calls for each case instead of the _markerPos calls)

While I'm grateful as hell for the solution you presented, I have to to know (sorry I'm a programmer by trade) what's wrong with the example that doesn't work to help me learn more and hopefully avoid mistakes in the future.

Are those marker names missiong an "A"? This code below outputs the correct numbers.... no problems there.

for "_i" from 1 to 20 do {
n1 = round ((random 6) + 0.5); // generates random number from 1 to 6
[color="#FF0000"]diag_log[/color] format ["n1: %1",n1];
sleep 0.01;
};

AS well as random... you also have floor and ceil to work with.

Also what would be the correct format for displaying a variable as a hint?

Would it be:

hint format ["Position %1", _markerPos];

Yes... you can also use diag_log as I did above to output to the report file.

Share this post


Link to post
Share on other sites

No the markers are properly named, I think it has something to do with the syntax of the _markerPos = getMarkerPos function call.

That seems to be where the problem is coming in, and I'm honestly stumped as to what's wrong with it.

Kind of thankful as well as it cut down the amount of scripting quite a bit.

Share this post


Link to post
Share on other sites

To be honest... I don't see anything wrong if the marker names are correct. Give it up for a little while and then come back to it... that usually works for me.

Sometimes you can dig yourself into a hole :)

Share this post


Link to post
Share on other sites

Heh yea I'm already past it, it's just one of those cases of damn it, it should work and I need to know why it doesn't.

It's the boon of a programmer's mind.

Share this post


Link to post
Share on other sites

It'll be something silly... I'll bet! Anyway good luck mate.

Share this post


Link to post
Share on other sites

Alright I've run into a new headache, I'm trying to spawn in an unarmed captive along with the enemy AI that is going to be rescued, but for some reason my script isn't working...

I swear this is almost as much of a pain as doing ASM

/////////////////////////////////////////////////////////
// Randomize placement of a group within 6 spots
// gue_random6.sqf
/////////////////////////////////////////////////////////

if (! isServer) exitwith {}; // NOTE: in multiplayer, only server should create random numbers.

// Create Group for units to be spawned into; must have group created BEFORE spawning units in.
groupAlpha = createGroup east;
groupHostage = createGroup resistance;
_SideHQ = createCenter east;
_SideHQ1 = createCenter resistance;

// Pick Location ///////////////////////////////////////////////////////////////////////
_markerPos = getMarkerPos format ["markerA%1",round ((random 6) + 0.5)];

// Show Enemy Spawn Location as a GPS Coord in Hint
_gridPos = mapGridPosition _markerPos;

hint format ["Position %1", _gridPos];

//Generate Hostage
H1 = "GUE_Soldier_MG" createunit [_markerPos, groupHostage];
groupHostage selectLeader H1;
H1 disableAI "MOVE";
H1 removeAllWeapons;
H1 setCaptive true;

//Generate Soldiers
G1 = "GUE_Soldier_CO" createunit [_markerPos, groupAlpha];
G1 setdir 360;
G2 = "GUE_Soldier_MG" createunit [_markerPos, groupAlpha];
G2 setdir 90;
G3 = "GUE_Soldier_GL" createunit [_markerPos, groupAlpha];
G3 setdir 180;
G4 = "GUE_Soldier_AT" createunit [_markerPos, groupAlpha];
G4 setdir 270;

Share this post


Link to post
Share on other sites
Alright I've run into a new headache, I'm trying to spawn in an unarmed captive along with the enemy AI that is going to be rescued, but for some reason my script isn't working...

I swear this is almost as much of a pain as doing ASM

....for removeAllweapons...

removeAllWeapons H1;

....and try creating the centers before you create the groups!

Share this post


Link to post
Share on other sites

I changed your createunit to createunit_array....and works fine now. Tested.

For some reason it didn't like the other createunit. I think I've had that problem before and now always use createunit_array.

Code in spoiler....

_EastHQ = createCenter east;
_GuerHQ = createCenter resistance;

// Create Group for units to be spawned into; must have group created BEFORE spawning units in.
groupAlpha = createGroup east;
groupHostage = createGroup resistance;

// Pick Location ///////////////////////////////////////////////////////////////////////
_markerPos = getMarkerPos format ["markerA%1",round ((random 6) + 0.5)];

// Show Enemy Spawn Location as a GPS Coord in Hint
_gridPos = mapGridPosition _markerPos;

hint format ["Position %1", _gridPos];

//Generate Hostage
H1 = groupHostage createUnit ["GUE_Soldier_MG", _markerPos, [], 0, "FORM"];

groupHostage selectLeader H1;

H1 disableAI "MOVE";

removeAllWeapons H1;

H1 setCaptive true;

//Generate Soldiers
G1 = groupAlpha createUnit ["GUE_Soldier_CO", _markerPos, [], 0, "FORM"];
G1 setdir 360;

G2 = groupAlpha createUnit ["GUE_Soldier_MG", _markerPos, [], 0, "FORM"];
G2 setdir 360;

G3 = groupAlpha createUnit ["GUE_Soldier_AT", _markerPos, [], 0, "FORM"];
G3 setdir 360;

G4 = groupAlpha createUnit ["GUE_Soldier_AT", _markerPos, [], 0, "FORM"];
G4 setdir 360;

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
Sign in to follow this  

×