From 6f6b0d15f86ad2435e6edae0ebc5b36739d2b03f Mon Sep 17 00:00:00 2001 From: Josuan Albin Date: Thu, 18 Oct 2018 18:14:26 +0200 Subject: [PATCH] Add curator garrison path drawing, clean up garrison code (#6643) --- addons/ai/CfgEventHandlers.hpp | 6 ++ addons/ai/XEH_PREP.hpp | 1 + addons/ai/XEH_postInit.sqf | 41 +-------- .../fnc_drawCuratorGarrisonPathing.sqf | 54 ++++++++++++ addons/ai/functions/fnc_garrison.sqf | 6 +- addons/ai/functions/fnc_garrisonMove.sqf | 84 ++++++++----------- addons/ai/functions/fnc_unGarrison.sqf | 12 +-- 7 files changed, 102 insertions(+), 102 deletions(-) create mode 100644 addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf diff --git a/addons/ai/CfgEventHandlers.hpp b/addons/ai/CfgEventHandlers.hpp index becf395052..9e715077f3 100644 --- a/addons/ai/CfgEventHandlers.hpp +++ b/addons/ai/CfgEventHandlers.hpp @@ -16,3 +16,9 @@ class Extended_PostInit_EventHandlers { init = QUOTE(call COMPILE_FILE(XEH_postInit)); }; }; + +class Extended_DisplayLoad_EventHandlers { + class RscDisplayCurator { + ADDON = QUOTE(call FUNC(drawCuratorGarrisonPathing)); + }; +}; diff --git a/addons/ai/XEH_PREP.hpp b/addons/ai/XEH_PREP.hpp index d3a61e3012..9596af3286 100644 --- a/addons/ai/XEH_PREP.hpp +++ b/addons/ai/XEH_PREP.hpp @@ -1,3 +1,4 @@ +PREP(drawCuratorGarrisonPathing); PREP(garrison); PREP(unGarrison); PREP(garrisonMove); diff --git a/addons/ai/XEH_postInit.sqf b/addons/ai/XEH_postInit.sqf index 4ce37fd314..901069cff3 100644 --- a/addons/ai/XEH_postInit.sqf +++ b/addons/ai/XEH_postInit.sqf @@ -22,8 +22,8 @@ params ["_unitsArray"]; { _x params ["_unit", "_pos"]; - _unit setDestination [_pos, "LEADER PLANNED", true]; _unit doMove _pos; + _unit setDestination [_pos, "LEADER PLANNED", true]; LOG_3("%1 doMove %2 | ID: %3",_unit,_pos,clientOwner); } forEach _unitsArray; }] call CBA_fnc_addEventHandler; @@ -68,42 +68,3 @@ params ["_unit", "_mode"]; _unit enableGunLights _mode; }] call CBA_fnc_addEventHandler; - -#ifdef DEBUG_MODE_FULL - addMissionEventHandler ["Draw3D", { - private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; - { - _x params ["_unit", "_pos"]; - - switch (true) do { - case (surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : { - for "_i" from 0 to 3 do { - drawLine3D [_unit modelToWorldVisualWorld [0,0,1], (AGLtoASL _pos), [1,0,0,1]]; - }; - drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75]; - }; - - case (!surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : { - for "_i" from 0 to 3 do { - drawLine3D [_unit modelToWorldVisual [0,0,1], _pos, [1,0,0,1]]; - }; - drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75]; - }; - - case (!surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : { - for "_i" from 0 to 3 do { - drawLine3D [_unit modelToWorldVisual [0,0,1], (AGLToASL _pos), [1,0,0,1]]; - }; - drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75]; - }; - - case (surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : { - for "_i" from 0 to 3 do { - drawLine3D [_unit modelToWorldVisualWorld [0,0,1], _pos, [1,0,0,1]]; - }; - drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75]; - }; - }; - } forEach _unitMoveList; - }]; -#endif diff --git a/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf b/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf new file mode 100644 index 0000000000..de9a5b4dc7 --- /dev/null +++ b/addons/ai/functions/fnc_drawCuratorGarrisonPathing.sqf @@ -0,0 +1,54 @@ +#include "script_component.hpp" +/* + * Author: alganthe + * Add draw3D eh to the curator interface. + * + * Arguments: + * None + * + * Return value: + * None + * + * Public: No +*/ + +addMissionEventHandler ["Draw3D", { + if (findDisplay 312 isEqualTo displayNull) exitWith { + removeMissionEventHandler ["Draw3D", _thisEventHandler]; + }; + + private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; + { + _x params ["_unit", "_pos"]; + + switch (true) do { + case (surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisualWorld [0,0,1], (AGLtoASL _pos), [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75]; + }; + + case (!surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisual [0,0,1], _pos, [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75]; + }; + + case (!surfaceIsWater (getPos _unit) && {surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisual [0,0,1], (AGLToASL _pos), [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], (AGLtoASL _pos), 0.75, 0.75, 0.75]; + }; + + case (surfaceIsWater (getPos _unit) && {!surfaceIsWater _pos}) : { + for "_i" from 0 to 3 do { + drawLine3D [_unit modelToWorldVisualWorld [0,0,1], _pos, [1,0,0,1]]; + }; + drawIcon3D ["\a3\ui_f\data\map\groupicons\waypoint.paa", [1,0,0,1], _pos, 0.75, 0.75, 0.75]; + }; + }; + } forEach _unitMoveList; +}]; diff --git a/addons/ai/functions/fnc_garrison.sqf b/addons/ai/functions/fnc_garrison.sqf index 5e5c34d19a..e206ea2589 100644 --- a/addons/ai/functions/fnc_garrison.sqf +++ b/addons/ai/functions/fnc_garrison.sqf @@ -79,11 +79,9 @@ if (_topDownFilling) then { //Remove positions units are already pathing to _buildingsIndex = _buildingsIndex apply { - private _testedBuilding = _x; - - _testedBuilding select { + _x select { private _testedPos = _x; - (({(_x select 1) isEqualTo _testedPos} count (missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []])) == 0) + ({(_x select 1) isEqualTo _testedPos} count (missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []])) == 0 } }; diff --git a/addons/ai/functions/fnc_garrisonMove.sqf b/addons/ai/functions/fnc_garrisonMove.sqf index 586c7b1f20..72935ec17e 100644 --- a/addons/ai/functions/fnc_garrisonMove.sqf +++ b/addons/ai/functions/fnc_garrisonMove.sqf @@ -53,6 +53,37 @@ if (isNil QGVAR(garrison_moveUnitPFH)) then { { _x params ["_unit", "_pos"]; + private _fnc_attemptFailed = { + if (_failSafeRemainingAttemps == 0 ) then { + _unit setVariable [QGVAR(garrisonMove_failSafe), nil, true]; + _unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; + [QGVAR(unGarrison), [[_unit]], _unit] call CBA_fnc_targetEvent; + _unitMoveList deleteAt (_unitMoveList find _x); + LOG("garrisonMove PFH: all moving commands failed | restoring AI capabilities"); + + } else { + _unit setVariable [QGVAR(garrisonMove_failSafe), [_failSafeTimer + 15, _failSafeRemainingAttemps - 1]]; + [QGVAR(doMove), [[[_unit, _pos]]], _unit] call CBA_fnc_targetEvent; + LOG("garrisonMove PFH unitReady: unit not close enough | Sending another doMove command"); + }; + }; + + private _fnc_attemptSuccessful = { + _unit setVariable [QGVAR(garrisonMove_failSafe), nil, true]; + _unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; + _unit setVariable [QGVAR(garrisonned), true, true]; + _unitMoveList deleteAt (_unitMoveList find _x); + + [QGVAR(AISection), [[_unit], ["PATH"], false], _unit] call CBA_fnc_targetEvent; + [QGVAR(AISection), [[_unit], ["FSM"], true], _unit] call CBA_fnc_targetEvent; + + if ({(_x select 0) in units _unit && {!isPlayer (_x select 0)}} count _unitMoveList == 0) then { + [QGVAR(enableAttack), [[_unit], true], _unit] call CBA_fnc_targetEvent; + }; + + LOG(format [ARR_2("garrisonMove PFH: unit in position | %1 units left", count _unitMoveList)]); + }; + // Check if unit is alive or even existing if (!alive _unit) then { _unitMoveList deleteAt (_unitMoveList find _x); @@ -69,37 +100,14 @@ if (isNil QGVAR(garrison_moveUnitPFH)) then { if (unitReady _unit) then { // Check for distance, doMove and AI are moody and may stop for no reason, within 6 meters and ready should be fine if (_unitPos distance _pos < 3) then { - _unit setVariable [QGVAR(garrisonMove_failSafe), nil, true]; - _unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; - _unit setVariable [QGVAR(garrisonned), true, true]; - _unitMoveList deleteAt (_unitMoveList find _x); - - [QGVAR(AISection), [[_unit], ["PATH"], false], _unit] call CBA_fnc_targetEvent; - [QGVAR(AISection), [[_unit], ["FSM"], true], _unit] call CBA_fnc_targetEvent; - - if ({(_x select 0) in units _unit && {!isPlayer (_x select 0)}} count _unitMoveList == 0) then { - [QGVAR(enableAttack), [[_unit], true], _unit] call CBA_fnc_targetEvent; - }; - - LOG(format [ARR_2("garrisonMove PFH: unit in position | %1 units left", count _unitMoveList)]); + call _fnc_attemptSuccessful; } else { // Tell the unit to move if an order wasn't given within 30s, avoid doMove spam (_unit getVariable [QGVAR(garrisonMove_failSafe), [CBA_missionTime, 5]]) params ["_failSafeTimer", "_failSafeRemainingAttemps"]; if (_failSafeTimer <= CBA_missionTime) then { - if (_failSafeRemainingAttemps == 0 ) then { - _unit setVariable [QGVAR(garrisonMove_failSafe), nil, true]; - _unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; - [QGVAR(unGarrison), [[_unit]], _unit] call CBA_fnc_targetEvent; - _unitMoveList deleteAt (_unitMoveList find _x); - LOG("garrisonMove PFH unitReady: all moving commands failed | restoring AI capabilities"); - - } else { - _unit setVariable [QGVAR(garrisonMove_failSafe), [_failSafeTimer + 15, _failSafeRemainingAttemps - 1]]; - [QGVAR(doMove), [[[_unit, _pos]]], _unit] call CBA_fnc_targetEvent; - LOG("garrisonMove PFH unitReady: unit not close enough | Sending another doMove command"); - }; + call _fnc_attemptFailed; }; }; } else { @@ -107,30 +115,12 @@ if (isNil QGVAR(garrison_moveUnitPFH)) then { // AI may sometimes not be able to report unitReady, this is to avoid the PFH running forever switch true do { - case ((_unitPosTimer + 15) < CBA_missionTime && {(_unitPos distance _pos) < 3}) : { - TRACE_1("case 1",_unit); - _unit setVariable [QGVAR(garrisonMove_failSafe), nil, true]; - _unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; - _unit setVariable [QGVAR(garrisonned), true, true]; - _unitMoveList deleteAt (_unitMoveList find _x); - - [QGVAR(AISection), [[_unit], ["PATH"], false], _unit] call CBA_fnc_targetEvent; - [QGVAR(AISection), [[_unit], ["FSM"], true], _unit] call CBA_fnc_targetEvent; - - if ({(_x select 0) in units _unit && {!isPlayer (_x select 0)}} count _unitMoveList == 0) then { - [QGVAR(enableAttack), [[_unit], true], _unit] call CBA_fnc_targetEvent; - }; - - LOG(format [ARR_2("garrisonMove PFH unitNotReady: unit in position | %1 units left", count _unitMoveList)]); + case ((_unitPos distance _pos) < 3) : { + call _fnc_attemptSuccessful; }; - case ((_unitPosTimer + 15) < CBA_missionTime && {_unitOldPos distance _unitPos < 0.5}) : { - TRACE_3("case 2",_unit, ((_unitPosTimer + 15) < CBA_missionTime), (_unitOldPos distance _unitPos < 0.5)); - _unit setVariable [QGVAR(garrisonMove_failSafe), nil, true]; - _unit setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; - [QGVAR(unGarrison), [[_unit]], _unit] call CBA_fnc_targetEvent; - _unitMoveList deleteAt (_unitMoveList find _x); - LOG("garrisonMove PFH unitNotReady: all moving commands failed | restoring AI capabilities"); + case ((_unitPosTimer + 5) < CBA_missionTime && {_unitOldPos distance _unitPos < 0.5}) : { + call _fnc_attemptFailed; }; case (_unitOldPos distance _unitPos < 0.5) : {}; diff --git a/addons/ai/functions/fnc_unGarrison.sqf b/addons/ai/functions/fnc_unGarrison.sqf index 8391c7f8e3..fa685fdd72 100644 --- a/addons/ai/functions/fnc_unGarrison.sqf +++ b/addons/ai/functions/fnc_unGarrison.sqf @@ -39,17 +39,7 @@ _units = _units select {local _x}; _x doMove ((nearestBuilding (getPos _x)) buildingExit 0); }; - private _fnc_countGarrisonnedUnits = { - params ["_unit", "_bool"]; - if (_bool) then { - ({(_x getVariable [QGVAR(garrisonned), false]) && {!isPlayer _x}} count units _unit) - } else { - ({!(_x getVariable [QGVAR(garrisonned), false]) && {!isPlayer _x}} count units _unit) - }; - - }; - - if ([_x, true] call _fnc_countGarrisonnedUnits == ({!isPlayer _x} count (units _x)) - 1 || {[_x, false] call _fnc_countGarrisonnedUnits == {!isPlayer _x} count (units _x)}) then { + if ({(_x getVariable [QGVAR(garrisonned), false]) && !isPlayer _x} count (units _x) == 0) then { LOG("fnc_ungarrison: enableAttack true"); (group _x) enableAttack true; };