Jump to content
jcae2798

Arrays, and subtracting issues

Recommended Posts

Hey guys.  I have the following array being spit out via diag_log message:

 

"[[[5072.71,6158.22]],[[3057.78,9808.44]],[[6092.15,11018.7]],[[10603.6,6410.72]],[[5989.99,8977.47]],[[1890.7,11867.5]],[[9951.81,11651.3]],[[6063.8,7256.97]],[[6030.72,5659.43]],[[4375.92,754.72]],[[3588.99,4284.47]],[[571.8,2810.97]],[[8622.05,2454.22]],[[3626.58,8510.97]],[[2009.21,7675.97]],[[1444.14,5732.22]],[[2537.21,5026.47]],[[1529.11,3582.72]],[[8238.39,7847.22]],[[11539.2,8318.97]],[[8888.11,5181.47]],[[5313.46,4740.72]],[[1950.86,349.72]],[[5932.74,1245.22]],[[6578.67,1955.22]],[[9009.33,1871.97]],[[10528.8,2429.22]],[[4078.33,11844.2]],[[12243.5,10420.3]],[[3642.99,11045.5]],[[2439.85,9625.41]],[[905.58,7858.33]],[[4563.67,9354.22]],[[8281.38,11166.5]],[[8112.86,9146.97]],[[5064.02,6865.22]],[[5278.46,3674.97]],[[3960.1,3118.73]],[[3572.92,1284.22]],[[6821.86,1384.93]],[[11858.2,2656.54]],[[9033.67,4428.03]],[[5638.16,11356.3]],[[9339.24,9956.22]],[[9128.25,6864.95]]]"

 

These are being returned as city locations.

 

I try to run the following code with no luck.

_exclusions = [[[5638.16,11356.3]],[[10603.6,6410.72]]];
_cities = _cities - _exclusions;
diag_log format ["%1", _cities];

For whatever reasons these two elements will not remove from the original array.  Any ideas?  no report errors that i can find...  The weirder thing is i had an extra exclusion in the mix earlier and it was the only one removing out of the three...  It's like these two specific locations don't want to remove themselves!

Share this post


Link to post
Share on other sites

Actually...i found a workaround.  Instead of relying on script to pull locations, i'm just going to store them manually.  This way no need to exclude.  Sorry and thanks

Share this post


Link to post
Share on other sites

Why is each array double nested?

 

Perhaps I'm not reading it right, or your paste didn't work as expected, but I'd structure the array like this;

 

[[city1 x, city1 y, city 1 z], [city 2 x, city 2 y, city 2 z]]

Share this post


Link to post
Share on other sites

Hey guys.  I have the following array being spit out via diag_log message:

 

"[[[5072.71,6158.22]],[[3057.78,9808.44]],[[6092.15,11018.7]],[[10603.6,6410.72]],[[5989.99,8977.47]],[[1890.7,11867.5]],[[9951.81,11651.3]],[[6063.8,7256.97]],[[6030.72,5659.43]],[[4375.92,754.72]],[[3588.99,4284.47]],[[571.8,2810.97]],[[8622.05,2454.22]],[[3626.58,8510.97]],[[2009.21,7675.97]],[[1444.14,5732.22]],[[2537.21,5026.47]],[[1529.11,3582.72]],[[8238.39,7847.22]],[[11539.2,8318.97]],[[8888.11,5181.47]],[[5313.46,4740.72]],[[1950.86,349.72]],[[5932.74,1245.22]],[[6578.67,1955.22]],[[9009.33,1871.97]],[[10528.8,2429.22]],[[4078.33,11844.2]],[[12243.5,10420.3]],[[3642.99,11045.5]],[[2439.85,9625.41]],[[905.58,7858.33]],[[4563.67,9354.22]],[[8281.38,11166.5]],[[8112.86,9146.97]],[[5064.02,6865.22]],[[5278.46,3674.97]],[[3960.1,3118.73]],[[3572.92,1284.22]],[[6821.86,1384.93]],[[11858.2,2656.54]],[[9033.67,4428.03]],[[5638.16,11356.3]],[[9339.24,9956.22]],[[9128.25,6864.95]]]"

 

These are being returned as city locations.

 

I try to run the following code with no luck.

_exclusions = [[[5638.16,11356.3]],[[10603.6,6410.72]]];
_cities = _cities - _exclusions;
diag_log format ["%1", _cities];

Any ideas?

 

Large numbers lose precision, so [10603.6,6410.72] for example that you typed in code could be different from [10603.6,6410.72] obtained via some command.

Share this post


Link to post
Share on other sites

Large numbers lose precision, so [10603.6,6410.72] for example that you typed in code could be different from [10603.6,6410.72] obtained via some command.

 

You may be on to something here. 

 

Anyways the locations above were from a script that looks for city locations based on Positions stored in the CONFIG file.  It looks for each city in the CONFIG, and then pulls the array from the config for that location.  Why its double nested, i have no idea, but that is how it pulls the arrays.  The code is not setup to nest it specifically this way.  The code was original written by "Sacha"  Example below:

Spawn_fnc_getCities = {
	private ["_locations","_cityTypes","_randomLoc","_x","_cities"];
	_customs = [[3005.33,4228.15],[2992.96,2755.22],[1404.01,450.117]];  //custom pos to add areas
	_cities = [];

	_locations = configfile >> "CfgWorlds" >> worldName >> "Names";
	_cityTypes = ["NameVillage","NameCity","NameCityCapital","NameLocal"];
	_exclusions = [[4977.17,1272.78],[309.63,2090.97]];  //custom pos of excluded areas

	for "_x" from 0 to (count _locations - 1) do {
		_randomLoc = _locations select _x;

		private["_cityPos","_cityType"];
		_cityPos = getArray(_randomLoc >> "position");
		_cityType = getText(_randomLoc >> "type");
		if (_cityType in _cityTypes) then {
			if !(_cityPos in _exclusions) then {
				_cities pushBack [ _cityPos];};
		};
	{_cities pushBack [ _x]} foreach _customs;
	};
	_cities
};

Actually now that I am looking at it again, i guess its double nested because of :

"[ _cityPos];};" instead of _cityPos;}; ....

Share this post


Link to post
Share on other sites

Why not filter by city names?

If for some reasons (I don't see yet) it is not possible, you can still use distance2D command, then compare to some threshold.
 
Some other considerations about the code:
1. Try to eliminate as much nested cycles as possible.
2. Get rid of hardcoded values in code (unless not in defaults list). Pass as function arguments, store in mission-specific locations: parameters, global variables, etc. If in some time in the future you will want to port your mission to another world you will have to do less work. Even if mission remains unported it will be much more readable.
Well, that's all words, here's the code.
Spawn_fnc_getCities = {
	params [  // params since 1.48
		["_exclNames", [], [[]]], // can be both config names and cities' display names
		["_exclPoses", [], [[]]], // probably will not be needed because of names are much easier to list
		["_inclTypes", ["NameVillage","NameCity","NameCityCapital","NameLocal"], [[]]], // default params values (reluctantly) hardcoded here. could be reference to global variable or smth.
		["_inclNames", [], [[]]], // can be both config names and cities' display names, even with types not specified in _inclTypes; positions included if names found
		["_inclPoses", [], [[]]], // unconditionally include these positions
		["_tol", 10, [3.14159]]
	];
	_tol = abs _tol; // in case negative specified
	// some more args validity checks could be performed here...

	private ["_locations", "_cities"];
	_cities = [];

	// after this line _locations will be filtered by type and excluded names
	_locations = (format ['(getText(_x >> "type") in %1) && !(getText(_x >> "name") in %2) && !(configName(_x) in %2)', _inclTypes, _exclNames]) configClasses (configfile >> "CfgWorlds" >> worldName >> "Names");

	// now filter by excluded positions
	{
		private ["_cityPos", "_good"];
		_cityPos = getArray(_x >> "position");
		_good = true;
		scopeName "locs";
		{
			if ((_x distance2D _cityPos) < abs(_tol)) then { // distance2D since 1.50
				_good = false;
				breakTo "locs";
			};
		} forEach _exclPoses;
		if (_good) then {
			_cities pushBack _cityPos;
		};
	} forEach _locations;

	// adding custom positions by names
	{
		_cities pushBack getArray(_x >> "position");
	} forEach ((format ['(getText(_x >> "name") in %1) || (configName(_x) in %1)', _inclNames]) configClasses (configfile >> "CfgWorlds" >> worldName >> "Names"));

	// adding custom positions by positions
	// select with code since 1.55 dev 155,133771. alternatively could be implemented as simple loop or _inclPoses added with + operator w/o validity check
	_cities = _cities + (_inclPoses select {((typeName _x) == "ARRAY") && ((count _x) == 2) && ((typeName (_x select 0)) == "SCALAR") && ((typeName (_x select 1)) == "SCALAR")});
	_cities
};

Share this post


Link to post
Share on other sites

 

Why not filter by city names?

If for some reasons (I don't see yet) it is not possible, you can still use distance2D command, then compare to some threshold.
 
Some other considerations about the code:
1. Try to eliminate as much nested cycles as possible.
2. Get rid of hardcoded values in code (unless not in defaults list). Pass as function arguments, store in mission-specific locations: parameters, global variables, etc. If in some time in the future you will want to port your mission to another world you will have to do less work. Even if mission remains unported it will be much more readable.
Well, that's all words, here's the code.

 

Thanks for sharing.  When it comes to scripting, i'm no expert.  I've learned all i have through this game only over the last year or two.  So my knowledge is still limited.  I will read through the code and try to make sense of it which i am sure i will be able to do.  I thank you for taking the time to write it up!

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

×