diff --git a/addons/advancedslingloading/CfgFunctions.hpp b/addons/advancedslingloading/CfgEventhandlers.hpp similarity index 100% rename from addons/advancedslingloading/CfgFunctions.hpp rename to addons/advancedslingloading/CfgEventhandlers.hpp diff --git a/addons/advancedslingloading/XEH_PREP.hpp b/addons/advancedslingloading/XEH_PREP.hpp index a4b521f2f..b7c49cf78 100644 --- a/addons/advancedslingloading/XEH_PREP.hpp +++ b/addons/advancedslingloading/XEH_PREP.hpp @@ -1 +1,63 @@ +PREP(addPlayerActions); +PREP(attachRopes); +PREP(attachRopesAction); +PREP(attachRopesActionCheck); +PREP(canAttachRopes); +PREP(canDeployRopes); +PREP(canDropRopes); +PREP(canExtendRopes); +PREP(canPickupRopes); +PREP(canReleaseCargo); +PREP(canRetractRopes); +PREP(canShortenRopes); +PREP(deployRopes); +PREP(deployRopesAction); +PREP(deployRopesActionCheck); +PREP(deployRopesCountAction); +PREP(deployRopesIndex); +PREP(deployRopesIndexAction); +PREP(dropRopes); +PREP(dropRopesAction); +PREP(dropRopesActionCheck); +PREP(extendRopes); +PREP(extendRopesAction); +PREP(extendRopesActionCheck); +PREP(extendRopesIndexAction); +PREP(findNearbyVehicles); +PREP(getActiveRopes); +PREP(getActiveRopesWithCargo); +PREP(getActiveRopesWithoutCargo); +PREP(getCargo); +PREP(getClosestRope); +PREP(getCornerPoints); +PREP(getInactiveRopes); +PREP(getRopes); +PREP(getRopesAndCargo); +PREP(getRopesCount); +PREP(getSlingLoadPoints); +PREP(hideObjectGlobal); +PREP(hint); PREP(initAdvancedSlingLoading); +PREP(isSupportedCargo); +PREP(isSupportedVehicle); +PREP(pickupRopes); +PREP(pickupRopesAction); +PREP(pickupRopesActionCheck); +PREP(releaseCargo); +PREP(releaseCargoAction); +PREP(releaseCargoActionCheck); +PREP(releaseCargoIndexAction); +PREP(remoteExec); +PREP(remoteExecServer); +PREP(retractRopes); +PREP(retractRopesAction); +PREP(retractRopesActionCheck); +PREP(retractRopesIndexAction); +PREP(ropeAdjustMass); +PREP(ropeGetLiftCapability); +PREP(ropeSetMass); +PREP(shortenRopes); +PREP(shortenRopesAction); +PREP(shortenRopesActionCheck); +PREP(shortenRopesIndexAction); +PREP(showSelectRopesMenu); diff --git a/addons/advancedslingloading/config.cpp b/addons/advancedslingloading/config.cpp index 1f05a8881..408ba999d 100644 --- a/addons/advancedslingloading/config.cpp +++ b/addons/advancedslingloading/config.cpp @@ -24,5 +24,5 @@ class CfgPatches { }; }; -#include "CfgFunctions.hpp" +#include "CfgEventhandlers.hpp" #include "CfgNetworkMessages.hpp" diff --git a/addons/advancedslingloading/functions/fnc_addPlayerActions.sqf b/addons/advancedslingloading/functions/fnc_addPlayerActions.sqf new file mode 100644 index 000000000..7e3c331b5 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_addPlayerActions.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Adds player actions for advanced sling loading + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ttt_advancedslingloading_fnc_addPlayerActions + * + * Public: No + */ + +player addAction ["Extend Cargo Ropes", { + [] call FUNC(extendRopesAction); +}, nil, 0, false, true, "", "call FUNC(extendRopesActionCheck)"]; + +player addAction ["Shorten Cargo Ropes", { + [] call FUNC(shortenRopesAction); +}, nil, 0, false, true, "", "call FUNC(shortenRopesActionCheck)"]; + +player addAction ["Release Cargo", { + [] call FUNC(releaseCargoAction); +}, nil, 0, false, true, "", "call FUNC(releaseCargoActionCheck)"]; + +player addAction ["Retract Cargo Ropes", { + [] call FUNC(retractRopesAction); +}, nil, 0, false, true, "", "call FUNC(retractRopesActionCheck)"]; + +player addAction ["Deploy Cargo Ropes", { + [] call FUNC(deployRopesAction); +}, nil, 0, false, true, "", "call FUNC(deployRopesActionCheck)"]; + +player addAction ["Attach To Cargo Ropes", { + [] call FUNC(attachRopesAction); +}, nil, 0, false, true, "", "call FUNC(attachRopesActionCheck)"]; + +player addAction ["Drop Cargo Ropes", { + [] call FUNC(dropRopesAction); +}, nil, 0, false, true, "", "call FUNC(dropRopesActionCheck)"]; + +player addAction ["Pickup Cargo Ropes", { + [] call FUNC(pickupRopesAction); +}, nil, 0, false, true, "", "call FUNC(pickupRopesActionCheck)"]; + +player addEventHandler ["Respawn", { + player setVariable ["ASL_Actions_Loaded", false]; +}]; diff --git a/addons/advancedslingloading/functions/fnc_attachRopes.sqf b/addons/advancedslingloading/functions/fnc_attachRopes.sqf new file mode 100644 index 000000000..dfab7c5b0 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_attachRopes.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Attaches ropes to cargo + * + * Arguments: + * 0: Cargo + * 1: Player + * + * Return Value: + * None + * + * Example: + * [_cargo, player] call ttt_advancedslingloading_fnc_attachRopes + * + * Public: No + */ + +params ["_cargo", "_player"]; +_vehicleWithIndex = _player getVariable ["ASL_Ropes_Vehicle", [objNull, 0]]; +_vehicle = _vehicleWithIndex select 0; +if (!isNull _vehicle) then { + if (local _vehicle) then { + private _ropes = [_vehicle, (_vehicleWithIndex select 1)] call FUNC(getRopes); + if (count _ropes == 4) then { + private _attachmentPoints = [_cargo] call FUNC(getCornerPoints); + private _ropeLength = (ropeLength (_ropes select 0)); + private _objDistance = (_cargo distance _vehicle) + 2; + if (_objDistance > _ropeLength) then { + [["The cargo ropes are too short. Move vehicle closer.", false], "ASL_Hint", _player] call FUNC(remoteExec); + } else { + [_vehicle, _player, (_vehicleWithIndex select 1)] call FUNC(dropRopes); + [_cargo, _attachmentPoints select 0, [0, 0, -1]] ropeAttachTo (_ropes select 0); + [_cargo, _attachmentPoints select 1, [0, 0, -1]] ropeAttachTo (_ropes select 1); + [_cargo, _attachmentPoints select 2, [0, 0, -1]] ropeAttachTo (_ropes select 2); + [_cargo, _attachmentPoints select 3, [0, 0, -1]] ropeAttachTo (_ropes select 3); + private _allCargo = _vehicle getVariable ["ASL_Cargo", []]; + _allCargo set [(_vehicleWithIndex select 1), _cargo]; + _vehicle setVariable ["ASL_Cargo", _allCargo, true]; + if (missionNamespace getVariable ["ASL_HEAVY_LIFTING_ENABLED", false]) then { + [_cargo, _vehicle, _ropes] spawn FUNC(ropeAdjustMass); + }; + }; + }; + } else { + [_this, "ASL_Attach_Ropes", _vehicle, true] call FUNC(remoteExec); + }; +}; diff --git a/addons/advancedslingloading/functions/fnc_attachRopesAction.sqf b/addons/advancedslingloading/functions/fnc_attachRopesAction.sqf new file mode 100644 index 000000000..1ae03f45a --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_attachRopesAction.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action handler for attaching ropes to cargo + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ttt_advancedslingloading_fnc_attachRopesAction + * + * Public: No + */ + +private ["_vehicle", "_cargo", "_canBeAttached"]; +_cargo = cursorTarget; +_vehicle = (player getVariable ["ASL_Ropes_Vehicle", [objNull, 0]]) select 0; +if ([_vehicle, _cargo] call FUNC(canAttachRopes)) then { + + _canBeAttached = true; + + if !(missionNamespace getVariable ["ASL_LOCKED_VEHICLES_ENABLED",false]) then { + if (locked _cargo > 1) then { + ["Cannot attach cargo ropes to locked vehicle", false] call FUNC(hint); + _canBeAttached = false; + }; + }; + + if !(missionNamespace getVariable ["ASL_EXILE_SAFEZONE_ENABLED",false]) then { + if (!isNil "ExilePlayerInSafezone") then { + if (ExilePlayerInSafezone) then { + ["Cannot attach cargo ropes in safe zone", false] call FUNC(hint); + _canBeAttached = false; + }; + }; + }; + + if (_canBeAttached) then { + [_cargo, player] call FUNC(attachRopes); + }; + +}; diff --git a/addons/advancedslingloading/functions/fnc_attachRopesActionCheck.sqf b/addons/advancedslingloading/functions/fnc_attachRopesActionCheck.sqf new file mode 100644 index 000000000..87ab4d4b5 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_attachRopesActionCheck.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action check for attaching ropes + * + * Arguments: + * None + * + * Return Value: + * Can attach ropes + * + * Example: + * [] call ttt_advancedslingloading_fnc_attachRopesActionCheck + * + * Public: No + */ + +private ["_vehicleWithIndex", "_cargo"]; +_vehicleWithIndex = player getVariable ["ASL_Ropes_Vehicle", [objNull, 0]]; +_cargo = cursorTarget; +[_vehicleWithIndex select 0, _cargo] call FUNC(canAttachRopes); diff --git a/addons/advancedslingloading/functions/fnc_canAttachRopes.sqf b/addons/advancedslingloading/functions/fnc_canAttachRopes.sqf new file mode 100644 index 000000000..0baff11d8 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_canAttachRopes.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Checks if ropes can be attached to cargo + * + * Arguments: + * 0: Vehicle + * 1: Cargo + * + * Return Value: + * Can attach ropes + * + * Example: + * [_vehicle, _cargo] call ttt_advancedslingloading_fnc_canAttachRopes + * + * Public: No + */ + +params ["_vehicle", "_cargo"]; +if (!isNull _vehicle && !isNull _cargo) then { + [_vehicle, _cargo] call FUNC(isSupportedCargo) && isNull objectParent player && player distance _cargo < ASL_PICKUP_DISTANCE && _vehicle != _cargo; +} else { + false; +}; diff --git a/addons/advancedslingloading/functions/fnc_canDeployRopes.sqf b/addons/advancedslingloading/functions/fnc_canDeployRopes.sqf new file mode 100644 index 000000000..6319b6bd6 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_canDeployRopes.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Checks if ropes can be deployed + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Can deploy ropes + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_canDeployRopes + * + * Public: No + */ + +params ["_vehicle"]; +if (player distance _vehicle > ASL_PICKUP_DISTANCE) exitWith { false }; +if !([_vehicle] call FUNC(isSupportedVehicle)) exitWith { false }; +_existingVehicle = player getVariable ["ASL_Ropes_Vehicle", []]; +if (count _existingVehicle > 0) exitWith { false }; +private _existingRopes = _vehicle getVariable ["ASL_Ropes", []]; +if ((count _existingRopes) == 0) exitWith { true }; +private _activeRopes = [_vehicle] call FUNC(getActiveRopes); +if ((count _existingRopes) > 0 && (count _existingRopes) == (count _activeRopes)) exitWith { false }; +true; diff --git a/addons/advancedslingloading/functions/fnc_canDropRopes.sqf b/addons/advancedslingloading/functions/fnc_canDropRopes.sqf new file mode 100644 index 000000000..1f6f07c6a --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_canDropRopes.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Checks if ropes can be dropped + * + * Arguments: + * None + * + * Return Value: + * Can drop ropes + * + * Example: + * [] call ttt_advancedslingloading_fnc_canDropRopes + * + * Public: No + */ + +count (player getVariable ["ASL_Ropes_Vehicle", []]) > 0 && isNull objectParent player; diff --git a/addons/advancedslingloading/functions/fnc_canExtendRopes.sqf b/addons/advancedslingloading/functions/fnc_canExtendRopes.sqf new file mode 100644 index 000000000..c2443dd9e --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_canExtendRopes.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Checks if ropes can be extended + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Can extend ropes + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_canExtendRopes + * + * Public: No + */ + +params ["_vehicle"]; +if (player distance _vehicle > ASL_PICKUP_DISTANCE) exitWith { false }; +if !([_vehicle] call FUNC(isSupportedVehicle)) exitWith { false }; +private _existingRopes = _vehicle getVariable ["ASL_Ropes", []]; +if ((count _existingRopes) == 0) exitWith { false }; +private _activeRopes = [_vehicle] call FUNC(getActiveRopes); +if ((count _activeRopes) == 0) exitWith { false }; +true; diff --git a/addons/advancedslingloading/functions/fnc_canPickupRopes.sqf b/addons/advancedslingloading/functions/fnc_canPickupRopes.sqf new file mode 100644 index 000000000..49586252f --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_canPickupRopes.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Checks if ropes can be picked up + * + * Arguments: + * None + * + * Return Value: + * Can pickup ropes + * + * Example: + * [] call ttt_advancedslingloading_fnc_canPickupRopes + * + * Public: No + */ + +count (player getVariable ["ASL_Ropes_Vehicle", []]) == 0 && count (missionNamespace getVariable ["ASL_Nearby_Vehicles", []]) > 0 && isNull objectParent player; diff --git a/addons/advancedslingloading/functions/fnc_canReleaseCargo.sqf b/addons/advancedslingloading/functions/fnc_canReleaseCargo.sqf new file mode 100644 index 000000000..1c4b35f0c --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_canReleaseCargo.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Checks if cargo can be released + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Can release cargo + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_canReleaseCargo + * + * Public: No + */ + +params ["_vehicle"]; +if (player distance _vehicle > ASL_PICKUP_DISTANCE) exitWith { false }; +if !([_vehicle] call FUNC(isSupportedVehicle)) exitWith { false }; +private _existingRopes = _vehicle getVariable ["ASL_Ropes", []]; +if ((count _existingRopes) == 0) exitWith { false }; +private _activeRopes = [_vehicle] call FUNC(getActiveRopesWithCargo); +if ((count _activeRopes) == 0) exitWith { false }; +true; diff --git a/addons/advancedslingloading/functions/fnc_canRetractRopes.sqf b/addons/advancedslingloading/functions/fnc_canRetractRopes.sqf new file mode 100644 index 000000000..871c0b1af --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_canRetractRopes.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Checks if ropes can be retracted + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Can retract ropes + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_canRetractRopes + * + * Public: No + */ + +params ["_vehicle"]; +if (player distance _vehicle > ASL_PLAYER_DISTANCE) exitWith { false }; +if !([_vehicle] call FUNC(isSupportedVehicle)) exitWith { false }; +private _existingRopes = _vehicle getVariable ["ASL_Ropes", []]; +if ((count _existingRopes) == 0) exitWith { false }; +private _activeRopes = [_vehicle] call FUNC(getActiveRopesWithoutCargo); +if ((count _activeRopes) == 0) exitWith { false }; +true; diff --git a/addons/advancedslingloading/functions/fnc_canShortenRopes.sqf b/addons/advancedslingloading/functions/fnc_canShortenRopes.sqf new file mode 100644 index 000000000..f95b9ba4e --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_canShortenRopes.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Checks if ropes can be shortened + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Can shorten ropes + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_canShortenRopes + * + * Public: No + */ + +params ["_vehicle"]; +if (player distance _vehicle > ASL_PICKUP_DISTANCE) exitWith { false }; +if !([_vehicle] call FUNC(isSupportedVehicle)) exitWith { false }; +private _existingRopes = _vehicle getVariable ["ASL_Ropes", []]; +if ((count _existingRopes) == 0) exitWith { false }; +private _activeRopes = [_vehicle] call FUNC(getActiveRopes); +if ((count _activeRopes) == 0) exitWith { false }; +true; diff --git a/addons/advancedslingloading/functions/fnc_deployRopes.sqf b/addons/advancedslingloading/functions/fnc_deployRopes.sqf new file mode 100644 index 000000000..d0dda2d8d --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_deployRopes.sqf @@ -0,0 +1,48 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Deploys cargo ropes from vehicle + * + * Arguments: + * 0: Vehicle + * 1: Player + * 2: Cargo count (optional, default 1) + * 3: Rope length (optional, default 15) + * + * Return Value: + * None + * + * Example: + * [_vehicle, player, 1, 15] call ttt_advancedslingloading_fnc_deployRopes + * + * Public: No + */ + +params ["_vehicle", "_player", ["_cargoCount", 1], ["_ropeLength", ASL_DEFAULT_ROPE_LENGTH]]; +if (local _vehicle) then { + private _slingLoadPoints = [_vehicle] call FUNC(getSlingLoadPoints); + private _existingRopes = _vehicle getVariable ["ASL_Ropes", []]; + if (count _existingRopes == 0) then { + if (count _slingLoadPoints == 0) exitWith { + [["Vehicle doesn't support cargo ropes", false], "ASL_Hint", _player] call FUNC(remoteExec); + }; + if (count _slingLoadPoints < _cargoCount) exitWith { + [["Vehicle doesn't support " + _cargoCount + " cargo ropes", false], "ASL_Hint", _player] call FUNC(remoteExec); + }; + private _cargoRopes = []; + private _cargo = []; + for "_i" from 0 to (_cargoCount - 1) do { + _cargoRopes pushBack []; + _cargo pushBack objNull; + }; + _vehicle setVariable ["ASL_Ropes", _cargoRopes, true]; + _vehicle setVariable ["ASL_Cargo", _cargo, true]; + for "_i" from 0 to (_cargoCount - 1) do { + [_vehicle, _player, _i] call FUNC(deployRopesIndex); + }; + } else { + [["Vehicle already has cargo ropes deployed", false], "ASL_Hint", _player] call FUNC(remoteExec); + }; +} else { + [_this, "ASL_Deploy_Ropes", _vehicle, true] call FUNC(remoteExec); +}; diff --git a/addons/advancedslingloading/functions/fnc_deployRopesAction.sqf b/addons/advancedslingloading/functions/fnc_deployRopesAction.sqf new file mode 100644 index 000000000..896bb2ed1 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_deployRopesAction.sqf @@ -0,0 +1,73 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action handler for deploying ropes + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ttt_advancedslingloading_fnc_deployRopesAction + * + * Public: No + */ + +private _vehicle = objNull; +if (isNull objectParent player) then { + _vehicle = cursorTarget; +} else { + _vehicle = vehicle player; +}; +if ([_vehicle] call FUNC(canDeployRopes)) then { + + private _canDeployRopes = true; + + if !(missionNamespace getVariable ["ASL_LOCKED_VEHICLES_ENABLED", false]) then { + if (locked _vehicle > 1) then { + ["Cannot deploy cargo ropes from locked vehicle", false] call FUNC(hint); + _canDeployRopes = false; + }; + }; + + if (_canDeployRopes) then { + + private _inactiveRopes = [_vehicle] call FUNC(getInactiveRopes); + + if (count _inactiveRopes > 0) then { + + if (count _inactiveRopes > 1) then { + player setVariable ["ASL_Deploy_Ropes_Index_Vehicle", _vehicle]; + ["Deploy Cargo Ropes", "ASL_Deploy_Ropes_Index_Action", _inactiveRopes] call FUNC(showSelectRopesMenu); + } else { + [_vehicle, player, (_inactiveRopes select 0) select 0] call FUNC(deployRopesIndex); + }; + + } else { + + private _slingLoadPoints = [_vehicle] call FUNC(getSlingLoadPoints); + if (count _slingLoadPoints > 1) then { + player setVariable ["ASL_Deploy_Count_Vehicle", _vehicle]; + ASL_Deploy_Ropes_Count_Menu = [ + ["Deploy Ropes", false] + ]; + ASL_Deploy_Ropes_Count_Menu pushBack ["For Single Cargo", [0], "", -5, [["expression", "[1] call ASL_Deploy_Ropes_Count_Action"]], "1", "1"]; + if ((count _slingLoadPoints) > 1) then { + ASL_Deploy_Ropes_Count_Menu pushBack ["For Double Cargo", [0], "", -5, [["expression", "[2] call ASL_Deploy_Ropes_Count_Action"]], "1", "1"]; + }; + if ((count _slingLoadPoints) > 2) then { + ASL_Deploy_Ropes_Count_Menu pushBack ["For Triple Cargo", [0], "", -5, [["expression", "[3] call ASL_Deploy_Ropes_Count_Action"]], "1", "1"]; + }; + showCommandingMenu ""; + showCommandingMenu "#USER:ASL_Deploy_Ropes_Count_Menu"; + } else { + [_vehicle, player] call FUNC(deployRopes); + }; + + }; + + }; + +}; diff --git a/addons/advancedslingloading/functions/fnc_deployRopesActionCheck.sqf b/addons/advancedslingloading/functions/fnc_deployRopesActionCheck.sqf new file mode 100644 index 000000000..55f311c11 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_deployRopesActionCheck.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action check for deploying ropes + * + * Arguments: + * None + * + * Return Value: + * Can deploy ropes + * + * Example: + * [] call ttt_advancedslingloading_fnc_deployRopesActionCheck + * + * Public: No + */ + +if (isNull objectParent player) then { + [cursorTarget] call FUNC(canDeployRopes); +} else { + [vehicle player] call FUNC(canDeployRopes); +}; diff --git a/addons/advancedslingloading/functions/fnc_deployRopesCountAction.sqf b/addons/advancedslingloading/functions/fnc_deployRopesCountAction.sqf new file mode 100644 index 000000000..af7f3f5fb --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_deployRopesCountAction.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Count action handler for deploying multiple rope sets + * + * Arguments: + * 0: Rope count + * + * Return Value: + * None + * + * Example: + * [2] call ttt_advancedslingloading_fnc_deployRopesCountAction + * + * Public: No + */ + +params ["_count"]; +private ["_vehicle", "_canDeployRopes"]; +_vehicle = player getVariable ["ASL_Deploy_Count_Vehicle", objNull]; +if (_count > 0 && !isNull _vehicle && [_vehicle] call FUNC(canDeployRopes)) then { + [_vehicle, player, _count] call FUNC(deployRopes); +}; diff --git a/addons/advancedslingloading/functions/fnc_deployRopesIndex.sqf b/addons/advancedslingloading/functions/fnc_deployRopesIndex.sqf new file mode 100644 index 000000000..d5a7a024e --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_deployRopesIndex.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Deploys rope at specific index + * + * Arguments: + * 0: Vehicle + * 1: Player + * 2: Rope index (optional, default 0) + * 3: Rope length (optional, default 15) + * + * Return Value: + * None + * + * Example: + * [_vehicle, player, 0, 15] call ttt_advancedslingloading_fnc_deployRopesIndex + * + * Public: No + */ + +params ["_vehicle", "_player", ["_ropesIndex", 0], ["_ropeLength", ASL_DEFAULT_ROPE_LENGTH]]; +if (local _vehicle) then { + private _existingRopes = [_vehicle, _ropesIndex] call FUNC(getRopes); + private _existingRopesCount = [_vehicle] call FUNC(getRopesCount); + if (count _existingRopes == 0) then { + _slingLoadPoints = [_vehicle] call FUNC(getSlingLoadPoints); + _cargoRopes = []; + _cargoRopes pushBack ropeCreate [_vehicle, (_slingLoadPoints select (_existingRopesCount - 1)) select _ropesIndex, 0]; + _cargoRopes pushBack ropeCreate [_vehicle, (_slingLoadPoints select (_existingRopesCount - 1)) select _ropesIndex, 0]; + _cargoRopes pushBack ropeCreate [_vehicle, (_slingLoadPoints select (_existingRopesCount - 1)) select _ropesIndex, 0]; + _cargoRopes pushBack ropeCreate [_vehicle, (_slingLoadPoints select (_existingRopesCount - 1)) select _ropesIndex, 0]; + { + ropeUnwind [_x, ASL_ROPE_UNWIND_SPEED, _ropeLength]; + } forEach _cargoRopes; + private _allRopes = _vehicle getVariable ["ASL_Ropes", []]; + _allRopes set [_ropesIndex, _cargoRopes]; + _vehicle setVariable ["ASL_Ropes", _allRopes, true]; + }; +} else { + [_this, "ASL_Deploy_Ropes_Index", _vehicle, true] call FUNC(remoteExec); +}; diff --git a/addons/advancedslingloading/functions/fnc_deployRopesIndexAction.sqf b/addons/advancedslingloading/functions/fnc_deployRopesIndexAction.sqf new file mode 100644 index 000000000..79bef1fea --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_deployRopesIndexAction.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Index action handler for deploying specific ropes + * + * Arguments: + * 0: Rope index + * + * Return Value: + * None + * + * Example: + * [0] call ttt_advancedslingloading_fnc_deployRopesIndexAction + * + * Public: No + */ + +params ["_ropesIndex"]; +private ["_vehicle"]; +_vehicle = player getVariable ["ASL_Deploy_Ropes_Index_Vehicle", objNull]; +if (_ropesIndex >= 0 && !isNull _vehicle && [_vehicle] call FUNC(canDeployRopes)) then { + [_vehicle, player, _ropesIndex] call FUNC(deployRopesIndex); +}; diff --git a/addons/advancedslingloading/functions/fnc_dropRopes.sqf b/addons/advancedslingloading/functions/fnc_dropRopes.sqf new file mode 100644 index 000000000..fe0cf31e2 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_dropRopes.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Drops ropes player is carrying + * + * Arguments: + * 0: Vehicle + * 1: Player + * 2: Rope index (optional, default 0) + * + * Return Value: + * None + * + * Example: + * [_vehicle, player, 0] call ttt_advancedslingloading_fnc_dropRopes + * + * Public: No + */ + +params ["_vehicle", "_player", ["_ropesIndex", 0]]; +if (local _vehicle) then { + private _helper = (_player getVariable ["ASL_Ropes_Pick_Up_Helper", objNull]); + if (!isNull _helper) then { + private _existingRopes = [_vehicle, _ropesIndex] call FUNC(getRopes); + { + _helper ropeDetach _x; + } forEach _existingRopes; + detach _helper; + deleteVehicle _helper; + }; + _player setVariable ["ASL_Ropes_Vehicle", nil, true]; + _player setVariable ["ASL_Ropes_Pick_Up_Helper", nil, true]; +} else { + [_this, "ASL_Drop_Ropes", _vehicle, true] call FUNC(remoteExec); +}; diff --git a/addons/advancedslingloading/functions/fnc_dropRopesAction.sqf b/addons/advancedslingloading/functions/fnc_dropRopesAction.sqf new file mode 100644 index 000000000..5cee2b991 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_dropRopesAction.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action handler for dropping ropes + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ttt_advancedslingloading_fnc_dropRopesAction + * + * Public: No + */ + +private ["_vehicleAndIndex"]; +if ([] call FUNC(canDropRopes)) then { + _vehicleAndIndex = player getVariable ["ASL_Ropes_Vehicle", []]; + if (count _vehicleAndIndex == 2) then { + [_vehicleAndIndex select 0, player, _vehicleAndIndex select 1] call FUNC(dropRopes); + }; +}; diff --git a/addons/advancedslingloading/functions/fnc_dropRopesActionCheck.sqf b/addons/advancedslingloading/functions/fnc_dropRopesActionCheck.sqf new file mode 100644 index 000000000..5e647a4df --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_dropRopesActionCheck.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action check for dropping ropes + * + * Arguments: + * None + * + * Return Value: + * Can drop ropes + * + * Example: + * [] call ttt_advancedslingloading_fnc_dropRopesActionCheck + * + * Public: No + */ + +[] call FUNC(canDropRopes); diff --git a/addons/advancedslingloading/functions/fnc_extendRopes.sqf b/addons/advancedslingloading/functions/fnc_extendRopes.sqf new file mode 100644 index 000000000..a15e0eaad --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_extendRopes.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Extends cargo ropes + * + * Arguments: + * 0: Vehicle + * 1: Player + * 2: Rope index (optional, default 0) + * + * Return Value: + * None + * + * Example: + * [_vehicle, player, 0] call ttt_advancedslingloading_fnc_extendRopes + * + * Public: No + */ + +params ["_vehicle", "_player", ["_ropeIndex", 0]]; +if (local _vehicle) then { + private _existingRopes = [_vehicle, _ropeIndex] call FUNC(getRopes); + if (count _existingRopes > 0) then { + _ropeLength = ropeLength (_existingRopes select 0); + if (_ropeLength <= 100) then { + { + ropeUnwind [_x, 3, ASL_ROPE_UNWIND_SPEED, true]; + } forEach _existingRopes; + }; + }; +} else { + [_this, "ASL_Extend_Ropes", _vehicle, true] call FUNC(remoteExec); +}; diff --git a/addons/advancedslingloading/functions/fnc_extendRopesAction.sqf b/addons/advancedslingloading/functions/fnc_extendRopesAction.sqf new file mode 100644 index 000000000..e08793d35 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_extendRopesAction.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action handler for extending ropes + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ttt_advancedslingloading_fnc_extendRopesAction + * + * Public: No + */ + +private _vehicle = vehicle player; +if ([_vehicle] call FUNC(canExtendRopes)) then { + private _activeRopes = [_vehicle] call FUNC(getActiveRopes); + if (count _activeRopes > 1) then { + player setVariable ["ASL_Extend_Index_Vehicle", _vehicle]; + ["Extend Cargo Ropes", "ASL_Extend_Ropes_Index_Action", _activeRopes] call FUNC(showSelectRopesMenu); + } else { + if (count _activeRopes == 1) then { + [_vehicle, player, (_activeRopes select 0) select 0] call FUNC(extendRopes); + }; + }; +}; diff --git a/addons/advancedslingloading/functions/fnc_extendRopesActionCheck.sqf b/addons/advancedslingloading/functions/fnc_extendRopesActionCheck.sqf new file mode 100644 index 000000000..444b3c5d1 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_extendRopesActionCheck.sqf @@ -0,0 +1,19 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action check for extending ropes + * + * Arguments: + * None + * + * Return Value: + * Can extend ropes + * + * Example: + * [] call ttt_advancedslingloading_fnc_extendRopesActionCheck + * + * Public: No + */ + +if (isNull objectParent player) exitWith {false}; +[vehicle player] call FUNC(canExtendRopes); diff --git a/addons/advancedslingloading/functions/fnc_extendRopesIndexAction.sqf b/addons/advancedslingloading/functions/fnc_extendRopesIndexAction.sqf new file mode 100644 index 000000000..8a91479cd --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_extendRopesIndexAction.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Index action handler for extending specific ropes + * + * Arguments: + * 0: Rope index + * + * Return Value: + * None + * + * Example: + * [0] call ttt_advancedslingloading_fnc_extendRopesIndexAction + * + * Public: No + */ + +params ["_ropeIndex"]; +private ["_vehicle", "_canDeployRopes"]; +_vehicle = player getVariable ["ASL_Extend_Index_Vehicle", objNull]; +if (_ropeIndex >= 0 && !isNull _vehicle && [_vehicle] call FUNC(canExtendRopes)) then { + [_vehicle, player, _ropeIndex] call FUNC(extendRopes); +}; diff --git a/addons/advancedslingloading/functions/fnc_findNearbyVehicles.sqf b/addons/advancedslingloading/functions/fnc_findNearbyVehicles.sqf new file mode 100644 index 000000000..9d952a568 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_findNearbyVehicles.sqf @@ -0,0 +1,43 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Finds nearby vehicles with ropes within player range + * + * Arguments: + * None + * + * Return Value: + * Array of nearby vehicles with ropes + * + * Example: + * [] call ttt_advancedslingloading_fnc_findNearbyVehicles + * + * Public: No + */ + +private _nearVehicles = []; +{ + _nearVehicles append (player nearObjects [_x, ASL_NEARBY_VEHICLE_DISTANCE]); +} forEach (missionNamespace getVariable ["ASL_Supported_Vehicles_OVERRIDE", missionNamespace getVariable ["ASL_Supported_Vehicles", []]]); +private _nearVehiclesWithRopes = []; +{ + private _vehicle = _x; + { + private _ropes = _vehicle getVariable ["ASL_Ropes", []]; + if (count _ropes > (_x select 0)) then { + _ropes = _ropes select (_x select 0); + { + private _ends = ropeEndPosition _x; + if (count _ends == 2) then { + private _end1 = _ends select 0; + private _end2 = _ends select 1; + private _playerPosAGL = ASLToAGL getPosASL player; + if ((_playerPosAGL distance _end1) < ASL_ROPE_PROXIMITY_DISTANCE || (_playerPosAGL distance _end2) < ASL_ROPE_PROXIMITY_DISTANCE) then { + _nearVehiclesWithRopes pushBack _vehicle; + } + }; + } forEach _ropes; + }; + } forEach ([_vehicle] call FUNC(getActiveRopes)); +} forEach _nearVehicles; +_nearVehiclesWithRopes; diff --git a/addons/advancedslingloading/functions/fnc_getActiveRopes.sqf b/addons/advancedslingloading/functions/fnc_getActiveRopes.sqf new file mode 100644 index 000000000..006d2e89b --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getActiveRopes.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets all active rope indexes and position labels + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Array of active rope indexes with labels + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_getActiveRopes + * + * Public: No + */ + +params ["_vehicle"]; +private _activeRopes = []; +private _existingRopes = _vehicle getVariable ["ASL_Ropes", []]; +private _ropeLabelSets = [["Center"], ["Front", "Rear"], ["Front", "Center", "Rear"]]; +private _ropeIndex = 0; +private _totalExistingRopes = count _existingRopes; +{ + if (count _x > 0) then { + private _ropeLabels = _ropeLabelSets select (_totalExistingRopes - 1); + _activeRopes pushBack [_ropeIndex, _ropeLabels select _ropeIndex]; + }; + _ropeIndex = _ropeIndex + 1; +} forEach _existingRopes; +_activeRopes; diff --git a/addons/advancedslingloading/functions/fnc_getActiveRopesWithCargo.sqf b/addons/advancedslingloading/functions/fnc_getActiveRopesWithCargo.sqf new file mode 100644 index 000000000..8dc3239a3 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getActiveRopesWithCargo.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets active ropes that have cargo attached + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Array of active rope indexes with cargo + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_getActiveRopesWithCargo + * + * Public: No + */ + +params ["_vehicle"]; +private _activeRopesWithCargo = []; +private _existingCargo = _vehicle getVariable ["ASL_Cargo", []]; +private _activeRopes = [_vehicle] call FUNC(getActiveRopes); +{ + private _cargo = _existingCargo select (_x select 0); + if (!isNull _cargo) then { + _activeRopesWithCargo pushBack _x; + }; +} forEach _activeRopes; +_activeRopesWithCargo; diff --git a/addons/advancedslingloading/functions/fnc_getActiveRopesWithoutCargo.sqf b/addons/advancedslingloading/functions/fnc_getActiveRopesWithoutCargo.sqf new file mode 100644 index 000000000..3a653a380 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getActiveRopesWithoutCargo.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets active ropes without cargo attached + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Array of active rope indexes without cargo + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_getActiveRopesWithoutCargo + * + * Public: No + */ + +params ["_vehicle"]; +private _activeRopesWithoutCargo = []; +private _existingCargo = _vehicle getVariable ["ASL_Cargo", []]; +private _activeRopes = [_vehicle] call FUNC(getActiveRopes); +{ + private _cargo = _existingCargo select (_x select 0); + if (isNull _cargo) then { + _activeRopesWithoutCargo pushBack _x; + }; +} forEach _activeRopes; +_activeRopesWithoutCargo; diff --git a/addons/advancedslingloading/functions/fnc_getCargo.sqf b/addons/advancedslingloading/functions/fnc_getCargo.sqf new file mode 100644 index 000000000..395b80c35 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getCargo.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets cargo at a specific rope index + * + * Arguments: + * 0: Vehicle + * 1: Rope index + * + * Return Value: + * Cargo object + * + * Example: + * [_vehicle, 0] call ttt_advancedslingloading_fnc_getCargo + * + * Public: No + */ + +params ["_vehicle", "_ropeIndex"]; +private _selectedCargo = objNull; +private _allCargo = _vehicle getVariable ["ASL_Cargo", []]; +if (count _allCargo > _ropeIndex) then { + _selectedCargo = _allCargo select _ropeIndex; +}; +_selectedCargo; diff --git a/addons/advancedslingloading/functions/fnc_getClosestRope.sqf b/addons/advancedslingloading/functions/fnc_getClosestRope.sqf new file mode 100644 index 000000000..e00b710fe --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getClosestRope.sqf @@ -0,0 +1,42 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets the closest rope to the player + * + * Arguments: + * None + * + * Return Value: + * Array [vehicle, ropeIndex] + * + * Example: + * [] call ttt_advancedslingloading_fnc_getClosestRope + * + * Public: No + */ + +private _nearbyVehicles = missionNamespace getVariable ["ASL_Nearby_Vehicles", []]; +private _closestVehicle = objNull; +private _closestRopeIndex = 0; +private _closestDistance = -1; +{ + private _vehicle = _x; + { + private _activeRope = _x; + private _ropes = [_vehicle, (_activeRope select 0)] call FUNC(getRopes); + { + private _ends = ropeEndPosition _x; + if (count _ends == 2) then { + private _end1 = _ends select 0; + private _end2 = _ends select 1; + private _minEndDistance = ((position player) distance _end1) min ((position player) distance _end2); + if (_closestDistance == -1 || _closestDistance > _minEndDistance) then { + _closestDistance = _minEndDistance; + _closestRopeIndex = (_activeRope select 0); + _closestVehicle = _vehicle; + }; + }; + } forEach _ropes; + } forEach ([_vehicle] call FUNC(getActiveRopes)); +} forEach _nearbyVehicles; +[_closestVehicle, _closestRopeIndex]; diff --git a/addons/advancedslingloading/functions/fnc_getCornerPoints.sqf b/addons/advancedslingloading/functions/fnc_getCornerPoints.sqf new file mode 100644 index 000000000..cb2ffa27c --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getCornerPoints.sqf @@ -0,0 +1,47 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets the corner points of a vehicle's bounding box + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Array of corner points [rear, rear2, front, front2] + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_getCornerPoints + * + * Public: No + */ + +params ["_vehicle"]; + +// Correct width and length factor for air +private _widthFactor = ASL_WIDTH_FACTOR_DEFAULT; +private _lengthFactor = ASL_LENGTH_FACTOR_DEFAULT; +if (_vehicle isKindOf "Air") then { + _widthFactor = ASL_WIDTH_FACTOR_AIR; +}; +if (_vehicle isKindOf "Helicopter") then { + _widthFactor = ASL_WIDTH_FACTOR_HELI; + _lengthFactor = ASL_LENGTH_FACTOR_HELI; +}; + +private _centerOfMass = getCenterOfMass _vehicle; +private _bbr = boundingBoxReal _vehicle; +private _p1 = _bbr select 0; +private _p2 = _bbr select 1; +private _maxWidth = abs ((_p2 select 0) - (_p1 select 0)); +private _widthOffset = ((_maxWidth / 2) - abs (_centerOfMass select 0)) * _widthFactor; +private _maxLength = abs ((_p2 select 1) - (_p1 select 1)); +private _lengthOffset = ((_maxLength / 2) - abs (_centerOfMass select 1)) * _lengthFactor; +private _maxHeight = abs ((_p2 select 2) - (_p1 select 2)); +private _heightOffset = _maxHeight / ASL_HEIGHT_DIVISOR; + +private _rearCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) - _lengthOffset, (_centerOfMass select 2) + _heightOffset]; +private _rearCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) - _lengthOffset, (_centerOfMass select 2) + _heightOffset]; +private _frontCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) + _lengthOffset, (_centerOfMass select 2) + _heightOffset]; +private _frontCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) + _lengthOffset, (_centerOfMass select 2) + _heightOffset]; + +[_rearCorner, _rearCorner2, _frontCorner, _frontCorner2]; diff --git a/addons/advancedslingloading/functions/fnc_getInactiveRopes.sqf b/addons/advancedslingloading/functions/fnc_getInactiveRopes.sqf new file mode 100644 index 000000000..65ed65396 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getInactiveRopes.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets all inactive rope indexes and position labels + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Array of inactive rope indexes with labels + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_getInactiveRopes + * + * Public: No + */ + +params ["_vehicle"]; +private _inactiveRopes = []; +private _existingRopes = _vehicle getVariable ["ASL_Ropes", []]; +private _ropeLabelSets = [["Center"], ["Front", "Rear"], ["Front", "Center", "Rear"]]; +private _ropeIndex = 0; +private _totalExistingRopes = count _existingRopes; +{ + if (count _x == 0) then { + private _ropeLabels = _ropeLabelSets select (_totalExistingRopes - 1); + _inactiveRopes pushBack [_ropeIndex, _ropeLabels select _ropeIndex]; + }; + _ropeIndex = _ropeIndex + 1; +} forEach _existingRopes; +_inactiveRopes; diff --git a/addons/advancedslingloading/functions/fnc_getRopes.sqf b/addons/advancedslingloading/functions/fnc_getRopes.sqf new file mode 100644 index 000000000..c2885c012 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getRopes.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets ropes at a specific index + * + * Arguments: + * 0: Vehicle + * 1: Rope index + * + * Return Value: + * Array of rope objects + * + * Example: + * [_vehicle, 0] call ttt_advancedslingloading_fnc_getRopes + * + * Public: No + */ + +params ["_vehicle", "_ropeIndex"]; +private _selectedRopes = []; +private _allRopes = _vehicle getVariable ["ASL_Ropes", []]; +if (count _allRopes > _ropeIndex) then { + _selectedRopes = _allRopes select _ropeIndex; +}; +_selectedRopes; diff --git a/addons/advancedslingloading/functions/fnc_getRopesAndCargo.sqf b/addons/advancedslingloading/functions/fnc_getRopesAndCargo.sqf new file mode 100644 index 000000000..6590a3475 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getRopesAndCargo.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets ropes and cargo at a specific index + * + * Arguments: + * 0: Vehicle + * 1: Rope index + * + * Return Value: + * Array [ropes, cargo] + * + * Example: + * [_vehicle, 0] call ttt_advancedslingloading_fnc_getRopesAndCargo + * + * Public: No + */ + +params ["_vehicle", "_ropeIndex"]; +private _selectedCargo = [_vehicle, _ropeIndex] call FUNC(getCargo); +private _selectedRopes = [_vehicle, _ropeIndex] call FUNC(getRopes); +[_selectedRopes, _selectedCargo]; diff --git a/addons/advancedslingloading/functions/fnc_getRopesCount.sqf b/addons/advancedslingloading/functions/fnc_getRopesCount.sqf new file mode 100644 index 000000000..5082e7c1f --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getRopesCount.sqf @@ -0,0 +1,19 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets the total number of rope sets + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Number of rope sets + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_getRopesCount + * + * Public: No + */ + +params ["_vehicle"]; +count (_vehicle getVariable ["ASL_Ropes", []]); diff --git a/addons/advancedslingloading/functions/fnc_getSlingLoadPoints.sqf b/addons/advancedslingloading/functions/fnc_getSlingLoadPoints.sqf new file mode 100644 index 000000000..cc0d9a433 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_getSlingLoadPoints.sqf @@ -0,0 +1,87 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets sling load attachment points on a vehicle + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Array of sling load point arrays + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_getSlingLoadPoints + * + * Public: No + */ + +params ["_vehicle"]; +private _slingLoadPointsArray = []; +private _cornerPoints = [_vehicle] call FUNC(getCornerPoints); +_frontCenterPoint = (((_cornerPoints select 2) vectorDiff (_cornerPoints select 3)) vectorMultiply 0.5) vectorAdd (_cornerPoints select 3); +private _rearCenterPoint = (((_cornerPoints select 0) vectorDiff (_cornerPoints select 1)) vectorMultiply 0.5) vectorAdd (_cornerPoints select 1); +_rearCenterPoint = ((_frontCenterPoint vectorDiff _rearCenterPoint) vectorMultiply 0.2) vectorAdd _rearCenterPoint; +_frontCenterPoint = ((_rearCenterPoint vectorDiff _frontCenterPoint) vectorMultiply 0.2) vectorAdd _frontCenterPoint; +_middleCenterPoint = ((_frontCenterPoint vectorDiff _rearCenterPoint) vectorMultiply 0.5) vectorAdd _rearCenterPoint; +private _vehicleUnitVectorUp = vectorNormalized (vectorUp _vehicle); + +_slingLoadPointHeightOffset = 0; +{ + if (_vehicle isKindOf (_x select 0)) then { + _slingLoadPointHeightOffset = (_x select 1); + }; +} forEach (missionNamespace getVariable ["ASL_Sling_Load_Point_Class_Height_Offset", []]); + +private _slingLoadPoints = []; +{ + private _modelPoint = _x; + private _modelPointASL = AGLToASL (_vehicle modelToWorldVisual _modelPoint); + private _surfaceIntersectStartASL = _modelPointASL vectorAdd (_vehicleUnitVectorUp vectorMultiply -5); + private _surfaceIntersectEndASL = _modelPointASL vectorAdd (_vehicleUnitVectorUp vectorMultiply 5); + + // Determine if the surface intersection line crosses below ground level + // If if does, move surfaceIntersectStartASL above ground level (lineIntersectsSurfaces + // doesn't work if starting below ground level for some reason + // See: https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection + + _la = ASLToAGL _surfaceIntersectStartASL; + _lb = ASLToAGL _surfaceIntersectEndASL; + + if (_la select 2 < 0 && _lb select 2 > 0) then { + _n = [0, 0, 1]; + _p0 = [0, 0, 0.1]; + _l = (_la vectorFromTo _lb); + if ((_l vectorDotProduct _n) != 0) then { + _d = (((_p0 vectorAdd (_la vectorMultiply -1)) vectorDotProduct _n) / (_l vectorDotProduct _n)); + _surfaceIntersectStartASL = AGLToASL ((_l vectorMultiply _d) vectorAdd _la); + }; + }; + + private _surfaces = lineIntersectsSurfaces [_surfaceIntersectStartASL, _surfaceIntersectEndASL, objNull, objNull, true, 100]; + private _intersectionASL = []; + { + private _intersectionObject = _x select 2; + if (_intersectionObject == _vehicle) exitWith { + _intersectionASL = _x select 0; + }; + } forEach _surfaces; + if (count _intersectionASL > 0) then { + _intersectionASL = _intersectionASL vectorAdd ((_surfaceIntersectStartASL vectorFromTo _surfaceIntersectEndASL) vectorMultiply (_slingLoadPointHeightOffset select (count _slingLoadPoints))); + _slingLoadPoints pushBack (_vehicle worldToModelVisual (ASLToAGL _intersectionASL)); + } else { + _slingLoadPoints pushBack []; + }; +} forEach [_frontCenterPoint, _middleCenterPoint, _rearCenterPoint]; + +if (count (_slingLoadPoints select 1) > 0) then { + _slingLoadPointsArray pushBack [_slingLoadPoints select 1]; + if (count (_slingLoadPoints select 0) > 0 && count (_slingLoadPoints select 2) > 0) then { + if (((_slingLoadPoints select 0) distance (_slingLoadPoints select 2)) > 3) then { + _slingLoadPointsArray pushBack [_slingLoadPoints select 0, _slingLoadPoints select 2]; + if (((_slingLoadPoints select 0) distance (_slingLoadPoints select 1)) > 3) then { + _slingLoadPointsArray pushBack [_slingLoadPoints select 0, _slingLoadPoints select 1, _slingLoadPoints select 2]; + }; + }; + }; +}; +_slingLoadPointsArray; diff --git a/addons/advancedslingloading/functions/fnc_hideObjectGlobal.sqf b/addons/advancedslingloading/functions/fnc_hideObjectGlobal.sqf new file mode 100644 index 000000000..c637032e2 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_hideObjectGlobal.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Hides an object globally + * + * Arguments: + * 0: Object + * + * Return Value: + * None + * + * Example: + * [_obj] call ttt_advancedslingloading_fnc_hideObjectGlobal + * + * Public: No + */ + +params ["_obj"]; +if (_obj isKindOf "Land_Can_V2_F") then { + hideObjectGlobal _obj; +}; diff --git a/addons/advancedslingloading/functions/fnc_hint.sqf b/addons/advancedslingloading/functions/fnc_hint.sqf new file mode 100644 index 000000000..66e5338a0 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_hint.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Shows a hint message, with Exile support + * + * Arguments: + * 0: Message + * 1: Is success (optional, default true) + * + * Return Value: + * None + * + * Example: + * ["Cargo attached", true] call ttt_advancedslingloading_fnc_hint + * + * Public: No + */ + +params ["_msg", ["_isSuccess", true]]; +if (isNil "ExileClient_gui_notification_event_addNotification") then { + hint _msg; +} else { + if (_isSuccess) then { + ["Success", [_msg]] call ExileClient_gui_notification_event_addNotification; + } else { + ["Whoops", [_msg]] call ExileClient_gui_notification_event_addNotification; + }; +}; diff --git a/addons/advancedslingloading/functions/fnc_initAdvancedSlingLoading.sqf b/addons/advancedslingloading/functions/fnc_initAdvancedSlingLoading.sqf index 54493506d..c838bcfdf 100644 --- a/addons/advancedslingloading/functions/fnc_initAdvancedSlingLoading.sqf +++ b/addons/advancedslingloading/functions/fnc_initAdvancedSlingLoading.sqf @@ -1,22 +1,26 @@ #include "..\script_component.hpp" - -ASL_Advanced_Sling_Loading_Install = { +/* + * Author: Seth Duda + * Initializes Advanced Sling Loading system + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ttt_advancedslingloading_fnc_initAdvancedSlingLoading + * + * Public: No + */ // Prevent advanced sling loading from installing twice -if(!isNil "ASL_ROPE_INIT") exitWith {}; +if (!isNil "ASL_ROPE_INIT") exitWith {}; ASL_ROPE_INIT = true; INFO("Advanced Sling Loading Loading..."); -ASL_Rope_Get_Lift_Capability = { - params ["_vehicle"]; - private ["_slingLoadMaxCargoMass"]; - _slingLoadMaxCargoMass = getNumber (configOf _vehicle >> "slingLoadMaxCargoMass"); - if(_slingLoadMaxCargoMass <= 0) then { - _slingLoadMaxCargoMass = 4000; - }; - _slingLoadMaxCargoMass; -}; - +// Initialize global configuration arrays ASL_Sling_Load_Point_Class_Height_Offset = [ ["All", [-0.05, -0.05, -0.05]], ["UK3CB_BAF_Merlin_HC3_18", [-0.05, -0.05, -0.05]], @@ -34,1126 +38,44 @@ ASL_Sling_Load_Point_Class_Height_Offset = [ ["CUP_B_MI6A_CDF", [-0.8, -1, -1.1]], ["B_Heli_Transport_03_F", [-0.35, -0.15, -0.05]], ["RHS_UH60M2_d", [-0.05, -0.05, -0.05]], - ["B_T_VTOL_01_Vehicle_F", [-0.9, -0.9, -0.9]] //ToDo Hatchet Mod + ["B_T_VTOL_01_Vehicle_F", [-0.9, -0.9, -0.9]] ]; -ASL_Get_Sling_Load_Points = { - params ["_vehicle"]; - private ["_slingLoadPointsArray","_cornerPoints","_rearCenterPoint","_vehicleUnitVectorUp"]; - private ["_slingLoadPoints","_modelPoint","_modelPointASL","_surfaceIntersectStartASL","_surfaceIntersectEndASL","_surfaces","_intersectionASL","_intersectionObject"]; - _slingLoadPointsArray = []; - _cornerPoints = [_vehicle] call ASL_Get_Corner_Points; - _frontCenterPoint = (((_cornerPoints select 2) vectorDiff (_cornerPoints select 3)) vectorMultiply 0.5) vectorAdd (_cornerPoints select 3); - _rearCenterPoint = (((_cornerPoints select 0) vectorDiff (_cornerPoints select 1)) vectorMultiply 0.5) vectorAdd (_cornerPoints select 1); - _rearCenterPoint = ((_frontCenterPoint vectorDiff _rearCenterPoint) vectorMultiply 0.2) vectorAdd _rearCenterPoint; - _frontCenterPoint = ((_rearCenterPoint vectorDiff _frontCenterPoint) vectorMultiply 0.2) vectorAdd _frontCenterPoint; - _middleCenterPoint = ((_frontCenterPoint vectorDiff _rearCenterPoint) vectorMultiply 0.5) vectorAdd _rearCenterPoint; - _vehicleUnitVectorUp = vectorNormalized (vectorUp _vehicle); - - _slingLoadPointHeightOffset = 0; - { - if(_vehicle isKindOf (_x select 0)) then { - _slingLoadPointHeightOffset = (_x select 1); - }; - } forEach ASL_Sling_Load_Point_Class_Height_Offset; - - _slingLoadPoints = []; - { - _modelPoint = _x; - _modelPointASL = AGLToASL (_vehicle modelToWorldVisual _modelPoint); - _surfaceIntersectStartASL = _modelPointASL vectorAdd ( _vehicleUnitVectorUp vectorMultiply -5 ); - _surfaceIntersectEndASL = _modelPointASL vectorAdd ( _vehicleUnitVectorUp vectorMultiply 5 ); - - // Determine if the surface intersection line crosses below ground level - // If if does, move surfaceIntersectStartASL above ground level (lineIntersectsSurfaces - // doesn't work if starting below ground level for some reason - // See: https://en.wikipedia.org/wiki/Line%E2%80%93plane_intersection - - _la = ASLToAGL _surfaceIntersectStartASL; - _lb = ASLToAGL _surfaceIntersectEndASL; - - if(_la select 2 < 0 && _lb select 2 > 0) then { - _n = [0,0,1]; - _p0 = [0,0,0.1]; - _l = (_la vectorFromTo _lb); - if((_l vectorDotProduct _n) != 0) then { - _d = ( ( _p0 vectorAdd ( _la vectorMultiply -1 ) ) vectorDotProduct _n ) / (_l vectorDotProduct _n); - _surfaceIntersectStartASL = AGLToASL ((_l vectorMultiply _d) vectorAdd _la); - }; - }; - - _surfaces = lineIntersectsSurfaces [_surfaceIntersectStartASL, _surfaceIntersectEndASL, objNull, objNull, true, 100]; - _intersectionASL = []; - { - _intersectionObject = _x select 2; - if(_intersectionObject == _vehicle) exitWith { - _intersectionASL = _x select 0; - }; - } forEach _surfaces; - if(count _intersectionASL > 0) then { - _intersectionASL = _intersectionASL vectorAdd (( _surfaceIntersectStartASL vectorFromTo _surfaceIntersectEndASL ) vectorMultiply (_slingLoadPointHeightOffset select (count _slingLoadPoints))); - _slingLoadPoints pushBack (_vehicle worldToModelVisual (ASLToAGL _intersectionASL)); - } else { - _slingLoadPoints pushBack []; - }; - } forEach [_frontCenterPoint, _middleCenterPoint, _rearCenterPoint]; - - if(count (_slingLoadPoints select 1) > 0) then { - _slingLoadPointsArray pushBack [_slingLoadPoints select 1]; - if(count (_slingLoadPoints select 0) > 0 && count (_slingLoadPoints select 2) > 0 ) then { - if( ((_slingLoadPoints select 0) distance (_slingLoadPoints select 2)) > 3 ) then { - _slingLoadPointsArray pushBack [_slingLoadPoints select 0,_slingLoadPoints select 2]; - if( ((_slingLoadPoints select 0) distance (_slingLoadPoints select 1)) > 3 ) then { - _slingLoadPointsArray pushBack [_slingLoadPoints select 0,_slingLoadPoints select 1,_slingLoadPoints select 2]; - }; - }; - }; - }; - _slingLoadPointsArray; -}; - -ASL_Rope_Set_Mass = { - private ["_obj","_mass"]; - _obj = [_this,0] call BIS_fnc_param; - _mass = [_this,1] call BIS_fnc_param; - _obj setMass _mass; -}; - -ASL_Rope_Adjust_Mass = { - params ["_obj","_heli",["_ropes",[]]]; - private ["_mass","_lift","_originalMass","_heavyLiftMinLift"]; - _lift = [_heli] call ASL_Rope_Get_Lift_Capability; - _originalMass = getMass _obj; - _heavyLiftMinLift = missionNamespace getVariable ["ASL_SET_MASS",4000]; - if( _originalMass >= ((_lift)*0.8) && _lift >= _heavyLiftMinLift ) then { - private ["_originalMassSet","_ends","_endDistance","_ropeLength"]; - _originalMassSet = (getMass _obj) == _originalMass; - while { _obj in (ropeAttachedObjects _heli) && _originalMassSet } do { - { - _ends = ropeEndPosition _x; - _endDistance = (_ends select 0) distance (_ends select 1); - _ropeLength = ropeLength _x; - if((_ropeLength - 2) <= _endDistance && ((position _heli) select 2) > 0 ) then { - [[_obj, ((_lift)*0.8)],"ASL_Rope_Set_Mass",_obj,true] call ASL_RemoteExec; - _originalMassSet = false; - }; - } forEach _ropes; - sleep 0.1; - }; - while { _obj in (ropeAttachedObjects _heli) } do { - sleep 0.5; - }; - [[_obj, _originalMass],"ASL_Rope_Set_Mass",_obj,true] call ASL_RemoteExec; - }; -}; - - -/* - Constructs an array of all active rope indexes and position labels (e.g. [[rope index,"Front"],[rope index,"Rear"]]) - for a specified vehicle -*/ -ASL_Get_Active_Ropes = { - params ["_vehicle"]; - private ["_activeRopes","_existingRopes","_ropeLabelSets","_ropeIndex","_totalExistingRopes","_ropeLabels"]; - _activeRopes = []; - _existingRopes = _vehicle getVariable ["ASL_Ropes",[]]; - _ropeLabelSets = [["Center"],["Front","Rear"],["Front","Center","Rear"]]; - _ropeIndex = 0; - _totalExistingRopes = count _existingRopes; - { - if(count _x > 0) then { - _ropeLabels = _ropeLabelSets select (_totalExistingRopes - 1); - _activeRopes pushBack [_ropeIndex,_ropeLabels select _ropeIndex]; - }; - _ropeIndex = _ropeIndex + 1; - } forEach _existingRopes; - _activeRopes; -}; - -/* - Constructs an array of all inactive rope indexes and position labels (e.g. [[rope index,"Front"],[rope index,"Rear"]]) - for a specified vehicle -*/ -ASL_Get_Inactive_Ropes = { - params ["_vehicle"]; - private ["_inactiveRopes","_existingRopes","_ropeLabelSets","_ropeIndex","_totalExistingRopes","_ropeLabels"]; - _inactiveRopes = []; - _existingRopes = _vehicle getVariable ["ASL_Ropes",[]]; - _ropeLabelSets = [["Center"],["Front","Rear"],["Front","Center","Rear"]]; - _ropeIndex = 0; - _totalExistingRopes = count _existingRopes; - { - if(count _x == 0) then { - _ropeLabels = _ropeLabelSets select (_totalExistingRopes - 1); - _inactiveRopes pushBack [_ropeIndex,_ropeLabels select _ropeIndex]; - }; - _ropeIndex = _ropeIndex + 1; - } forEach _existingRopes; - _inactiveRopes; -}; - -ASL_Get_Active_Ropes_With_Cargo = { - params ["_vehicle"]; - private ["_activeRopesWithCargo","_existingCargo","_activeRopes","_cargo"]; - _activeRopesWithCargo = []; - _existingCargo = _vehicle getVariable ["ASL_Cargo",[]]; - _activeRopes = call ASL_Get_Active_Ropes; - { - _cargo = _existingCargo select (_x select 0); - if(!isNull _cargo) then { - _activeRopesWithCargo pushBack _x; - }; - } forEach _activeRopes; - _activeRopesWithCargo; -}; - -ASL_Get_Active_Ropes_Without_Cargo = { - params ["_vehicle"]; - private ["_activeRopesWithoutCargo","_existingCargo","_activeRopes","_cargo"]; - _activeRopesWithoutCargo = []; - _existingCargo = _vehicle getVariable ["ASL_Cargo",[]]; - _activeRopes = call ASL_Get_Active_Ropes; - { - _cargo = _existingCargo select (_x select 0); - if(isNull _cargo) then { - _activeRopesWithoutCargo pushBack _x; - }; - } forEach _activeRopes; - _activeRopesWithoutCargo; -}; - -ASL_Get_Ropes = { - params ["_vehicle","_ropeIndex"]; - private ["_allRopes","_selectedRopes"]; - _selectedRopes = []; - _allRopes = _vehicle getVariable ["ASL_Ropes",[]]; - if(count _allRopes > _ropeIndex) then { - _selectedRopes = _allRopes select _ropeIndex; - }; - _selectedRopes; -}; - - -ASL_Get_Ropes_Count = { - params ["_vehicle"]; - count (_vehicle getVariable ["ASL_Ropes",[]]); -}; - -ASL_Get_Cargo = { - params ["_vehicle","_ropeIndex"]; - private ["_allCargo","_selectedCargo"]; - _selectedCargo = objNull; - _allCargo = _vehicle getVariable ["ASL_Cargo",[]]; - if(count _allCargo > _ropeIndex) then { - _selectedCargo = _allCargo select _ropeIndex; - }; - _selectedCargo; -}; - -ASL_Get_Ropes_And_Cargo = { - params ["_vehicle","_ropeIndex"]; - private ["_selectedCargo","_selectedRopes"]; - _selectedCargo = (call ASL_Get_Cargo); - _selectedRopes = (call ASL_Get_Ropes); - [_selectedRopes, _selectedCargo]; -}; - -ASL_Show_Select_Ropes_Menu = { - params ["_title", "_functionName","_ropesIndexAndLabelArray",["_ropesLabel","Ropes"]]; - ASL_Show_Select_Ropes_Menu_Array = [[_title,false]]; - { - ASL_Show_Select_Ropes_Menu_Array pushBack [ (_x select 1) + " " + _ropesLabel, [0], "", -5, [["expression", "["+(str (_x select 0))+"] call " + _functionName]], "1", "1"]; - } forEach _ropesIndexAndLabelArray; - ASL_Show_Select_Ropes_Menu_Array pushBack ["All " + _ropesLabel, [0], "", -5, [["expression", "{ [_x] call " + _functionName + " } forEach [0,1,2];"]], "1", "1"]; - showCommandingMenu ""; - showCommandingMenu "#USER:ASL_Show_Select_Ropes_Menu_Array"; -}; - -ASL_Extend_Ropes = { - params ["_vehicle","_player",["_ropeIndex",0]]; - if(local _vehicle) then { - private ["_existingRopes"]; - _existingRopes = [_vehicle,_ropeIndex] call ASL_Get_Ropes; - if(count _existingRopes > 0) then { - _ropeLength = ropeLength (_existingRopes select 0); - if(_ropeLength <= 100 ) then { - { - ropeUnwind [_x, 3, 5, true]; - } forEach _existingRopes; - }; - }; - } else { - [_this,"ASL_Extend_Ropes",_vehicle,true] call ASL_RemoteExec; - }; -}; - -ASL_Extend_Ropes_Action = { - private ["_vehicle"]; - _vehicle = vehicle player; - if([_vehicle] call ASL_Can_Extend_Ropes) then { - private ["_activeRopes"]; - _activeRopes = [_vehicle] call ASL_Get_Active_Ropes; - if(count _activeRopes > 1) then { - player setVariable ["ASL_Extend_Index_Vehicle", _vehicle]; - ["Extend Cargo Ropes","ASL_Extend_Ropes_Index_Action",_activeRopes] call ASL_Show_Select_Ropes_Menu; - } else { - if(count _activeRopes == 1) then { - [_vehicle,player,(_activeRopes select 0) select 0] call ASL_Extend_Ropes; - }; - }; - }; -}; - -ASL_Extend_Ropes_Index_Action = { - params ["_ropeIndex"]; - private ["_vehicle","_canDeployRopes"]; - _vehicle = player getVariable ["ASL_Extend_Index_Vehicle", objNull]; - if(_ropeIndex >= 0 && !isNull _vehicle && [_vehicle] call ASL_Can_Extend_Ropes) then { - [_vehicle,player,_ropeIndex] call ASL_Extend_Ropes; - }; -}; - -ASL_Extend_Ropes_Action_Check = { - if(isNull objectParent player) exitWith {false}; - [vehicle player] call ASL_Can_Extend_Ropes; -}; - -ASL_Can_Extend_Ropes = { - params ["_vehicle"]; - private ["_existingRopes","_activeRopes"]; - if(player distance _vehicle > 10) exitWith { false }; - if!([_vehicle] call ASL_Is_Supported_Vehicle) exitWith { false }; - _existingRopes = _vehicle getVariable ["ASL_Ropes",[]]; - if((count _existingRopes) == 0) exitWith { false }; - _activeRopes = [_vehicle] call ASL_Get_Active_Ropes; - if((count _activeRopes) == 0) exitWith { false }; - true; -}; - -ASL_Shorten_Ropes = { - params ["_vehicle","_player",["_ropeIndex",0]]; - if(local _vehicle) then { - private ["_existingRopes"]; - _existingRopes = [_vehicle,_ropeIndex] call ASL_Get_Ropes; - if(count _existingRopes > 0) then { - _ropeLength = ropeLength (_existingRopes select 0); - if(_ropeLength <= 2 ) then { - call ASL_Release_Cargo; - } else { - { - if(_ropeLength >= 10) then { - ropeUnwind [_x, 3, -5, true]; - } else { - ropeUnwind [_x, 3, -1, true]; - }; - } forEach _existingRopes; - }; - }; - } else { - [_this,"ASL_Shorten_Ropes",_vehicle,true] call ASL_RemoteExec; - }; -}; - -ASL_Shorten_Ropes_Action = { - private ["_vehicle"]; - _vehicle = vehicle player; - if([_vehicle] call ASL_Can_Shorten_Ropes) then { - private ["_activeRopes"]; - _activeRopes = [_vehicle] call ASL_Get_Active_Ropes; - if(count _activeRopes > 1) then { - player setVariable ["ASL_Shorten_Index_Vehicle", _vehicle]; - ["Shorten Cargo Ropes","ASL_Shorten_Ropes_Index_Action",_activeRopes] call ASL_Show_Select_Ropes_Menu; - } else { - if(count _activeRopes == 1) then { - [_vehicle,player,(_activeRopes select 0) select 0] call ASL_Shorten_Ropes; - }; - }; - }; -}; - -ASL_Shorten_Ropes_Index_Action = { - params ["_ropeIndex"]; - private ["_vehicle"]; - _vehicle = player getVariable ["ASL_Shorten_Index_Vehicle", objNull]; - if(_ropeIndex >= 0 && !isNull _vehicle && [_vehicle] call ASL_Can_Shorten_Ropes) then { - [_vehicle,player,_ropeIndex] call ASL_Shorten_Ropes; - }; -}; - -ASL_Shorten_Ropes_Action_Check = { - if(isNull objectParent player) exitWith {false}; - [vehicle player] call ASL_Can_Shorten_Ropes; -}; - -ASL_Can_Shorten_Ropes = { - params ["_vehicle"]; - private ["_existingRopes","_activeRopes"]; - if(player distance _vehicle > 10) exitWith { false }; - if!([_vehicle] call ASL_Is_Supported_Vehicle) exitWith { false }; - _existingRopes = _vehicle getVariable ["ASL_Ropes",[]]; - if((count _existingRopes) == 0) exitWith { false }; - _activeRopes = [_vehicle] call ASL_Get_Active_Ropes; - if((count _activeRopes) == 0) exitWith { false }; - true; -}; - -ASL_Release_Cargo = { - params ["_vehicle","_player",["_ropeIndex",0]]; - if(local _vehicle) then { - private ["_existingRopesAndCargo","_existingRopes","_existingCargo","_allCargo"]; - _existingRopesAndCargo = [_vehicle,_ropeIndex] call ASL_Get_Ropes_And_Cargo; - _existingRopes = _existingRopesAndCargo select 0; - _existingCargo = _existingRopesAndCargo select 1; - { - _existingCargo ropeDetach _x; - } forEach _existingRopes; - _allCargo = _vehicle getVariable ["ASL_Cargo",[]]; - _allCargo set [_ropeIndex,objNull]; - _vehicle setVariable ["ASL_Cargo",_allCargo, true]; - call ASL_Retract_Ropes; - } else { - [_this,"ASL_Release_Cargo",_vehicle,true] call ASL_RemoteExec; - }; -}; - -ASL_Release_Cargo_Action = { - private ["_vehicle"]; - _vehicle = vehicle player; - if([_vehicle] call ASL_Can_Release_Cargo) then { - private ["_activeRopes"]; - _activeRopes = [_vehicle] call ASL_Get_Active_Ropes_With_Cargo; - if(count _activeRopes > 1) then { - player setVariable ["ASL_Release_Cargo_Index_Vehicle", _vehicle]; - ["Release Cargo","ASL_Release_Cargo_Index_Action",_activeRopes,"Cargo"] call ASL_Show_Select_Ropes_Menu; - } else { - if(count _activeRopes == 1) then { - [_vehicle,player,(_activeRopes select 0) select 0] call ASL_Release_Cargo; - }; - }; - }; -}; - -ASL_Release_Cargo_Index_Action = { - params ["_ropesIndex"]; - private ["_vehicle"]; - _vehicle = player getVariable ["ASL_Release_Cargo_Index_Vehicle", objNull]; - if(_ropesIndex >= 0 && !isNull _vehicle && [_vehicle] call ASL_Can_Release_Cargo) then { - [_vehicle,player,_ropesIndex] call ASL_Release_Cargo; - }; -}; - -ASL_Release_Cargo_Action_Check = { - if(isNull objectParent player) exitWith {false}; - [vehicle player] call ASL_Can_Release_Cargo; -}; - -ASL_Can_Release_Cargo = { - params ["_vehicle"]; - private ["_existingRopes","_activeRopes"]; - if(player distance _vehicle > 10) exitWith { false }; - if!([_vehicle] call ASL_Is_Supported_Vehicle) exitWith { false }; - _existingRopes = _vehicle getVariable ["ASL_Ropes",[]]; - if((count _existingRopes) == 0) exitWith { false }; - _activeRopes = [_vehicle] call ASL_Get_Active_Ropes_With_Cargo; - if((count _activeRopes) == 0) exitWith { false }; - true; -}; - -ASL_Retract_Ropes = { - params ["_vehicle","_player",["_ropeIndex",0]]; - if(local _vehicle) then { - private ["_existingRopesAndCargo","_existingRopes","_existingCargo","_allRopes","_activeRopes"]; - _existingRopesAndCargo = [_vehicle,_ropeIndex] call ASL_Get_Ropes_And_Cargo; - _existingRopes = _existingRopesAndCargo select 0; - _existingCargo = _existingRopesAndCargo select 1; - if(isNull _existingCargo) then { - call ASL_Drop_Ropes; - { - [_x,_vehicle] spawn { - params ["_rope","_vehicle"]; - private ["_count"]; - _count = 0; - ropeUnwind [_rope, 3, 0]; - while {(!ropeUnwound _rope) && _count < 20} do { - sleep 1; - _count = _count + 1; - }; - ropeDestroy _rope; - }; - } forEach _existingRopes; - _allRopes = _vehicle getVariable ["ASL_Ropes",[]]; - _allRopes set [_ropeIndex,[]]; - _vehicle setVariable ["ASL_Ropes",_allRopes,true]; - }; - _activeRopes = [_vehicle] call ASL_Get_Active_Ropes; - if(count _activeRopes == 0) then { - _vehicle setVariable ["ASL_Ropes",nil,true]; - }; - } else { - [_this,"ASL_Retract_Ropes",_vehicle,true] call ASL_RemoteExec; - }; -}; - -ASL_Retract_Ropes_Action = { - private ["_vehicle"]; - if(isNull objectParent player) then { - _vehicle = cursorTarget; - } else { - _vehicle = vehicle player; - }; - if([_vehicle] call ASL_Can_Retract_Ropes) then { - private ["_activeRopes"]; - _activeRopes = [_vehicle] call ASL_Get_Active_Ropes_Without_Cargo; - if(count _activeRopes > 1) then { - player setVariable ["ASL_Retract_Ropes_Index_Vehicle", _vehicle]; - ["Retract Cargo Ropes","ASL_Retract_Ropes_Index_Action",_activeRopes] call ASL_Show_Select_Ropes_Menu; - } else { - if(count _activeRopes == 1) then { - [_vehicle,player,(_activeRopes select 0) select 0] call ASL_Retract_Ropes; - }; - }; - }; -}; - -ASL_Retract_Ropes_Index_Action = { - params ["_ropesIndex"]; - private ["_vehicle"]; - _vehicle = player getVariable ["ASL_Retract_Ropes_Index_Vehicle", objNull]; - if(_ropesIndex >= 0 && !isNull _vehicle && [_vehicle] call ASL_Can_Retract_Ropes) then { - [_vehicle,player,_ropesIndex] call ASL_Retract_Ropes; - }; -}; - -ASL_Retract_Ropes_Action_Check = { - if(isNull objectParent player) then { - [cursorTarget] call ASL_Can_Retract_Ropes; - } else { - [vehicle player] call ASL_Can_Retract_Ropes; - }; -}; - -ASL_Can_Retract_Ropes = { - params ["_vehicle"]; - private ["_existingRopes","_activeRopes"]; - if(player distance _vehicle > 30) exitWith { false }; - if!([_vehicle] call ASL_Is_Supported_Vehicle) exitWith { false }; - _existingRopes = _vehicle getVariable ["ASL_Ropes",[]]; - if((count _existingRopes) == 0) exitWith { false }; - _activeRopes = [_vehicle] call ASL_Get_Active_Ropes_Without_Cargo; - if((count _activeRopes) == 0) exitWith { false }; - true; -}; - -ASL_Deploy_Ropes = { - params ["_vehicle","_player",["_cargoCount",1],["_ropeLength",15]]; - if(local _vehicle) then { - private ["_existingRopes","_cargoRopes","_slingLoadPoints"]; - _slingLoadPoints = [_vehicle] call ASL_Get_Sling_Load_Points; - _existingRopes = _vehicle getVariable ["ASL_Ropes",[]]; - if(count _existingRopes == 0) then { - if(count _slingLoadPoints == 0) exitWith { - [["Vehicle doesn't support cargo ropes", false],"ASL_Hint",_player] call ASL_RemoteExec; - }; - if(count _slingLoadPoints < _cargoCount) exitWith { - [["Vehicle doesn't support " + _cargoCount + " cargo ropes", false],"ASL_Hint",_player] call ASL_RemoteExec; - }; - _cargoRopes = []; - _cargo = []; - for "_i" from 0 to (_cargoCount-1) do - { - _cargoRopes pushBack []; - _cargo pushBack objNull; - }; - _vehicle setVariable ["ASL_Ropes",_cargoRopes,true]; - _vehicle setVariable ["ASL_Cargo",_cargo,true]; - for "_i" from 0 to (_cargoCount-1) do - { - [_vehicle,_player,_i] call ASL_Deploy_Ropes_Index; - }; - } else { - [["Vehicle already has cargo ropes deployed", false],"ASL_Hint",_player] call ASL_RemoteExec; - }; - } else { - [_this,"ASL_Deploy_Ropes",_vehicle,true] call ASL_RemoteExec; - }; -}; - -ASL_Deploy_Ropes_Index = { - params ["_vehicle","_player",["_ropesIndex",0],["_ropeLength",15]]; - if(local _vehicle) then { - private ["_existingRopes","_existingRopesCount","_allRopes"]; - _existingRopes = [_vehicle,_ropesIndex] call ASL_Get_Ropes; - _existingRopesCount = [_vehicle] call ASL_Get_Ropes_Count; - if(count _existingRopes == 0) then { - _slingLoadPoints = [_vehicle] call ASL_Get_Sling_Load_Points; - _cargoRopes = []; - _cargoRopes pushBack ropeCreate [_vehicle, (_slingLoadPoints select (_existingRopesCount - 1)) select _ropesIndex, 0]; - _cargoRopes pushBack ropeCreate [_vehicle, (_slingLoadPoints select (_existingRopesCount - 1)) select _ropesIndex, 0]; - _cargoRopes pushBack ropeCreate [_vehicle, (_slingLoadPoints select (_existingRopesCount - 1)) select _ropesIndex, 0]; - _cargoRopes pushBack ropeCreate [_vehicle, (_slingLoadPoints select (_existingRopesCount - 1)) select _ropesIndex, 0]; - { - ropeUnwind [_x, 5, _ropeLength]; - } forEach _cargoRopes; - _allRopes = _vehicle getVariable ["ASL_Ropes",[]]; - _allRopes set [_ropesIndex,_cargoRopes]; - _vehicle setVariable ["ASL_Ropes",_allRopes,true]; - }; - } else { - [_this,"ASL_Deploy_Ropes_Index",_vehicle,true] call ASL_RemoteExec; - }; -}; - -ASL_Deploy_Ropes_Action = { - private ["_vehicle","_canDeployRopes"]; - if(isNull objectParent player) then { - _vehicle = cursorTarget; - } else { - _vehicle = vehicle player; - }; - if([_vehicle] call ASL_Can_Deploy_Ropes) then { - - _canDeployRopes = true; - - if!(missionNamespace getVariable ["ASL_LOCKED_VEHICLES_ENABLED",false]) then { - if( locked _vehicle > 1 ) then { - ["Cannot deploy cargo ropes from locked vehicle",false] call ASL_Hint; - _canDeployRopes = false; - }; - }; - - if(_canDeployRopes) then { - - _inactiveRopes = [_vehicle] call ASL_Get_Inactive_Ropes; - - if(count _inactiveRopes > 0) then { - - if(count _inactiveRopes > 1) then { - player setVariable ["ASL_Deploy_Ropes_Index_Vehicle", _vehicle]; - ["Deploy Cargo Ropes","ASL_Deploy_Ropes_Index_Action",_inactiveRopes] call ASL_Show_Select_Ropes_Menu; - } else { - [_vehicle,player,(_inactiveRopes select 0) select 0] call ASL_Deploy_Ropes_Index; - }; - - } else { - - _slingLoadPoints = [_vehicle] call ASL_Get_Sling_Load_Points; - if(count _slingLoadPoints > 1) then { - player setVariable ["ASL_Deploy_Count_Vehicle", _vehicle]; - ASL_Deploy_Ropes_Count_Menu = [ - ["Deploy Ropes",false] - ]; - ASL_Deploy_Ropes_Count_Menu pushBack ["For Single Cargo", [0], "", -5, [["expression", "[1] call ASL_Deploy_Ropes_Count_Action"]], "1", "1"]; - if((count _slingLoadPoints) > 1) then { - ASL_Deploy_Ropes_Count_Menu pushBack ["For Double Cargo", [0], "", -5, [["expression", "[2] call ASL_Deploy_Ropes_Count_Action"]], "1", "1"]; - }; - if((count _slingLoadPoints) > 2) then { - ASL_Deploy_Ropes_Count_Menu pushBack ["For Triple Cargo", [0], "", -5, [["expression", "[3] call ASL_Deploy_Ropes_Count_Action"]], "1", "1"]; - }; - showCommandingMenu ""; - showCommandingMenu "#USER:ASL_Deploy_Ropes_Count_Menu"; - } else { - [_vehicle,player] call ASL_Deploy_Ropes; - }; - - }; - - }; - - }; -}; - -ASL_Deploy_Ropes_Index_Action = { - params ["_ropesIndex"]; - private ["_vehicle"]; - _vehicle = player getVariable ["ASL_Deploy_Ropes_Index_Vehicle", objNull]; - if(_ropesIndex >= 0 && !isNull _vehicle && [_vehicle] call ASL_Can_Deploy_Ropes) then { - [_vehicle,player,_ropesIndex] call ASL_Deploy_Ropes_Index; - }; -}; - -ASL_Deploy_Ropes_Count_Action = { - params ["_count"]; - private ["_vehicle","_canDeployRopes"]; - _vehicle = player getVariable ["ASL_Deploy_Count_Vehicle", objNull]; - if(_count > 0 && !isNull _vehicle && [_vehicle] call ASL_Can_Deploy_Ropes) then { - [_vehicle,player,_count] call ASL_Deploy_Ropes; - }; -}; - -ASL_Deploy_Ropes_Action_Check = { - if(isNull objectParent player) then { - [cursorTarget] call ASL_Can_Deploy_Ropes; - } else { - [vehicle player] call ASL_Can_Deploy_Ropes; - }; -}; - -ASL_Can_Deploy_Ropes = { - params ["_vehicle"]; - private ["_existingRopes","_activeRopes"]; - if(player distance _vehicle > 10) exitWith { false }; - if!([_vehicle] call ASL_Is_Supported_Vehicle) exitWith { false }; - _existingVehicle = player getVariable ["ASL_Ropes_Vehicle", []]; - if(count _existingVehicle > 0) exitWith { false }; - _existingRopes = _vehicle getVariable ["ASL_Ropes",[]]; - if((count _existingRopes) == 0) exitWith { true }; - _activeRopes = [_vehicle] call ASL_Get_Active_Ropes; - if((count _existingRopes) > 0 && (count _existingRopes) == (count _activeRopes)) exitWith { false }; - true; -}; - -ASL_Get_Corner_Points = { - params ["_vehicle"]; - private ["_centerOfMass","_bbr","_p1","_p2","_rearCorner","_rearCorner2","_frontCorner","_frontCorner2"]; - private ["_maxWidth","_widthOffset","_maxLength","_lengthOffset","_widthFactor","_lengthFactor","_maxHeight","_heightOffset"]; - - // Correct width and length factor for air - _widthFactor = 0.5; - _lengthFactor = 0.5; - if(_vehicle isKindOf "Air") then { - _widthFactor = 0.3; - }; - if(_vehicle isKindOf "Helicopter") then { - _widthFactor = 0.2; - _lengthFactor = 0.45; - }; - - _centerOfMass = getCenterOfMass _vehicle; - _bbr = boundingBoxReal _vehicle; - _p1 = _bbr select 0; - _p2 = _bbr select 1; - _maxWidth = abs ((_p2 select 0) - (_p1 select 0)); - _widthOffset = ((_maxWidth / 2) - abs ( _centerOfMass select 0 )) * _widthFactor; - _maxLength = abs ((_p2 select 1) - (_p1 select 1)); - _lengthOffset = ((_maxLength / 2) - abs (_centerOfMass select 1 )) * _lengthFactor; - _maxHeight = abs ((_p2 select 2) - (_p1 select 2)); - _heightOffset = _maxHeight/6; - - _rearCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) - _lengthOffset, (_centerOfMass select 2)+_heightOffset]; - _rearCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) - _lengthOffset, (_centerOfMass select 2)+_heightOffset]; - _frontCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) + _lengthOffset, (_centerOfMass select 2)+_heightOffset]; - _frontCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) + _lengthOffset, (_centerOfMass select 2)+_heightOffset]; - - [_rearCorner,_rearCorner2,_frontCorner,_frontCorner2]; -}; - - -ASL_Attach_Ropes = { - params ["_cargo","_player"]; - _vehicleWithIndex = _player getVariable ["ASL_Ropes_Vehicle", [objNull,0]]; - _vehicle = _vehicleWithIndex select 0; - if(!isNull _vehicle) then { - if(local _vehicle) then { - private ["_ropes","_attachmentPoints","_objDistance","_ropeLength","_allCargo"]; - _ropes = [_vehicle,(_vehicleWithIndex select 1)] call ASL_Get_Ropes; - if(count _ropes == 4) then { - _attachmentPoints = [_cargo] call ASL_Get_Corner_Points; - _ropeLength = (ropeLength (_ropes select 0)); - _objDistance = (_cargo distance _vehicle) + 2; - if( _objDistance > _ropeLength ) then { - [["The cargo ropes are too short. Move vehicle closer.", false],"ASL_Hint",_player] call ASL_RemoteExec; - } else { - [_vehicle,_player,(_vehicleWithIndex select 1)] call ASL_Drop_Ropes; - [_cargo, _attachmentPoints select 0, [0,0,-1]] ropeAttachTo (_ropes select 0); - [_cargo, _attachmentPoints select 1, [0,0,-1]] ropeAttachTo (_ropes select 1); - [_cargo, _attachmentPoints select 2, [0,0,-1]] ropeAttachTo (_ropes select 2); - [_cargo, _attachmentPoints select 3, [0,0,-1]] ropeAttachTo (_ropes select 3); - _allCargo = _vehicle getVariable ["ASL_Cargo",[]]; - _allCargo set [(_vehicleWithIndex select 1),_cargo]; - _vehicle setVariable ["ASL_Cargo",_allCargo, true]; - if(missionNamespace getVariable ["ASL_HEAVY_LIFTING_ENABLED",false]) then { - [_cargo, _vehicle, _ropes] spawn ASL_Rope_Adjust_Mass; - }; - }; - }; - } else { - [_this,"ASL_Attach_Ropes",_vehicle,true] call ASL_RemoteExec; - }; - }; -}; - -ASL_Attach_Ropes_Action = { - private ["_vehicle","_cargo","_canBeAttached"]; - _cargo = cursorTarget; - _vehicle = (player getVariable ["ASL_Ropes_Vehicle", [objNull,0]]) select 0; - if([_vehicle,_cargo] call ASL_Can_Attach_Ropes) then { - - _canBeAttached = true; - - if!(missionNamespace getVariable ["ASL_LOCKED_VEHICLES_ENABLED",false]) then { - if( locked _cargo > 1 ) then { - ["Cannot attach cargo ropes to locked vehicle",false] call ASL_Hint; - _canBeAttached = false; - }; - }; - - if!(missionNamespace getVariable ["ASL_EXILE_SAFEZONE_ENABLED",false]) then { - if(!isNil "ExilePlayerInSafezone") then { - if( ExilePlayerInSafezone ) then { - ["Cannot attach cargo ropes in safe zone",false] call ASL_Hint; - _canBeAttached = false; - }; - }; - }; - - if(_canBeAttached) then { - [_cargo,player] call ASL_Attach_Ropes; - }; - - }; -}; - -ASL_Attach_Ropes_Action_Check = { - private ["_vehicleWithIndex","_cargo"]; - _vehicleWithIndex = player getVariable ["ASL_Ropes_Vehicle", [objNull,0]]; - _cargo = cursorTarget; - [_vehicleWithIndex select 0,_cargo] call ASL_Can_Attach_Ropes; -}; - -ASL_Can_Attach_Ropes = { - params ["_vehicle","_cargo"]; - if(!isNull _vehicle && !isNull _cargo) then { - [_vehicle,_cargo] call ASL_Is_Supported_Cargo && isNull objectParent player && player distance _cargo < 10 && _vehicle != _cargo; - } else { - false; - }; -}; - -ASL_Drop_Ropes = { - params ["_vehicle","_player",["_ropesIndex",0]]; - if(local _vehicle) then { - private ["_helper","_existingRopes"]; - _helper = (_player getVariable ["ASL_Ropes_Pick_Up_Helper", objNull]); - if(!isNull _helper) then { - _existingRopes = [_vehicle,_ropesIndex] call ASL_Get_Ropes; - { - _helper ropeDetach _x; - } forEach _existingRopes; - detach _helper; - deleteVehicle _helper; - }; - _player setVariable ["ASL_Ropes_Vehicle", nil,true]; - _player setVariable ["ASL_Ropes_Pick_Up_Helper", nil,true]; - } else { - [_this,"ASL_Drop_Ropes",_vehicle,true] call ASL_RemoteExec; - }; -}; - -ASL_Drop_Ropes_Action = { - private ["_vehicleAndIndex"]; - if([] call ASL_Can_Drop_Ropes) then { - _vehicleAndIndex = player getVariable ["ASL_Ropes_Vehicle", []]; - if(count _vehicleAndIndex == 2) then { - [_vehicleAndIndex select 0, player, _vehicleAndIndex select 1] call ASL_Drop_Ropes; - }; - }; -}; - -ASL_Drop_Ropes_Action_Check = { - [] call ASL_Can_Drop_Ropes; -}; - -ASL_Can_Drop_Ropes = { - count (player getVariable ["ASL_Ropes_Vehicle", []]) > 0 && isNull objectParent player; -}; - -ASL_Get_Closest_Rope = { - private ["_nearbyVehicles","_closestVehicle","_closestRopeIndex","_closestDistance"]; - private ["_vehicle","_activeRope","_ropes","_ends"]; - private ["_end1","_end2","_minEndDistance"]; - _nearbyVehicles = missionNamespace getVariable ["ASL_Nearby_Vehicles",[]]; - _closestVehicle = objNull; - _closestRopeIndex = 0; - _closestDistance = -1; - { - _vehicle = _x; - { - _activeRope = _x; - _ropes = [_vehicle,(_activeRope select 0)] call ASL_Get_Ropes; - { - _ends = ropeEndPosition _x; - if(count _ends == 2) then { - _end1 = _ends select 0; - _end2 = _ends select 1; - _minEndDistance = ((position player) distance _end1) min ((position player) distance _end2); - if(_closestDistance == -1 || _closestDistance > _minEndDistance) then { - _closestDistance = _minEndDistance; - _closestRopeIndex = (_activeRope select 0); - _closestVehicle = _vehicle; - }; - }; - } forEach _ropes; - } forEach ([_vehicle] call ASL_Get_Active_Ropes); - } forEach _nearbyVehicles; - [_closestVehicle,_closestRopeIndex]; -}; - -ASL_Pickup_Ropes = { - params ["_vehicle","_player",["_ropesIndex",0]]; - if(local _vehicle) then { - private ["_existingRopesAndCargo","_existingRopes","_existingCargo","_helper","_allCargo"]; - _existingRopesAndCargo = [_vehicle,_ropesIndex] call ASL_Get_Ropes_And_Cargo; - _existingRopes = _existingRopesAndCargo select 0; - _existingCargo = _existingRopesAndCargo select 1; - if(!isNull _existingCargo) then { - { - _existingCargo ropeDetach _x; - } forEach _existingRopes; - _allCargo = _vehicle getVariable ["ASL_Cargo",[]]; - _allCargo set [_ropesIndex,objNull]; - _vehicle setVariable ["ASL_Cargo",_allCargo, true]; - }; - _helper = "Land_Can_V2_F" createVehicle position _player; - { - [_helper, [0, 0, 0], [0,0,-1]] ropeAttachTo _x; - _helper attachTo [_player, [-0.1, 0.1, 0.15], "Pelvis"]; - } forEach _existingRopes; - hideObject _helper; - [[_helper],"ASL_Hide_Object_Global"] call ASL_RemoteExecServer; - _player setVariable ["ASL_Ropes_Vehicle", [_vehicle,_ropesIndex],true]; - _player setVariable ["ASL_Ropes_Pick_Up_Helper", _helper,true]; - } else { - [_this,"ASL_Pickup_Ropes",_vehicle,true] call ASL_RemoteExec; - }; -}; - -ASL_Pickup_Ropes_Action = { - private ["_nearbyVehicles","_canPickupRopes","_closestRope"]; - _nearbyVehicles = missionNamespace getVariable ["ASL_Nearby_Vehicles",[]]; - if([] call ASL_Can_Pickup_Ropes) then { - _closestRope = [] call ASL_Get_Closest_Rope; - if(!isNull (_closestRope select 0)) then { - _canPickupRopes = true; - if!(missionNamespace getVariable ["ASL_LOCKED_VEHICLES_ENABLED",false]) then { - if( locked (_closestRope select 0) > 1 ) then { - ["Cannot pick up cargo ropes from locked vehicle",false] call ASL_Hint; - _canPickupRopes = false; - }; - }; - if(_canPickupRopes) then { - [(_closestRope select 0), player, (_closestRope select 1)] call ASL_Pickup_Ropes; - }; - }; - }; -}; - -ASL_Pickup_Ropes_Action_Check = { - [] call ASL_Can_Pickup_Ropes; -}; - -ASL_Can_Pickup_Ropes = { - count (player getVariable ["ASL_Ropes_Vehicle", []]) == 0 && count (missionNamespace getVariable ["ASL_Nearby_Vehicles",[]]) > 0 && isNull objectParent player; -}; - ASL_Supported_Vehicles = [ "Helicopter", "VTOL_Base_F" ]; -ASL_Is_Supported_Vehicle = { - params ["_vehicle","_isSupported"]; - _isSupported = false; - if(not isNull _vehicle) then { - { - if(_vehicle isKindOf _x) then { - _isSupported = true; - }; - } forEach (missionNamespace getVariable ["ASL_Supported_Vehicles_OVERRIDE",ASL_Supported_Vehicles]); - }; - _isSupported; -}; - ASL_Sling_Rules = [ - ["All","CAN_SLING","All"] + ["All", "CAN_SLING", "All"] ]; -ASL_Is_Supported_Cargo = { - params ["_vehicle","_cargo"]; - private ["_canSling"]; - _canSling = false; - if(not isNull _vehicle && not isNull _cargo) then { - { - if(_vehicle isKindOf (_x select 0)) then { - if(_cargo isKindOf (_x select 2)) then { - if( (toUpper (_x select 1)) == "CAN_SLING" ) then { - _canSling = true; - } else { - _canSling = false; - }; - }; - }; - } forEach (missionNamespace getVariable ["ASL_Sling_Rules_OVERRIDE",ASL_Sling_Rules]); - }; - _canSling; -}; - -ASL_Hint = { - params ["_msg",["_isSuccess",true]]; - if(isNil "ExileClient_gui_notification_event_addNotification") then { - hint _msg; - } else { - if(_isSuccess) then { - ["Success", [_msg]] call ExileClient_gui_notification_event_addNotification; - } else { - ["Whoops", [_msg]] call ExileClient_gui_notification_event_addNotification; - }; - }; -}; - -ASL_Hide_Object_Global = { - params ["_obj"]; - if( _obj isKindOf "Land_Can_V2_F" ) then { - hideObjectGlobal _obj; - }; -}; - -ASL_Find_Nearby_Vehicles = { - private ["_nearVehicles","_nearVehiclesWithRopes","_vehicle","_ends","_end1","_end2","_playerPosAGL"]; - _nearVehicles = []; - { - _nearVehicles append (player nearObjects [_x, 30]); - } forEach (missionNamespace getVariable ["ASL_Supported_Vehicles_OVERRIDE",ASL_Supported_Vehicles]); - _nearVehiclesWithRopes = []; - { - _vehicle = _x; - { - _ropes = _vehicle getVariable ["ASL_Ropes",[]]; - if(count _ropes > (_x select 0)) then { - _ropes = _ropes select (_x select 0); - { - _ends = ropeEndPosition _x; - if(count _ends == 2) then { - _end1 = _ends select 0; - _end2 = _ends select 1; - _playerPosAGL = ASLToAGL getPosASL player; - if((_playerPosAGL distance _end1) < 5 || (_playerPosAGL distance _end2) < 5 ) then { - _nearVehiclesWithRopes = _nearVehiclesWithRopes + [_vehicle]; - } - }; - } forEach _ropes; - }; - } forEach ([_vehicle] call ASL_Get_Active_Ropes); - } forEach _nearVehicles; - _nearVehiclesWithRopes; -}; - -ASL_Add_Player_Actions = { - - player addAction ["Extend Cargo Ropes", { - [] call ASL_Extend_Ropes_Action; - }, nil, 0, false, true, "", "call ASL_Extend_Ropes_Action_Check"]; - - player addAction ["Shorten Cargo Ropes", { - [] call ASL_Shorten_Ropes_Action; - }, nil, 0, false, true, "", "call ASL_Shorten_Ropes_Action_Check"]; - - player addAction ["Release Cargo", { - [] call ASL_Release_Cargo_Action; - }, nil, 0, false, true, "", "call ASL_Release_Cargo_Action_Check"]; - - player addAction ["Retract Cargo Ropes", { - [] call ASL_Retract_Ropes_Action; - }, nil, 0, false, true, "", "call ASL_Retract_Ropes_Action_Check"]; - - player addAction ["Deploy Cargo Ropes", { - [] call ASL_Deploy_Ropes_Action; - }, nil, 0, false, true, "", "call ASL_Deploy_Ropes_Action_Check"]; - - player addAction ["Attach To Cargo Ropes", { - [] call ASL_Attach_Ropes_Action; - }, nil, 0, false, true, "", "call ASL_Attach_Ropes_Action_Check"]; - - player addAction ["Drop Cargo Ropes", { - [] call ASL_Drop_Ropes_Action; - }, nil, 0, false, true, "", "call ASL_Drop_Ropes_Action_Check"]; - - player addAction ["Pickup Cargo Ropes", { - [] call ASL_Pickup_Ropes_Action; - }, nil, 0, false, true, "", "call ASL_Pickup_Ropes_Action_Check"]; - - player addEventHandler ["Respawn", { - player setVariable ["ASL_Actions_Loaded",false]; - }]; - -}; - -if(!isDedicated) then { +// Client side initialization +if (!isDedicated) then { [] spawn { while {true} do { - if(!isNull player && isPlayer player) then { - if!( player getVariable ["ASL_Actions_Loaded",false] ) then { - [] call ASL_Add_Player_Actions; - player setVariable ["ASL_Actions_Loaded",true]; + if (!isNull player && isPlayer player) then { + if !( player getVariable ["ASL_Actions_Loaded", false] ) then { + [] call FUNC(addPlayerActions); + player setVariable ["ASL_Actions_Loaded", true]; }; }; - missionNamespace setVariable ["ASL_Nearby_Vehicles", (call ASL_Find_Nearby_Vehicles)]; - sleep 2; - }; - }; -}; - -ASL_RemoteExec = { - params ["_params","_functionName","_target",["_isCall",false]]; - if(isNil "ExileClient_system_network_send") then { - if(_isCall) then { - _params remoteExecCall [_functionName, _target]; - } else { - _params remoteExec [_functionName, _target]; - }; - } else { - ["AdvancedSlingLoadingRemoteExecClient",[_params,_functionName,_target,_isCall]] call ExileClient_system_network_send; - }; -}; - -ASL_RemoteExecServer = { - params ["_params","_functionName",["_isCall",false]]; - if(isNil "ExileClient_system_network_send") then { - if(_isCall) then { - _params remoteExecCall [_functionName, 2]; - } else { - _params remoteExec [_functionName, 2]; + missionNamespace setVariable ["ASL_Nearby_Vehicles", (call FUNC(findNearbyVehicles))]; + sleep ASL_NEARBY_CHECK_INTERVAL; }; - } else { - ["AdvancedSlingLoadingRemoteExecServer",[_params,_functionName,_isCall]] call ExileClient_system_network_send; }; }; -if(isServer) then { - - // Adds support for exile network calls (Only used when running exile) // - - ASL_Supported_RemoteExecServer_Functions = ["ASL_Hide_Object_Global"]; - - ExileServer_AdvancedSlingLoading_network_AdvancedSlingLoadingRemoteExecServer = { - params ["_sessionId", "_messageParameters",["_isCall",false]]; - _messageParameters params ["_params","_functionName"]; - if(_functionName in ASL_Supported_RemoteExecServer_Functions) then { - if(_isCall) then { - _params call (missionNamespace getVariable [_functionName,{}]); - } else { - _params spawn (missionNamespace getVariable [_functionName,{}]); - }; - }; - }; - - ASL_Supported_RemoteExecClient_Functions = ["ASL_Pickup_Ropes","ASL_Deploy_Ropes_Index","ASL_Rope_Set_Mass","ASL_Extend_Ropes","ASL_Shorten_Ropes","ASL_Release_Cargo","ASL_Retract_Ropes","ASL_Deploy_Ropes","ASL_Hint","ASL_Attach_Ropes","ASL_Drop_Ropes"]; +// Server side initialization +if (isServer) then { + // Install Advanced Sling Loading on all clients (plus JIP) // - ExileServer_AdvancedSlingLoading_network_AdvancedSlingLoadingRemoteExecClient = { - params ["_sessionId", "_messageParameters"]; - _messageParameters params ["_params","_functionName","_target",["_isCall",false]]; - if(_functionName in ASL_Supported_RemoteExecClient_Functions) then { - if(_isCall) then { - _params remoteExecCall [_functionName, _target]; - } else { - _params remoteExec [_functionName, _target]; - }; - }; + ASL_Advanced_Sling_Loading_Install = { + [] call FUNC(initAdvancedSlingLoading); }; - // Install Advanced Sling Loading on all clients (plus JIP) // - publicVariable "ASL_Advanced_Sling_Loading_Install"; - remoteExecCall ["ASL_Advanced_Sling_Loading_Install", -2,true]; + remoteExecCall ["ASL_Advanced_Sling_Loading_Install", -2, true]; }; @@ -1164,9 +86,3 @@ SA_Rope_Drop_Rope_Action_Check = {false}; SA_Rope_Attach_Rope_Action_Check = {false}; INFO("Advanced Sling Loading Loaded"); - -}; - -if(isServer) then { - [] call ASL_Advanced_Sling_Loading_Install; -}; diff --git a/addons/advancedslingloading/functions/fnc_isSupportedCargo.sqf b/addons/advancedslingloading/functions/fnc_isSupportedCargo.sqf new file mode 100644 index 000000000..50c3b8d05 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_isSupportedCargo.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Checks if cargo can be slung by a vehicle + * + * Arguments: + * 0: Vehicle + * 1: Cargo + * + * Return Value: + * Can sling cargo + * + * Example: + * [_vehicle, _cargo] call ttt_advancedslingloading_fnc_isSupportedCargo + * + * Public: No + */ + +params ["_vehicle", "_cargo"]; +private _canSling = false; +if (not isNull _vehicle && not isNull _cargo) then { + { + if (_vehicle isKindOf (_x select 0)) then { + if (_cargo isKindOf (_x select 2)) then { + if ((toUpper (_x select 1)) == "CAN_SLING") then { + _canSling = true; + } else { + _canSling = false; + }; + }; + }; + } forEach (missionNamespace getVariable ["ASL_Sling_Rules_OVERRIDE", missionNamespace getVariable ["ASL_Sling_Rules", []]]); +}; +_canSling; diff --git a/addons/advancedslingloading/functions/fnc_isSupportedVehicle.sqf b/addons/advancedslingloading/functions/fnc_isSupportedVehicle.sqf new file mode 100644 index 000000000..177177454 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_isSupportedVehicle.sqf @@ -0,0 +1,27 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Checks if a vehicle is supported for advanced sling loading + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Is supported + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_isSupportedVehicle + * + * Public: No + */ + +params ["_vehicle", "_isSupported"]; +_isSupported = false; +if (not isNull _vehicle) then { + { + if (_vehicle isKindOf _x) then { + _isSupported = true; + }; + } forEach (missionNamespace getVariable ["ASL_Supported_Vehicles_OVERRIDE", missionNamespace getVariable ["ASL_Supported_Vehicles", []]]); +}; +_isSupported; diff --git a/addons/advancedslingloading/functions/fnc_pickupRopes.sqf b/addons/advancedslingloading/functions/fnc_pickupRopes.sqf new file mode 100644 index 000000000..3b560b158 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_pickupRopes.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Picks up ropes for cargo attachment + * + * Arguments: + * 0: Vehicle + * 1: Player + * 2: Rope index (optional, default 0) + * + * Return Value: + * None + * + * Example: + * [_vehicle, player, 0] call ttt_advancedslingloading_fnc_pickupRopes + * + * Public: No + */ + +params ["_vehicle", "_player", ["_ropesIndex", 0]]; +if (local _vehicle) then { + private _existingRopesAndCargo = [_vehicle, _ropesIndex] call FUNC(getRopesAndCargo); + private _existingRopes = _existingRopesAndCargo select 0; + private _existingCargo = _existingRopesAndCargo select 1; + if (!isNull _existingCargo) then { + { + _existingCargo ropeDetach _x; + } forEach _existingRopes; + private _allCargo = _vehicle getVariable ["ASL_Cargo", []]; + _allCargo set [_ropesIndex, objNull]; + _vehicle setVariable ["ASL_Cargo", _allCargo, true]; + }; + private _helper = "Land_Can_V2_F" createVehicle position _player; + { + [_helper, [0, 0, 0], [0, 0, -1]] ropeAttachTo _x; + _helper attachTo [_player, [-0.1, 0.1, 0.15], "Pelvis"]; + } forEach _existingRopes; + hideObject _helper; + [[_helper], "ASL_Hide_Object_Global"] call FUNC(remoteExecServer); + _player setVariable ["ASL_Ropes_Vehicle", [_vehicle, _ropesIndex], true]; + _player setVariable ["ASL_Ropes_Pick_Up_Helper", _helper, true]; +} else { + [_this, "ASL_Pickup_Ropes", _vehicle, true] call FUNC(remoteExec); +}; diff --git a/addons/advancedslingloading/functions/fnc_pickupRopesAction.sqf b/addons/advancedslingloading/functions/fnc_pickupRopesAction.sqf new file mode 100644 index 000000000..c2e25b666 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_pickupRopesAction.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action handler for picking up ropes + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ttt_advancedslingloading_fnc_pickupRopesAction + * + * Public: No + */ + +private ["_nearbyVehicles", "_canPickupRopes", "_closestRope"]; +_nearbyVehicles = missionNamespace getVariable ["ASL_Nearby_Vehicles", []]; +if ([] call FUNC(canPickupRopes)) then { + _closestRope = [] call FUNC(getClosestRope); + if (!isNull (_closestRope select 0)) then { + _canPickupRopes = true; + if !(missionNamespace getVariable ["ASL_LOCKED_VEHICLES_ENABLED",false]) then { + if (locked (_closestRope select 0) > 1) then { + ["Cannot pick up cargo ropes from locked vehicle", false] call FUNC(hint); + _canPickupRopes = false; + }; + }; + if (_canPickupRopes) then { + [(_closestRope select 0), player, (_closestRope select 1)] call FUNC(pickupRopes); + }; + }; +}; diff --git a/addons/advancedslingloading/functions/fnc_pickupRopesActionCheck.sqf b/addons/advancedslingloading/functions/fnc_pickupRopesActionCheck.sqf new file mode 100644 index 000000000..c7c75ba67 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_pickupRopesActionCheck.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action check for picking up ropes + * + * Arguments: + * None + * + * Return Value: + * Can pickup ropes + * + * Example: + * [] call ttt_advancedslingloading_fnc_pickupRopesActionCheck + * + * Public: No + */ + +[] call FUNC(canPickupRopes); diff --git a/addons/advancedslingloading/functions/fnc_releaseCargo.sqf b/addons/advancedslingloading/functions/fnc_releaseCargo.sqf new file mode 100644 index 000000000..8449cb580 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_releaseCargo.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Releases cargo from ropes + * + * Arguments: + * 0: Vehicle + * 1: Player + * 2: Rope index (optional, default 0) + * + * Return Value: + * None + * + * Example: + * [_vehicle, player, 0] call ttt_advancedslingloading_fnc_releaseCargo + * + * Public: No + */ + +params ["_vehicle", "_player", ["_ropeIndex", 0]]; +if (local _vehicle) then { + private _existingRopesAndCargo = [_vehicle, _ropeIndex] call FUNC(getRopesAndCargo); + private _existingRopes = _existingRopesAndCargo select 0; + private _existingCargo = _existingRopesAndCargo select 1; + { + _existingCargo ropeDetach _x; + } forEach _existingRopes; + private _allCargo = _vehicle getVariable ["ASL_Cargo", []]; + _allCargo set [_ropeIndex, objNull]; + _vehicle setVariable ["ASL_Cargo", _allCargo, true]; + [_vehicle, _player, _ropeIndex] call FUNC(retractRopes); +} else { + [_this, "ASL_Release_Cargo", _vehicle, true] call FUNC(remoteExec); +}; diff --git a/addons/advancedslingloading/functions/fnc_releaseCargoAction.sqf b/addons/advancedslingloading/functions/fnc_releaseCargoAction.sqf new file mode 100644 index 000000000..47a5726c1 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_releaseCargoAction.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action handler for releasing cargo + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ttt_advancedslingloading_fnc_releaseCargoAction + * + * Public: No + */ + +private _vehicle = vehicle player; +if ([_vehicle] call FUNC(canReleaseCargo)) then { + private _activeRopes = [_vehicle] call FUNC(getActiveRopesWithCargo); + if (count _activeRopes > 1) then { + player setVariable ["ASL_Release_Cargo_Index_Vehicle", _vehicle]; + ["Release Cargo", "ASL_Release_Cargo_Index_Action", _activeRopes, "Cargo"] call FUNC(showSelectRopesMenu); + } else { + if (count _activeRopes == 1) then { + [_vehicle, player, (_activeRopes select 0) select 0] call FUNC(releaseCargo); + }; + }; +}; diff --git a/addons/advancedslingloading/functions/fnc_releaseCargoActionCheck.sqf b/addons/advancedslingloading/functions/fnc_releaseCargoActionCheck.sqf new file mode 100644 index 000000000..06411d845 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_releaseCargoActionCheck.sqf @@ -0,0 +1,19 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action check for releasing cargo + * + * Arguments: + * None + * + * Return Value: + * Can release cargo + * + * Example: + * [] call ttt_advancedslingloading_fnc_releaseCargoActionCheck + * + * Public: No + */ + +if (isNull objectParent player) exitWith {false}; +[vehicle player] call FUNC(canReleaseCargo); diff --git a/addons/advancedslingloading/functions/fnc_releaseCargoIndexAction.sqf b/addons/advancedslingloading/functions/fnc_releaseCargoIndexAction.sqf new file mode 100644 index 000000000..d27d63ca4 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_releaseCargoIndexAction.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Index action handler for releasing specific cargo + * + * Arguments: + * 0: Rope index + * + * Return Value: + * None + * + * Example: + * [0] call ttt_advancedslingloading_fnc_releaseCargoIndexAction + * + * Public: No + */ + +params ["_ropesIndex"]; +private ["_vehicle"]; +_vehicle = player getVariable ["ASL_Release_Cargo_Index_Vehicle", objNull]; +if (_ropesIndex >= 0 && !isNull _vehicle && [_vehicle] call FUNC(canReleaseCargo)) then { + [_vehicle, player, _ropesIndex] call FUNC(releaseCargo); +}; diff --git a/addons/advancedslingloading/functions/fnc_remoteExec.sqf b/addons/advancedslingloading/functions/fnc_remoteExec.sqf new file mode 100644 index 000000000..2aa99d519 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_remoteExec.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Execute remote function with Exile support + * + * Arguments: + * 0: Parameters + * 1: Function name + * 2: Target + * 3: Is call (optional, default false) + * + * Return Value: + * None + * + * Example: + * [[_cargo, 1000], "ASL_Rope_Set_Mass", _cargo, true] call ttt_advancedslingloading_fnc_remoteExec + * + * Public: No + */ + +params ["_params", "_functionName", "_target", ["_isCall", false]]; +if (isNil "ExileClient_system_network_send") then { + if (_isCall) then { + _params remoteExecCall [_functionName, _target]; + } else { + _params remoteExec [_functionName, _target]; + }; +} else { + ["AdvancedSlingLoadingRemoteExecClient", [_params, _functionName, _target, _isCall]] call ExileClient_system_network_send; +}; diff --git a/addons/advancedslingloading/functions/fnc_remoteExecServer.sqf b/addons/advancedslingloading/functions/fnc_remoteExecServer.sqf new file mode 100644 index 000000000..3e4e82dcc --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_remoteExecServer.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Execute remote function on server with Exile support + * + * Arguments: + * 0: Parameters + * 1: Function name + * 2: Is call (optional, default false) + * + * Return Value: + * None + * + * Example: + * [[_helper], "ASL_Hide_Object_Global", false] call ttt_advancedslingloading_fnc_remoteExecServer + * + * Public: No + */ + +params ["_params", "_functionName", ["_isCall", false]]; +if (isNil "ExileClient_system_network_send") then { + if (_isCall) then { + _params remoteExecCall [_functionName, 2]; + } else { + _params remoteExec [_functionName, 2]; + }; +} else { + ["AdvancedSlingLoadingRemoteExecServer", [_params, _functionName, _isCall]] call ExileClient_system_network_send; +}; diff --git a/addons/advancedslingloading/functions/fnc_retractRopes.sqf b/addons/advancedslingloading/functions/fnc_retractRopes.sqf new file mode 100644 index 000000000..01857b9d8 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_retractRopes.sqf @@ -0,0 +1,49 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Retracts empty cargo ropes + * + * Arguments: + * 0: Vehicle + * 1: Player + * 2: Rope index (optional, default 0) + * + * Return Value: + * None + * + * Example: + * [_vehicle, player, 0] call ttt_advancedslingloading_fnc_retractRopes + * + * Public: No + */ + +params ["_vehicle", "_player", ["_ropeIndex", 0]]; +if (local _vehicle) then { + private _existingRopesAndCargo = [_vehicle, _ropeIndex] call FUNC(getRopesAndCargo); + private _existingRopes = _existingRopesAndCargo select 0; + private _existingCargo = _existingRopesAndCargo select 1; + if (isNull _existingCargo) then { + [_vehicle, _player, _ropeIndex] call FUNC(dropRopes); + { + [_x, _vehicle] spawn { + params ["_rope", "_vehicle"]; + private _count = 0; + ropeUnwind [_rope, 3, 0]; + while {(!ropeUnwound _rope) && _count < 20} do { + sleep 1; + _count = _count + 1; + }; + ropeDestroy _rope; + }; + } forEach _existingRopes; + private _allRopes = _vehicle getVariable ["ASL_Ropes", []]; + _allRopes set [_ropeIndex, []]; + _vehicle setVariable ["ASL_Ropes", _allRopes, true]; + }; + private _activeRopes = [_vehicle] call FUNC(getActiveRopes); + if (count _activeRopes == 0) then { + _vehicle setVariable ["ASL_Ropes", nil, true]; + }; +} else { + [_this, "ASL_Retract_Ropes", _vehicle, true] call FUNC(remoteExec); +}; diff --git a/addons/advancedslingloading/functions/fnc_retractRopesAction.sqf b/addons/advancedslingloading/functions/fnc_retractRopesAction.sqf new file mode 100644 index 000000000..fb9e9b5e3 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_retractRopesAction.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action handler for retracting ropes + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ttt_advancedslingloading_fnc_retractRopesAction + * + * Public: No + */ + +private _vehicle = objNull; +if (isNull objectParent player) then { + _vehicle = cursorTarget; +} else { + _vehicle = vehicle player; +}; +if ([_vehicle] call FUNC(canRetractRopes)) then { + private _activeRopes = [_vehicle] call FUNC(getActiveRopesWithoutCargo); + if (count _activeRopes > 1) then { + player setVariable ["ASL_Retract_Ropes_Index_Vehicle", _vehicle]; + ["Retract Cargo Ropes", "ASL_Retract_Ropes_Index_Action", _activeRopes] call FUNC(showSelectRopesMenu); + } else { + if (count _activeRopes == 1) then { + [_vehicle, player, (_activeRopes select 0) select 0] call FUNC(retractRopes); + }; + }; +}; diff --git a/addons/advancedslingloading/functions/fnc_retractRopesActionCheck.sqf b/addons/advancedslingloading/functions/fnc_retractRopesActionCheck.sqf new file mode 100644 index 000000000..fcba8f59a --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_retractRopesActionCheck.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action check for retracting ropes + * + * Arguments: + * None + * + * Return Value: + * Can retract ropes + * + * Example: + * [] call ttt_advancedslingloading_fnc_retractRopesActionCheck + * + * Public: No + */ + +if (isNull objectParent player) then { + [cursorTarget] call FUNC(canRetractRopes); +} else { + [vehicle player] call FUNC(canRetractRopes); +}; diff --git a/addons/advancedslingloading/functions/fnc_retractRopesIndexAction.sqf b/addons/advancedslingloading/functions/fnc_retractRopesIndexAction.sqf new file mode 100644 index 000000000..47a470d29 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_retractRopesIndexAction.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Index action handler for retracting specific ropes + * + * Arguments: + * 0: Rope index + * + * Return Value: + * None + * + * Example: + * [0] call ttt_advancedslingloading_fnc_retractRopesIndexAction + * + * Public: No + */ + +params ["_ropesIndex"]; +private ["_vehicle"]; +_vehicle = player getVariable ["ASL_Retract_Ropes_Index_Vehicle", objNull]; +if (_ropesIndex >= 0 && !isNull _vehicle && [_vehicle] call FUNC(canRetractRopes)) then { + [_vehicle, player, _ropesIndex] call FUNC(retractRopes); +}; diff --git a/addons/advancedslingloading/functions/fnc_ropeAdjustMass.sqf b/addons/advancedslingloading/functions/fnc_ropeAdjustMass.sqf new file mode 100644 index 000000000..3b2a74652 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_ropeAdjustMass.sqf @@ -0,0 +1,42 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Adjusts cargo mass based on helicopter lift capability + * + * Arguments: + * 0: Cargo object + * 1: Helicopter + * 2: Ropes (optional) + * + * Return Value: + * None + * + * Example: + * [_cargo, _heli, _ropes] call ttt_advancedslingloading_fnc_ropeAdjustMass + * + * Public: No + */ + +params ["_obj", "_heli", ["_ropes", []]]; +private _lift = [_heli] call FUNC(ropeGetLiftCapability); +private _originalMass = getMass _obj; +private _heavyLiftMinLift = missionNamespace getVariable ["ASL_SET_MASS", ASL_HEAVY_LIFT_MIN_LIFT]; +if (_originalMass >= ((_lift) * ASL_HEAVY_LIFT_MASS_FACTOR) && _lift >= _heavyLiftMinLift) then { + private _originalMassSet = (getMass _obj) == _originalMass; + while { _obj in (ropeAttachedObjects _heli) && _originalMassSet } do { + { + private _ends = ropeEndPosition _x; + private _endDistance = (_ends select 0) distance (_ends select 1); + private _ropeLength = ropeLength _x; + if ((_ropeLength - ASL_ROPE_DISTANCE_THRESHOLD) <= _endDistance && ((position _heli) select 2) > 0) then { + [[_obj, ((_lift) * ASL_HEAVY_LIFT_MASS_FACTOR)], "ASL_Rope_Set_Mass", _obj, true] call FUNC(remoteExec); + _originalMassSet = false; + }; + } forEach _ropes; + sleep ASL_HEAVY_LIFT_SLEEP_TIME; + }; + while { _obj in (ropeAttachedObjects _heli) } do { + sleep ASL_HEAVY_LIFT_WAIT_TIME; + }; + [[_obj, _originalMass], "ASL_Rope_Set_Mass", _obj, true] call FUNC(remoteExec); +}; diff --git a/addons/advancedslingloading/functions/fnc_ropeGetLiftCapability.sqf b/addons/advancedslingloading/functions/fnc_ropeGetLiftCapability.sqf new file mode 100644 index 000000000..52b036a7e --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_ropeGetLiftCapability.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Gets the maximum lift capability of a vehicle + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Maximum lift capability in kg + * + * Example: + * [_vehicle] call ttt_advancedslingloading_fnc_ropeGetLiftCapability + * + * Public: No + */ + +params ["_vehicle"]; +private ["_slingLoadMaxCargoMass"]; +_slingLoadMaxCargoMass = getNumber (configOf _vehicle >> "slingLoadMaxCargoMass"); +if (_slingLoadMaxCargoMass <= 0) then { + _slingLoadMaxCargoMass = 4000; +}; +_slingLoadMaxCargoMass; diff --git a/addons/advancedslingloading/functions/fnc_ropeSetMass.sqf b/addons/advancedslingloading/functions/fnc_ropeSetMass.sqf new file mode 100644 index 000000000..70d6af417 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_ropeSetMass.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Sets the mass of an object + * + * Arguments: + * 0: Object + * 1: Mass in kg + * + * Return Value: + * None + * + * Example: + * [_object, 1000] call ttt_advancedslingloading_fnc_ropeSetMass + * + * Public: No + */ + +private ["_obj", "_mass"]; +_obj = [_this, 0] call BIS_fnc_param; +_mass = [_this, 1] call BIS_fnc_param; +_obj setMass _mass; diff --git a/addons/advancedslingloading/functions/fnc_shortenRopes.sqf b/addons/advancedslingloading/functions/fnc_shortenRopes.sqf new file mode 100644 index 000000000..821bcc5d5 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_shortenRopes.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Shortens cargo ropes + * + * Arguments: + * 0: Vehicle + * 1: Player + * 2: Rope index (optional, default 0) + * + * Return Value: + * None + * + * Example: + * [_vehicle, player, 0] call ttt_advancedslingloading_fnc_shortenRopes + * + * Public: No + */ + +params ["_vehicle", "_player", ["_ropeIndex", 0]]; +if (local _vehicle) then { + private _existingRopes = [_vehicle, _ropeIndex] call FUNC(getRopes); + if (count _existingRopes > 0) then { + _ropeLength = ropeLength (_existingRopes select 0); + if (_ropeLength <= 2) then { + [_vehicle, _player, _ropeIndex] call FUNC(releaseCargo); + } else { + { + if (_ropeLength >= 10) then { + ropeUnwind [_x, 3, -ASL_ROPE_UNWIND_SPEED, true]; + } else { + ropeUnwind [_x, 3, -1, true]; + }; + } forEach _existingRopes; + }; + }; +} else { + [_this, "ASL_Shorten_Ropes", _vehicle, true] call FUNC(remoteExec); +}; diff --git a/addons/advancedslingloading/functions/fnc_shortenRopesAction.sqf b/addons/advancedslingloading/functions/fnc_shortenRopesAction.sqf new file mode 100644 index 000000000..60ce9dcae --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_shortenRopesAction.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action handler for shortening ropes + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * [] call ttt_advancedslingloading_fnc_shortenRopesAction + * + * Public: No + */ + +private _vehicle = vehicle player; +if ([_vehicle] call FUNC(canShortenRopes)) then { + private _activeRopes = [_vehicle] call FUNC(getActiveRopes); + if (count _activeRopes > 1) then { + player setVariable ["ASL_Shorten_Index_Vehicle", _vehicle]; + ["Shorten Cargo Ropes", "ASL_Shorten_Ropes_Index_Action", _activeRopes] call FUNC(showSelectRopesMenu); + } else { + if (count _activeRopes == 1) then { + [_vehicle, player, (_activeRopes select 0) select 0] call FUNC(shortenRopes); + }; + }; +}; diff --git a/addons/advancedslingloading/functions/fnc_shortenRopesActionCheck.sqf b/addons/advancedslingloading/functions/fnc_shortenRopesActionCheck.sqf new file mode 100644 index 000000000..bfcd640ab --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_shortenRopesActionCheck.sqf @@ -0,0 +1,19 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Action check for shortening ropes + * + * Arguments: + * None + * + * Return Value: + * Can shorten ropes + * + * Example: + * [] call ttt_advancedslingloading_fnc_shortenRopesActionCheck + * + * Public: No + */ + +if (isNull objectParent player) exitWith {false}; +[vehicle player] call FUNC(canShortenRopes); diff --git a/addons/advancedslingloading/functions/fnc_shortenRopesIndexAction.sqf b/addons/advancedslingloading/functions/fnc_shortenRopesIndexAction.sqf new file mode 100644 index 000000000..1f75de6dc --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_shortenRopesIndexAction.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Index action handler for shortening specific ropes + * + * Arguments: + * 0: Rope index + * + * Return Value: + * None + * + * Example: + * [0] call ttt_advancedslingloading_fnc_shortenRopesIndexAction + * + * Public: No + */ + +params ["_ropeIndex"]; +private ["_vehicle"]; +_vehicle = player getVariable ["ASL_Shorten_Index_Vehicle", objNull]; +if (_ropeIndex >= 0 && !isNull _vehicle && [_vehicle] call FUNC(canShortenRopes)) then { + [_vehicle, player, _ropeIndex] call FUNC(shortenRopes); +}; diff --git a/addons/advancedslingloading/functions/fnc_showSelectRopesMenu.sqf b/addons/advancedslingloading/functions/fnc_showSelectRopesMenu.sqf new file mode 100644 index 000000000..bac1c3083 --- /dev/null +++ b/addons/advancedslingloading/functions/fnc_showSelectRopesMenu.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Author: Seth Duda + * Shows a menu for selecting specific ropes + * + * Arguments: + * 0: Menu title + * 1: Function name to call + * 2: Ropes index and label array + * 3: Ropes label (optional, default "Ropes") + * + * Return Value: + * None + * + * Example: + * ["Extend Cargo Ropes", "ASL_Extend_Ropes_Index_Action", [[0,"Front"]], "Ropes"] call ttt_advancedslingloading_fnc_showSelectRopesMenu + * + * Public: No + */ + +params ["_title", "_functionName", "_ropesIndexAndLabelArray", ["_ropesLabel", "Ropes"]]; +ASL_Show_Select_Ropes_Menu_Array = [[_title, false]]; +{ + ASL_Show_Select_Ropes_Menu_Array pushBack [(_x select 1) + " " + _ropesLabel, [0], "", -5, [["expression", "[" + (str (_x select 0)) + "] call " + _functionName]], "1", "1"]; +} forEach _ropesIndexAndLabelArray; +ASL_Show_Select_Ropes_Menu_Array pushBack ["All " + _ropesLabel, [0], "", -5, [["expression", "{ [_x] call " + _functionName + " } forEach [0, 1, 2];"]], "1", "1"]; +showCommandingMenu ""; +showCommandingMenu "#USER:ASL_Show_Select_Ropes_Menu_Array"; diff --git a/addons/advancedslingloading/script_component.hpp b/addons/advancedslingloading/script_component.hpp index 8a25a5c26..0ec7aaa8b 100644 --- a/addons/advancedslingloading/script_component.hpp +++ b/addons/advancedslingloading/script_component.hpp @@ -3,3 +3,24 @@ #include "\z\ttt\addons\main\script_mod.hpp" #include "\z\ttt\addons\main\script_macros.hpp" + +// Magic numbers +#define ASL_NEARBY_VEHICLE_DISTANCE 30 +#define ASL_ROPE_PROXIMITY_DISTANCE 5 +#define ASL_PICKUP_DISTANCE 10 +#define ASL_PLAYER_DISTANCE 30 +#define ASL_ROPE_UNWIND_SPEED 5 +#define ASL_DEFAULT_ROPE_LENGTH 15 +#define ASL_ROPE_LENGTH_STEP 5 +#define ASL_HEAVY_LIFT_MIN_LIFT 4000 +#define ASL_HEAVY_LIFT_MASS_FACTOR 0.8 +#define ASL_HEIGHT_DIVISOR 6 +#define ASL_WIDTH_FACTOR_DEFAULT 0.5 +#define ASL_WIDTH_FACTOR_AIR 0.3 +#define ASL_WIDTH_FACTOR_HELI 0.2 +#define ASL_LENGTH_FACTOR_DEFAULT 0.5 +#define ASL_LENGTH_FACTOR_HELI 0.45 +#define ASL_ROPE_DISTANCE_THRESHOLD 2 +#define ASL_HEAVY_LIFT_SLEEP_TIME 0.1 +#define ASL_HEAVY_LIFT_WAIT_TIME 0.5 +#define ASL_NEARBY_CHECK_INTERVAL 2