From 194c089cf9eef30935ecea197c487ebc01f81549 Mon Sep 17 00:00:00 2001 From: SilentSpike Date: Sat, 16 Jul 2016 15:55:30 +0100 Subject: [PATCH 1/3] Fix building search loop in taskSearchArea If a building search was enacted, the waypoint would be locked by the searchNearby function before it is actually considered completed. This would result in AI repeatedly going back to the same waypoint and triggering the onCompletion statement causing another building search. --- addons/ai/fnc_taskSearchArea.sqf | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/addons/ai/fnc_taskSearchArea.sqf b/addons/ai/fnc_taskSearchArea.sqf index 3d9de23dc..0bbd8cdf7 100644 --- a/addons/ai/fnc_taskSearchArea.sqf +++ b/addons/ai/fnc_taskSearchArea.sqf @@ -64,16 +64,21 @@ private _pos = [_area] call CBA_fnc_randPosArea; if ((_pos isEqualTo []) || {_area isEqualTo ""} || {isNull _group}) exitWith {}; // Prepare recursive function call statement -private _statement = "[this] call CBA_fnc_taskSearchArea;"; +private _statements = ["[this] call CBA_fnc_taskSearchArea"]; // Prepare building search statement private _building = nearestBuilding _pos; if ((_building distanceSqr _pos) < 400) then { - _statement = _statement + "[this] call CBA_fnc_searchNearby;"; + // Clear waypoint to prevent getting stuck in a search loop + _statements append [ + "deleteWaypoint [group this, currentWaypoint (group this)]", + "[group this] call CBA_fnc_searchNearby" + ]; }; // Inject the statement in this order to ensure valid syntax -_onComplete = _statement + _onComplete; +_statements pushBack _onComplete; +_onComplete = _statements joinString ";"; // Add the waypoint [ From 4e038bbb22f8cae68e1790230822238529ee202f Mon Sep 17 00:00:00 2001 From: SilentSpike Date: Sat, 16 Jul 2016 16:00:06 +0100 Subject: [PATCH 2/3] Fix resetting of building positions in taskDefend The array of building positions stored by the function would be set to `nil` then subsequently set to an empty array in the event of all positions being used up. This would result in the building never being used again by future calls to the function. --- addons/ai/fnc_taskDefend.sqf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/addons/ai/fnc_taskDefend.sqf b/addons/ai/fnc_taskDefend.sqf index f8446227d..90847c105 100644 --- a/addons/ai/fnc_taskDefend.sqf +++ b/addons/ai/fnc_taskDefend.sqf @@ -79,8 +79,9 @@ private _assigned = 0; if (_array isEqualTo []) then { _buildings = _buildings - [_building]; _building setVariable ["CBA_taskDefend_positions",nil]; + } else { + _building setVariable ["CBA_taskDefend_positions",_array]; }; - _building setVariable ["CBA_taskDefend_positions",_array]; // AI manipulation trickey to keep them in position until commanded to move [_x, _pos] spawn { From 6d7906b494de8675ad5da0d5544d0f1da66aea31 Mon Sep 17 00:00:00 2001 From: SilentSpike Date: Sat, 16 Jul 2016 16:11:57 +0100 Subject: [PATCH 3/3] Improve behaviour of AI function taskDefend - Minor optimization - Using the new `disableAI "PATH"` simplifies the code and allows it to be easily reverted unlike `doStop` - If patrol is enabled then units should patrol regardless of how many are assigned, otherwise they end up standing around - Units in position are told to stay upright for better use of windows and more engaging combat - No longer need to `enableAttack false` since no longer using `doStop` - which allows unassigned units to counterattack in case of contact --- addons/ai/fnc_taskDefend.sqf | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/addons/ai/fnc_taskDefend.sqf b/addons/ai/fnc_taskDefend.sqf index 90847c105..f5e3d4501 100644 --- a/addons/ai/fnc_taskDefend.sqf +++ b/addons/ai/fnc_taskDefend.sqf @@ -38,13 +38,12 @@ _position = [_position,_group] select (_position isEqualTo []); _position = _position call CBA_fnc_getPos; [_group] call CBA_fnc_clearWaypoints; -_group enableAttack false; private _statics = _position nearObjects ["StaticWeapon", _radius]; private _buildings = _position nearObjects ["Building", _radius]; // Filter out occupied statics -[_statics,{(_x emptyPositions "Gunner") > 0},true] call CBA_fnc_filter; +_statics = _statics select {(_x emptyPositions "Gunner") > 0}; // Filter out buildings below the size threshold (and store positions for later use) _buildings = _buildings select { @@ -57,15 +56,17 @@ _buildings = _buildings select { count (_positions) > _threshold }; +// If patrolling is enabled then the leader must be free to lead it private _units = units _group; -private _assigned = 0; +if (_patrol && {count _units > 1}) then { + _units deleteAt (_units find (leader _group)); +}; + { // 31% chance to occupy nearest free static weapon if ((random 1 < 0.31) && { !(_statics isEqualto []) }) then { _x assignAsGunner (_statics deleteAt 0); [_x] orderGetIn true; - - _assigned = _assigned + 1; } else { // 93% chance to occupy a random nearby building position if ((random 1 < 0.93) && { !(_buildings isEqualto []) }) then { @@ -77,13 +78,13 @@ private _assigned = 0; // If building positions are all taken remove from possible buildings if (_array isEqualTo []) then { - _buildings = _buildings - [_building]; + _buildings deleteAt (_buildings find _building); _building setVariable ["CBA_taskDefend_positions",nil]; } else { _building setVariable ["CBA_taskDefend_positions",_array]; }; - // AI manipulation trickey to keep them in position until commanded to move + // Wait until AI is in position then force them to stay [_x, _pos] spawn { params ["_unit","_pos"]; if (surfaceIsWater _pos) exitwith {}; @@ -91,19 +92,15 @@ private _assigned = 0; _unit doMove _pos; sleep 5; waituntil {unitReady _unit}; - _unit disableAI "move"; - doStop _unit; - waituntil {!(unitReady _unit)}; - _unit enableAI "move"; + _unit disableAI "PATH"; + _unit setUnitPos "UP"; }; - - _assigned = _assigned + 1; }; }; }; } forEach _units; -// If half of the group's units aren't assigned then patrol -if (_patrol && {_assigned < (count _units) * 0.5}) then { - [_group, _position, _radius, 5, "sad", "safe", "red", "limited"] call CBA_fnc_taskpatrol; +// Remaining units will patrol if enabled +if (_patrol) then { + [_group, _position, _radius, 5, "sad", "safe", "red", "limited"] call CBA_fnc_taskPatrol; };