redarmy 422 Posted October 6, 2023 I came up with an idea for a scenario that is quite simple: If Player has radio in assigned items,then he is able to activate a radio trigger,and the nearest West / friendly side AI should join his group. So condition looks like so: Radio trigger Alpha: Condition: "ItemRadio" in assignedItems player (the next part is tricky,i know multiple way to make AI join a player group however iv no idea how to go about finding the nearest friendly unit distance wise on map,and having that AI join,as that AI will be dynamically spawned and wont have a variable name) On activation should resemble something like this : {side _x == <friendly side>} count nearestObjects join player; Obviosly the above on activation isnt correct. Iv tried a few different things but i am unable to get it to work Share this post Link to post Share on other sites
mrcurry 496 Posted October 6, 2023 10 hours ago, redarmy said: the nearest West / friendly side AI should join his group. The naive solution would be to just iterate over units BLUFOR and compare distances. To save on perf we can use distanceSqr to compare. Assuming the code runs rarely ( as in not several times per frame ) this should be fine even with a lot of units: private _nearest = objNull; private _minDistance = 1e39; // infinity { if ( !isPlayer _x ) then { private _d = _x distanceSqr player; if( _d < _minDistance ) then { _nearest = _x; _minDistance = _d; }; }; } forEach units BLUFOR; // _nearest now contains the closest blufor AI [_nearest] joinSilent group player; 1 Share this post Link to post Share on other sites
redarmy 422 Posted October 6, 2023 3 minutes ago, mrcurry said: The naive solution would be to just iterate over units BLUFOR and compare distances. To save on perf we can use distanceSqr to compare. Assuming the code runs rarely ( as in not several times per second ) this should be fine even with a lot of units: private _nearest = objNull; private _minDistance = 1e39; // infinity { if ( !isPlayer _x ) then { private _d = _x distanceSqr player; if( _d < _minDistance ) then { _nearest = _x; _minDistance = _d; }; }; } forEach units BLUFOR; // _nearest now contains the closest blufor AI [_neatest] joinSilent group player; Thank you. theres a typo in nearest last line. I actually want to make it as simple as is possible. im going to forget about "nearest",and instead complicate condition. How can i edit this to include any blufor on the map? allunits join player; Iv tried various iterations of "allunits side==west" etc and jus am met with syntax errors Share this post Link to post Share on other sites
mrcurry 496 Posted October 6, 2023 5 minutes ago, redarmy said: tried various iterations of "allunits side==west" etc and jus am met with syntax errors units side select { !isPlayer _x } joinSilent group player Share this post Link to post Share on other sites
redarmy 422 Posted October 6, 2023 22 minutes ago, mrcurry said: units side select { !isPlayer _x } joinSilent group player what is "units side select"? iv never seen this before. you mean replace this with what? as is written i just get errors and changing unit side select to allunits gives errors. Im simply trying to change "allunits join player;" to something that replaces allunits with all west units. But every variation i try produces errors in syntax another example of what m trying without success { if ((side _x) == West) then { joinSilent player }; } forEach allUnits; Share this post Link to post Share on other sites
mrcurry 496 Posted October 6, 2023 21 minutes ago, redarmy said: what is "units side select"? iv never seen this before. you mean replace this with what? as is written i just get errors and changing unit side select to allunits gives errors. Replace side with BLUFOR or whichever given side you wish to get units for. 1 Share this post Link to post Share on other sites
redarmy 422 Posted October 6, 2023 3 minutes ago, mrcurry said: Replace side with BLUFOR or whichever given side you wish to get units for. Ah ok i understand that now. cheers Share this post Link to post Share on other sites
fn_Quiksilver 1636 Posted October 8, 2023 On 10/6/2023 at 3:52 PM, redarmy said: I came up with an idea for a scenario that is quite simple: If Player has radio in assigned items,then he is able to activate a radio trigger,and the nearest West / friendly side AI should join his group. So condition looks like so: Radio trigger Alpha: Condition: "ItemRadio" in assignedItems player (the next part is tricky,i know multiple way to make AI join a player group however iv no idea how to go about finding the nearest friendly unit distance wise on map,and having that AI join,as that AI will be dynamically spawned and wont have a variable name) On activation should resemble something like this : {side _x == <friendly side>} count nearestObjects join player; Obviosly the above on activation isnt correct. Iv tried a few different things but i am unable to get it to work Alternative to "ItemRadio" in (assignedItems player) is (player getSlotItemName 611) isNotEqualTo "" which is mod-friendly for non-vanilla radio items 1 Share this post Link to post Share on other sites
redarmy 422 Posted October 8, 2023 4 hours ago, fn_Quiksilver said: Alternative to "ItemRadio" in (assignedItems player) is (player getSlotItemName 611) isNotEqualTo "" which is mod-friendly for non-vanilla radio items Interesting. Can you elaborate? "gearslot" itemname(custom class name?) 611(whats this reference?) Essentially are you saying there are gear slots for NVG's,compass,map etc etc and i can detect them as there or not,modded or vanilla more easily? Share this post Link to post Share on other sites
pierremgi 4851 Posted October 8, 2023 You could test something like that: - addAction on player instead of radio A (so there is no addAction if no radio!) - the addAction opens map (you need a map also in this case) while the map is opened, you can click on unit icons (markers) of your side (only), not already in your group. So You can CHOOSE unit type along with its distance. if you close the map the action is closed but you can recall it (don't forget to recall if you want to continue recruiting). The code is: MGI_activeMap = FALSE; MGI_potRecruits = []; private _EHMap = addMissionEventHandler ["MapSingleClick", { params ["_units", "_pos", "_alt", "_shift"]; if MGI_activeMap then { { _x params ["_unit","_uPos"]; if (_pos distance2D _uPos < 10) exitWith { if !(_unit in units player or isPlayer _unit) then { [_unit] join player; }; deleteMarkerLocal name _unit; }; } forEach MGI_potRecruits; }; }]; player addAction ["recruit",{ params ["_tgt","_caller","_id","_parms"]; openMap [TRUE,FALSE]; MGI_potRecruits = units playerSide - units player; private _mkrs = []; private "_dot"; { _dot = createMarkerLocal [name _x, getPos _x]; _dot setMarkerTypeLocal "mil_dot"; _dot setMarkerColorLocal format ["color%1", str playerSide]; _dot setMarkerTextLocal typeof _x; _mkrs pushBack _dot; } forEach MGI_potRecruits; MGI_potRecruits = MGI_potRecruits apply {[_x, getPos _x]}; while {sleep 0.5; visibleMap} do {MGI_activeMap = TRUE}; MGI_activeMap = FALSE; MGI_potRecruits = []; {deleteMarkerLocal _x} count _mkrs; },nil,1.5,true,true,"", "(_this getSlotItemName 611) isNotEqualTo ''" ]; Share this post Link to post Share on other sites
redarmy 422 Posted October 8, 2023 3 hours ago, pierremgi said: You could test something like that: - addAction on player instead of radio A (so there is no addAction if no radio!) - the addAction opens map (you need a map also in this case) while the map is opened, you can click on unit icons (markers) of your side (only), not already in your group. So You can CHOOSE unit type along with its distance. if you close the map the action is closed but you can recall it (don't forget to recall if you want to continue recruiting). The code is: MGI_activeMap = FALSE; MGI_potRecruits = []; private _EHMap = addMissionEventHandler ["MapSingleClick", { params ["_units", "_pos", "_alt", "_shift"]; if MGI_activeMap then { { _x params ["_unit","_uPos"]; if (_pos distance2D _uPos < 10) exitWith { if !(_unit in units player or isPlayer _unit) then { [_unit] join player; }; deleteMarkerLocal name _unit; }; } forEach MGI_potRecruits; }; }]; player addAction ["recruit",{ params ["_tgt","_caller","_id","_parms"]; openMap [TRUE,FALSE]; MGI_potRecruits = units playerSide - units player; private _mkrs = []; private "_dot"; { _dot = createMarkerLocal [name _x, getPos _x]; _dot setMarkerTypeLocal "mil_dot"; _dot setMarkerColorLocal format ["color%1", str playerSide]; _dot setMarkerTextLocal typeof _x; _mkrs pushBack _dot; } forEach MGI_potRecruits; MGI_potRecruits = MGI_potRecruits apply {[_x, getPos _x]}; while {sleep 0.5; visibleMap} do {MGI_activeMap = TRUE}; MGI_activeMap = FALSE; MGI_potRecruits = []; {deleteMarkerLocal _x} count _mkrs; },nil,1.5,true,true,"", "(_this getSlotItemName 611) isNotEqualTo ''" ]; This is actually very cool indeed. Originally i was just looking to quickly recruit one blufor anywhere on map as only one or two get created at a time,however iv modified things and this will be pretty cool,gona try it out. Cheers man! Share this post Link to post Share on other sites
fn_Quiksilver 1636 Posted October 11, 2023 On 10/8/2023 at 2:46 PM, redarmy said: Interesting. Can you elaborate? "gearslot" itemname(custom class name?) 611(whats this reference?) Essentially are you saying there are gear slots for NVG's,compass,map etc etc and i can detect them as there or not,modded or vanilla more easily? https://community.bistudio.com/wiki/getSlotItemName There are hardcoded slot numbers 603 - Goggles 605 - Headgear 608 - Map 609 - Compass 610 - Watch 611 - Radio 612 - GPS 616 - HMD 617 - Binoculars 701 - Vest 801 - Uniform 901 - Backpack So if you are trying to determine if the player has a radio (vanilla or modded), you just do (player getSlotItemName 611) isNotEqualTo "" // the player has a radio of some sort since it will return "" if there is nothing in the radio slot Share this post Link to post Share on other sites
redarmy 422 Posted October 11, 2023 2 hours ago, fn_Quiksilver said: https://community.bistudio.com/wiki/getSlotItemName There are hardcoded slot numbers 603 - Goggles 605 - Headgear 608 - Map 609 - Compass 610 - Watch 611 - Radio 612 - GPS 616 - HMD 617 - Binoculars 701 - Vest 801 - Uniform 901 - Backpack So if you are trying to determine if the player has a radio (vanilla or modded), you just do (player getSlotItemName 611) isNotEqualTo "" // the player has a radio of some sort since it will return "" if there is nothing in the radio slot I had no idea about the slot numbers,thats useful. Actually i was trying to replicate the DAYZ mechanic,where when shot in say the backpack,items in there can get ruined. Since arma3 has no item state,i would just remove a random item. Could i use that syntax above to make a randm array of sorts,that if player took damage,to randomly remove one of those slot numbers,and if slot number was 901, 801,or701,to then choose a random item from backpack/vest/uniform and remove it? Im sure theres probably an easier way just wondering. As an example i currently use this to randomly remove vest with a 10% chance if hit in "pelvis" player addEventHandler ["HitPart", { (_this select 0) params ["_unit", "_shooter", "_bullet", "_pos", "_vel", "_hitLoc"]; if ((vest _unit) != "") then { { if (_x == "pelvis" && 10 > random 100) then { removeVest _unit; }; } forEach _hitLoc; }; Share this post Link to post Share on other sites