diff --git a/addons/ai/XEH_PREP.hpp b/addons/ai/XEH_PREP.hpp index 909031ea9b9..d3a61e30129 100644 --- a/addons/ai/XEH_PREP.hpp +++ b/addons/ai/XEH_PREP.hpp @@ -1,2 +1,3 @@ PREP(garrison); PREP(unGarrison); +PREP(garrisonMove); diff --git a/addons/ai/XEH_postInit.sqf b/addons/ai/XEH_postInit.sqf index b4d24d21e53..5caacf0ba6c 100644 --- a/addons/ai/XEH_postInit.sqf +++ b/addons/ai/XEH_postInit.sqf @@ -1,8 +1,38 @@ #include "script_component.hpp" [QGVAR(disableAI), { - params [["_units", [], [[]]], "_section"]; - {_x disableAI _section} foreach (_units select {local _x}); + params [["_units", [], [[]]], ["_sections", [], [[]]]]; + { + private _section = _x; + { + _x disableAI _section; + LOG(format [ARR_4("XEH_postInit: %1 disableAI %2 | ID %3", _x, _section, clientOwner)]); + } foreach (_units select {local _x}); + } foreach _sections }] call CBA_fnc_addEventHandler; [QGVAR(unGarrison), FUNC(unGarrison)] call CBA_fnc_addEventHandler; +[QGVAR(doMove), { + params ["_unitsArray"]; + { + _x params ["_unit", "_pos"]; + _unit doMove _pos; + LOG(format [ARR_4("XEH_postInit: %1 doMove %2 | ID %3", _unit, _pos, clientOwner)]); + } foreach _unitsArray +}] call CBA_fnc_addEventHandler; +[QGVAR(setBehaviour), { + params ["_groupsArray", "_behaviour"]; + { + _x params ["_group"]; + _group setBehaviour _behaviour; + LOG(format [ARR_4("XEH_postInit: %1 setBehaviour %2 | ID %3", _group, _behaviour, clientOwner)]); + } foreach _groupsArray +}] call CBA_fnc_addEventHandler; +[QGVAR(enableAttack), { + params ["_unitsArray", "_mode"]; + { + _x params ["_unit"]; + _unit enableAttack _mode; + LOG(format [ARR_4("XEH_postInit: %1 enableAttack %2 | ID %3", _unit, _mode, clientOwner)]); + } foreach _unitsArray +}] call CBA_fnc_addEventHandler; \ No newline at end of file diff --git a/addons/ai/functions/fnc_garrison.sqf b/addons/ai/functions/fnc_garrison.sqf index 527883f2240..32fc7a58709 100644 --- a/addons/ai/functions/fnc_garrison.sqf +++ b/addons/ai/functions/fnc_garrison.sqf @@ -8,31 +8,32 @@ * 2: Units that will be garrisoned * 3: Radius to fill building(s) (default: 50) * 4: 0: even filling, 1: building by building, 2: random filling (default: 0) - * 5: True to fill building(s) from top to bottom (default: false) + * 5: True to fill building(s) from top to bottom (default: false) (note: only works with filling mode 0 and 1) + * 6: Teleport units (default: false) * Return Value: * Units not garrisoned * * Example: - * [position, nil, [unit1, unit2, unit3, unitN], 200, 1, false] call ace_ai_fnc_garrison + * [position, nil, [unit1, unit2, unit3, unitN], 200, 1, false, false] call ace_ai_fnc_garrison * * Public: Yes */ #include "script_component.hpp" -params [["_startingPos",[0,0,0], [[]], 3], ["_buildingTypes", ["Building"], [[]]], ["_unitsArray", [], [[]]], ["_fillingRadius", 50, [0]], ["_fillingType", 0, [0]], ["_topDownFilling", false, [true]]]; +params [["_startingPos",[0,0,0], [[]], 3], ["_buildingTypes", ["Building"], [[]]], ["_unitsArray", [], [[]]], ["_fillingRadius", 50, [0]], ["_fillingType", 0, [0]], ["_topDownFilling", false, [true]], ["_teleport", false, [true]]]; -TRACE_6("fnc_garrison start",_startingPos,_buldingTypes,_unitsArray,_fillingRadius,_fillingTYpe,_topDownFilling); +TRACE_6("fnc_garrison: Start",_startingPos,_buldingTypes,count _unitsArray,_fillingRadius,_fillingTYpe,_topDownFilling); _unitsArray = _unitsArray select {alive _x && {!isPlayer _x}}; if (_startingPos isEqualTo [0,0,0]) exitWith { - TRACE_1("fnc_garrison startingPos error",_startingPos); + TRACE_1("fnc_garrison: StartingPos error",_startingPos); [LSTRING(GarrisonInvalidPosition)] call EFUNC(common,displayTextStructured); }; if (count _unitsArray == 0 || {isNull (_unitsArray select 0)}) exitWith { - TRACE_1("fnc_garrison units error",_unitsArray); + TRACE_1("fnc_garrison: Units error",_unitsArray); [LSTRING(GarrisonNoUnits)] call EFUNC(common,displayTextStructured); }; @@ -42,11 +43,11 @@ if (_fillingRadius >= 50) then { }; if (count _buildings == 0) exitWith { - TRACE_1("fnc_garrison building error",_buildings); + TRACE_1("fnc_garrison: Building error",_buildings); [LSTRING(GarrisonNoBuilding)] call EFUNC(common,displayTextStructured); }; -private _buildingsIndexes = []; +private _buildingsIndex = []; if (_topDownFilling) then { { @@ -63,54 +64,99 @@ if (_topDownFilling) then { reverse _x; } foreach _buildingPos; - _buildingsIndexes pushBack _buildingPos; + _buildingsIndex pushBack _buildingPos; } foreach _buildings; } else { { - _buildingsIndexes pushBack (_x buildingPos -1); + _buildingsIndex pushBack (_x buildingPos -1); } foreach _buildings; }; // Remove buildings without positions { - _buildingsIndexes deleteAt (_buildingsIndexes find _x); -} foreach (_buildingsIndexes select {count _x == 0}); + _buildingsIndex deleteAt (_buildingsIndex find _x); +} foreach (_buildingsIndex select {count _x == 0}); + +//Remove positions units are already pathing to +_buildingsIndex = _buildingsIndex apply { + private _testedBuilding = _x; + + _testedBuilding select { + private _testedPos = _x; + (({(_x select 1) isEqualTo _testedPos} count (missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []])) == 0) + } +}; // Warn the user that there's not enough positions to place all units private _count = 0; -{_count = _count + count _x} foreach _buildingsIndexes; +{_count = _count + count _x} foreach _buildingsIndex; if ( (count _unitsArray) - _count > 0) then { - TRACE_4("fnc_garrison not enough spots",_unitsArray,count _unitsArray,_count,((count _unitsArray) - _count > 0)); + TRACE_4("fnc_garrison: Not enough spots to place all units",_unitsArray,count _unitsArray,_count,((count _unitsArray) - _count > 0)); [LSTRING(GarrisonNotEnoughPos)] call EFUNC(common,displayTextStructured); }; private _placedUnits = []; +private _unitMoveList = []; + +// Force all units to un-garrison +[QGVAR(unGarrison), [_unitsArray], _unitsArray] call CBA_fnc_targetEvent; + +private _fnc_comparePos = { + params ["_nearestUnits", "_pos"]; + ({ + if (surfaceIsWater getPos _x) then { + floor ((getPosASL _x) select 2) == floor ((AGLtoASL _pos) select 2) + } else { + floor ((getPosATL _x) select 2) == floor (_pos select 2) + }; + } count _nearestUnits) > 0 +}; // Do the placement switch (_fillingType) do { - + // Even filling case 0: { + while {count _unitsArray > 0} do { - if (count _buildingsIndexes == 0) exitWith {}; - private _building = _buildingsIndexes select 0; + if (count _buildingsIndex == 0) exitWith {}; + private _building = _buildingsIndex select 0; if (_building isEqualTo []) then { - _buildingsIndexes deleteAt 0; + LOG(format [ARR_2("fnc_garrison: Empty building array | removing building from buildingsIndex | %1 buildings remaining",count _buildingsIndex)]); + _buildingsIndex deleteAt 0; + } else { private _pos = _building select 0; - private _nearestUnits = (_pos nearEntities ["CAManBase", 1]); + private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + + if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { + LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); + _buildingsIndex set [0, _building - [_pos]]; - if (count _nearestUnits > 0 && {count (_nearestUnits select {getPos _x select 2 == _pos select 2}) > 0}) then { - _buildingsIndexes set [0, _building - [_pos]]; } else { private _unit = _unitsArray select 0; - _unit setPos _pos; + private _posSurface = surfaceIsWater _pos; + + if (_teleport) then { + doStop _unit; + if (_posSurface) then { + _unit setPosASL (AGLtoASL _pos); + } else { + _unit setPosATL _pos; + }; + + } else { + _unitMoveList pushBack [_unit,[_pos, AGLToASL _pos] select (_posSurface)]; + }; + _placedUnits pushBack _unit; _unitsArray deleteAt (_unitsArray find _unit); _building deleteAt 0; - _buildingsIndexes deleteAt 0; - _buildingsIndexes pushBackUnique _building; + _buildingsIndex deleteAt 0; + _buildingsIndex pushBackUnique _building; + _unit setVariable [QGVAR(garrisonned), true, true]; }; }; }; @@ -118,24 +164,44 @@ switch (_fillingType) do { // Building by building case 1: { + while {count _unitsArray > 0} do { - if (count _buildingsIndexes == 0) exitWith {}; - private _building = _buildingsIndexes select 0; + if (count _buildingsIndex == 0) exitWith {}; + private _building = _buildingsIndex select 0; if (_building isEqualTo []) then { - _buildingsIndexes deleteAt 0; + LOG(format [ARR_2("fnc_garrison: empty building array | removing building from buildingsIndex | %1 buildings remaining",count _buildingsIndex)]); + _buildingsIndex deleteAt 0; + } else { private _pos = _building select 0; - private _nearestUnits = (_pos nearEntities ["CAManBase", 1]); + private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + + if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { + LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); + _buildingsIndex set [0, _building - [_pos]]; - if (count _nearestUnits > 0 && {count (_nearestUnits select {getPos _x select 2 == _pos select 2}) > 0}) then { - _buildingsIndexes set [0, _building - [_pos]]; } else { private _unit = _unitsArray select 0; - _unit setPos _pos; + private _posSurface = surfaceIsWater _pos; + + if (_teleport) then { + doStop _unit; + if (_posSurface) then { + _unit setPosASL (AGLtoASL _pos); + } else { + _unit setPosATL _pos; + }; + + } else { + _unitMoveList pushBack [_unit,[_pos, AGLToASL _pos] select (_posSurface)]; + }; + _placedUnits pushBack _unit; _unitsArray deleteAt (_unitsArray find _unit); - _buildingsIndexes set [0, _building - [_pos]]; + _buildingsIndex set [0, _building - [_pos]]; + _unit setVariable [QGVAR(garrisonned), true, true]; }; }; }; @@ -143,31 +209,68 @@ switch (_fillingType) do { // Random case 2: { + while {count _unitsArray > 0} do { - if (count _buildingsIndexes == 0) exitWith {}; - private _building = selectRandom _buildingsIndexes; + if (count _buildingsIndex == 0) exitWith {}; + private _building = selectRandom _buildingsIndex; if (_building isEqualTo []) then { - _buildingsIndexes deleteAt (_buildingsIndexes find _building); + LOG(format [ARR_2("fnc_garrison: empty building array | removing building from buildingsIndex | %1 buildings remaining",count _buildingsIndex)]); + _buildingsIndex deleteAt (_buildingsIndex find _building); + } else { private _pos = selectRandom _building; - private _nearestUnits = (_pos nearEntities ["CAManBase", 1]); + private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + + if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { + LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); + _buildingsIndex set [(_buildingsIndex find _building), _building - [_pos]]; - if (count _nearestUnits > 0 && {count (_nearestUnits select {getPos _x select 2 == _pos select 2}) > 0}) then { - _buildingsIndexes set [(_buildingsIndexes find _building), _building - [_pos]]; } else { private _unit = _unitsArray select 0; - _unit setPos _pos; - _unitsArray deleteAt (_unitsArray find _unit); + private _posSurface = surfaceIsWater _pos; + + if (_teleport) then { + doStop _unit; + if (_posSurface) then { + _unit setPosASL (AGLtoASL _pos); + } else { + _unit setPosATL _pos; + }; + + } else { + _unitMoveList pushBack [_unit,[_pos, AGLToASL _pos] select (_posSurface)]; + }; + _placedUnits pushBack _unit; - _buildingsIndexes set [(_buildingsIndexes find _building), _building - [_pos]]; + _unitsArray deleteAt (_unitsArray find _unit); + _buildingsIndex set [(_buildingsIndex find _building), _building - [_pos]]; + _unit setVariable [QGVAR(garrisonned), true, true]; }; }; }; }; }; -[QGVAR(disableAI), [_placedUnits, "AUTOCOMBAT"], _placedUnits] call CBA_fnc_targetEvent; -[QGVAR(disableAI), [_placedUnits, "PATH"], _placedUnits] call CBA_fnc_targetEvent; -TRACE_2("fnc_garrison ended, leftover units",_unitsArray,count _unitsArray); +TRACE_1(format [ARR_2("fnc_garrison: while loop ended | %1 units ready to be treated by PFH",count _unitMoveList)], _teleport); + +// Update the unit list and remove duplicate positions and units +private _garrison_unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; +_garrison_unitMoveList append (_unitMoveList select { + _x params ["_testedUnit", "_testedPos"]; + (({(_x select 0) isEqualTo _testedUnit} count _garrison_unitMoveList) == 0) && + (({(_x select 1) isEqualTo _testedPos} count _garrison_unitMoveList) == 0) +}); + +missionNameSpace setVariable [QGVAR(garrison_unitMoveList), _garrison_unitMoveList, true]; + +if (_teleport) then { + [QGVAR(disableAI), [_placedUnits, ["PATH"]], _placedUnits] call CBA_fnc_targetEvent; + +} else { + [_unitMoveList] call FUNC(garrisonMove); +}; + +TRACE_1(format [ARR_3("fnc_garrison: End | %1 units left | %2 buildings left", count _unitsArray, count _buildingsIndex)], _unitsArray); _unitsArray diff --git a/addons/ai/functions/fnc_garrisonMove.sqf b/addons/ai/functions/fnc_garrisonMove.sqf new file mode 100644 index 00000000000..314a4548749 --- /dev/null +++ b/addons/ai/functions/fnc_garrisonMove.sqf @@ -0,0 +1,142 @@ +/* + * Author: alganthe + * Internal function used by ace_ai_fnc_garrison to make the units move to the positions it picked. + * + * Arguments: + * 0: Array of arrays + * 0: Unit needing to be placed + * 1: Position the unit need to be placed at + * + * Return Value: + * Nothing + * + * Example: + * [ [unit1, [10, 10, 10]], [unit2, [30, 30, 30]], [unitN, getPos player] ] call ace_ai_fnc_garrisonMove + * + * Public: No +*/ +#include "script_component.hpp" + +params [ ["_unitMoveList", nil, [[]]] ]; + +if (isNil "_unitMoveList") exitWith {}; + +// Start initial movement +private _unitMoveListUnits = (_garrison_unitMoveList apply {_x select 0}); +[QGVAR(setBehaviour), [(_unitMoveListUnits select {leader _x == _x}), "SAFE"], _unitMoveListUnits] call CBA_fnc_targetEvent; +[QGVAR(doMove), [_unitMoveList], _unitMoveListUnits] call CBA_fnc_targetEvent; +[QGVAR(enableAttack), [_unitMoveListUnits select {leader _x == _x}, false], _unitMoveListUnits] call CBA_fnc_targetEvent; + +{ + _x setVariable [QGVAR(garrisonMove_failSafe), nil, true]; + _x setVariable [QGVAR(garrisonMove_unitPosMemory), nil, true]; +} foreach _unitMoveListUnits; + +// Avoid duplicate PFHs +if (isNil QGVAR(garrison_moveUnitPFH)) then { + missionNameSpace setVariable [QGVAR(garrison_moveUnitPFH), true, true]; + + // PFH checking if the units have reached their destination + [{ + params ["_args", "_pfhID"]; + _args params ["_startTime"]; + + private _unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; + + // End PFH if all units are placed / unable to reach position + if (_unitMoveList isEqualTo []) then { + missionNameSpace setVariable [QGVAR(garrison_moveUnitPFH), nil, true]; + LOG("garrisonMove PFH: PFH finished it's job | deleting PFH"); + _pfhID call CBA_fnc_removePerFrameHandler; + + } else { + { + _x params ["_unit", "_pos"]; + + // Check if unit is alive or even existing + if (!alive _unit) then { + _unitMoveList deleteAt (_unitMoveList find _x); + LOG(format [ARR_2("garrisonMove PFH: unit dead or deleted | %1 units left", count _unitMoveList)]); + + } else { + private _unitPos = getPos _unit; + + 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 distance2D _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(disableAI), [[_unit], ["PATH"]], _unit] call CBA_fnc_targetEvent; + + if ({(_x select 0) in units _unit} 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)]); + + } 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 + 30, _failSafeRemainingAttemps - 1]]; + [QGVAR(doMove), [[[_unit, _pos]]], _unit] call CBA_fnc_targetEvent; + LOG("garrisonMove PFH unitReady: unit not close enough | Sending another doMove command"); + }; + }; + }; + } else { + (_unit getVariable [QGVAR(garrisonMove_unitPosMemory), [CBA_missionTime, [0,0,0]]]) params ["_unitPosTimer", "_unitOldPos"]; + + // AI may sometimes not be able to report unitReady, this is to avoid the PFH running forever + switch true do { + case ((_unitPosTimer + 30) < CBA_missionTime && {(_unitPos distance2D _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(disableAI), [[_unit], ["PATH"]], _unit] call CBA_fnc_targetEvent; + + if ({(_x select 0) in units _unit} 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 ((_unitPosTimer + 30) < CBA_missionTime && {_unitOldPos distance _unitPos < 2}) : { + TRACE_3("case 2",_unit, ((_unitPosTimer + 30) < CBA_missionTime), (_unitOldPos distance _unitPos < 2)); + _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 (_unitOldPos distance _unitPos < 2); + + default { + _unit setVariable [QGVAR(garrisonMove_unitPosMemory), [CBA_missionTime, _unitPos]]; + }; + }; + }; + }; + } foreach _unitMoveList; + + missionNameSpace setVariable [QGVAR(garrison_unitMoveList), _unitMoveList, true]; + }; + }, 1, []] call CBA_fnc_addPerFrameHandler; +}; diff --git a/addons/ai/functions/fnc_unGarrison.sqf b/addons/ai/functions/fnc_unGarrison.sqf index 1f52db1e103..2e6e5122889 100644 --- a/addons/ai/functions/fnc_unGarrison.sqf +++ b/addons/ai/functions/fnc_unGarrison.sqf @@ -21,12 +21,15 @@ params [["_units", [], [[]]]]; _units = _units select {local _x}; { - if !(isPlayer _x || {!local _x}) then { - _x enableAI "AUTOCOMBAT"; + if (!isPlayer _x && {local _x}) then { _x enableAI "PATH"; private _leader = leader _x; + TRACE_3("fnc_ungarrison: unit and leader",_x , _leader, (_leader == _x)); + + _x setVariable [QGVAR(garrisonned), false, true]; + if (_leader != _x) then { doStop _x; _x doFollow _leader; @@ -34,5 +37,20 @@ _units = _units select {local _x}; } else { _x doMove ((nearestBuilding (getPos _x)) buildingExit 0); }; + + private _fnc_countGarrisonnedUnits = { + params ["_unit", "_bool"]; + if (_bool) then { + ({(_x getVariable [QGVAR(garrisonned), false])} count units _unit) + } else { + ({!(_x getVariable [QGVAR(garrisonned), false])} count units _unit) + }; + + }; + + if ([_x, true] call _fnc_countGarrisonnedUnits == count (units _x) -1 || {[_x, false] call _fnc_countGarrisonnedUnits == count (units _x)}) then { + LOG("fnc_ungarrison: enableAttack true"); + (group _x) enableAttack true; + }; }; } foreach _units; diff --git a/addons/ai/script_component.hpp b/addons/ai/script_component.hpp index 0626f696c72..3a05db6896b 100644 --- a/addons/ai/script_component.hpp +++ b/addons/ai/script_component.hpp @@ -2,8 +2,8 @@ #define COMPONENT_BEAUTIFIED AI #include "\z\ace\addons\main\script_mod.hpp" - #define DEBUG_MODE_FULL - #define DISABLE_COMPILE_CACHE +//#define DEBUG_MODE_FULL +//#define DISABLE_COMPILE_CACHE // #define ENABLE_PERFORMANCE_COUNTERS #ifdef DEBUG_ENABLED_AI diff --git a/addons/zeus/functions/fnc_moduleGarrison.sqf b/addons/zeus/functions/fnc_moduleGarrison.sqf index 23198c1670f..9b8e2df0a2b 100644 --- a/addons/zeus/functions/fnc_moduleGarrison.sqf +++ b/addons/zeus/functions/fnc_moduleGarrison.sqf @@ -20,7 +20,7 @@ #include "script_component.hpp" -params ["_logic", "_pos", "_radius" ,"_mode" , "_topDownMode"]; +params ["_logic", "_pos", "_radius" ,"_mode" , "_topDownMode", "_teleport"]; private _unit = (attachedTo _logic); private _building = nearestBuilding (getPosASL _unit); @@ -57,6 +57,6 @@ private _units = units _unit; }; } forEach _units; -[_pos, ["Building"], _units, _radius, _mode, _topDownMode] call EFUNC(ai,garrison); +[_pos, ["Building"], _units, _radius, _mode, _topDownMode, _teleport] call EFUNC(ai,garrison); deleteVehicle _logic; diff --git a/addons/zeus/functions/fnc_ui_garrison.sqf b/addons/zeus/functions/fnc_ui_garrison.sqf index 88fd7d8e78e..b408d8595c7 100644 --- a/addons/zeus/functions/fnc_ui_garrison.sqf +++ b/addons/zeus/functions/fnc_ui_garrison.sqf @@ -36,7 +36,7 @@ private _fnc_errorAndClose = { params ["_msg"]; _display closeDisplay 0; deleteVehicle _logic; - [_msg] call EFUNC(common,displayTextStructured); + [_msg] call FUNC(showMessage); breakOut "Main"; }; @@ -56,7 +56,7 @@ switch (false) do { }; //Specific on-load stuff: -private _listbox = _display displayCtrl 73062; +private _listbox = _display displayCtrl 73063; { _listbox lbSetValue [_listbox lbAdd (_x select 0), _x select 1]; } forEach [ @@ -69,6 +69,7 @@ _listbox lbSetCurSel 0; //Specific on-load stuff: (_display displayCtrl 73061) cbSetChecked (_logic getVariable ["TopDownFilling",false]); +(_display displayCtrl 73062) cbSetChecked (_logic getVariable ["Teleport",false]); private _fnc_onUnload = { params ["_display"]; @@ -76,8 +77,7 @@ private _fnc_onUnload = { private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); if (isNull _logic) exitWith {}; - // Store checkbox value for reopening - _logic setVariable ["TopDownFilling", cbChecked (_display displayCtrl 73061)]; + deleteVehicle _logic; }; private _fnc_onConfirm = { @@ -89,14 +89,15 @@ private _fnc_onConfirm = { private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objnull); if (isNull _logic) exitWith {}; - private _lb = _display displayCtrl 73062; + private _lb = _display displayCtrl 73063; private _radius = GETVAR(_display,GVAR(radius),50); private _position = GETVAR(_display,GVAR(position),getPos _logic); private _mode = _lb lbValue (lbCurSel _lb); private _TopDownFilling = cbChecked (_display displayCtrl 73061); + private _teleport = cbChecked (_display displayCtrl 73062); - [_logic, _position ,_radius, _mode, _TopDownFilling] call FUNC(moduleGarrison); + [_logic, _position ,_radius, _mode, _TopDownFilling, _teleport] call FUNC(moduleGarrison); }; _display displayAddEventHandler ["unload", _fnc_onUnload]; diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index 5c68ef1689a..db2da4e9252 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -1112,6 +1112,10 @@ Random filling Remplir au hasard + + Teleport + Téléporter + Unit must not be a player L'unité ne doit pas être un joueur diff --git a/addons/zeus/ui/RscAttributes.hpp b/addons/zeus/ui/RscAttributes.hpp index 9abd553a0d8..2bb2c97d852 100644 --- a/addons/zeus/ui/RscAttributes.hpp +++ b/addons/zeus/ui/RscAttributes.hpp @@ -507,19 +507,35 @@ class GVAR(RscGarrison): RscDisplayAttributes { w = W_PART(1); h = H_PART(1); }; + class TeleportTitle: Title { + idc = -1; + text = CSTRING(ModuleGarrison_TeleportText); + x = 0; + y = H_PART(2.3); + w = W_PART(10); + h = H_PART(1); + colorBackground[] = {0,0,0,0.5}; + }; + class Teleport: RscCheckBox { + idc = 73062; + x = W_PART(10.1); + y = H_PART(2.3); + w = W_PART(1); + h = H_PART(1); + }; class FillingModeTitle: RscText { idc = -1; text = CSTRING(ModuleGarrison_FillingModeText); x = 0; - y = H_PART(2.3); + y = H_PART(3.5); w = W_PART(26); h = H_PART(1); colorBackground[] = {0,0,0,0.5}; }; class FillingMode: RscListbox { - idc = 73062; + idc = 73063; x = 0; - y = H_PART(3.3); + y = H_PART(4.5); w = W_PART(26); h = H_PART(4); };