Jump to content
TheGeneral2899

Coding shortcut - Very large array with same naming convention

Recommended Posts

Once again, I have a best practices question.   Here is the situation:

 

I have a series of objects (over 100) spread through the map to dictate where the crates will spawn and call it in an array: 

_crateSpawns = [cratespawn_1, cratespawn_2, cratespawn_3, cratespawn_4, cratespawn_5, cratespawn_6, cratespawn_7, cratespawn_8, cratespawn_9, cratespawn_10];

Is there a way to save myself time of writing out 100 of these cratespawn_x and just populate the array with all objects that contain "cratespawn_" for instance?

 

Not sure if even possible, but I have a feeling a more experienced coder would know.

 

Thanks!

Share this post


Link to post
Share on other sites

Are you talking about objects or markers?

For objects select all of them, right click one and edit the init fields of all objects like this:

 

this setVariable ["MyCratespawn",true];

 

To collect them all (if they are objects and not units):

_crateSpawns = vehicles select {_x getVariable ["MyCratespawn",false]};

 

If they're markers and you named them cratespawn_1 to cratespawn_100(attention, case sensitive):

 

_crateSpawnMarkers = allMapMarkers select {_x find "cratespawn_" >= 0};

 

Cheers

Share this post


Link to post
Share on other sites

Marker prefixes are great.

I personally use em like this:

_prefix = "spawncrate_";
_len = count _prefix;
_markers = allMapMarkers select { (_x select [0, _len]) isEqualTo _prefix };

 

Using splitString you can also include parameters in the markernames, making them even more versatile.

Share this post


Link to post
Share on other sites

You really need to specify in your post exactly what your Objects are for people to be able to help you properly.

 

Here's a catch all example for Objects as the command vehicles does not pickup units or gameLogics.

_crateSpawns = allMissionObjects "" select { vehicleVarName _x select [ 0, 10 ] == "cratespawn" } }

 

Share this post


Link to post
Share on other sites

Oh bless you all for the amazing answers.

@Grumpy Old Man - I was referring to objects in the post, but markers would have been a follow-up question.  :eyeheart:

 

@Tajin - Looks straight forward, what I am not clear about is the [0, _len] part.  If the _len variable is catching the number of characters in the string _prefix (which would be 11), wouldn't the array be empty as I am saying isEqualTo?  For instance, all the markers in this case would be "cratespawn_(11Here)12(Character#12)". Thus not equal to anything?  Maybe I'm misunderstanding!

 

@Larrow - Sorry I will be more specific!  I am referring to pencils placed down in locations so not units or gameLogics, but good to know!   

 

I will try all these methods when I get home and see which works.  Appreciate as always the awesome community here and try to give back as much as I can as well!

 

 

 

Share this post


Link to post
Share on other sites

_len stores the length of the prefix string. select then uses _len to cuts off a segment of the markername that is equal in length to the prefix, then it compares that string to the prefix.

 

This way it accepts the prefix only at the beginning of the markername and it may also be a tiny bit faster than when using "find".

Share this post


Link to post
Share on other sites

@Tajin - Ahhhhhhhh!!! That makes sense now!  Thank you!

 

Just to confirm, the entire array will be filled with all the objects that contain the same prefix as defined, however with their full name correct?  Meaning the array wont append the prefix or anything so the array will just be filled with [1,2,3,4,5,6,] but rather the full [cratespawn_1, cratespawn_2] etc.  

 

I ask because I want to run a while loop in order to populate all of the object locations such as:  

_prefix = "spawncrate_";
_len = count _prefix;
_crateSpawns = allMapMarkers select { (_x select [0, _len]) isEqualTo _prefix };

while {#WhateverImChecking} do {

	// Selects random crate location
	_rndCrate = selectRandom _crateSpawns;

  	#Whatever code I want to run in each loop
      
    // Removes the completed crate location from array
	_crateSpawns = _crateSpawns - _rndGroup;

};

 

Technically, that would work right?  For reference this will all be sitting in a function being called in a script.  Not sure if its important to note or not.

Share this post


Link to post
Share on other sites

The array will contain the full markernames, ready to be used for whatever.

 

To remove the randomly selected crate from the array, use this instead:

_rndCrate = selectRandom _crateSpawns;
  ...
_crateSpawns = _crateSpawns - [_rndCrate];

 

Share this post


Link to post
Share on other sites

_rndCrate = _crateSpawns deleteAt (floor random count _crateSpawns); // not sure it's faster but done in one line.

Share this post


Link to post
Share on other sites
5 hours ago, Tajin said:

  ...
_crateSpawns = _crateSpawns - [_rndCrate];

 

 

It looks cool, but ... Allocate in memory an array with a removed element  ->  compare elements of two arrays  ->  allocate new array to storing result    ->  partially copy elements of source array into resulting.  Isn't too expensive?

 

Share this post


Link to post
Share on other sites

Yup, using deleteAt is probably cheaper but certainly not much.

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

×