Jump to content
Sign in to follow this  
cds1984

dynamic unit name creation question in sqf

Recommended Posts

I am trying to create an area mission inside an sqf file that is loaded after another area mission trigger is finished.

Using the ingame editor I can set unit names and then tasks and triggers using those unit names.

eg.

OF1 is the name of an OPFor officer.

set a trigger to show a hint when OF1 is killed.

If i want to do the same thing in the sqf but with multiple named units which are dynamically created I would create (or so I thought)

_officers = [
["O_officer_F","OF1",'this addGoggles "G_Shades_Blue"',1,"CORPORAL"],
["O_officer_F","OF8",'Removeuniform this;this addGoggles "G_Shades_Blue"',1,"CORPORAL"]
];

_pos = position player;
_grp = creategroup east;
_ocount = (count _officers) - 1;

for "_o" from 0 to _ocount do
{
 _class = (_officers select _o) select 0;
 _var = (_officers select _o) select 1;
 _init = (_officers select _o) select 2;
 _skill = (_officers select _o) select 3;
 _rank = (_officers select _o) select 4;
 call compile format ["%1 = _class createUnit [_pos,_grp,_init,_skill,_rank]",_var];
};

if (!alive OF1) then
{
 hint "OF1 is not alive!";
}
else
{  
 hint "OF1 is alive!";
};

I do end up with the units created but no references to the OF1 or OF8 variable are valid as they still aren't initialiased.

Any pointers, at all, on this concept would be excellent. Thanks!

Share this post


Link to post
Share on other sites

replace your call compile line with:

_unit = _class createUnit [_pos,_grp,_init,_skill,_rank];
missionNameSpace setVariable [_var, _unit];
publicVariable _var;

Share this post


Link to post
Share on other sites

Thanks for that.

I have been grinding away at the two options(call compile and missionnamespace set variable) I found on the forum for awhile now, I should have mentioned, and have ended up in the same place.

Perhaps I'm missing something altogether...

I have this in a script file "test.sqf",

_officers = [
["O_officer_F","OF1",'this addGoggles "G_Shades_Blue"',1,"CORPORAL"],
["O_officer_F","OF8",'Removeuniform this;this addGoggles "G_Shades_Blue"',1,"CORPORAL"]
];

_pos = position player;
_grp = creategroup east;
_ocount = (count _officers) - 1;

for "_o" from 0 to _ocount do
{
 _class = (_officers select _o) select 0;
 _var = (_officers select _o) select 1;
 _init = (_officers select _o) select 2;
 _skill = (_officers select _o) select 3;
 _rank = (_officers select _o) select 4;
 _unit = _class createUnit [_pos,_grp,_init,_skill,_rank];
 missionNameSpace setVariable [_var, _unit];
 publicVariable _var;  
 //call compile format ["%1 = _class createUnit [_pos,_grp,_init,_skill,_rank]",_var];
};

if (!alive OF1) then
{
 hint "OF1 is not alive!";
}
else
{  
 hint "OF1 is alive!";
};

and I'm calling it via a straight player init when the map loads to test,

nul = execVM "test.sqf";

What I get is this,

http://www.diagnostic.net.au/images/2officers.jpg (200 kB)

Any more suggestions would be great! Thanks again.

Share this post


Link to post
Share on other sites

OF1 is not defined anywhere before you run this script. That's the meaning of "undefined variable" error :)

Of course, "undefined variable" can also mean you tried using an undefined variable when you defined it, but I doubt it's the case as you probably just wanted to use OP1 as an editor name of a unit (which is a bad idea if the unit will not exist 100% of the time - If unit might not exist you'll have to check isNil first, and handle accordingly if the unit does not exist at all).

Share this post


Link to post
Share on other sites
replace your call compile line with:

_unit = _class createUnit [_pos,_grp,_init,_skill,_rank];
missionNameSpace setVariable [_var, _unit];
publicVariable _var;

Quick question but isn't it enough to use the third parameter on setVariable to broadcast it? Or is missionNameSpace different?

Share this post


Link to post
Share on other sites

So far it looks like I was using the wrong syntax for createunit and should have been using createunit array.

This works... so far at any rate :)

_officers = [
["O_officer_F","OF1"],
["O_officer_F","OF8"]
];

_pos = position player;
_grp = creategroup east;
_ocount = (count _officers) - 1;

for "_o" from 0 to _ocount do
{
 _class = (_officers select _o) select 0;
 _var = (_officers select _o) select 1;
 //_init = (_officers select _o) select 2;
 //_skill = (_officers select _o) select 3;
 //_rank = (_officers select _o) select 4;
 //_unit = _class createUnit [_pos,_grp,_init,_skill,_rank];
 _unit = _grp createUnit [_class,_pos,[],0,"NONE"];
 missionNameSpace setVariable [_var, _unit];
 publicVariable _var;  
 //call compile format ["%1 = _class createUnit [_pos,_grp,_init,_skill,_rank]",_var];
};

if (!isNil "OF1" && alive OF1) then
{
 sleep 5;
 task2 = player createSimpleTask ["task2"];
 task2 setSimpleTaskDescription ["Make this dynamic variable allocation work!","Kill OF1...",""]; 
 task2 setTaskState "Created"; 
 task2 setSimpleTaskDestination position OF1;
 ["TaskCreated",["","Kill OF1..."]] call bis_fnc_showNotification;

 while {!isNil "OF1"} do
 {
   if (!alive OF1) then
   { 
     task2 setTaskState "Succeeded";
     ["TaskSucceeded",["","Kill OF1...",""]] call bis_fnc_showNotification;
     OF1 = nil;
   };
 };
};

I have lost the built in "init","skill","class" elements in the changeover but I'm hoping there will be another array driven function to slot in after the unit is created.

Thanks again for the help.

Share this post


Link to post
Share on other sites

As you have realised createUnit does not return the created object, you need to use createUnit ARRAY instead.

If you wish to use the other format you will need to assign the variable (OF1) in the init string e.g

_officers = [
["O_officer_F","OF1",'this addGoggles "G_Shades_Blue"',1,"CORPORAL"],
["O_officer_F","OF8",'Removeuniform this;this addGoggles "G_Shades_Blue"',1,"CORPORAL"]
];
_pos = position player;
_grp = creategroup east;
_ocount = (count _officers) - 1;

for "_o" from 0 to _ocount do
{
 _class = (_officers select _o) select 0;
 _var = (_officers select _o) select 1;
 _init = (_officers select _o) select 2;
 _initString = format["%1 = this;%2",_var,_init];
 _skill = (_officers select _o) select 3;
 _rank = (_officers select _o) select 4;
 _class createUnit [_pos,_grp,_initString,_skill,_rank];
};

if (!alive OF1) then
{
 hint "OF1 is not alive!";
}
else
{  
 hint "OF1 is alive!";
};

OR change your array around and incorporate the OF1 = this; directly in the init string part.

_officers = [
["O_officer_F",'OF1 =this; this addGoggles "G_Shades_Blue"',1,"CORPORAL"],
["O_officer_F",'OF8 = this; Removeuniform this;this addGoggles "G_Shades_Blue"',1,"CORPORAL"]
];

_pos = position player;
_grp = creategroup east;
_ocount = (count _officers) - 1;

for "_o" from 0 to _ocount do
{
 _class = (_officers select _o) select 0;
 _init = (_officers select _o) select 1;
 _skill = (_officers select _o) select 2;
 _rank = (_officers select _o) select 3;
 _class createUnit [_pos,_grp,_init,_skill,_rank];
};

if (!alive OF1) then
{
 hint "OF1 is not alive!";
}
else
{  
 hint "OF1 is alive!";
};

If you need access to this unit via its variable (OF1 etc) on any other machine other than the one where it was create, then option 1 is better as you still have a reference to just its variable and you can then just

publicVariable _var;

Edited by Larrow

Share this post


Link to post
Share on other sites

Larrow I was trying to work out how to name a unit and ran across the VAR=this but couldn't work out where to apply it! Thanks this is exactly what I had in mind now. :)

Share this post


Link to post
Share on other sites
Quick question but isn't it enough to use the third parameter on setVariable to broadcast it? Or is missionNameSpace different?

That's the example the devs posted for how to do that so that's what I'm going with. But as with anything ArmA and as this thread shows, there's multiple ways to do it.

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  

×