diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index ebfbd31ef44..689911bf63e 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -317,6 +317,49 @@ GVAR(OldIsCamera) = false; END_COUNTER(stateChecker); }, 0.5, []] call CBA_fnc_addPerFrameHandler; +// Add event handler for UAV control change +ACE_controlledUAV = [objNull, objNull, [], ""]; +addMissionEventHandler ["PlayerViewChanged", { + // On non-server client this command is semi-broken + // arg index 5 should be the controlled UAV, but it will often be objNull (delay from locality switching?) + // On PlayerViewChanged event, start polling for new uav state for a few seconds (should be done within a few frames) + + params ["", "", "", "", "_newCameraOn", "_UAV"]; + TRACE_2("PlayerViewChanged",_newCameraOn,_UAV); + + [{ + if (isNull player) exitWith {true}; + private _UAV = getConnectedUAV player; + if (!alive player) then {_UAV = objNull;}; + private _position = (UAVControl _UAV) param [1, ""]; + private _seatAI = objNull; + private _turret = []; + switch (toLower _position) do { + case (""): { + _UAV = objNull; // set to objNull if not actively controlling + }; + case ("driver"): { + _turret = [-1]; + _seatAI = driver _UAV; + }; + case ("gunner"): { + _turret = [0]; + _seatAI = gunner _UAV; + }; + }; + + private _newArray = [_UAV, _seatAI, _turret, _position]; + if (_newArray isEqualTo ACE_controlledUAV) exitWith {false}; // no change yet + + TRACE_2("Seat Change",_newArray,ACE_controlledUAV); + ACE_controlledUAV = _newArray; + ["ACE_controlledUAV", _newArray] call CBA_fnc_localEvent; + + // stay in the loop as we might switch from gunner -> driver, and there may be a empty position event in-between + false + }, {}, [], 3, {TRACE_1("timeout",_this);}] call CBA_fnc_waitUntilAndExecute; +}]; + ////////////////////////////////////////////////// // Eventhandlers for player controlled machines @@ -355,7 +398,9 @@ GVAR(OldIsCamera) = false; // Players can always interact with his vehicle {vehicle _unit == _target} || // Players can always interact with passengers of the same vehicle - {_unit != _target && {vehicle _unit == vehicle _target}} + {_unit != _target && {vehicle _unit == vehicle _target}} || + // Players can always interact with connected UAV + {!(isNull (ACE_controlledUAV select 0))} }] call FUNC(addCanInteractWithCondition); ["isNotInZeus", {isNull curatorCamera}] call FUNC(addCanInteractWithCondition); diff --git a/addons/hellfire/XEH_postInit.sqf b/addons/hellfire/XEH_postInit.sqf index 34fc5b92ba9..b5dc8bf9fef 100644 --- a/addons/hellfire/XEH_postInit.sqf +++ b/addons/hellfire/XEH_postInit.sqf @@ -7,4 +7,13 @@ GVAR(pfID) = -1; ["ace_settingsInitialized", { ["turret", LINKFUNC(showHud), false] call CBA_fnc_addPlayerEventHandler; ["vehicle", LINKFUNC(showHud), true] call CBA_fnc_addPlayerEventHandler; // only one of these needs the retro flag + + // Add UAV Control Compatibility + ["ACE_controlledUAV", { + params ["_UAV", "_seatAI", "_turret", "_position"]; + TRACE_4("ACE_controlledUAV EH",_UAV,_seatAI,_turret,_position); + if (!isNull _seatAI) then { + [_seatAI] call FUNC(showHud); + }; + }] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/interact_menu/functions/fnc_keyDown.sqf b/addons/interact_menu/functions/fnc_keyDown.sqf index 52388ffe89d..f3a04c6fc8e 100644 --- a/addons/interact_menu/functions/fnc_keyDown.sqf +++ b/addons/interact_menu/functions/fnc_keyDown.sqf @@ -41,6 +41,7 @@ GVAR(lastTimeSearchedActions) = -1000; GVAR(ParsedTextCached) = []; GVAR(useCursorMenu) = (vehicle ACE_player != ACE_player) || + (!(isNull (ACE_controlledUAV select 0))) || visibleMap || (!isNull curatorCamera) || {(_menuType == 1) && {(isWeaponDeployed ACE_player) || GVAR(AlwaysUseCursorSelfInteraction) || {cameraView == "GUNNER"}}} || @@ -93,12 +94,20 @@ GVAR(selfMenuOffset) = (AGLtoASL (positionCameraToWorld [0, 0, 2])) vectorDiff ( //Auto expand the first level when self, mounted vehicle or zeus (skips the first animation as there is only one choice) if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (vehicle ACE_player != ACE_player) then { - GVAR(menuDepthPath) = [["ACE_SelfActions", (vehicle ACE_player)]]; + if (!(isNull (ACE_controlledUAV select 0))) then { + GVAR(menuDepthPath) = [["ACE_SelfActions", (ACE_controlledUAV select 0)]]; GVAR(expanded) = true; GVAR(expandedTime) = diag_tickTime; GVAR(lastPath) = +GVAR(menuDepthPath); GVAR(startHoverTime) = -1000; + } else { + if (vehicle ACE_player != ACE_player) then { + GVAR(menuDepthPath) = [["ACE_SelfActions", (vehicle ACE_player)]]; + GVAR(expanded) = true; + GVAR(expandedTime) = diag_tickTime; + GVAR(lastPath) = +GVAR(menuDepthPath); + GVAR(startHoverTime) = -1000; + }; }; } else { GVAR(menuDepthPath) = [["ACE_ZeusActions", (getAssignedCuratorLogic player)]]; diff --git a/addons/interact_menu/functions/fnc_renderActionPoints.sqf b/addons/interact_menu/functions/fnc_renderActionPoints.sqf index 0572f15fa6c..8d0e2de3979 100644 --- a/addons/interact_menu/functions/fnc_renderActionPoints.sqf +++ b/addons/interact_menu/functions/fnc_renderActionPoints.sqf @@ -130,17 +130,22 @@ GVAR(collectedActionPoints) resize 0; // Render nearby actions, unit self actions or vehicle self actions as appropiate if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (vehicle ACE_player == ACE_player) then { - if (diag_tickTime > GVAR(lastTimeSearchedActions) + 0.20) then { - // Once every 0.2 secs, collect nearby objects active and visible action points and render them - call _fnc_renderNearbyActions; + if (!(isNull (ACE_controlledUAV select 0))) then { + // Render UAV self actions when in control of UAV AI + (ACE_controlledUAV select 0) call _fnc_renderSelfActions; + } else { + if (vehicle ACE_player == ACE_player) then { + if (diag_tickTime > GVAR(lastTimeSearchedActions) + 0.20) then { + // Once every 0.2 secs, collect nearby objects active and visible action points and render them + call _fnc_renderNearbyActions; + } else { + // The rest of the frames just draw the same action points rendered the last frame + call _fnc_renderLastFrameActions; + }; } else { - // The rest of the frames just draw the same action points rendered the last frame - call _fnc_renderLastFrameActions; + // Render vehicle self actions when in vehicle + (vehicle ACE_player) call _fnc_renderSelfActions; }; - } else { - // Render vehicle self actions when in vehicle - (vehicle ACE_player) call _fnc_renderSelfActions; }; } else { // Render zeus actions when zeus open diff --git a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf index 4b88212d59d..fefab99721c 100644 --- a/addons/interact_menu/functions/fnc_renderBaseMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderBaseMenu.sqf @@ -37,7 +37,7 @@ private _pos = if((count _this) > 2) then { // For non-self actions, exit if the action is too far away or ocluded private _distanceToBasePoint = 0; //This will be 0 for self/zeus/in-vehicle (used later to check sub action distance) -if ((GVAR(openedMenuType) == 0) && {vehicle ACE_player == ACE_player} && {isNull curatorCamera} && +if ((GVAR(openedMenuType) == 0) && {isNull (ACE_controlledUAV select 0)} && {vehicle ACE_player == ACE_player} && {isNull curatorCamera} && { private _headPos = ACE_player modelToWorldVisual (ACE_player selectionPosition "pilot"); _distanceToBasePoint = _headPos distance _pos; diff --git a/addons/laser/functions/fnc_keyLaserCodeChange.sqf b/addons/laser/functions/fnc_keyLaserCodeChange.sqf index c5140709e09..14c6ab70b61 100644 --- a/addons/laser/functions/fnc_keyLaserCodeChange.sqf +++ b/addons/laser/functions/fnc_keyLaserCodeChange.sqf @@ -24,12 +24,18 @@ if ((!alive ACE_player) || {!([ACE_player, vehicle ACE_player, []] call EFUNC(co private _currentShooter = objNull; private _currentWeapon = ""; -if (ACE_player call CBA_fnc_canUseWeapon) then { - _currentShooter = ACE_player; - _currentWeapon = currentWeapon ACE_player; +if (isNull (ACE_controlledUAV param [0, objNull])) then { + if (ACE_player call CBA_fnc_canUseWeapon) then { + _currentShooter = ACE_player; + _currentWeapon = currentWeapon ACE_player; + } else { + _currentShooter = vehicle ACE_player; + private _turretPath = if (ACE_player == (driver _currentShooter)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + _currentWeapon = _currentShooter currentWeaponTurret _turretPath; + }; } else { - _currentShooter = vehicle ACE_player; - private _turretPath = if (ACE_player == (driver _currentShooter)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + _currentShooter = ACE_controlledUAV select 0; + private _turretPath = ACE_controlledUAV select 2; _currentWeapon = _currentShooter currentWeaponTurret _turretPath; }; diff --git a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf index a878924ed57..89fe20b41f2 100644 --- a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf +++ b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf @@ -24,14 +24,21 @@ if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) private ["_currentShooter", "_currentMagazine"]; -if (((vehicle ACE_player) == ACE_player) || {ACE_player call CBA_fnc_canUseWeapon}) then { - _currentShooter = ACE_player; - _currentMagazine = currentMagazine ACE_player; +if (isNull (ACE_controlledUAV param [0, objNull])) then { + if (((vehicle ACE_player) == ACE_player) || {ACE_player call CBA_fnc_canUseWeapon}) then { + _currentShooter = ACE_player; + _currentMagazine = currentMagazine ACE_player; + } else { + _currentShooter = vehicle ACE_player; + private _turretPath = if (ACE_player == (driver _currentShooter)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + _currentMagazine = _currentShooter currentMagazineTurret _turretPath; + }; } else { - _currentShooter = vehicle ACE_player; - private _turretPath = if (ACE_player == (driver _currentShooter)) then {[-1]} else {ACE_player call CBA_fnc_turretPath}; + _currentShooter = ACE_controlledUAV select 0; + private _turretPath = ACE_controlledUAV select 2; _currentMagazine = _currentShooter currentMagazineTurret _turretPath; }; + if (_currentMagazine == "") exitWith {TRACE_1("no magazine",_currentMagazine)}; private _ammo = getText (configFile >> "CfgMagazines" >> _currentMagazine >> "ammo");