-
Notifications
You must be signed in to change notification settings - Fork 737
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix quickmount for vehicle interactions
- Loading branch information
Showing
2 changed files
with
90 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,131 +1,125 @@ | ||
#include "..\script_component.hpp" | ||
/* | ||
* Author: Kingsley | ||
* Mount the player in the vehicle they are directly looking at based on their distance. | ||
* Author: Kingsley, johnb43 | ||
* Mounts the player in the vehicle they are directly looking at based on their distance. | ||
* | ||
* Arguments: | ||
* 0: Target <OBJECT>(Optional) | ||
* 0: Target <OBJECT> (default: objNull) | ||
* | ||
* Return Value: | ||
* None | ||
* | ||
* Example: | ||
* [] call ace_quickmount_fnc_getInNearest; | ||
* call ace_quickmount_fnc_getInNearest | ||
* | ||
* Public: No | ||
*/ | ||
|
||
if (!GVAR(enabled) || | ||
if ( | ||
!GVAR(enabled) || | ||
{isNull ACE_player} || | ||
{vehicle ACE_player != ACE_player} || | ||
{!alive ACE_player} || | ||
{ACE_player getVariable ["ace_unconscious", false]} | ||
{!isNull objectParent ACE_player} || | ||
{!(ACE_player call EFUNC(common,isAwake))} | ||
) exitWith {}; | ||
|
||
params [["_interactionTarget", objNull, [objNull]]]; | ||
TRACE_1("getInNearest",_interactionTarget); | ||
params [["_target", objNull, [objNull]]]; | ||
TRACE_1("getInNearest",_target); | ||
|
||
private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot"); | ||
private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); | ||
private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; | ||
private _target = (_objects param [0, []]) param [2, objNull]; | ||
|
||
if ((isNull _target) && {alive _interactionTarget}) then { | ||
_end = _start vectorAdd ((_start vectorFromTo (aimPos _interactionTarget)) vectorMultiply GVAR(distance)); | ||
_objects = lineIntersectsSurfaces [_start, _end, ACE_player]; | ||
TRACE_1("2nd ray attempt at interaction target aim pos",_objects); | ||
// If target is not defined (e.g. keybind was used), search for valid target | ||
if (isNull _target) then { | ||
private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot"); | ||
private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); | ||
private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; | ||
_target = (_objects param [0, []]) param [2, objNull]; | ||
}; | ||
|
||
if (locked _target in [2,3] || {!simulationEnabled _target}) exitWith { | ||
[localize LSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); | ||
true | ||
if (!alive _target) exitWith {}; | ||
|
||
if (locked _target >= 2 || {!simulationEnabled _target}) exitWith { | ||
[LLSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); | ||
}; | ||
|
||
TRACE_2("",_target,typeOf _target); | ||
|
||
if (!isNull _target && | ||
{alive _target} && | ||
{{_target isKindOf _x} count ["Air","LandVehicle","Ship","StaticMortar"] > 0} && | ||
{([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} && | ||
{speed _target <= GVAR(speed)} | ||
) then { | ||
if ( | ||
(speed _target > GVAR(speed)) || | ||
{["Air", "LandVehicle", "Ship", "StaticMortar"] findIf {_target isKindOf _x} == -1} || | ||
{!([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} | ||
) exitWith {}; | ||
|
||
private _seats = ["driver", "gunner", "commander", "cargo"]; | ||
private _sortedSeats = [_seats select GVAR(priority)]; | ||
_seats deleteAt GVAR(priority); | ||
_sortedSeats append _seats; | ||
|
||
if (GVAR(priority) > 3 || GVAR(priority) < 0) then { | ||
GVAR(priority) = 0; | ||
}; | ||
private _fullCrew = fullCrew [_target, "", true]; | ||
|
||
private _seats = ["Driver", "Gunner", "Commander", "Cargo"]; | ||
private _sortedSeats = [_seats select GVAR(priority)]; | ||
_seats deleteAt GVAR(priority); | ||
_sortedSeats append _seats; | ||
private _hasAction = false; | ||
scopeName "SearchForSeat"; | ||
|
||
{ | ||
private _desiredRole = _x; | ||
|
||
private _hasAction = false; | ||
scopeName "SearchForSeat"; | ||
{ | ||
private _desiredRole = _x; | ||
{ | ||
_x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; | ||
if ((isNull _unit) || {!alive _unit}) then { | ||
private _effectiveRole = toLowerANSI _role; | ||
|
||
if ((_effectiveRole in ["driver", "gunner"]) && {unitIsUAV _target}) exitWith {}; // Ignoring UAV Driver/Gunner | ||
if ((_effectiveRole == "driver") && {(getNumber (configOf _target >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons) | ||
|
||
// Seats can be locked independently of the main vehicle | ||
if ((_role == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);}; | ||
if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);}; | ||
if ((_turretPath isNotEqualTo []) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; | ||
|
||
if (_effectiveRole == "turret") then { | ||
private _turretConfig = [_target, _turretPath] call CBA_fnc_getTurret; | ||
if (getNumber (_turretConfig >> "isCopilot") == 1) exitWith { | ||
_effectiveRole = "driver"; | ||
}; | ||
if ( | ||
_cargoIndex >= 0 // FFV | ||
|| {"" isEqualTo getText (_turretConfig >> "gun")} // turret without weapon | ||
) exitWith { | ||
_effectiveRole = "cargo"; | ||
}; | ||
_effectiveRole = "gunner"; // door gunners / 2nd turret | ||
_x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; | ||
|
||
if (!alive _unit) then { | ||
private _effectiveRole = _role; | ||
|
||
if ((_effectiveRole in ["driver", "gunner"]) && {unitIsUAV _target}) exitWith {}; // Ignoring UAV Driver/Gunner | ||
if ((_effectiveRole == "driver") && {(getNumber (configOf _target >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons) | ||
|
||
// Seats can be locked independently of the main vehicle | ||
if ((_effectiveRole == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);}; | ||
if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);}; | ||
if ((_turretPath isNotEqualTo []) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; | ||
|
||
if (_effectiveRole == "turret") then { | ||
private _turretConfig = [_target, _turretPath] call CBA_fnc_getTurret; | ||
|
||
if (getNumber (_turretConfig >> "isCopilot") == 1) exitWith { | ||
_effectiveRole = "driver"; | ||
}; | ||
TRACE_2("",_effectiveRole,_x); | ||
if (_effectiveRole != _desiredRole) exitWith {}; | ||
|
||
if (_turretPath isNotEqualTo []) then { | ||
// Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander | ||
ACE_player action ["GetInTurret", _target, _turretPath]; | ||
TRACE_3("Geting In Turret",_x,_role,_turretPath); | ||
} else { | ||
if (_cargoIndex > -1) then { | ||
// GetInCargo expects the index of the seat in the "cargo" array from fullCrew | ||
// See description: https://community.bistudio.com/wiki/fullCrew | ||
private _cargoActionIndex = -1; | ||
{ | ||
if ((_x select 2) == _cargoIndex) exitWith {_cargoActionIndex = _forEachIndex}; | ||
} forEach (fullCrew [_target, "cargo", true]); | ||
|
||
ACE_player action ["GetInCargo", _target, _cargoActionIndex]; | ||
TRACE_4("Geting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex); | ||
} else { | ||
ACE_player action ["GetIn" + _role, _target]; | ||
TRACE_2("Geting In",_x,_role); | ||
}; | ||
if ( | ||
_cargoIndex >= 0 || // FFV | ||
{getText (_turretConfig >> "gun") == ""} // Turret without weapon | ||
) exitWith { | ||
_effectiveRole = "cargo"; | ||
}; | ||
|
||
_hasAction = true; | ||
breakTo "SearchForSeat"; | ||
_effectiveRole = "gunner"; // Door gunners / 2nd turret | ||
}; | ||
} forEach (fullCrew [_target, "", true]); | ||
} forEach _sortedSeats; | ||
|
||
if (!_hasAction) then { | ||
TRACE_1("no empty seats",_hasAction); | ||
[localize LSTRING(VehicleFull)] call EFUNC(common,displayTextStructured); | ||
}; | ||
}; | ||
TRACE_2("",_effectiveRole,_x); | ||
|
||
if (_effectiveRole != _desiredRole) exitWith {}; | ||
|
||
if (_turretPath isNotEqualTo []) then { | ||
// Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander | ||
ACE_player action ["GetInTurret", _target, _turretPath]; | ||
TRACE_3("Getting In Turret",_x,_role,_turretPath); | ||
} else { | ||
if (_cargoIndex > -1) then { | ||
// GetInCargo expects the index of the seat in the "cargo" array from fullCrew | ||
// See description: https://community.bistudio.com/wiki/fullCrew | ||
private _cargoActionIndex = (fullCrew [_target, "cargo", true]) findIf {(_x select 2) == _cargoIndex}; | ||
|
||
true | ||
ACE_player action ["GetInCargo", _target, _cargoActionIndex]; | ||
TRACE_4("Getting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex); | ||
} else { | ||
ACE_player action ["GetIn" + _role, _target]; | ||
TRACE_2("Getting In",_x,_role); | ||
}; | ||
}; | ||
|
||
_hasAction = true; | ||
breakTo "SearchForSeat"; | ||
}; | ||
} forEach _fullCrew; | ||
} forEach _sortedSeats; | ||
|
||
if (!_hasAction) then { | ||
TRACE_1("no empty seats",_hasAction); | ||
[LLSTRING(VehicleFull)] call EFUNC(common,displayTextStructured); | ||
}; |