Gen. MERICA 3 Posted December 18, 2018 (edited) Hello everyone, I am trying to draw a border through a set of markers like so, https://imgur.com/a/MkLDa7R But due to the ctrlAddEventHandler I cant pass local variables to it, so I need to make them global somehow. I ended up using global place placeholders to pass it through the ctrlAddEventHandler and end up with this, https://imgur.com/a/sEfyE9I I believe its due to the way the loop ends up cycling through itself, and it seems to just move the corresponding line. Does anyone know of a clever work around to this? _marker = param[0]; _markerName = param[1]; _pos = param[2]; _markerText = param[3]; _borderLines = []; { _borderMarker = toArray _x; _borderMarkerName = toString _borderMarker; _borderPos = getMarkerPos _x; _borderMarkerText = markerText _x; if((_borderMarkerName find _markerText >= 0) && (_borderMarkerName find "Border" >= 0)) then { //DEBUG systemChat ((format["%1", _borderMarkerText]) + " recognized as border to " +(format["%1", _markerText])); //DEBUG _border = [_borderMarker, _borderMarkerName, _borderPos, _borderMarkerText]; _borderLines = _borderLines + [_border]; }; } forEach allMapMarkers; _i = 0; { if(_i != ((count _borderLines) - 1)) then { PlaceHolder1 = ((_borderLines select _i) select 2); PlaceHolder2 = ((_borderLines select (_i + 1)) select 2); (findDisplay 12 displayCtrl 51) ctrlAddEventHandler ["Draw"," (_this select 0) drawLine [ PlaceHolder2, PlaceHolder3, [1,1,1,1] ]; "]; }else{ PlaceHolder3 = ((_borderLines select (0)) select 2); (findDisplay 12 displayCtrl 51) ctrlAddEventHandler ["Draw"," (_this select 0) drawLine [ PlaceHolder1, PlaceHolder3, [1,1,1,1] ]; "]; }; _i = _i + 1; }forEach _borderLines; FYI the border markers share the same name and text in case this leads to something. I tried thinking of a solution where it looks for similar names and then links them but it ends up creating a spider web unfortunately. Thanks in advance Edited December 18, 2018 by Gen. MERICA Solved! Share this post Link to post Share on other sites
Grumpy Old Man 3546 Posted December 18, 2018 28 minutes ago, Gen. MERICA said: Hello everyone, I am trying to draw a border through a set of markers like so, https://imgur.com/a/MkLDa7R But due to the ctrlAddEventHandler I cant pass local variables to it, so I need to make them global somehow. I ended up using global place placeholders to pass it through the ctrlAddEventHandler and end up with this, https://imgur.com/a/sEfyE9I I believe its due to the way the loop ends up cycling through itself, and it seems to just move the corresponding line. Does anyone know of a clever work around to this? FYI the border markers share the same name and text in case this leads to something. I tried thinking of a solution where it looks for similar names and then links them but it ends up creating a spider web unfortunately. Thanks in advance You simply need to sort the array of fitting markers and to close the polygon add the first marker to the end of the array: (findDisplay 12 displayCtrl 51) ctrlAddEventHandler ["Draw"," _markers = allMapMarkers select {toUpper _x find 'BORDER' >= 0}; _markers sort true; _positions = _markers apply {getMarkerPos _x}; _positions pushBack (_positions#0); { if (_forEachIndex < count _positions - 1) then { (_this select 0) drawLine [ _x, (_positions select (_forEachIndex + 1)), [1,1,1,1] ]; } } forEach _positions; "]; This way you simple create one marker named "border" and copy paste it, the automatic marker naming will work fine with the sort command (pasted markers will be named "border_1", "border_2" etc). Check out the wiki entries of the respective commands, if things are unclear ask again. Cheers 3 Share this post Link to post Share on other sites
pierremgi 4905 Posted December 18, 2018 Why not drawPolygon? 2 Share this post Link to post Share on other sites
Gen. MERICA 3 Posted December 18, 2018 Thank you both for the quick responses, GrumpyOldMan that is an interesting solution that I hadn't thought of. I didn't think of having the loop be inside the string to get it to work to avoid passing anything. Although I plan to have multiple borders so I would still have to pass through what location borders we are looking for (there would've been no way for you to know that, I should've had that in my post, my bad.). I definitely plan to save your example for creating compact and effective loops in the future. pierremgi I plan to use polygons but I wanted to get lines working first before I attempt a polygon lol, baby steps. But I did discover something that I never knew you could do with event handlers. _i = 0; { if(_i != ((count _borderLines) - 1)) then { (findDisplay 12 displayCtrl 51) ctrlAddEventHandler ["Draw"," (_this select 0) drawLine [" + str((_borderLines select _i) select 2) + "," + str((_borderLines select (_i + 1)) select 2) + ", [1,1,1,1] ]; "]; }else{ (findDisplay 12 displayCtrl 51) ctrlAddEventHandler ["Draw"," (_this select 0) drawLine [" + str((_borderLines select _i) select 2) + "," + str((_borderLines select (0)) select 2) + ", [1,1,1,1] ]; "]; }; _i = _i + 1; }forEach _borderLines; You CAN pass local variables to an event handler _var = "it" "You have to structure" + _var + "like so."; 2 Share this post Link to post Share on other sites
Grumpy Old Man 3546 Posted December 18, 2018 37 minutes ago, Gen. MERICA said: Thank you both for the quick responses, GrumpyOldMan that is an interesting solution that I hadn't thought of. I didn't think of having the loop be inside the string to get it to work to avoid passing anything. Although I plan to have multiple borders so I would still have to pass through what location borders we are looking for (there would've been no way for you to know that, I should've had that in my post, my bad.). I definitely plan to save your example for creating compact and effective loops in the future. pierremgi I plan to use polygons but I wanted to get lines working first before I attempt a polygon lol, baby steps. But I did discover something that I never knew you could do with event handlers. You CAN pass local variables to an event handler _var = "it" "You have to structure" + _var + "like so."; That's just string manipulation, you don't pass variables towards EH scope that way. You can also go fancy with multiple borders like this, even add custom color for every border etc: GOM_fnc_drawBorders = { params ["_borderArray"]; { (findDisplay 12 displayCtrl 51) ctrlAddEventHandler ["Draw",format [" _border = %1; _border params ['_markerPrefix','_color']; _markers = allMapMarkers select {toUpper _x find toUpper _markerPrefix >= 0}; _markers sort true; _positions = _markers apply {getMarkerPos _x}; _positions pushBack (_positions#0); { if (_forEachIndex < count _positions - 1) then { (_this select 0) drawLine [ _x, (_positions select (_forEachIndex + 1)), _color ]; } } forEach _positions; ", _x]]; } forEach _borderArray; }; _customBorders = [["RED",[1,0,0,1]],["BLUE",[0,0,1,1]]]; [_customBorders] call GOM_fnc_drawBorders; Pretty easy to build upon. 3 hours ago, pierremgi said: Why not drawPolygon? Sure, why not? GOM_fnc_drawBordersAsLeFancyPolygon = { params ["_borderArray"]; { (findDisplay 12 displayCtrl 51) ctrlAddEventHandler ["Draw",format [" _border = %1; _border params ['_markerPrefix','_color']; _markers = allMapMarkers select {toUpper _x find toUpper _markerPrefix >= 0}; _markers sort true; _positions = _markers apply {getMarkerPos _x}; (_this select 0) drawPolygon [_positions,_color] ", _x]]; } forEach _borderArray; }; _customBorders = [["RED",[1,0,0,1]],["BLUE",[0,0,1,1]]]; [_customBorders] call GOM_fnc_drawBordersAsLeFancyPolygon; Cheers 1 Share this post Link to post Share on other sites