Jump to content
Sertica

CalculatePath Test Mission

Recommended Posts

I'm starting work on a system for procedural generation of waypoints guaranteed to be reachable.

https://community.bistudio.com/wiki/calculatePath

1. I followed the warning advice and put this in init.sqf:

isNil { calculatePath ["man", "aware", startMark, endMark] addEventHandler ["PathCalculated", { 
		params ["_agent", "_path"];
		for "_idx" from 0 to (count _path) do {
			player sideChat (str (_path select _idx));
			_marker = createMarker["",_path select _idx];
			_marker setMarkerColor "ColorWEST";
			_marker setMarkerShape "hd_dot";
		};
	}]
}

The code does not execute.

2.  I tried removing the isNil block, then got an error about startMark variable undefined.  But it is defined on a marker placed in the editor.  I've never had a problem reading editor placed global variables from init before.

Share this post


Link to post
Share on other sites

Marker names are strings: "startMark", "endMark"

Share this post


Link to post
Share on other sites

There is something strange going on.  I used the alt method because I can't have the bug with this command.  But the event handler gets fired endlessly.  This is not feasible.  I need it to run once.

private _agent1 = createAgent [typeOf player, getMarkerPos "startMark", [], 0, "NONE"];
_agent1 setBehaviour "AWARE";
_agent1 addEventHandler ["PathCalculated",
{
	{ 
		private _marker = createMarker ["marker" + str _forEachIndex, _x]; 
		_marker setMarkerType "mil_dot";
		_marker setMarkerColor "ColorBLUE";
		//_marker setMarkerText str _forEachIndex; 
	} 
	forEach (_this select 1);
	//player sideChat "PathCalculated Done: "+str(count (_this select 1));
}];
_agent1 setDestination [getMarkerPos "endMark", "LEADER PLANNED", true];

 

Share this post


Link to post
Share on other sites
private _agent1 = createAgent [typeOf player, getMarkerPos "startMark", [], 0, "NONE"];
//_agent1 setBehaviour "AWARE";
_agent1 addEventHandler ["PathCalculated",
{
	{ 
		private _marker = createMarker ["marker" + str _forEachIndex, _x]; 
		_marker setMarkerType "mil_dot";
		_marker setMarkerColor "ColorBLUE";
		//_marker setMarkerText str _forEachIndex; 
	} 
	forEach (_this select 1);
	player sideChat "PathCalculated Done: "+str(count (_this select 1));
	_agent1 removeEventHandler["PathCalculated",_thisEventHandler];
	_agent1 = nil;
}];
_agent1 setDestination [getMarkerPos "endMark", "LEADER PLANNED", true];

:smiley-grimmace:  The  event handler is removed.  The agent is nil.  Yet the ghost keeps coming back to haunt me every 5 seconds in side chat with a new calculation.

Share this post


Link to post
Share on other sites

Where/how are you running this snippet of code? Perhaps you are looping it's execution somewhere by mistake. 

Share this post


Link to post
Share on other sites
35 minutes ago, beno_83au said:

Where/how are you running this snippet of code? Perhaps you are looping it's execution somewhere by mistake. 

What I pasted above is the entire code in the mission folder, in init.  It does the same thing if run from a player action.

checkPath = {
private _agent1 = createAgent [typeOf player, getMarkerPos "startMark", [], 0, "NONE"];
	//_agent1 setBehaviour "AWARE";
	_agent1 addEventHandler ["PathCalculated",
	{
		{ 
			private _marker = createMarker ["marker" + str _forEachIndex, _x]; 
			_marker setMarkerType "mil_dot";
			_marker setMarkerColor "ColorBLUE";
			//_marker setMarkerText str _forEachIndex; 
		} 
		forEach (_this select 1);
		player sideChat "PathCalculated Done: "+str(count (_this select 1));
		_agent1 removeEventHandler["PathCalculated",_thisEventHandler];
		_agent1 = nil;
	}];
	_agent1 setDestination [getMarkerPos "endMark", "LEADER PLANNED", true];
};
player addAction["Check Path",checkPath];

 

Share this post


Link to post
Share on other sites

Right, pretty simple one really. You haven't declared the agent within the eventhandler: https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#PathCalculated

 

Those param values are there for a reason. Their values are what are passed into the EH and can be used by the code within it. Simply declaring the agent as _agent1 outside of the EH's scope wont mean anything to the code inside. Example:

//WRONG, and will throw an error
_a = "A";
nul = [] spawn {
 systemChat _a;
};

//RIGHT
_a = "A";
nul = [_a] spawn {
 params ["_a"];
 systemChat _a;
};

So using params is like using _this select 0, and in your code you used _this select 1 which obviously grabbed the second value, the path array. You could also just use _this select 0 in place of any _agent reference in the EH code, but the more params and the bigger an EH's code becomes the harder it becomes to keep track of all the values. You could also use private _agent = _this select 0 etc, but it's easier to use params. So below is your code corrected and cleaned up a little:

private _agent1 = createAgent [typeOf player, getMarkerPos "startMark", [], 0, "NONE"];

_agent1 addEventHandler ["PathCalculated",{
	params ["_agent","_path"];
	{ 
		private _marker = createMarker ["marker" + str _forEachIndex, _x]; 
		_marker setMarkerType "mil_dot";
		_marker setMarkerColor "ColorBLUE";
	} forEach _path;
	player sideChat "PathCalculated Done: "+str(count (_this select 1));
	_agent removeEventHandler ["PathCalculated",_thisEventHandler];
}];

_agent1 setDestination [getMarkerPos "endMark", "LEADER PLANNED", true];

Params are a thing of beauty and make life a lot easier. Get used to using them!! ☺️

  • Thanks 1

Share this post


Link to post
Share on other sites

I assumed that local variables declared at file base level had scope anywhere in the file.

Share this post


Link to post
Share on other sites

Nope. So things like event handlers, spawned/called/execVMed scripts and functions, and addActions all need to take this into account. There might be a few other circumstances but the ones above spring to mind so keep that in the back of your mind. 

Share this post


Link to post
Share on other sites
3 hours ago, beno_83au said:

Nope. So things like event handlers, spawned/called/execVMed scripts and functions, and addActions all need to take this into account.

With a little difference for call:

you can use it without params/argument:

_a = "Z";
_lines = "anyThing/lines code without working on _a";
_fnc2 = call {systemChat _a};  // Z

 

or even, somewhere in different scopes:

Spoiler

 

MGI_fnc = {systemChat _a};

then, somewhere else:

_a = "Z";

_lines = "anyThing/lines code without working on _a";

call MGI_fnc;  // Z

 


 

Spoiler

 

MGI_fnc = {_a = _a +6};

then, somewhere else

0 = [] spawn {

  _a = 3;
  _lines = "anyThing/lines code without working on _a";
  call MGI_fnc;
  systemChat str _a

};

 

Not a good practice, anyway!

 

 

  • Like 1

Share this post


Link to post
Share on other sites

The rules are baffling.  These statements seem to contradict.

Quote

A local variable is only visible in the script, function or Control Structure in which it was defined.

Quote

Local variables in callable code (e.g Functions) should be scoped using the command private, otherwise you may modify local variables of the calling script that are visible in the function.

🤔How can local variable be visible to function if defined in and only visible in the calling script?

So the difference with private modifier is unclear.

For Java it is so easy.  Just look at the access levels table: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html

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

×