Jump to content
Sign in to follow this  
dealman

Array Not Being Passed - Returns NaN and any

Recommended Posts

Okay so I've been working on a little script for a while, and it's a rather simple one - at least it should be. But due to Bohemia's rather odd and unnecessarily complex language, I keep getting stuck on the most simple of things. I simply can't figure out what's going on anymore, and I've lost far too much hair trying to figure it out.

Basically what I'm working on is a script to be used with Exile, to place loot markers via the laserdesignator on an AR-2 Darter. The script will then copy the necessary code in a format where the user can just copy and paste it.

So far I have this;

[] spawn {
	call LootMenu;
};

LootMenu = {
	removeAllActions player;
	player addAction ["<t color=""#00BB00"">Select Target</t>", SelectTarget];
};

SelectTarget = {
	removeAllActions player;
	// Store the player's old position and direction for whenever they "exit"
	_oldPlayerPos = getPosATLVisual player;
	_oldPlayerDir = getDir player;
	
	// Get the current cursortarget
	_obj = cursortarget;
	
	// Teleport the player to the location and create the object at the player's location
	player setPosATL[4575.77, 10190.5, 0];
	_dummyObject = (typeOf _obj) createVehicle position player;
	
	// Make sure the player doesn't get stuck inside the object
	_objectSize = sizeOf (typeOf _obj);
	_relPos = [_dummyObject, _objectSize, getDir _dummyObject] call BIS_fnc_relPos;
	player setPosATL _relPos;
	
	// Spawn an AR-2 Darter and give the player the UAV Terminal, connect the drone to the player
	player addWeapon "B_UavTerminal";
	_theDarter = "B_UAV_01_F" createVehicle ([player, 0, getDir player] call BIS_fnc_relPos);
	createVehicleCrew _theDarter;
	_theDarter assignTeam (assignedTeam player);
	player connectTerminalToUAV _theDarter;
	_theDarter allowDamage false;
	systemChat "A Darter has been spawned next to you, use this(laserdesignator) to place loot locations.";
	
	// Create the actions for adding a loot marker, and exiting edit mode
	_theDarter addAction ["<t color=""#00BB00"">Add Loot Marker</t>", AddLootMarker, [_theDarter, _dummyObject]];
	player addAction ["<t color=""#BB0000"">Exit Edit Mode</t>", ReturnPlayer, [_oldPlayerPos, _oldPlayerDir, _dummyObject]];
};

AddLootMarker = {
	// Grab the darter and object elements, store them in variables
	_theDarter = _this select 3 select 0;
	_dummyObject = _this select 3 select 1;
	
	// Get the laserdesignators current target position, create a temporary marker for visual feedback
	_designatedPos = getPosATL laserTarget _theDarter;
	_lootSpot = "Sign_Sphere25cm_F" createVehicle _designatedPos;
	_lootSpot setPosATL _designatedPos;
	_lootSpot enableSimulation false;
	
	// Convert the world coordinates of the marker to relative of the objects TODO: Doesn't work because ??????
	_designatedPos = _dummyObject worldToModel _designatedPos;
	_lootMarkerArray pushBack _designatedPos;
	
	// Add the new actions
	removeAllActions _theDarter;
	_theDarter addAction ["<t color=""#00BB00"">Add Loot Marker</t>", AddLootMarker, [_theDarter, _dummyObject]];
	_theDarter addAction ["<t color=""#0000BB"">Copy Data to Clipboard</t>", CopyMarkersToClipboard, [_lootMarkerArray, _dummyObject]];
	_theDarter addAction ["<t color=""#BB0000"">Remove Previous Marker</t>", RemovePreviousMarker, _lootMarkerArray];
	_theDarter addAction ["<t color=""#BB0000"">Remove All Markers</t>", RemoveAllMarkers];
};


CopyMarkersToClipboard = {
	// Store the loot marker array and dummy object in variables
	_data = _this select 3 select 0;
	_dummyObject = _this select 3 select 1;
	
	// Create the prefix for the code output
	_objectName = str(typeOf _dummyObject);
	_dumpString = ""+_objectName+toString[10]+"{"+toString[10, 9]+"table = ""LootTableNameHere"";"+toString[10, 9]+"positions[] = {";
	_allMarkers = allMissionObjects "Sign_Sphere25cm_F";
	_strang = ""; // <- temporary variable name, ignore :P
	
	_cnt = (count _allMarkers);
	systemChat (format ["Copied %1 loot markers to the clipboard!", str(_cnt)]);
	
	// Format the elements so the last one doesn't end with a comma
	{
		if(_forEachIndex == count _allMarkers-1) then
		{
			_strang = _strang+format["%1", (getPosATL _x)];
		}
		else
		{
			_strang = _strang+format["%1, ", (getPosATL _x)];
		} 
	} forEach _allMarkers;
	
	// Since Bohemia doesn't really have any useful string functions whatsoever, use CBA to easily replace stuff in a string
	_dumpString = "class "+_dumpString+_strang+"};"+toString[10]+"};";
	_newString = [_dumpString, '"'] call CBA_fnc_replace;
	_newString = [_newString, 'LootTableNameHere', '"LootTableNameHere"'] call CBA_fnc_replace;
	_newString = [_newString, '[', '{'] call CBA_fnc_replace;
	_newString = [_newString, ']', '}'] call CBA_fnc_replace;
	_newString = [_newString, 'positions{}', 'positions[]'] call CBA_fnc_replace;
	// Copy it all to clipboard! \o/
	copyToClipboard str _newString;
};

RemovePreviousMarker = {
	// For whatever reason NEITHER of anything in here works at all
	_lootMarkerArray = _this select 3 select 0;
	
	systemChat format["Removing marker with ID %1", (count _lootMarkerArray-1)];
	systemChat format["Removed: %1", (_lootMarkerArray select (count _lootMarkerArray-1))];	
	{
		if(_forEachIndex == count _lootMarkerArray-1) then
		{
			hint "Test 1";
			//_theMarker = nearestObject (_lootMarkerArray select _forEachIndex);
			//deleteVehicle _theMarker;
		}
	} forEach _lootMarkerArray;
	
	removeAllActions player;
	_theDarter addAction ["<t color=""#0000BB"">Copy Data to Clipboard</t>", CopyMarkersToClipboard, _lootMarkerArray];
};

RemoveAllMarkers = {
	hint "";
};

ReturnPlayer = {
	// Retrieve the passed arguments
	_oldPlayerPos = _this select 3 select 0;
	_oldPlayerDir = _this select 3 select 1;
	_dummyObject = _this select 3 select 2;
	
	// Delete the object and return the player to their old location
	deleteVehicle _dummyObject;
	player setPosATL _oldPlayerPos;
	player setDir _oldPlayerDir;
	removeAllActions player;
	sleep 0.1;
	player addAction ["<t color=""#00BB00"">Select Target</t>", SelectTarget];
}; 

 

So the issue is that I can't seem to pass the array containing the locations to my function RemovePreviousMarker. The systemChat messages used to out put "scalar NaN" and "any" respectively - but now for some reason nothing happens. And I simply can't figure out what on earth is going on. I've tried to set all variables as private in the main scope, but that didn't help at all.

I simply don't understand why the other functions work, but that particular one does not...? Am I overlooking something here? Has this language of theirs made me gone insane?  :o

 

I have some experience with scripting and programming, mostly Lua and C# - but this is giving me headaches like I have never before experienced.

Share this post


Link to post
Share on other sites

_lootMarkerArray pushBack _designatedPos;

 _lootMarkerArray is nowhere defined in AddLootMarker. 

I suggest start your arma with -showScriptErrors for starters, so that you will be able to catch things like that.

Share this post


Link to post
Share on other sites

Cheers for noticing that, I forgot to define it. Before I used pushBack, I defined it like this;

_lootMarkerArray = _lootMarkerArray + _designatedPos;

I have that parameter set in my ArmA 3 launcher, but for whatever reason it's not working. And for some reason my function CopyMarkersToClipboard is not working anymore, it used to work exactly like how I wanted it with the exception for worldToModel not working. I'll try and get the script errors to show as it would help tremendously.

I'm sure I must have messed something up while I was losing my patience working on this script last night. Hopefully I'll be able to spot it, or maybe someone of y'all will.

 

Another question, is there a way to make the variables visible to all of my functions without having to pass them as arguments with addAction? I'm used to the simplicity that Lua offers, switching to this is like being hit with a truck  :lol: Oh and if you can spot something that could be written better I would appreciate any suggestions you might have.  :wub:

Share this post


Link to post
Share on other sites
Before I used pushBack, I defined it like this;

 

That was also wrong.

 

_lootMarkerArray = [];

_lootMarkerArray pushback _designatedPos;

 

^^^ this is correct way to do it.

Share this post


Link to post
Share on other sites

So I managed to get it to show the errors, and I noticed that it always kept reporting an error on my commented lines - so after removing all of the comments it now works. Well, AddLootMarker and CopyMarkersToClipboard now work, with the exception of worldToModel still not doing anything.

 

Now there's some oddities going on with this piece of code;

systemChat format["Removing marker with ID %1", (count _lootMarkerArray-1)];
systemChat format["Removed: %1", (_lootMarkerArray select (count _lootMarkerArray-1))];	

The second systemChat works like I want it, it outputs the 3 positions in that element. However, the first one always outputs 0, no matter how many markers I add...?

Edit:

I now see why I thought worldToMatel wasn't working, I don't use the array I created for them and instead use allMissionObjects and just get their ATL position. Rookie mistake :)

 

Edit2:

Alright I made some progress, it all now works how I want it. Spotted quite a few logical errors I had made, and knowing that comments entirely breaks your script was helpful. Is there no way to make it so the variables are visible to all my functions without having to pass them as arguments along with addAction every time? It would be a fair bit less confusing that way.

Only thing left now is to add the feature to remove all the markers which should be a very easy task. Thanks for the help killzone, really appreciate it!  B)

Share this post


Link to post
Share on other sites

comments shouldn't be breaking your script if they are in the right places.

 

Don't use them in init boxes in the editor or in eventhandlers or addactions.

Share this post


Link to post
Share on other sites

comments shouldn't be breaking your script if they are in the right places.

 

Don't use them in init boxes in the editor or in eventhandlers or addactions.

 

Comments are removed by preprocessor. Preprocessed files are files loaded with execVM, prerpocessFile and preprocessFileLineNumbers. Other than that, "comment" command can be used.

Share this post


Link to post
Share on other sites

I did some research and managed to figure out how event handlers work, and I'm rather curious about using the Fired event handler instead of the UAV since it's not exactly optimal for indoor environments. :P However, there's an issue with the marker not being very accurate, and not being placed at all if it ricochets.

Do you guys know if there's any workaround for this? IE, get the first impact location only or something similar?

I was also looking at the event EpeContactStart but this is only for PhysX collisions, so I would assume it only works for vehicles and not actual projectiles...?

Edit:

I found a thread related to this very subject, and using part of their code I managed to get this to work;

LootHandler = player addEventHandler["Fired", 
{
	_this spawn
	{
		_theBullet = _this select 6;
		_screenPos = screenToWorld[0.5, 0.5];
		_test = (_screenPos nearestObject "#crater");
		_pos = getPosATL _test;
		_lootSpot = "Sign_Sphere25cm_F" createVehicle _pos;
	};
}];

Now I just need to further extend upon this, and see how it works on objects inside the buildings.

 

Edit2:

As suspected it didn't work at all inside or on buildings, using #crateronvehicle worked sometimes - but only on the floor. Any ideas? :(

 

Edit3:

 

It would seem there is no reliable way of getting impact location nor the location you're currently looking at. Using screenToWorld works relatively well, but only outdoors. If you're inside a building, it most of the time will not work at all. If you mix screenToWorld with a nearby crater object, like in the code above - it's extremely accurate, but again, only outdoors.

 

It's rather odd for a game like ArmA to not have an event for projectile impacts since this would be very useful for a variety of things.

 

So in the end, it seems like using laserTarget is the most reliable way to do it. But this also has its drawbacks. Using the Darter is good and all, but trying to maneuver this inside a building is simply not a very good way of doing things. And using the handheld laserdesignator would work as well if not better - I would assume, but then, the issue is the minimum zoom level of x5.0.

 

If anyone has any suggestions on how to go about doing this, it would be greatly appreciated!

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  

×