Jump to content

Sign in to follow this  
daimyo21

Createvehicle with random "Classname";

Recommended Posts

So I have an array of classnames,

    _randFood = ["land_basket_ep1", "land_wicket_basket_ep1", "Land_bags_stack_ep1", "land_bag_ep1", "land_crates_ep1", "land_vase_loam_3_ep1", "land_vase_ep1", "land_vase_loam_2_ep1", "land_vase_loam_ep1"];

And im trying to spawn a random one like this:

_genfood=(floor(random(count _randfood))) createvehicle getpos _nobject;

and I tried
_genfood="(floor(random(count _randfood)))" createvehicle getpos _nobject;

I just dont know how to properly enter it in the "" before createvehicle.

Share this post


Link to post
Share on other sites

Try this...

_genfood = _randfood select floor (random (count _randfood)) createvehicle getpos _nobject;

Share this post


Link to post
Share on other sites

Once again im stuck on filling a random role in thatll save me hours of time.

 _randBuild = ["bt25", "bt35", "bt45"];


_genwater setPos (_randbuild select (floor (random (count _randbuild))) buildingpos (floor(random 23))); 

This doesnt work...

the way I had it before was:

_genwater setPos (bt25 buildingpos (floor(random 23))); 

obviously that only does the one.. so Im looking at an array for close to 150 buildings. So you could imagine the time saved if I can choose from random array.

Btw for future reference so I can try on my own, whats the trick when filling in selections from an array.

Share this post


Link to post
Share on other sites
  twirly said:
This post will help you a lot... http://forums.bistudio.com/showthread.php?t=100559

That post is very helpful but I dont see what else I need to do to make this line of code work.

I have the array :

 _randBuild = ["bt25", "bt35", "bt45"];

and I am using same method as before to count random from the array:

_genwater setPos (_randbuild select (floor (random (count _randbuild))) buildingpos (floor(random 23)));  

I even tried this way:

_genwater setPos (_randbuild select floor (random (count _randbuild)) buildingpos (floor(random 23)));  

and :

[php]_genwater setPos _randbuild select (floor (random (count _randbuild))) buildingpos (floor(random 23));  

[/php]

Share this post


Link to post
Share on other sites

It looks like you are trying to select a random point in a random building. Try breaking the code down into separate bits. I changed things here a little.

To select a random item from the array _randbuilds...

_randbuilds = ["bt25", "bt35", "bt45"];
_build = _randbuilds select (floor (random (count _randbuilds)));

The problem will be knowing how many positions are available in the chosen building. I don't know offhand how to find this out. Maybe someone working with buildings at the moment can help there.

SOLVED!

To get the available positions in the chosen building....

while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" } do {
_pos = _build buildingPos _cnt;
_posarray = _posarray + [_pos];
_cnt = _cnt + 1;
sleep 0.02;
};

_rndpos = _posarray select (floor (random (count (_posarray))));

Finally...

_genwater setPos (_build buildingPos _rndpos);

Edited by twirly
Major changes...added more code.

Share this post


Link to post
Share on other sites
  twirly said:
It looks like you are trying to select a random point in a random building. Try breaking the code down into separate bits. I changed things here a little.

To select a random item from the array _randbuilds...

_randbuilds = ["bt25", "bt35", "bt45"];
_build = _randbuilds select (floor (random (count _randbuilds)));

The problem will be knowing how many positions are available in the chosen building. I don't know offhand how to find this out. Maybe someone working with buildings at the moment can help there.

SOLVED!

To get the available positions in the chosen building....

while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" } do {
_pos = _build buildingPos _cnt;
_posarray = _posarray + [_pos];
_cnt = _cnt + 1;
sleep 0.02;
};

_rndpos = _posarray select (floor (random (count (_posarray))));

Finally...

_genwater setPos (_build buildingPos _rndpos);

Just because my scripting abilities arent quite at that level, Let me get this straight..

If I have an array of buildings bt25, bt35, bt45 and so on (all building names)

The array would be _build = ["bt25", "bt35", etc... ];

And the WHILE loop gets the max number of positions in the building? Then it sets _rndpos as the positions of the building?

BTW thanks again in advanced

Share this post


Link to post
Share on other sites

Well... as it is:-

_randbuilds is the array containing ["bt25", "bt35", etc... ]

_build is one random building selected from _randbuilds.

The while loop finds the available positions in _build and adds them to an array called _posarray

_rndpos is one random position selected from _posarray

_genwater is then setpos'd to _rndpos

Still confused??

Share this post


Link to post
Share on other sites
  twirly said:
Well... as it is:-

_randbuilds is the array containing ["bt25", "bt35", etc... ]

_build is one random building selected from _randbuilds.

The while loop finds the available positions in _build and adds them to an array called _posarray

_rndpos is one random position selected from _posarray

_genwater is then setpos'd to _rndpos

Still confused??

With help from shuko im trying to get this portion work with yours effeciently.



[] spawn {
 waituntil {!isnil "SHK_pv_waterAction"};
 {
   _x addAction[("<t color=""#0F81EB"">" + ("Take Water!") +"</t>"),"example_scripts\take_water.sqf", [], 1, false, false, "", ""];
 } foreach SHK_pv_wateraction;
};

if(isServer) then { 

 _randFood = ["land_basket_ep1", "land_wicker_basket_ep1", "land_bag_ep1", "land_vase_loam_3_ep1", "land_vase_ep1", "land_vase_loam_2_ep1", "land_vase_loam_ep1"];
 _randBuild = ["bt25", "bt35", "bt45"];
 _baskets = [];
 while {format ["%1", _randbuild buildingpos _cnt] != "[0,0,0]" } do {
_pos = _randbuild buildingPos _cnt;
_posarray = _posarray + [_pos];
_cnt = _cnt + 1;
sleep 0.02;
};

 _rndpos = _posarray select (floor (random (count (_posarray))));

 for "_i" from 1 to (floor(random 10)) do {
   _genfood = _randfood select floor (random (count _randfood)) createvehicle getpos bt25;
   _genfood setPos (_randbuild buildingPos _rndpos); 
   _baskets set [count _baskets, _genfood];
 };
 SHK_pv_foodAction = _baskets;
 publicvariable "SHK_pv_foodAction";
};

before _genfood setpos was like: (which didnt work)

_genfood setPos (_randBuild select (floor (random (count _randbuild))) buildingpos (floor(random 23))); 

As you can see from above, im trying to randomly spawn 1 to random 10 (food) inside a building. But I want it to select a random building like it did with the random food

 _genfood = _randfood select floor (random (count _randfood)) 

Now with your method of finding the max position in a house, that saves alot more time because I actually spent a good 45 minutes mapping out each building in my mission and getting its number of positions manually.

So how do I implement your code efficiently with mine? Ill try different methods in the mean time.

Share this post


Link to post
Share on other sites

I can give you the code to fix this.... but you will not learn anything that way. Look at what I posted...then look at what you wrote.... see any difference?

You really need to understand the basics before taking on a project mate!

Share this post


Link to post
Share on other sites
  twirly said:
I can give you the code to fix this.... but you will not learn anything that way. Look at what I posted...then look at what you wrote.... see any difference?

You really need to understand the basics before taking on a project mate!

Sorry about before, I misinterpreted the code and totally left out a line so it confused me and I thought we were on a different page.

This was the line I didnt see which now the hwole thing makes sense:

_randbuilds = ["bt25", "bt35", "bt45"];
_build = _randbuilds select (floor (random (count _randbuilds)));

I have now tried to implement it in a few different ways with no objects spawning at all now.

This is what i have now which seems most logical to what I was originally trying to do.

[] spawn {
 waituntil {!isnil "SHK_pv_foodAction";};
 {
   _x addAction[("<t color=""#FF0000"">" + ("Take Food!") +"</t>"),"example_scripts\take_food.sqf", [], 1, false, false, "", ""];
 } foreach SHK_pv_foodAction;
};

if(isServer) then { 

 _randFood = ["land_basket_ep1", "land_wicker_basket_ep1", "land_bag_ep1", "land_vase_loam_3_ep1", "land_vase_ep1", "land_vase_loam_2_ep1", "land_vase_loam_ep1"];
 _randbuilds = ["bt25", "bt35", "bt45"];
 _build = _randbuilds select (floor (random (count _randbuilds)));
 _baskets = [];
while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" } do {
_pos = _build buildingPos _cnt;
_posarray = _posarray + [_pos];
_cnt = _cnt + 1;
sleep 0.02;
};


for "_i" from 1 to (floor(random 10)) do {
   _rndpos = _posarray select (floor (random (count (_posarray))));
   _genfood = _randfood select floor (random (count _randfood)) createvehicle getpos _build;
   _genfood setPos (_build buildingPos _rndpos); 
   _baskets set [count _baskets, _genfood];
};
 SHK_pv_foodAction = _baskets;
 publicvariable "SHK_pv_foodAction";
};


Also using Squint and it saying most of my _variables arent declared private.. whats the difference if declared private? Do you see anything wrong in the code above thats not making it spawn any objects at all?

Share this post


Link to post
Share on other sites

You should be able to replace these two lines with one....

_genfood = _randfood select floor (random (count _randfood)) createvehicle getpos _build;
_genfood setPos (_build buildingPos _rndpos);

Instead of creating _genfood and moving it just create it at _rndpos... so...

_genfood = _randfood select floor (random (count _randfood)) createvehicle _rndpos;

Also... you need to initialise some things before you use them. That's probably why you aren't getting results.

_baskets = []; _pos =[]; _posarray = [];_rndpos = [];
_cnt = 0;

Use hint or hintsilent to output stuff to the screen along the way to see what's going on.

For example add this line after the while loop to see if _posarray actually contains any positions.

hint format ["_posarray: %1",_posarray];

EDIT: Added this....

The reason squint is telling you about Private variables is that it is good practice to declare all the variables you use in your script as private to the script using a Private declaration. This is supposed to stop variables from bouncing heads when running multiple versions of the script or scripts that use the same variable names.

Look at other peoples scripts to see how they have used it.

private ["_randfood","_ranbuilds","_build","_baskets.... etc];

Edited by twirly
Additions

Share this post


Link to post
Share on other sites
  twirly said:
You should be able to replace these two lines with one....

_genfood = _randfood select floor (random (count _randfood)) createvehicle getpos _build;
_genfood setPos (_build buildingPos _rndpos);

Instead of creating _genfood and moving it just create it at _rndpos... so...

_genfood = _randfood select floor (random (count _randfood)) createvehicle _rndpos;

Also... you need to initialise some things before you use them. That's probably why you aren't getting results.

_baskets = []; _pos =[]; _posarray = [];_rndpos = [];
_cnt = 0;

Use hint or hintsilent to output stuff to the screen along the way to see what's going on.

For example add this line after the while loop to see if _posarray actually contains any positions.

hint format ["_posarray: %1",_posarray];

EDIT: Added this....

The reason squint is telling you about Private variables is that it is good practice to declare all the variables you use in your script as private to the script using a Private declaration. This is supposed to stop variables from bouncing heads when running multiple versions of the script or scripts that use the same variable names.

Look at other peoples scripts to see how they have used it.

private ["_randfood","_ranbuilds","_build","_baskets.... etc];

I did all the above and configured left and right, I feel like its the portion that finds the amount of positions in the building in which I have NO IDEA wth its doing:

while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" } do {
_pos = _build buildingPos _cnt;
_posarray = _posarray + [_pos];
_cnt = _cnt + 1;
sleep 0.02;
};

Also, how do I use -ShowScriptErrors ? Do I place that in a shortcut path when I start the game or does that go into the scripts somewhere?

EDIT *** I tried a more simpler version, and when I use :

_build = _randbuilds select (floor (random (count _randbuilds))); then use _genfood setPos (_build buildingpos (floor(random 23))); it doesnt spawn them inside any of the buildings.. is that piece of code proper? _randbuilds are names of dynamically created buildings

Edited by Daimyo21

Share this post


Link to post
Share on other sites

OK... the while loop :-

If you've got your head around the hint example I gave you above...this is similar.

while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" do {

When _cnt is 0 this means :-

while {(_build buildingpos 0) != "[0,0,0]"} do {

or in English :-

while building position zero is not equal to the text string "[0,0,0]" then do the following code

In every loop _cnt is incremented by 1 and the while loop executed again.

An invalid building position will return "[0,0,0]"...so it loops until a building position of "[0,0,0]" is returned. Then it exits the while loop.

At this point you have built an array of all valid positions in the building (_posarray).

For -showscripterrors... open your shortcut on your desktop or wherever and add -showscripterrors to the Target line.

It should look something like this.. but may contain other stuff there. I'm not sure what is already in your shorcut....

"J:\ArmA 2\arma2.exe" -showscripterrors

Also you can check your .rpt (report) file for errors. The Arma 2 report file can usually be found in the folder :-

C:\Documents and Settings\your_user_name\Local Settings\Application Data\ArmA 2

or for OA...

C:\Documents and Settings\your_user_name\Local Settings\Application Data\ArmA 2 OA

You can also use diag_log much the same as hint except that diag_log will output to the .rpt file and not to the screen. This way you can capture to a file whatever you need to track.

It's a bit to take in ...but I hope it helps you.

Edited by twirly
Spelling

Share this post


Link to post
Share on other sites
  twirly said:
OK... the while loop :-

If you've got your head around the hint example I gave you above...this is similar.

while {format ["%1", _build buildingpos _cnt] != "[0,0,0]" do {

When _cnt is 0 this means :-

while {(_build buildingpos 0) != "[0,0,0]"} do {

or in English :-

while building position zero is not equal to the text string "[0,0,0]" then do the following code

In every loop _cnt is incremented by 1 and the while loop executed again.

An invalid building position will return "[0,0,0]"...so it loops until a building position of "[0,0,0]" is returned. Then it exits the while loop.

At this point you have built an array of all valid positions in the building (_posarray).

For -showscripterrors... open your shortcut on your desktop or wherever and add -showscripterrors to the Target line.

It should look something like this.. but may contain other stuff there. I'm not sure what is already in your shorcut....

"J:\ArmA 2\arma2.exe" -showscripterrors

Also you can check your .rpt (report) file for errors. The Arma 2 report file can usually be found in the folder :-

C:\Documents and Settings\your_user_name\Local Settings\Application Data\ArmA 2

or for OA...

C:\Documents and Settings\your_user_name\Local Settings\Application Data\ArmA 2 OA

You can also use diag_log much the same as hint except that diag_log will output to the .rpt file and not to the screen. This way you can capture to a file whatever you need to track.

It's a bit to take in ...but I hope it helps you.

Ok so Ive been using notepad++, squint, and now -showscripterrors and ive found that this line is causing some sort of error:

_genfood setPos (_build buildingpos (floor(random 23))); 

Note that this is without the while loop just for basic reference.

So when _build takes out one of the buildings from the array, bt25, bt35, bt45. I try and setpos it to one of the random 3 buildings and then buildingpos it to one of the random 23 positions inside.

Heres what -showscripterrors says:

_genfood setpos (_build |#| buildingpos etc...

Error setpos: type string, expected array.

Now when I replace _build with one of the buildings (say bt25):

_genfood setPos (bt25 buildingpos (floor(random 23))); 

itworks.. no errors, items end up in building etc.. but than Id have to select each building individually and I rather have it choose randomly from an array.

The main thing i want to work is for it to select a building name out of the array bt25, 35, 45 etc (remember, buildings are created dynamically from init lines of invisible helipad as createvehiclelocal buildings that cant be damaged/destroyed). Any thoughts?

Share this post


Link to post
Share on other sites

OK back to your original post...

_randbuilds = ["bt25", "bt35", "bt45"];
[b]_build[/b] = _randbuilds select (floor (random (count _randbuilds)));

That will select a random building from the list of buildings.

Then...

_cnt=0;
while {format ["%1", [b]_build[/b] buildingpos _cnt] != "[0,0,0]" } do {
   _pos = _build buildingPos _cnt;
   [b]_posarray[/b] = [b]_posarray[/b] + [_pos];
   _cnt = _cnt + 1;
   sleep 0.02;
};

That will fill the array _posarray with a list of available positions in the building (_build) selected above.

_posarray will look something like this [[2345.56,1234.45,4.5],[4567.78,2345.45,4.5],[1234.67,3245.45,5.8]].

Use hint or diag_log to see the contents simply to know what the contents of an array like this will look like. This is an array of coordinates...which is what you need.

In my example above the array contains 3 available positions. The number of available positions will vary for different buildings.

You are having a problem with....

_genfood setPos (_build buildingpos (floor(random 23)));

Well... this is just plain wrong because you are trying to setpos _genfood at a random position number... from 0 to 23.... in the building. It probably does not have as many as 23 positions!

Because the building may not have 23 positions... "[0,0,0]" is being returned when an un-available position is selected. "[0,0,0]" is a string....hence your error.

You need to setpos _genfood at a random position chosen from _posarray. So....

[b]_rndpos[/b] = _posarray select (floor (random (count (_posarray))));
_genfood setPos [b]_rndpos[/b];

_rndpos will be a set of coordinates [xxxx.xx,xxxx.xx,x.x].... which I believe is what you need.

From what I understand the flow should be...

Select a random building

Find all the available positions in that building

Select a random position from the available positions

Setpos _genfood at this position

Edited by twirly
Clarity

Share this post


Link to post
Share on other sites
  twirly said:
OK back to your original post...

_randbuilds = ["bt25", "bt35", "bt45"];
[b]_build[/b] = _randbuilds select (floor (random (count _randbuilds)));

That will select a random building from the list of buildings.

Then...

_cnt=0;
while {format ["%1", [b]_build[/b] buildingpos _cnt] != "[0,0,0]" } do {
   _pos = _build buildingPos _cnt;
   [b]_posarray[/b] = [b]_posarray[/b] + [_pos];
   _cnt = _cnt + 1;
   sleep 0.02;
};

That will fill the array _posarray with a list of available positions in the building (_build) selected above.

_posarray will look something like this [[2345.56,1234.45,4.5],[4567.78,2345.45,4.5],[1234.67,3245.45,5.8]].

Use hint or diag_log to see the contents simply to know what the contents of an array like this will look like. This is an array of coordinates...which is what you need.

In my example above the array contains 3 available positions. The number of available positions will vary for different buildings.

You are having a problem with....

_genfood setPos (_build buildingpos (floor(random 23)));

Well... this is just plain wrong because you are trying to setpos _genfood at a random position number... from 0 to 23.... in the building. It probably does not have as many as 23 positions!

Because the building may not have 23 positions... "[0,0,0]" is being returned when an un-available position is selected. "[0,0,0]" is a string....hence your error.

You need to setpos _genfood at a random position chosen from _posarray. So....

[b]_rndpos[/b] = _posarray select (floor (random (count (_posarray))));
_genfood setPos [b]_rndpos[/b];

_rndpos will be a set of coordinates [xxxx.xx,xxxx.xx,x.x].... which I believe is what you need.

From what I understand the flow should be...

Select a random building

Find all the available positions in that building

Select a random position from the available positions

Setpos _genfood at this position

Unfortunately I already researched all buildings and know each buildings # of positions. You can also do a waypoint on static buildings on stock maps to see how many positions show up. The building im doing has 23 positions. When I simply use the building name "bt25", it works, object spawn inside, all is good. When I use _build = _randbuild select etc etc.. then use setpos _build etc it gives me the errors and doesnt spawn them as posted above

EDIT**** just to help to clarify something.

Whenever i used _build = bt25; than use setpos (_build buildingpos etc... it works,no errors and they spawn in. But when I say _build = take out of _randbuilds array. then it doesnt work

As a secondary backup option, how could I do something like this:

_genfood = _randfood select floor (random (count _randfood)) createvehicle getpos bt25;

Ive tried this :

_genfood setPos (_randbuilds select floor (random (count _randbuilds)) buildingpos (floor(random 23)));

But it doesnt work

Edited by Daimyo21

Share this post


Link to post
Share on other sites

So all the buildings have 23 positions available?

Share this post


Link to post
Share on other sites

in scripting its all about the details, most of the time little and subtle.

You said:

  Quote
Whenever i used _build = bt25; than use setpos (_build buildingpos etc... it works,no errors and they spawn in. But when I say _build = take out of _randbuilds array. then it doesnt work

you have:

  Quote
_randbuilds = ["bt25", "bt35", "bt45"];

you see now?

Share this post


Link to post
Share on other sites
  Demonized said:
in scripting its all about the details, most of the time little and subtle.

You said:

you have:

you see now?

Totall misstyped that when trying to explain my problem. TRUST me im doing my best to not do those kinda silly mistakes of misplacing words. Now that im using notepadd++ and squint i dont havethose issues as much. just a shitty keyboard that misses keystrokes.

EDIT*** ^^ :: wait I didnt misstype that... I said

"Whenever i used _build = bt25; than use setpos (_build buildingpos etc... it works,no errors and they spawn in. But when I say _build = take out of _randbuilds array. then it doesnt work"

Whenever I use _build = _randbuilds select floor (random (count _randbuilds));

_genfood setPos (_build buildingpos (floor(random 23))); doesnt work.

Basically, what i asked at the beginning of this post, thats all im asking again because I tried now 5 different ways and I cant even express to you how many hours of searching, testnig, I put into thisproblem, I cant moveforward with this problem sitting here.. At least now I can detect it with -showscript errors asap. Please dont mistake my frustration for being unappreciated because I truly do appreciate help given.

  twirly said:
So all the buildings have 23 positions available?

Yes im currently using the same building bt25, bt35, bt45 for testing reasons, but im using acollection of maybe 30 unique buildings and I have mapped out allpossible positions and plan on using them in a way that I can set them in classes without making it too complicated on myscripting skills.

Edited by Daimyo21

Share this post


Link to post
Share on other sites

i dont think you see it as i described,

whenever you use _build = bt25 it works but when you use

"take out of _randbuilds array" it doesnt because you use qoutes around it inside the array.

correct array should be:

_randbuilds = [bt25, bt35, bt45];

Share this post


Link to post
Share on other sites
  Demonized said:
i dont think you see it as i described,

whenever you use _build = bt25 it works but when you use

"take out of _randbuilds array" it doesnt because you use qoutes around it inside the array.

correct array should be:

_randbuilds = [bt25, bt35, bt45];

wow... i thot if it was in an array it had to be in quotes.. why does it work in quotes with :

_randFood = ["land_basket_ep1", "land_wicker_basket_ep1", "land_bag_ep1", "land_vase_loam_3_ep1", "land_vase_ep1", "land_vase_loam_2_ep1", "land_vase_loam_ep1"];

then

_genfood = _randfood select floor (random (count _randfood)) createvehicle getpos bt25;

Share this post


Link to post
Share on other sites

this is an item = item

this is an array = []

array has items in it = [item]

"land_basket_ep1" this is a classname and uses qoutes around it, also markers always uses qoutes around them, but whatever something is outside of an array its same on the inside.

So bt25 outside of array is [bt25] when inside, you should really read that guide twirly posted in a previous post, many of these basic things are covered, a editors/scripters first bible.

Share this post


Link to post
Share on other sites

Here mate... I made a demo mission for you. There seems to be a few quirky things when creating objects in buildings.

Now remember this is not going to be exactly what you need but it is tested and works.... it is also heavily commented.

I tried to get it as close as possible to what I think you need.

Demo mission here.

EDIT: Oh yeah... 5 "Fuel_cans" will be hidden in the buildings in front of you. There's hints that output the values of the arrays etc.

Hope it helps!

Edited by twirly

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  

×