Blitzen88 18 Posted October 19, 2021 Good morning, I’m having some trouble figuring out how to delete “extra” units after an array has been resized. Here is what I got if (count _SquadUnits > count _TrenchPos) then { _SquadUnits resize (count _TrenchPos) }; //Delete "Extra" Units _SquadUnitsToDelete = _TrenchGroup - _SquadUnits; {deletevehicle _x } foreach _SquadUnitsToDelete; Basically, I want to delete “extra” units so that the number of SquadUnits is equal to the number of Trenchpos. Share this post Link to post Share on other sites
Ibragim A 161 Posted October 19, 2021 Good evening. It would be nice to look at the contents of both arrays in the example, then it will be possible to understand whether you are trying to act correctly. 1 Share this post Link to post Share on other sites
Blitzen88 18 Posted October 19, 2021 28 minutes ago, Ibragim A said: Good evening. It would be nice to look at the contents of both arrays in the example, then it will be possible to understand whether you are trying to act correctly. /*========================================================================================== Arma III - Trench WIP Created by Blitzen =========================================================================================== * Blah * Parameters: - SquadLeader: Trench group's squadleader - Radius: Search radius for defined object (trench position) * Call with: [This, 200, "Sign_Arrow_Blue_F"] execVM "Scripts\AI\AI_Trench.sqf" ===========================================================================================*/ //Define Input Variables _SquadLeader = _this select 0; _Radius = _this select 1; _TrenchPosObject = _this select 2; //Create Variables that will be used by the script _TrenchUnits = units group _Squadleader; //Get Trench Positions and shuffle the array _TrenchPositions = getpos _SquadLeader nearObjects [_TrenchPosObject, _Radius]; _TrenchPositions = _TrenchPositions call BIS_fnc_arrayShuffle; //If there are more units than positions then resize the units array and delete "extra" units if (count _TrenchUnits > count _TrenchPositions) then { _TrenchUnits = _TrenchUnits resize (count _TrenchPositions); if !(_x in _TrenchUnits) then {deletevehicle _x} foreach units group _Squadleader; }; //Count the squad units for the loop _CountTrenchUnits = count _TrenchUnits; //Start Loop while {_CountTrenchUnits > 0} do { //Select the Unit _Unit = _TrenchUnits select 0; //Remove the selected unit from the array _TrenchUnits = _TrenchUnits - [_Unit]; //Select the Trench object _SelectedTrenchPosition = _TrenchPositions select 0; //Remove the Selected Trench object from the array _TrenchPositions = _TrenchPositions - [_SelectedTrenchPosition]; //Get the Object's position - thats what we really want _SavedTrenchPosition = getpos _SelectedTrenchPosition; //Delete the object since we have the object's position saved deletevehicle _SelectedTrenchPosition; _unit setpos _SavedTrenchPosition; _unit disableAI "Path"; _unit setUnitPos "Up"; sleep 1; //Reduce the SquadUnits Count by 1 _CountSquadUnit = _CountSquadUnit - 1; //End Loop }; //Delete Remaining positions if (count _TrenchPositions > 0) then { {deletevehicle _x} foreach _TrenchPositions; }; Share this post Link to post Share on other sites
Ibragim A 161 Posted October 19, 2021 1 hour ago, Blitzen88 said: _TrenchUnits = _TrenchUnits resize (count _TrenchPositions); The resize command does not return a value, so this line contains an error. Rewrite it like this: _TrenchUnits resize (count _TrenchPositions); 2 Share this post Link to post Share on other sites
Blitzen88 18 Posted October 19, 2021 3 minutes ago, Ibragim A said: The resize command does not return a value, so this line contains an error. Rewrite it like this: _TrenchUnits resize (count _TrenchPositions); Will do. Does my deletion of extra units work? Share this post Link to post Share on other sites
Ibragim A 161 Posted October 19, 2021 I only looked at the part of the code you asked the question for and did not see any other errors in it. Share this post Link to post Share on other sites
opusfmspol 279 Posted October 19, 2021 Variables containing arrays are a reference to an array. That means when an array gets changed (i.e., resized), all the variables that refer to that array will also see and reflect that change. _units = units group leader; // Gets the (units group) array. _unitsToDelete = _units; // Both _units and _unitsToDelete now refer to the same array. _units resize 3; // Both _units and _unitsToDelete change (they refer to the same array). _unitsToDelete = _unitsToDelete - _units; //Both _units and _unitsToDelete become empty; they're the same array. To prevent a change in one variable from affecting other variables through array reference, you make a copy of the array. _units = +(units group _leader); // Makes a separate copy of the (units group) array. _unitsToDelete = +_units; // Makes a separate copy of the _units array. _units resize 3; // Doesn't effect the _unitsToDelete array by reference. _unitsToDelete = _unitsToDelete - _units; // Doesn't effect the _units array by reference. 3 1 Share this post Link to post Share on other sites
pierremgi 4832 Posted October 19, 2021 You can use also deleteAt command private _units = units group _squadLeader; private _trenchPositions = getpos _SquadLeader nearObjects [_TrenchPosObject, _Radius]; // I can't check that private _trenchPositions = _trenchPositions call BIS_fnc_arrayShuffle; // no need to shuffle each time { if (count _trenchPositions >0) then { _pos = getpos (_trenchPositions deleteAt 0); _x setpos _pos; } else { deleteVehicle _x; } } forEach _units 3 Share this post Link to post Share on other sites
ZaellixA 383 Posted October 20, 2021 Hey there @pierremgi. Nice piece of code there but I have a question... I don't really get the _x setPos getPos _pos; line. Isn't _pos already a position? If yes, why should you use getPos again? If not, then what does it contain (since in the previous line you initialise _pos with the result of a getPos command)? This part got me kinda confused... Could you please clarify that? Thanks in advance :). 1 Share this post Link to post Share on other sites
pierremgi 4832 Posted October 20, 2021 _trenchPositions are objects extracted by nearObjects. I copied the Blitzen88's code, confused with this name, which is probably a test one with arrows. Anyway, you're right getPos is for objects and _pos is already a position.. Corrected. 2 Share this post Link to post Share on other sites
ZaellixA 383 Posted October 21, 2021 Well, I guess that a combination of opusfmspol's and pierremgi's suggestions make a quite nice solution to your problem at hand. It could look something like // Your code private _trenchUnits = units group _Squadleader; // Pierremgi's code private _units = units group leader; private _trenchPositions = getpos _SquadLeader nearObjects [_TrenchPosObject, _Radius]; private _trenchPositions = _trenchPositions call BIS_fnc_arrayShuffle; // Pierremgi's code adapted based on opusfmspol's code { deleteVehicle _x; } forEach (_trenchUnits - ((+_trenchUnits) resize _trenchPositions)); Not sure this is a good or bad solution but, at least to me, it looks like a quite compact one. It's up to you to decide whether it is OK for you or not and of course the rest of the contributors might have something to add or suggest. 1 Share this post Link to post Share on other sites
killzone_kid 1329 Posted October 22, 2021 On 10/19/2021 at 3:18 PM, Blitzen88 said: Good morning, I’m having some trouble figuring out how to delete “extra” units after an array has been resized. Like this: _arr = [objNull, objNull, objNull, objNull, objNull]; _maxUnits = 3; while { count _arr > _maxUnits } do { deleteVehicle (_arr deleteAt (count arr - 1)); }; _arr 3 Share this post Link to post Share on other sites
Blitzen88 18 Posted October 23, 2021 This is what I came up with....seems to work for me: /*========================================================================================== Arma III - Trench Created by Blitzen =========================================================================================== * Defines "positions" by capturing user placed objects * Can be used to define defensive positions in a trench/FOB style of fortification * Script is necessary for units that respawn and need to occupy the same position * Script will delete "unused" units and will hide unused trench positions * Parameters: - SquadLeader: Trench group's squadleader - Radius: Search radius for defined object (trench position) - Object: Object that is used to identify a trench position (highly recommend the "helper signs (ie arrows) since they dont have collision * Call with: [This, 200, "Sign_Arrow_Blue_F"] execVM "Scripts\AI\AI_Trench.sqf" ===========================================================================================*/ //Define Input Variables _SquadLeader = _this select 0; _Radius = _this select 1; _TrenchPosObject = _this select 2; //Create Variables that will be used by the script _TrenchUnits = units group _Squadleader; //Get Trench Positions and shuffle the array _TrenchPositions = getpos _SquadLeader nearObjects [_TrenchPosObject, _Radius]; _TrenchPositions = _TrenchPositions call BIS_fnc_arrayShuffle; {hideObject _x} foreach _TrenchPositions; {_x allowDamage false} foreach _TrenchPositions; if ((Count _TrenchPositions) == 0) exitWith {Player groupChat "Trench Script - No Trench Positions Detected;"}; //Count the Trench units for the loop _CountTrenchPositions = count _TrenchPositions; //Go ahead and disable movement and set unit positions {_x disableai "path"} foreach _TrenchUnits; {_x setUnitPos "Up"} foreach _TrenchUnits; //Start Loop _Go = True; while {_Go} do { if ((count _TrenchUnits) == 0) exitWith {_Go = False}; if ((count _TrenchPositions) == 0) exitWith {_Go = False}; //Select the Unit _Unit = _TrenchUnits select 0; //Remove the selected unit from the array _TrenchUnits = _TrenchUnits - [_Unit]; //Select the Trench object _SelectedTrenchPosition = _TrenchPositions select 0; //Remove the Selected Trench object from the array _TrenchPositions = _TrenchPositions - [_SelectedTrenchPosition]; //Get the Object's position - thats what we really want _SavedTrenchPosition = getpos _SelectedTrenchPosition; _unit setpos _SavedTrenchPosition; sleep 1; //Reduce the SquadUnits Count by 1 _CountTrenchPositions = _CountTrenchPositions - 1; //End Loop }; if (count _TrenchUnits > 0) then { {deletevehicle _x} foreach _TrenchUnits; }; 1 Share this post Link to post Share on other sites
pierremgi 4832 Posted October 24, 2021 As said above, you can use deleteAt command. It's useless allowing damage false for arrows! Your loop seems to me convoluted. Exact same result: params ["_SquadLeader","_Radius","_TrenchPosObject"]; private _trenchUnits = units group _Squadleader; private _trenchPositions = getpos _SquadLeader nearObjects [_TrenchPosObject, _Radius]; private _trenchPositions = _trenchPositions call BIS_fnc_arrayShuffle; {_x hideObject TRUE} count _TrenchPositions; { if (count _trenchPositions >0) then { _pos = getpos (_trenchPositions deleteAt 0); _x setpos _pos; _x disableai "path"; _x setUnitPos "Up" } else { deleteVehicle _x; } } forEach _trenchUnits; 2 Share this post Link to post Share on other sites
Blitzen88 18 Posted October 25, 2021 On 10/24/2021 at 9:00 AM, pierremgi said: As said above, you can use deleteAt command. It's useless allowing damage false for arrows! Your loop seems to me convoluted. Exact same result: Im just not that good at scripting and I try to stick to what I know. I will check out your script and will check out deleteat. thank you! 1 Share this post Link to post Share on other sites