Sertica 18 Posted April 19, 2021 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
RCA3 581 Posted April 19, 2021 Marker names are strings: "startMark", "endMark" Share this post Link to post Share on other sites
Sertica 18 Posted April 23, 2021 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
Sertica 18 Posted April 23, 2021 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]; 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
beno_83au 1362 Posted April 23, 2021 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
Sertica 18 Posted April 23, 2021 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
beno_83au 1362 Posted April 24, 2021 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!! ☺️ 1 Share this post Link to post Share on other sites
Sertica 18 Posted April 25, 2021 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
beno_83au 1362 Posted April 25, 2021 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
pierremgi 4736 Posted April 25, 2021 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! 1 Share this post Link to post Share on other sites
Sertica 18 Posted April 25, 2021 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
panther42 40 Posted April 30, 2021 @Sertica Perhaps a bit more reading would help? KK scopes See also from KillZoneKid: Variables Three parts I also forgot, you can see this post Share this post Link to post Share on other sites
panther42 40 Posted April 30, 2021 sorry, duplicate Share this post Link to post Share on other sites