Crazy_Man 36 Posted November 20, 2020 Hi all, I'm interested in a script that would detect AI units that get stuck for a while and are not in combat. If you have good ideas on the subject, don't hesitate to post them. I am creating a mission where, once a city is taken, reinforcements are spawned at random and secure positions and must reach the city. So I don't want to be bothered by vehicles stuck on the way slowing the reinforcements, I prefer to delete them if they are not in combat. for the moment, I've this: if (!isServer) exitWith {}; timeIdle = 60*10; // 10 minutes //timeIdle = 30; // TEST !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! mission_fnc_idle = { params ["_gr"]; //{_x disableAI "PATH"} forEach units _gr; // TEST !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! _distToDelete = 5; // Get all group's vehicle(s) _vehs = [_gr, true] call BIS_fnc_groupVehicles; // initialize vars {if (alive _x) then {_x setVariable ["idlePos", position _x]}} forEach units _gr; _timeOut = time + timeIdle; // MAIN LOOP while {{alive _x} count units _gr > 0} do { sleep 5; if (isNil "_gr" or {{alive _x} count units _gr < 1}) exitWith {}; // CHECK IDLE UNITS if ({alive _x} count units _gr > 0 and _timeOut < time) then { _units = []; _unitsToDelete = []; _vehsToDelete = []; // get all units near their idle position {if (alive _x and _x distance (_x getVariable "idlePos") < _distToDelete) then {_units pushBackUnique _x}} forEach units _gr; { // if unit in vehicle if (vehicle _x != _x) then { _veh = vehicle _x; if (!((crew _veh) call mission_fnc_isEngaging)) then { {_unitsToDelete pushBackUnique _x} forEach crew _veh; _vehsToDelete = _vehsToDelete + [_veh]; }; }; // if unit not in vehicle if (vehicle _x == _x and !(_x call mission_fnc_isEngaging)) then { _unitsToDelete pushBackUnique _x; }; } forEach _units; // delete idle units and vehicles {deleteVehicle _x} forEach _unitsToDelete + _vehsToDelete; // reset vars {if (alive _x) then {_x setVariable ["idlePos", position _x]}} forEach units _gr; _timeOut = time + timeIdle; }; }; }; // Thanks to rübe mission_fnc_isEngaging = { /* Author: rübe Description: returns true if anybody of the given unit(s)/group is engaging Parameter(s): _this: unit(s)/group (unit, array of units or group) Returns: boolean */ private ["_units", "_engaging"]; _units = []; _engaging = false; switch (true) do { case ((typeName _this) == "ARRAY"): { _units = _this; }; case ((typeName _this) == "GROUP"): { _units = units _this; }; default { _units = [_this]; }; }; { if ((currentCommand _x) in ["ATTACK", "ATTACKFIRE", "FIRE"]) exitWith { _engaging = true; }; } forEach _units; // return status _engaging }; Share this post Link to post Share on other sites
Smart Games 76 Posted November 20, 2020 Round 1) Safe every unit and it's position in an array. Round 2) Get the positions again and compare array 1 with array 2, if the position are within a small range, delete the unit 1 Share this post Link to post Share on other sites
pierremgi 4850 Posted November 20, 2020 Hi @Crazy_Man That's a very good topic! I'm on it before releasing a (possible) advanced waypoint for searching in houses (within a radius). Difficult! That's lead for this comments: - spawning vehicles or units in safe place is not too difficult. There are BI functions: bis_fnc_findSafePos BIS_fnc_CPFindEmptyPosition (coming from Combat Patrol) or commands : findEmptyPosition selectBestPlaces (isFlatEmpty ) That's for placement.. - moving vehicles or units. Here come the paths and the ability for AIs to find them, follow them. There is a new tool, but not achieved imho, with an EN "calculatedPath" and the command calculatePath In an ideal world, this tool should say at once if a path from A to B is existing (returning something different than an empty array or nothing!). In real arma world, the tool is bugged (EH runs twice and the returned path is quickly overridden by a useless array - see problem in BIKI). My own workaround: isNil { _agent = calculatePath ["man", "aware", Position1, Position2] addEventHandler ["PathCalculated", { params ["_agent","_path"]; if (isNil {_agent getVariable "passed"}) then { _agent setVariable ["passed",true]; pathArray = _path } } ]; }; You just can say: if no calculated path, no move. Spoiler But a returned path don't guarantee that the vehicle will follow it. It's easy to check that with a calculation for "wheeled_APC" and a true "B_APC_Wheeled_01_cannon_F" in Stratis - Agia Marina city. There are probably some re-calculation when the vehicle detects an obstacle (like house in curve) So, When a unit/vehicle is stuck? You can check unit readiness; unitReady returning TRUE is not "really" stuck. Unit is "probably" ready for a new move. But sometimes a stuck unit becomes ready after a delay (especially when there is no possible path). That depends also on the animation state. For example a unit can be indefinitely stuck trying to climb a ladder without success (Tanoa example: Land_Shop_City_07_f) Spoiler Imho, There is a lack of command for setting a unit to be ready, something like setUnitReady which cancel the current move/waypoint if no path/no success for current destination. The behavior of the unit is also important! If you start to delete all units finding a cover to fire, while there are underway for a destination, you will not keep too much fighting units! So, your topic is huge. For me, it's WIP for a while! 1 1 Share this post Link to post Share on other sites
jandrews 116 Posted November 21, 2020 Good topic. I know mission makers have always struggled with units and vehicles that get stuck. That boat driver who drives up on the sandbar and doesn't move, The mrap driver who rides up on a rock and can't figure it out..... Ugh Share this post Link to post Share on other sites
Crazy_Man 36 Posted November 21, 2020 Ok so I've done some tests with the EH "PathCalculated" but for now it doesn't seems to help. It can detect whether or not the vehicle can reach the desired position (water for a vehicle that is not amphibious for example). But even if the vehicle is on its back and can therefore no longer move, it will still find a path. With the player placed in the desired vehicle and a logic game named "logictest" (for the position to reach) : Water on the way without an amphibious land vehicle : return false No water on the way and same vehicle but on its back : return true KK_fnc_setPosAGLS = { params ["_obj", "_pos", "_offset"]; _offset = _pos select 2; if (isNil "_offset") then {_offset = 0}; _pos set [2, worldSize]; _obj setPosASL _pos; _pos set [2, vectorMagnitude (_pos vectorDiff getPosVisual _obj) + _offset]; _obj setPosASL _pos; }; mission_fnc_calculatedPath = { params ["_veh", "_destPos"]; _agent = createAgent [typeOf (crew _veh select 0), [0,0,10000], [], 100, "CAN_COLLIDE"]; //_vehAgent = createVehicle [(typeOf _veh), [0,0,10000], [], 100, "CAN_COLLIDE"]; _vehAgent = createVehicle [(typeOf _veh), position _veh, [], 0, "NONE"]; _agent moveInDriver _vehAgent; //_vehAgent hideObjectGlobal true; //sleep 0.5; //[_vehAgent, position _veh] call KK_fnc_setPosAGLS; _vehAgent setVectorDirAndUp [vectorDir _veh, vectorUp _veh]; sleep 0.5; _agent addEventHandler ["PathCalculated", { params ["_agent","_path"]; if (isNil {_agent getVariable "passed"}) then { _agent setVariable ["passed", true]; { _marker = createMarker ["marker" + str _forEachIndex, _x]; _marker setMarkerType "mil_dot"; _marker setMarkerText str _forEachIndex; } forEach _path; } } ]; _agent setDestination [_destPos, "LEADER PLANNED", false]; _timeOut = time + 5; waitUntil {_agent getVariable ["passed", false] or _timeOut <= time}; systemChat str (_agent getVariable ["passed", false]); //deleteVehicle _agent; //deleteVehicle _vehAgent; }; [vehicle player, position logictest] spawn mission_fnc_calculatedPath; Share this post Link to post Share on other sites