Godis_1 63 Posted March 15, 2017 Hello everyone. I don't know how to desribe my problem in the title, my English isn't good enough on that.. I want let the script to randomly pick a marker. My problem is that the markers are being created dependant on the amount of towns on the map. It detects all towns and creates an invisible marker at each, with name "Mark_1", "Mark_2", etc... I need to know how can I let my script at first count all created markers (as each map has a different amount of villages) and then randomly pick one of these markers. The markers are being created as follows (a part of the script): towns.sqf /* Location finder for towns, villages and cities Places triggers and/or markers at these locations */ // Get each locations of villages or cities and create trigger/marker // Original script for finding locations by BrotherhoodOfHam // Final script by Godis if (!isServer) exitWith {}; //#define MARK #define OFFSET 0 _locations = (nearestLocations [[0,0,0], ["NameCity", "NameVillage", "NameCityCapital"], 40000]); { _xy = size _x; _trig = createTrigger ["EmptyDetector", position _x]; _trig setTriggerArea [ (_xy select 0) + OFFSET, (_xy select 1) + OFFSET, direction _x, false ]; _trig setTriggerActivation [ "WEST", "PRESENT", true ]; _trig setTriggerStatements [ "this", "hint 'Entered Village: Watch out in this area';", "hint 'Leaving Village...';" ]; //#ifdef MARK _mkr = createMarker [format ["Mark_%1", _forEachIndex], position _x]; _mkr setMarkerShape "ELLIPSE"; _mkr setMarkerAlpha 0.0; _mkr setMarkerSize [ (_xy select 0) + OFFSET, (_xy select 1) + OFFSET ]; //#endif } forEach _locations; // Now place units I thought I could just add a counter to towns.sqf, so I would get the total amount of all created markers stored in a variable, like: all_markers = 0; // Content of towns.sqf here (create markers) all_markers = all_markers + 1; // count each marker and store number in 'all_markers' But this would need another check for this variable's value, and also another code to select one of them according to the amount of created markers. I think it's kind of inconvenient. There must be another easier way to archive that, I guess. Is there any code I can use to get that in only a few lines? At the end I just need to: 1. find the amount of markers with name Mark_1, Mark_2, Mark_3, etc, etc 2. Randomly select one of these (i.e. to make it visible by setMarkerAlpha or sth else) Thanks in advance. Share this post Link to post Share on other sites
serena 150 Posted March 15, 2017 // select all settlement markers private _settlements = allMapMarkers select {_x find "Mark_" isEqualTo 0}; // result: ["Mark_1", "Mark_2", "Mark_3"] // select random settlement marker private _settlement = selectRandom _settlements; // result: "Mark_?" // get settlement markers count private _count = count _settlements; // result: 3 * code updated 2 Share this post Link to post Share on other sites
Godis_1 63 Posted March 15, 2017 20 minutes ago, serena said: // select all settlement markers private _settlements = allMapMarkers select {_x find "Mark_" isEqualTo 0}; // result: ["Mark_1", "Mark_2", "Mark_3"] // select random settlement marker private _settlement = selectRandom _settlements; // result: "Mark_?" // get settlement markers count private _count = count _settlements; // result: 3 Thank you :-) I guess this is what I was searching for... Share this post Link to post Share on other sites
Godis_1 63 Posted March 15, 2017 Forgot sth. Can I "split" the result of "_settlements" into even and odd numbers and put them into a new array? I mean, two arrays in this case. One for the odd numbers, another for even numbers. And, In example, I am calling a function which needs markers to be defined in an array: null = [["Mark_4","Mark_10","Mark_16","Mark_20","Mark_24","Mark_30"], [blabla], ... is there another way to define them more accurate instead of putting them manually? Otherwise I would have to write an endless "if (_count > whatever_nr) then {};" condition, based off the amount resulted by "_count". Edit: Maybe this would work by "selectmarkers = _settlements select [0,3,5,7,9...]" // would that work? Edit 2: Ok, I got sth from the wiki: _even = [1,2,3,4,5,6,7,8,9,0] select {_x%2 == 0}; In this case can I replace the array with number with the "_settlements" array? _even = [_settlements] select {_x%2 == 0}; Share this post Link to post Share on other sites
serena 150 Posted March 16, 2017 12 hours ago, Godis_1 said: Can I "split" the result of "_settlements" into even and odd numbers and put them into a new array? private _all = ["A", "B", "C", "D", "E"]; private _evn = []; private _odd = []; { if (_forEachIndex % 2 > 0) then {_evn pushBack _x} else {_odd pushBack _x} } forEach _all; // Result: // _evn = ["B","D"] // _odd = ["A","C","E"] 1 Share this post Link to post Share on other sites
Godis_1 63 Posted March 16, 2017 10 hours ago, serena said: private _all = ["A", "B", "C", "D", "E"]; private _evn = []; private _odd = []; { if (_forEachIndex % 2 > 0) then {_evn pushBack _x} else {_odd pushBack _x} } forEach _all; // Result: // _evn = ["B","D"] // _odd = ["A","C","E"] All right, thanks again :-) Going to try around. Share this post Link to post Share on other sites
Godis_1 63 Posted March 17, 2017 Hi again, my last problem :) So far you helped me a lot, thx a lot for this! However, I didn't want to open an extra thread for this. Now I got everything working so far. What I need is to put the content of the resulting array (_settlements in this case) into another array which is part of a function call. Example: ["Mark1","Mark_2","Mark_3"] call function_now; I got the whole list of towns inside the "_settlements" array (_settlements = ["Mark_1", "Mark_2", "Mark_3"];) but I'm not able to figure how I could put its content inside the function call. This doesn't work: [_settlements] call function_now; // also doesn't work ["%1",_settlements] call function_now; and tried some other things.. Might it work using the "str" or "set" command somehow? I don't know how to use it properly, am still very much in the learning process. Edit: After some further researching I found it could be done somehow using "select"... I'm trying to find it by myself, but will be thankful if someone could point me into the right direction here. thx So, what about sth like this: [(_settlements select (count _settlements))] call function_now; Share this post Link to post Share on other sites
mrcurry 470 Posted March 17, 2017 So close with: [_settlements] call function_now; Use: _settlements call function_now; 1 Share this post Link to post Share on other sites
Godis_1 63 Posted March 17, 2017 Awwww... Damn! I'm realy dumb! I guess I can use what's already there... [allMapMarkers select {_x find "Mark_" isEqualTo 0}] call function_here; ?? :-D Share this post Link to post Share on other sites
Godis_1 63 Posted March 17, 2017 3 minutes ago, mrcurry said: So close with: [_settlements] call function_now; Use: _settlements call function_now; Ooops, lol. Many thanks!! Seems we posted the same moment. Share this post Link to post Share on other sites
serena 150 Posted March 17, 2017 // function call _settlements call function_now; // inside function_now private _settlements = _this; // _this variable always references arguments passed to function 1 Share this post Link to post Share on other sites
Godis_1 63 Posted March 19, 2017 Thx to you guys helping me out. Got another thing, nothing complicated, but still not sure. I just want to select the last element of an array. According to the wiki it should be sth like the following, would it work like that? if (array > 0) then { _select_last_element = (_array select (count _array)); }; Share this post Link to post Share on other sites
mrcurry 470 Posted March 19, 2017 Again so close :) Count gives you the amount but the indexes start at 0 the last element will always be amount-1. 1 Share this post Link to post Share on other sites
Godis_1 63 Posted March 19, 2017 9 minutes ago, mrcurry said: No, count gives you the amount but since the indexes start at 0 the last element will always be amount-1. Well, then it must be: if (array > 0) then { _select_last_element = (_array select (count _array-1)); }; ?? But doesn't that also remove the last element from the array? Or is it just selected this way? Thank you, :) EDIT: Nevermind, this would indeed move the last selected element i.e. to another one, if there was another array in front of it, like "... array1 + (array2 select (count array2 -1));" Thx. :) 1 Share this post Link to post Share on other sites
serena 150 Posted March 19, 2017 3 hours ago, Godis_1 said: Well, then it must be: // last element if array contains something, otherwise nothing: private _last = if (count _array < 1) then {nil} else {_array select (count _array - 1)}; // if you want to get default value when array empty - just replace nil constant: private _last = if (count _array < 1) then {"This is default value - array is empty"} else {_array select (count _array - 1)}; Another way is to use the param command: private _last = _array param [count _array - 1]; private _last = _array param [count _array - 1, "Default value - when array empty"]; 1 Share this post Link to post Share on other sites
killzone_kid 1326 Posted March 19, 2017 nvm didn't read the reply to the end Share this post Link to post Share on other sites
Godis_1 63 Posted March 19, 2017 32 minutes ago, killzone_kid said: nvm didn't read the reply to the end mine? No, I've edited it just after posting.. :) Share this post Link to post Share on other sites
Godis_1 63 Posted March 19, 2017 1 hour ago, serena said: // last element if array contains something, otherwise nothing: private _last = if (count _array < 1) then {nil} else {_array select (count _array - 1)}; // if you want to get default value when array empty - just replace nil constant: private _last = if (count _array < 1) then {"This is default value - array is empty"} else {_array select (count _array - 1)}; Another way is to use the param command: private _last = _array param [count _array - 1]; private _last = _array param [count _array - 1, "Default value - when array empty"]; // So it doesn't need an extra check (i.e. "If () then {];" condition) to verfify if the array is emtpy? // How would that be used to keep it emtpy in case nothing was stored inside? // Does it work with: private _last = _array param [count _array - 1, []]; // or: private _last = _array param [count _array - 1, ""]; ? Thank you. Due to code otpimization "param" could be the faster one, cause it doesn't nee a check if array is empty..Just thinking.. Share this post Link to post Share on other sites
serena 150 Posted March 19, 2017 26 minutes ago, Godis_1 said: So it doesn't need an extra check to verify if the array is empty? Yes 26 minutes ago, Godis_1 said: How would that be used to keep it empty in case nothing was stored inside? private _last = _array param [count _array - 1]; Note, if array is empty you got nil value attempt to use which will cause an error. So, if you not sure array is not empty then use syntax with default value or check result before use: if (not isNil "_last") then { // code here executed only if _last variable contains value (array not empty) }; 1 Share this post Link to post Share on other sites
Godis_1 63 Posted March 19, 2017 Maybe a totally dumb question, but I'm curious about if there's any difference between: "this" and "_this" ? In Jquery "this" is a selector (and in sqf it's that too, or called "magic variable".), and "_this" is a normal variable. Is it the same for SQF? Share this post Link to post Share on other sites
killzone_kid 1326 Posted March 19, 2017 When in doubt always consult with BIKI... https://community.bistudio.com/wiki/this Share this post Link to post Share on other sites
Godis_1 63 Posted March 19, 2017 11 minutes ago, killzone_kid said: When in doubt always consult with BIKI... https://community.bistudio.com/wiki/this Hey, thank you. :) I always do - but googling "Arma 3 sqf this" didn't bring me there lol... I should have tried it by "alt+e" in Sublime Text, lol. Thx :) Share this post Link to post Share on other sites
Godis_1 63 Posted March 19, 2017 BTW: You debug_console extension is a great one!! Share this post Link to post Share on other sites