I'd like to request a variation of inAreaArray command that returns matching indexes instead of array elements. Non-object entities have to be represented as positions and to determine which non-object entity was matched by the command, you have to resort to hacky approaches like storing indexes as position Z coordinate which creates additional overhead for high-performing scripts, for which inAreaArray command very useful.
Description
Description
Details
Details
- Severity
- Feature
- Resolution
- Fixed
- Reproducibility
- N/A
- Operating System
- Windows 10 x64
- Category
- Scripting
Additional Information
Current inAreaArray output:
[ [0,0,0], [100,0,0], [200,0,0] ] inAreaArrayIndexes [[0,0,0], 150, 150]
>[[0,0,0],[100,0,0]]
Proposed inAreaArrayIndexes output:
[ [0,0,0], [100,0,0], [200,0,0] ] inAreaArrayIndexes [[0,0,0], 150, 150]
>[0,1]
Related Objects
Related Objects
Event Timeline
Comment Actions
rev 150318 https://community.bistudio.com/wiki/inAreaArrayIndexes
Please check every variation thoroughly
Comment Actions
resort to hacky approaches like storing indexes as position Z coordinate
You can just store them as hashmaps now
Comment Actions
Did tests for all possible combination, works properly. Shitty test code:
if(!isNil"markers") then {{deleteMarker _x} forEach markers;}; markers = []; if(!isNil"objects") then {{deleteVehicle _x} forEach objects}; objects = []; if(!isNil"locations") then {{deleteLocation _x} forEach locations}; locations = []; positions = []; if(isNil"testgroups") then {{{deleteVehicle _x} forEach units _x; deleteGroup _x} forEach testgroups}; testgroups = []; private _marker_types = "true" configClasses (configFile >> "CfgMarkers") apply {configName _x}; testalpha = 0.3; for "_i" from 1 to 50 do { for "_j" from 1 to 10 do { private _pos = getPosWorld player vectorAdd [_i * 100, _j * 100, 0]; switch(true) do { case (_i <= 10): { private _m = createMarker [str round random 1e10, _pos]; _m setMarkerShape selectRandom ["RECTANGLE", "ELLIPSE", "ICON", "ICON"]; if(markerShape _m == "ICON") then { _m setMarkerType selectRandom _marker_types; _m setMarkerSize [1, 1]; } else { _m setMarkerSize [50, 50]; }; _m setMarkerDir random 360; _m setMarkerColor "ColorRed"; markers pushBack _m; }; case (_i <= 20): { private _obj = "Logic" createVehicleLocal _pos; objects pushBack _obj; }; case (_i <= 30): { private _loc = createLocation ["o_inf", _pos, 50, 50]; locations pushBack _loc; }; case (_i <= 40): { positions pushBack _pos; }; case (_i <= 50): { private _group = createGroup blufor; _group createUnit ["Logic", _pos, [], 0, "CAN_COLLIDE"]; testgroups pushBack _group; }; }; }; }; if(isNil"draweh") then {draweh = findDisplay 12 displayCtrl 51 ctrlAddEventHandler ["Draw", {call mapdraw}];}; if(!isNil"trig") then {deleteVehicle trig}; trig = createTrigger ["EmptyDetector", getPosWorld objNull, false]; if(!isNil"loc") then {deleteLocation loc}; loc = createLocation ["Name", getPosWorld objNull, 0, 0]; if(!isNil"mark") then {deleteMarker mark}; mark = createMarker [str random 1e10, getPosWorld objNull]; mark setMarkerColor "ColorWhite"; mark setMarkerAlpha testalpha; mark setMarkerType selectRandom _marker_types; mark setMarkerBrush "SolidFull"; mapdraw = { params ["_map"]; private _scale = ctrlMapScale _map; private _rev_time = 5; private _rect = (diag_tickTime % (_rev_time * 2) > _rev_time); private _dir = diag_tickTime % _rev_time / _rev_time * 360; private _width = 5000 * _scale; private _height = 2000 * _scale; private _array_check = [_map ctrlMapScreenToWorld getMousePosition, _width, _height, _dir, _rect, -1]; private _ui_offset_y = SafeZOneH / 3; private _ui_offset_x = _ui_offset_y * 3/4; trig setTriggerArea [_width, _height, _dir, _rect, -1]; trig setPos (_map ctrlMapScreenToWorld (getMousePosition vectorAdd [-_ui_offset_x,0])); loc setDirection _dir; loc setRectangular _rect; loc setSize [_width, _height]; loc setPosition (_map ctrlMapScreenToWorld (getMousePosition vectorAdd [_ui_offset_x,0])); mark setMarkerPos (_map ctrlMapScreenToWorld (getMousePosition vectorAdd [0,_ui_offset_y])); mark setMarkerDir _dir; mark setMarkerShape (if(_rect) then { mark setMarkerShape "RECTANGLE"; mark setMarkerSize [_width, _height]; } else { mark setMarkerShape "ELLIPSE"; mark setMarkerSize [_width, _height]; }); private _matched_positions_indexes = []; { private _indexes = (_x inAreaArrayIndexes _array_check) + (_x inAreaArrayIndexes trig) + (_x inAreaArrayIndexes loc) + (_x inAreaArrayIndexes mark); switch(true) do { case(_x isEqualRef markers): { { if(_forEachIndex in _indexes) then { _x setMarkerColor "ColorGreen"; } else { _x setMarkerColor "ColorRed"; }; } forEach markers; }; case(_x isEqualRef positions): { _matched_positions_indexes = _indexes; }; case(_x isEqualRef locations): { { if(_forEachIndex in _indexes) then { _x setType "b_inf"; } else { _x setType "o_inf"; }; } forEach locations; }; default { { _x setVariable ["matched", _forEachIndex in _indexes]; } forEach _x; }; }; } forEach [markers, objects, locations, positions, testgroups]; { _map drawIcon [ getText(configFile >> "CfgVehicles" >> typeOf _x >> "icon") ,if(_x getVariable ["matched", false]) then {[0,1,0,1]} else {[1,0,0,1]} ,getPosWorld _x ,20 ,20 ,getDir _x ,"" ,2 ]; } forEach objects; { _map drawIcon [ "iconExplosiveAT" ,if(_forEachIndex in _matched_positions_indexes) then {[0,1,0,1]} else {[1,0,0,1]} ,_x ,30 ,30 ,0 ,"Pos" ,2 ]; } forEach positions; { _map drawIcon [ "iconExplosiveGP" ,if(_x getVariable ["matched", false]) then {[0,1,0,1]} else {[1,0,0,1]} ,getPosWorld leader _x ,30 ,30 ,0 ,"Grp" ,2 ]; } forEach testgroups; if(_rect) then { _map drawRectangle [_array_check select 0, _width, _height, _dir, [1,1,1,testalpha], "#(rgb,8,8,3)color(1,1,1,1)"]; _map drawRectangle [locationPosition loc, size loc select 0, size loc select 1, direction loc, [1,1,1,testalpha], "#(rgb,8,8,3)color(1,1,1,1)"]; _map drawRectangle [getPosWorld trig, triggerArea trig select 0, triggerArea trig select 1, triggerArea trig select 2, [1,1,1,testalpha], "#(rgb,8,8,3)color(1,1,1,1)"]; } else { _map drawEllipse [_array_check select 0, _width, _height, _dir, [1,1,1,testalpha], "#(rgb,8,8,3)color(1,1,1,1)"]; _map drawEllipse [locationPosition loc, size loc select 0, size loc select 1, direction loc, [1,1,1,testalpha], "#(rgb,8,8,3)color(1,1,1,1)"]; _map drawEllipse [getPosWorld trig, triggerArea trig select 0, triggerArea trig select 1, triggerArea trig select 2, [1,1,1,testalpha], "#(rgb,8,8,3)color(1,1,1,1)"]; }; private _text_offset = [0,1000*_scale,0]; _map drawIcon ["iconExplosiveAT", [1,1,1,1], _array_check select 0 vectorAdd _text_offset, 1e-6, 1e-6, 0, "Array check", 2]; _map drawIcon ["iconExplosiveAT", [1,1,1,1], locationPosition loc vectorAdd _text_offset, 1e-6, 1e-6, 0, "Location check", 2]; _map drawIcon ["iconExplosiveAT", [1,1,1,1], getPosWorld trig vectorAdd _text_offset, 1e-6, 1e-6, 0, "Trigger check", 2]; _map drawIcon ["iconExplosiveAT", [1,1,1,1], markerPos mark vectorAdd _text_offset, 1e-6, 1e-6, 0, "Marker check", 2]; }; 0
Comment Actions
New command is great, but I'd also like to request tweaks to existing commands, here are the tickets:
T171744 - Have inAreaArray and inAreaArrayIndexes take ENTITY as argument like inArea does
T171699 - Have inPolygon take ENTITY as argument
T171524 - inAreaArray variant that takes both list of areas and list of positions to check
Comment Actions
Bug found in inAreaArrayIndexes, it ignores c for height:
private _area = [positionCameraToWorld [0,0,0], 20, 20, 0, true, 20]; [ [player] inAreaArrayIndexes _area ,[player] inAreaArray _area ]