From 26cb92e9339b9675fc300274e8c9838351f92f43 Mon Sep 17 00:00:00 2001 From: Andx Date: Sat, 4 Oct 2025 17:25:54 +0200 Subject: [PATCH 01/20] split up, todo check --- addons/advancedtowing/XEH_PREP.hpp | 33 + .../functions/fnc_addPlayerTowActions.sqf | 40 + .../functions/fnc_attachTowRopes.sqf | 64 ++ .../functions/fnc_attachTowRopesAction.sqf | 36 + .../fnc_attachTowRopesActionCheck.sqf | 21 + .../functions/fnc_canAttachTowRopes.sqf | 24 + .../functions/fnc_canDropTowRopes.sqf | 18 + .../functions/fnc_canPickupTowRopes.sqf | 18 + .../functions/fnc_canPutAwayTowRopes.sqf | 25 + .../functions/fnc_canTakeTowRopes.sqf | 26 + .../functions/fnc_customHideObjectGlobal.sqf | 22 + .../functions/fnc_customHint.sqf | 20 + .../functions/fnc_customRemoteExec.sqf | 24 + .../functions/fnc_customRemoteExecServer.sqf | 24 + .../functions/fnc_customSetOwner.sqf | 20 + .../functions/fnc_dropTowRopes.sqf | 36 + .../functions/fnc_dropTowRopesAction.sqf | 22 + .../functions/fnc_dropTowRopesActionCheck.sqf | 18 + .../functions/fnc_findNearbyTowVehicles.sqf | 39 + .../functions/fnc_getCornerPoints.sqf | 58 ++ .../functions/fnc_getHitchPoints.sqf | 30 + addons/advancedtowing/functions/fnc_init.sqf | 93 ++ .../functions/fnc_initAdvancedTowing.sqf | 892 ------------------ .../advancedtowing/functions/fnc_install.sqf | 19 + .../functions/fnc_isSupportedCargo.sqf | 35 + .../functions/fnc_isSupportedVehicle.sqf | 28 + .../functions/fnc_pickupTowRopes.sqf | 44 + .../functions/fnc_pickupTowRopesAction.sqf | 36 + .../fnc_pickupTowRopesActionCheck.sqf | 18 + .../functions/fnc_putAwayTowRopes.sqf | 34 + .../functions/fnc_putAwayTowRopesAction.sqf | 35 + .../fnc_putAwayTowRopesActionCheck.sqf | 18 + .../functions/fnc_simulateTowing.sqf | 168 ++++ .../functions/fnc_simulateTowingSpeed.sqf | 80 ++ .../functions/fnc_takeTowRopes.sqf | 34 + .../functions/fnc_takeTowRopesAction.sqf | 36 + .../functions/fnc_takeTowRopesActionCheck.sqf | 18 + 37 files changed, 1314 insertions(+), 892 deletions(-) create mode 100644 addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf create mode 100644 addons/advancedtowing/functions/fnc_attachTowRopes.sqf create mode 100644 addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf create mode 100644 addons/advancedtowing/functions/fnc_attachTowRopesActionCheck.sqf create mode 100644 addons/advancedtowing/functions/fnc_canAttachTowRopes.sqf create mode 100644 addons/advancedtowing/functions/fnc_canDropTowRopes.sqf create mode 100644 addons/advancedtowing/functions/fnc_canPickupTowRopes.sqf create mode 100644 addons/advancedtowing/functions/fnc_canPutAwayTowRopes.sqf create mode 100644 addons/advancedtowing/functions/fnc_canTakeTowRopes.sqf create mode 100644 addons/advancedtowing/functions/fnc_customHideObjectGlobal.sqf create mode 100644 addons/advancedtowing/functions/fnc_customHint.sqf create mode 100644 addons/advancedtowing/functions/fnc_customRemoteExec.sqf create mode 100644 addons/advancedtowing/functions/fnc_customRemoteExecServer.sqf create mode 100644 addons/advancedtowing/functions/fnc_customSetOwner.sqf create mode 100644 addons/advancedtowing/functions/fnc_dropTowRopes.sqf create mode 100644 addons/advancedtowing/functions/fnc_dropTowRopesAction.sqf create mode 100644 addons/advancedtowing/functions/fnc_dropTowRopesActionCheck.sqf create mode 100644 addons/advancedtowing/functions/fnc_findNearbyTowVehicles.sqf create mode 100644 addons/advancedtowing/functions/fnc_getCornerPoints.sqf create mode 100644 addons/advancedtowing/functions/fnc_getHitchPoints.sqf create mode 100644 addons/advancedtowing/functions/fnc_init.sqf delete mode 100644 addons/advancedtowing/functions/fnc_initAdvancedTowing.sqf create mode 100644 addons/advancedtowing/functions/fnc_install.sqf create mode 100644 addons/advancedtowing/functions/fnc_isSupportedCargo.sqf create mode 100644 addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf create mode 100644 addons/advancedtowing/functions/fnc_pickupTowRopes.sqf create mode 100644 addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf create mode 100644 addons/advancedtowing/functions/fnc_pickupTowRopesActionCheck.sqf create mode 100644 addons/advancedtowing/functions/fnc_putAwayTowRopes.sqf create mode 100644 addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf create mode 100644 addons/advancedtowing/functions/fnc_putAwayTowRopesActionCheck.sqf create mode 100644 addons/advancedtowing/functions/fnc_simulateTowing.sqf create mode 100644 addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf create mode 100644 addons/advancedtowing/functions/fnc_takeTowRopes.sqf create mode 100644 addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf create mode 100644 addons/advancedtowing/functions/fnc_takeTowRopesActionCheck.sqf diff --git a/addons/advancedtowing/XEH_PREP.hpp b/addons/advancedtowing/XEH_PREP.hpp index 370253134..4e2ee41da 100644 --- a/addons/advancedtowing/XEH_PREP.hpp +++ b/addons/advancedtowing/XEH_PREP.hpp @@ -1 +1,34 @@ +PREP(addPlayerTowActions); +PREP(attachTowRopes); +PREP(attachTowRopesAction); +PREP(attachTowRopesActionCheck); +PREP(canAttachTowRopes); +PREP(canDropTowRopes); +PREP(canPickupTowRopes); +PREP(canPutAwayTowRopes); +PREP(canTakeTowRopes); +PREP(customHideObjectGlobal); +PREP(customHint); +PREP(customRemoteExec); +PREP(customRemoteExecServer); +PREP(customSetOwner); +PREP(dropTowRopes); +PREP(dropTowRopesAction); +PREP(dropTowRopesActionCheck); +PREP(findNearbyTowVehicles); +PREP(getCornerPoints); +PREP(getHitchPoints); +PREP(init); PREP(initAdvancedTowing); +PREP(isSupportedCargo); +PREP(isSupportedVehicle); +PREP(pickupTowRopes); +PREP(pickupTowRopesAction); +PREP(pickupTowRopesActionCheck); +PREP(putAwayTowRopes); +PREP(putAwayTowRopesAction); +PREP(putAwayTowRopesActionCheck); +PREP(simulateTowingSpeed); +PREP(takeTowRopes); +PREP(takeTowRopesAction); +PREP(takeTowRopesActionCheck); diff --git a/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf b/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf new file mode 100644 index 000000000..8838ab70b --- /dev/null +++ b/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_addPlayerTowActions + * + * Public: No + */ + +player addAction ["Deploy Tow Ropes", { //ToDo Localize + call FUNC(takeTowRopesAction); +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(deployTowRopesActionCheck), _this)] call CBA_fnc_directCall)]; + +player addAction ["Put Away Tow Ropes", { //ToDo Localize + call FUNC(putAwayTowRopesAction); +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(putAwayTowRopesActionCheck), _this)] call CBA_fnc_directCall)]; + +player addAction ["Attach To Tow Ropes", { //ToDo Localize + call FUNC(attachTowRopesAction); +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(attachTowRopesActionCheck), _this)] call CBA_fnc_directCall)]; + +player addAction ["Drop Tow Ropes", { //ToDo Localize + call FUNC(dropTowRopesAction); +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(dropTowRopesActionCheck), _this)] call CBA_fnc_directCall)]; + +player addAction ["Pickup Tow Ropes", { //ToDo Localize + call FUNC(pickupTowRopesAction); +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(pickupTowRopesActionCheck), _this)] call CBA_fnc_directCall)]; + +player addEventHandler ["Respawn", { + player setVariable [QGVAR(Actions_Loaded), false]; +}]; diff --git a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf new file mode 100644 index 000000000..85452d4e3 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf @@ -0,0 +1,64 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_attachTowRopes + * + * Public: No + */ + +params ["_cargo", "_player"]; + +_vehicle = _player getVariable [QGVAR(ropes_vehicle), objNull]; + +if(!isNull _vehicle) then { + if(local _vehicle) then { + private ["_cargoHitch","_objDistance","_ropeLength"]; + private _towRopes = _vehicle getVariable [QGVAR(Ropes), []]; + + if(count _towRopes == 1) then { + + private ["_cargoHitchPoints","_distanceToFrontHitch","_distanceToRearHitch","_isRearCargoHitch"]; + + _cargoHitchPoints = [_cargo] call FUNC(getHitchPoints); + _distanceToFrontHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 0)); + _distanceToRearHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 1)); + if( _distanceToFrontHitch < _distanceToRearHitch ) then { + _cargoHitch = _cargoHitchPoints select 0; + _isRearCargoHitch = false; + } else { + _cargoHitch = _cargoHitchPoints select 1; + _isRearCargoHitch = true; + }; + + + _cargoHitch = ([_cargo] call FUNC(getHitchPoints)) select 0; + + private _vehicleHitch = ([_vehicle] call FUNC(getHitchPoints)) select 1; + _ropeLength = (ropeLength (_towRopes select 0)); + _objDistance = ((_vehicle modelToWorld _vehicleHitch) distance (_cargo modelToWorld _cargoHitch)); + if( _objDistance > _ropeLength ) then { + [["The tow ropes are too short. Move vehicle closer.", false],FUNC(customHint), _player] call FUNC(customRemoteExec); //ToDo Localize + } else { + [_vehicle,_player] call FUNC(dropTowRopes); + _helper = "Land_Can_V2_F" createVehicle position _cargo; + _helper attachTo [_cargo, _cargoHitch]; + _helper setVariable [GVAR(Cargo), _cargo, true]; + hideObject _helper; + [[_helper], QFUNC(customHideObjectGlobal)] call FUNC(customRemoteExecServer); + [_helper, [0, 0, 0], [0, 0, -1]] ropeAttachTo (_towRopes select 0); + [_vehicle, _vehicleHitch, _cargo, _cargoHitch, _ropeLength] spawn FUNC(simulateTowing); + }; + }; + } else { + [_this, QFUNC(attachTowRopes), _vehicle, true] call FUNC(customRemoteExec); + }; +}; diff --git a/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf new file mode 100644 index 000000000..14622f916 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_attachTowRopesAction + * + * Public: No + */ + +private _cargo = cursorTarget; +private _vehicle = player getVariable [QGVAR(Ropes_Vehicle), objNull]; + +if([_vehicle, _cargo] call FUNC(canAttachTowRopes)) then { + + private _canBeTowed = true; + + if!(missionNamespace getVariable [QGVAR(LOCKED_VEHICLES_ENABLED), false]) then { + if( locked _cargo > 1 ) then { + ["Cannot attach tow ropes to locked vehicle", false] call FUNC(customHint);//ToDo Localize + _canBeTowed = false; + }; + }; + + if(_canBeTowed) then { + [_cargo, player] call FUNC(attachTowRopes); + }; + +}; diff --git a/addons/advancedtowing/functions/fnc_attachTowRopesActionCheck.sqf b/addons/advancedtowing/functions/fnc_attachTowRopesActionCheck.sqf new file mode 100644 index 000000000..e3b99d3ba --- /dev/null +++ b/addons/advancedtowing/functions/fnc_attachTowRopesActionCheck.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_attachTowRopesActionCheck + * + * Public: No + */ + +private _vehicle = player getVariable [QGVAR(Ropes_Vehicle), objNull]; +private _cargo = cursorTarget; + +[_vehicle, _cargo] call FUNC(canAttachTowRopes); diff --git a/addons/advancedtowing/functions/fnc_canAttachTowRopes.sqf b/addons/advancedtowing/functions/fnc_canAttachTowRopes.sqf new file mode 100644 index 000000000..20fe51037 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_canAttachTowRopes.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_canAttachTowRopes + * + * Public: No + */ + +params ["_vehicle", "_cargo"]; + +if(!isNull _vehicle && !isNull _cargo) then { + [_vehicle, _cargo] call FUNC(isSupportedCargo) && isNull objectParent player && player distance _cargo < 10 && _vehicle != _cargo; +} else { + false; +}; diff --git a/addons/advancedtowing/functions/fnc_canDropTowRopes.sqf b/addons/advancedtowing/functions/fnc_canDropTowRopes.sqf new file mode 100644 index 000000000..4347da228 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_canDropTowRopes.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_canDropTowRopes + * + * Public: No + */ + +!isNull (player getVariable [QGVAR(Ropes_Vehicle), objNull]) && isNull objectParent player; diff --git a/addons/advancedtowing/functions/fnc_canPickupTowRopes.sqf b/addons/advancedtowing/functions/fnc_canPickupTowRopes.sqf new file mode 100644 index 000000000..cd4dee4d2 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_canPickupTowRopes.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_canPickupTowRopes + * + * Public: No + */ + +isNull (player getVariable [QGVAR(Ropes_Vehicle), objNull]) && count (missionNamespace getVariable [QGVAR(Nearby_Tow_Vehicles), []]) > 0 && isNull objectParent player; diff --git a/addons/advancedtowing/functions/fnc_canPutAwayTowRopes.sqf b/addons/advancedtowing/functions/fnc_canPutAwayTowRopes.sqf new file mode 100644 index 000000000..5ec726cd0 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_canPutAwayTowRopes.sqf @@ -0,0 +1,25 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_canPutAwayTowRopes + * + * Public: No + */ + +params ["_vehicle"]; + +if([_vehicle] call FUNC(isSupportedVehicle)) then { + private _existingTowRopes = _vehicle getVariable [QGVAR(Ropes),[]]; + isNull objectParent player && player distance _vehicle < 10 && (count _existingTowRopes) > 0; +} else { + false; +}; diff --git a/addons/advancedtowing/functions/fnc_canTakeTowRopes.sqf b/addons/advancedtowing/functions/fnc_canTakeTowRopes.sqf new file mode 100644 index 000000000..0eb538ac4 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_canTakeTowRopes.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_canTakeTowRopes + * + * Public: No + */ + +params ["_vehicle"]; + +if([_vehicle] call FUNC(isSupportedVehicle)) then { + private _existingTowRopes = _vehicle getVariable [QGVAR(Ropes),[]]; + private _existingVehicle = player getVariable [QGVAR(Ropes_Vehicle), objNull]; + isNull objectParent player && player distance _vehicle < 10 && (count _existingTowRopes) == 0 && isNull _existingVehicle; +} else { + false; +}; diff --git a/addons/advancedtowing/functions/fnc_customHideObjectGlobal.sqf b/addons/advancedtowing/functions/fnc_customHideObjectGlobal.sqf new file mode 100644 index 000000000..1b83558a2 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_customHideObjectGlobal.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_customHideObjectGlobal + * + * Public: No + */ + +params ["_obj"]; + +if( _obj isKindOf "Land_Can_V2_F" ) then { + hideObjectGlobal _obj; +}; diff --git a/addons/advancedtowing/functions/fnc_customHint.sqf b/addons/advancedtowing/functions/fnc_customHint.sqf new file mode 100644 index 000000000..0c043557a --- /dev/null +++ b/addons/advancedtowing/functions/fnc_customHint.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_customHint + * + * Public: No + */ + +params ["_msg",["_isSuccess",true]]; + +hint _msg; diff --git a/addons/advancedtowing/functions/fnc_customRemoteExec.sqf b/addons/advancedtowing/functions/fnc_customRemoteExec.sqf new file mode 100644 index 000000000..a43572c87 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_customRemoteExec.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_customRemoteExec + * + * Public: No + */ + +params ["_params", "_functionName", "_target", ["_isCall", false]]; + +if(_isCall) then { + _params remoteExecCall [_functionName, _target]; +} else { + _params remoteExec [_functionName, _target]; +}; diff --git a/addons/advancedtowing/functions/fnc_customRemoteExecServer.sqf b/addons/advancedtowing/functions/fnc_customRemoteExecServer.sqf new file mode 100644 index 000000000..c575f3a95 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_customRemoteExecServer.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_customRemoteExecServer + * + * Public: No + */ + +params ["_params", "_functionName", ["_isCall", false]]; + +if(_isCall) then { + _params remoteExecCall [_functionName, 2]; +} else { + _params remoteExec [_functionName, 2]; +}; diff --git a/addons/advancedtowing/functions/fnc_customSetOwner.sqf b/addons/advancedtowing/functions/fnc_customSetOwner.sqf new file mode 100644 index 000000000..54b1f451f --- /dev/null +++ b/addons/advancedtowing/functions/fnc_customSetOwner.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_customSetOwner + * + * Public: No + */ + +params ["_obj", "_client"]; + +_obj setOwner _client; diff --git a/addons/advancedtowing/functions/fnc_dropTowRopes.sqf b/addons/advancedtowing/functions/fnc_dropTowRopes.sqf new file mode 100644 index 000000000..05cdd4a26 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_dropTowRopes.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_dropTowRopes + * + * Public: No + */ + +params ["_vehicle", "_player"]; + +if(local _vehicle) then { + private _helper = (_player getVariable [QGVAR(Ropes_Pick_Up_Helper), objNull]); + + if(!isNull _helper) then { + { + _helper ropeDetach _x; + } forEach (_vehicle getVariable [QGVAR(Ropes),[]]); + detach _helper; + deleteVehicle _helper; + }; + + _player setVariable [QGVAR(Ropes_Vehicle), nil, true]; + _player setVariable [QGVAR(Ropes_Pick_Up_Helper), nil, true]; + +} else { + [_this, QFUNC(dropTowRopes), _vehicle, true] call FUNC(customRemoteExec); +}; diff --git a/addons/advancedtowing/functions/fnc_dropTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_dropTowRopesAction.sqf new file mode 100644 index 000000000..065d80818 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_dropTowRopesAction.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_dropTowRopesAction + * + * Public: No + */ + +private _vehicle = player getVariable [QGVAR(Ropes_Vehicle), objNull]; + +if([] call FUNC(canDropTowRopes)) then { + [_vehicle, player] call FUNC(dropTowRopes); +}; diff --git a/addons/advancedtowing/functions/fnc_dropTowRopesActionCheck.sqf b/addons/advancedtowing/functions/fnc_dropTowRopesActionCheck.sqf new file mode 100644 index 000000000..0141020bf --- /dev/null +++ b/addons/advancedtowing/functions/fnc_dropTowRopesActionCheck.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_dropTowRopesActionCheck + * + * Public: No + */ + +[] call SA_Can_Drop_Tow_Ropes; diff --git a/addons/advancedtowing/functions/fnc_findNearbyTowVehicles.sqf b/addons/advancedtowing/functions/fnc_findNearbyTowVehicles.sqf new file mode 100644 index 000000000..c832c468e --- /dev/null +++ b/addons/advancedtowing/functions/fnc_findNearbyTowVehicles.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_findNearbyTowVehicles + * + * Public: No + */ + +private _nearVehicles = []; + +{ + _nearVehicles append (position player nearObjects [_x, 30]); +} forEach (missionNamespace getVariable [QGVAR(SUPPORTED_VEHICLES_OVERRIDE), SA_tow_supported_vehicles]); + +private _nearVehiclesWithTowRopes = []; +{ + private _vehicle = _x; + { + private _ends = ropeEndPosition _x; + if(count _ends == 2) then { + private _end1 = _ends select 0; + private _end2 = _ends select 1; + if(((position player) distance _end1) < 5 || ((position player) distance _end2) < 5 ) then { + _nearVehiclesWithTowRopes pushBack _vehicle; + } + }; + } forEach (_vehicle getVariable [QGVAR(Ropes), []]); +} forEach _nearVehicles; + +_nearVehiclesWithTowRopes; diff --git a/addons/advancedtowing/functions/fnc_getCornerPoints.sqf b/addons/advancedtowing/functions/fnc_getCornerPoints.sqf new file mode 100644 index 000000000..4a04b0324 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_getCornerPoints.sqf @@ -0,0 +1,58 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_getCornerPoints + * + * Public: No + */ + +params ["_vehicle"]; + +// Correct width and length factor for air +private _widthFactor = 0.75; +private _lengthFactor = 0.75; + +if(_vehicle isKindOf "Air") then { + _widthFactor = 0.3; +}; +if(_vehicle isKindOf "Helicopter") then { + _widthFactor = 0.2; + _lengthFactor = 0.45; +}; + +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 _rearCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) - _lengthOffset, _centerOfMass select 2]; +private _rearCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) - _lengthOffset, _centerOfMass select 2]; +private _frontCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) + _lengthOffset, _centerOfMass select 2]; +private _frontCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) + _lengthOffset, _centerOfMass select 2]; + +if(missionNamespace getVariable [QGVAR(DEBUG_ENABLED), false]) then { + if(isNil "sa_tow_debug_arrow_1") then { + sa_tow_debug_arrow_1 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; + sa_tow_debug_arrow_2 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; + sa_tow_debug_arrow_3 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; + sa_tow_debug_arrow_4 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; + }; + sa_tow_debug_arrow_1 setPosASL AGLToASL (_vehicle modelToWorldVisual _rearCorner); + sa_tow_debug_arrow_2 setPosASL AGLToASL (_vehicle modelToWorldVisual _rearCorner2); + sa_tow_debug_arrow_3 setPosASL AGLToASL (_vehicle modelToWorldVisual _frontCorner); + sa_tow_debug_arrow_4 setPosASL AGLToASL (_vehicle modelToWorldVisual _frontCorner2); +}; + +[_rearCorner,_rearCorner2,_frontCorner,_frontCorner2]; diff --git a/addons/advancedtowing/functions/fnc_getHitchPoints.sqf b/addons/advancedtowing/functions/fnc_getHitchPoints.sqf new file mode 100644 index 000000000..4afb3ec13 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_getHitchPoints.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_getHitchPoints + * + * Public: No + */ + +params ["_vehicle"]; + +private _cornerPoints = [_vehicle] call FUNC(getCornerPoints); +private _rearCorner = _cornerPoints select 0; +private _rearCorner2 = _cornerPoints select 1; +private _frontCorner = _cornerPoints select 2; +private _frontCorner2 = _cornerPoints select 3; +private _rearHitchPoint = ((_rearCorner vectorDiff _rearCorner2) vectorMultiply 0.5) vectorAdd _rearCorner2; +private _frontHitchPoint = ((_frontCorner vectorDiff _frontCorner2) vectorMultiply 0.5) vectorAdd _frontCorner2; +//_sideLeftPoint = ((_frontCorner vectorDiff _rearCorner) vectorMultiply 0.5) vectorAdd _frontCorner; +//_sideRightPoint = ((_frontCorner2 vectorDiff _rearCorner2) vectorMultiply 0.5) vectorAdd _frontCorner2; + +[_frontHitchPoint,_rearHitchPoint]; diff --git a/addons/advancedtowing/functions/fnc_init.sqf b/addons/advancedtowing/functions/fnc_init.sqf new file mode 100644 index 000000000..644d0311a --- /dev/null +++ b/addons/advancedtowing/functions/fnc_init.sqf @@ -0,0 +1,93 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_init + * + * Public: No + */ + + SA_TOW_LOCKED_VEHICLES_ENABLED = true; + +_isRearCargoHitch = 0; +#define SA_Find_Surface_ASL_Under_Position(_object,_positionAGL,_returnSurfaceASL,_canFloat) \ +_objectASL = AGLToASL (_object modelToWorldVisual (getCenterOfMass _object)); \ +_surfaceIntersectStartASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) + 1]; \ +_surfaceIntersectEndASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) - 5]; \ +_surfaces = lineIntersectsSurfaces [_surfaceIntersectStartASL, _surfaceIntersectEndASL, _object, objNull, true, 5]; \ +_returnSurfaceASL = AGLToASL _positionAGL; \ +{ \ + scopeName "surfaceLoop"; \ + if( isNull (_x select 2) ) then { \ + _returnSurfaceASL = _x select 0; \ + breakOut "surfaceLoop"; \ + } else { \ + if!((_x select 2) isKindOf "RopeSegment") then { \ + _objectFileName = str (_x select 2); \ + if((_objectFileName find " t_") == -1 && (_objectFileName find " b_") == -1) then { \ + _returnSurfaceASL = _x select 0; \ + breakOut "surfaceLoop"; \ + }; \ + }; \ + }; \ +} forEach _surfaces; \ +if(_canFloat && (_returnSurfaceASL select 2) < 0) then { \ + _returnSurfaceASL set [2,0]; \ +}; \ + +#define SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceASL,_canFloat) \ +SA_Find_Surface_ASL_Under_Position(_object,(_object modelToWorldVisual _modelOffset),_returnSurfaceASL,_canFloat); + +#define SA_Find_Surface_AGL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat) \ +SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat); \ +_returnSurfaceAGL = ASLtoAGL _returnSurfaceAGL; + +#define SA_Get_Cargo(_vehicle,_cargo) \ +if( count (ropeAttachedObjects _vehicle) == 0 ) then { \ + _cargo = objNull; \ +} else { \ + _cargo = ((ropeAttachedObjects _vehicle) select 0) getVariable ["SA_Cargo",objNull]; \ +}; + +SA_tow_supported_vehicles = [ + //"Tank", "Car", "Ship" +]; + +SA_TOW_RULES = [ + ["Tank","CAN_TOW","Tank"], + ["Tank","CAN_TOW","Car"], + ["Tank","CAN_TOW","Ship"], + ["Tank","CAN_TOW","Air"], + //["Car","CAN_TOW","Tank"], + ["Car","CAN_TOW","Car"], + ["Car","CAN_TOW","Ship"], + ["Car","CAN_TOW","Air"], + ["Ship","CAN_TOW","Ship"] +]; + +if(!isDedicated) then { + [] spawn { + while {true} do { + if(!isNull player && isPlayer player) then { + if!( player getVariable [QGVAR(Actions_Loaded), false] ) then { + [] callFUNC(addPlayerTowActions); + player setVariable [QGVAR(Actions_Loaded), true]; + }; + }; + missionNamespace setVariable [QGVAR(Nearby_Tow_Vehicles), (call FUNC(findNearbyTowVehicles))]; + sleep 2; + }; + }; +}; + +if(isServer) then { + [] call FUNC(Install); +}; diff --git a/addons/advancedtowing/functions/fnc_initAdvancedTowing.sqf b/addons/advancedtowing/functions/fnc_initAdvancedTowing.sqf deleted file mode 100644 index 9182f6a90..000000000 --- a/addons/advancedtowing/functions/fnc_initAdvancedTowing.sqf +++ /dev/null @@ -1,892 +0,0 @@ -#include "..\script_component.hpp" - -/* -The MIT License (MIT) - -Copyright (c) 2016 Seth Duda - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ - -SA_TOW_LOCKED_VEHICLES_ENABLED = true; - -_isRearCargoHitch = 0; -#define SA_Find_Surface_ASL_Under_Position(_object,_positionAGL,_returnSurfaceASL,_canFloat) \ -_objectASL = AGLToASL (_object modelToWorldVisual (getCenterOfMass _object)); \ -_surfaceIntersectStartASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) + 1]; \ -_surfaceIntersectEndASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) - 5]; \ -_surfaces = lineIntersectsSurfaces [_surfaceIntersectStartASL, _surfaceIntersectEndASL, _object, objNull, true, 5]; \ -_returnSurfaceASL = AGLToASL _positionAGL; \ -{ \ - scopeName "surfaceLoop"; \ - if( isNull (_x select 2) ) then { \ - _returnSurfaceASL = _x select 0; \ - breakOut "surfaceLoop"; \ - } else { \ - if!((_x select 2) isKindOf "RopeSegment") then { \ - _objectFileName = str (_x select 2); \ - if((_objectFileName find " t_") == -1 && (_objectFileName find " b_") == -1) then { \ - _returnSurfaceASL = _x select 0; \ - breakOut "surfaceLoop"; \ - }; \ - }; \ - }; \ -} forEach _surfaces; \ -if(_canFloat && (_returnSurfaceASL select 2) < 0) then { \ - _returnSurfaceASL set [2,0]; \ -}; \ - -#define SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceASL,_canFloat) \ -SA_Find_Surface_ASL_Under_Position(_object,(_object modelToWorldVisual _modelOffset),_returnSurfaceASL,_canFloat); - -#define SA_Find_Surface_AGL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat) \ -SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat); \ -_returnSurfaceAGL = ASLtoAGL _returnSurfaceAGL; - -#define SA_Get_Cargo(_vehicle,_cargo) \ -if( count (ropeAttachedObjects _vehicle) == 0 ) then { \ - _cargo = objNull; \ -} else { \ - _cargo = ((ropeAttachedObjects _vehicle) select 0) getVariable ["SA_Cargo",objNull]; \ -}; - -SA_Advanced_Towing_Install = { - -// Prevent advanced towing from installing twice -if(!isNil "SA_TOW_INIT") exitWith {}; -SA_TOW_INIT = true; - -INFO("Advanced Towing Loading..."); - -SA_Simulate_Towing_Speed = { - - params ["_vehicle"]; - - private ["_runSimulation","_currentCargo","_maxVehicleSpeed","_vehicleMass"]; - - _maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); - _vehicleMass = 1000 max (getMass _vehicle); - _maxTowedCargo = missionNamespace getVariable ["SA_MAX_TOWED_CARGO",2]; - _runSimulation = true; - - private ["_currentVehicle","_totalCargoMass","_totalCargoCount","_findNextCargo","_towRopes","_ropeLength"]; - private ["_ends","_endsDistance","_currentMaxSpeed","_newMaxSpeed"]; - - while {_runSimulation} do { - - // Calculate total mass and count of cargo being towed (only takes into account - // cargo that's actively being towed (e.g. there's no slack in the rope) - - _currentVehicle = _vehicle; - _totalCargoMass = 0; - _totalCargoCount = 0; - _findNextCargo = true; - while {_findNextCargo} do { - _findNextCargo = false; - SA_Get_Cargo(_currentVehicle,_currentCargo); - if(!isNull _currentCargo) then { - _towRopes = _currentVehicle getVariable ["SA_Tow_Ropes",[]]; - if(count _towRopes > 0) then { - _ropeLength = ropeLength (_towRopes select 0); - _ends = ropeEndPosition (_towRopes select 0); - _endsDistance = (_ends select 0) distance (_ends select 1); - if( _endsDistance >= _ropeLength - 2 ) then { - _totalCargoMass = _totalCargoMass + (1000 max (getMass _currentCargo)); - _totalCargoCount = _totalCargoCount + 1; - _currentVehicle = _currentCargo; - _findNextCargo = true; - }; - }; - }; - }; - - _newMaxSpeed = _maxVehicleSpeed / (1 max ((_totalCargoMass / _vehicleMass) * 2)); - _newMaxSpeed = (_maxVehicleSpeed * 0.75) min _newMaxSpeed; - - // Prevent vehicle from moving if trying to move more cargo than pre-defined max - if(_totalCargoCount > _maxTowedCargo) then { - _newMaxSpeed = 0; - }; - - _currentMaxSpeed = _vehicle getVariable ["SA_Max_Tow_Speed",_maxVehicleSpeed]; - - if(_currentMaxSpeed != _newMaxSpeed) then { - _vehicle setVariable ["SA_Max_Tow_Speed",_newMaxSpeed]; - }; - - sleep 0.1; - - }; -}; - -SA_Simulate_Towing = { - - params ["_vehicle","_vehicleHitchModelPos","_cargo","_cargoHitchModelPos","_ropeLength"]; - - private ["_lastCargoHitchPosition","_lastCargoVectorDir","_cargoLength","_maxDistanceToCargo","_lastMovedCargoPosition","_cargoHitchPoints"]; - private ["_vehicleHitchPosition","_cargoHitchPosition","_newCargoHitchPosition","_cargoVector","_movedCargoVector","_currentCargo"]; - private ["_newCargoDir","_lastCargoVectorDir","_newCargoPosition","_doExit","_cargoPosition","_vehiclePosition","_maxVehicleSpeed","_vehicleMass","_cargoMass","_cargoCanFloat"]; - private ["_cargoCorner1AGL","_cargoCorner1ASL","_cargoCorner2AGL","_cargoCorner2ASL","_cargoCorner3AGL","_cargoCorner3ASL","_cargoCorner4AGL","_cargoCorner4ASL","_surfaceNormal1","_surfaceNormal2","_surfaceNormal"]; - private ["_cargoCenterASL","_surfaceHeight","_surfaceHeight2","_maxSurfaceHeight"]; - - _maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); - _cargoCanFloat = [false, true] select (getNumber ((configOf _cargo) >> "canFloat") == 1); - - private ["_cargoCenterOfMassAGL","_cargoModelCenterGroundPosition"]; - SA_Find_Surface_AGL_Under_Model(_cargo,getCenterOfMass _cargo,_cargoCenterOfMassAGL,_cargoCanFloat); - _cargoModelCenterGroundPosition = _cargo worldToModelVisual _cargoCenterOfMassAGL; - _cargoModelCenterGroundPosition set [0,0]; - _cargoModelCenterGroundPosition set [1,0]; - _cargoModelCenterGroundPosition set [2, (_cargoModelCenterGroundPosition select 2) - 0.05]; // Adjust height so that it doesn't ride directly on ground - - // Calculate cargo model corner points - private ["_cargoCornerPoints"]; - _cargoCornerPoints = [_cargo] call SA_Get_Corner_Points; - _corner1 = _cargoCornerPoints select 0; - _corner2 = _cargoCornerPoints select 1; - _corner3 = _cargoCornerPoints select 2; - _corner4 = _cargoCornerPoints select 3; - - - // Try to set cargo owner if the towing client doesn't own the cargo - if(local _vehicle && !local _cargo) then { - [[_cargo, clientOwner],"SA_Set_Owner"] call SA_RemoteExecServer; - }; - - _vehicleHitchModelPos set [2,0]; - _cargoHitchModelPos set [2,0]; - - _lastCargoHitchPosition = _cargo modelToWorld _cargoHitchModelPos; - _lastCargoVectorDir = vectorDir _cargo; - _lastMovedCargoPosition = getPos _cargo; - - _cargoHitchPoints = [_cargo] call SA_Get_Hitch_Points; - _cargoLength = (_cargoHitchPoints select 0) distance (_cargoHitchPoints select 1); - - _vehicleMass = 1 max (getMass _vehicle); - _cargoMass = getMass _cargo; - if(_cargoMass == 0) then { - _cargoMass = _vehicleMass; - }; - - _maxDistanceToCargo = _ropeLength; - - _doExit = false; - - // Start vehicle speed simulation - [_vehicle] spawn SA_Simulate_Towing_Speed; - - while {!_doExit} do { - - _vehicleHitchPosition = _vehicle modelToWorld _vehicleHitchModelPos; - _vehicleHitchPosition set [2,0]; - _cargoHitchPosition = _lastCargoHitchPosition; - _cargoHitchPosition set [2,0]; - - _cargoPosition = getPos _cargo; - _vehiclePosition = getPos _vehicle; - - if(_vehicleHitchPosition distance _cargoHitchPosition > _maxDistanceToCargo) then { - - // Calculated simulated towing position + direction - _newCargoHitchPosition = _vehicleHitchPosition vectorAdd ((_vehicleHitchPosition vectorFromTo _cargoHitchPosition) vectorMultiply _ropeLength); - _cargoVector = _lastCargoVectorDir vectorMultiply _cargoLength; - _movedCargoVector = _newCargoHitchPosition vectorDiff _lastCargoHitchPosition; - _newCargoDir = vectorNormalized (_cargoVector vectorAdd _movedCargoVector); - //if(_isRearCargoHitch) then { - // _newCargoDir = _newCargoDir vectorMultiply -1; - //}; - _lastCargoVectorDir = _newCargoDir; - _newCargoPosition = _newCargoHitchPosition vectorAdd (_newCargoDir vectorMultiply -(vectorMagnitude (_cargoHitchModelPos))); - - SA_Find_Surface_ASL_Under_Position(_cargo,_newCargoPosition,_newCargoPosition,_cargoCanFloat); - - // Calculate surface normal (up) (more realistic than surfaceNormal function) - SA_Find_Surface_ASL_Under_Model(_cargo,_corner1,_cargoCorner1ASL,_cargoCanFloat); - SA_Find_Surface_ASL_Under_Model(_cargo,_corner2,_cargoCorner2ASL,_cargoCanFloat); - SA_Find_Surface_ASL_Under_Model(_cargo,_corner3,_cargoCorner3ASL,_cargoCanFloat); - SA_Find_Surface_ASL_Under_Model(_cargo,_corner4,_cargoCorner4ASL,_cargoCanFloat); - _surfaceNormal1 = (_cargoCorner1ASL vectorFromTo _cargoCorner3ASL) vectorCrossProduct (_cargoCorner1ASL vectorFromTo _cargoCorner2ASL); - _surfaceNormal2 = (_cargoCorner4ASL vectorFromTo _cargoCorner2ASL) vectorCrossProduct (_cargoCorner4ASL vectorFromTo _cargoCorner3ASL); - _surfaceNormal = _surfaceNormal1 vectorAdd _surfaceNormal2; - - if(missionNamespace getVariable ["SA_TOW_DEBUG_ENABLED", false]) then { - if(isNil "sa_tow_debug_arrow_1") then { - sa_tow_debug_arrow_1 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; - sa_tow_debug_arrow_2 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; - sa_tow_debug_arrow_3 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; - sa_tow_debug_arrow_4 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; - }; - sa_tow_debug_arrow_1 setPosASL _cargoCorner1ASL; - sa_tow_debug_arrow_1 setVectorUp _surfaceNormal; - sa_tow_debug_arrow_2 setPosASL _cargoCorner2ASL; - sa_tow_debug_arrow_2 setVectorUp _surfaceNormal; - sa_tow_debug_arrow_3 setPosASL _cargoCorner3ASL; - sa_tow_debug_arrow_3 setVectorUp _surfaceNormal; - sa_tow_debug_arrow_4 setPosASL _cargoCorner4ASL; - sa_tow_debug_arrow_4 setVectorUp _surfaceNormal; - }; - - // Calculate adjusted surface height based on surface normal (prevents vehicle from clipping into ground) - _cargoCenterASL = AGLToASL (_cargo modelToWorldVisual [0,0,0]); - _cargoCenterASL set [2,0]; - _surfaceHeight = ((_cargoCorner1ASL vectorAdd ( _cargoCenterASL vectorMultiply -1)) vectorDotProduct _surfaceNormal1) / ([0,0,1] vectorDotProduct _surfaceNormal1); - _surfaceHeight2 = ((_cargoCorner1ASL vectorAdd ( _cargoCenterASL vectorMultiply -1)) vectorDotProduct _surfaceNormal2) / ([0,0,1] vectorDotProduct _surfaceNormal2); - _maxSurfaceHeight = (_newCargoPosition select 2) max _surfaceHeight max _surfaceHeight2; - _newCargoPosition set [2, _maxSurfaceHeight ]; - - _newCargoPosition = _newCargoPosition vectorAdd ( _cargoModelCenterGroundPosition vectorMultiply -1 ); - - _cargo setVectorDir _newCargoDir; - _cargo setVectorUp _surfaceNormal; - _cargo setPosWorld _newCargoPosition; - - _lastCargoHitchPosition = _newCargoHitchPosition; - _maxDistanceToCargo = _vehicleHitchPosition distance _newCargoHitchPosition; - _lastMovedCargoPosition = _cargoPosition; - - _massAdjustedMaxSpeed = _vehicle getVariable ["SA_Max_Tow_Speed",_maxVehicleSpeed]; - if(speed _vehicle > (_massAdjustedMaxSpeed)+0.1) then { - _vehicle setVelocity ((vectorNormalized (velocity _vehicle)) vectorMultiply (_massAdjustedMaxSpeed/3.6)); - }; - - } else { - - if(_lastMovedCargoPosition distance _cargoPosition > 2) then { - _lastCargoHitchPosition = _cargo modelToWorld _cargoHitchModelPos; - _lastCargoVectorDir = vectorDir _cargo; - }; - - }; - - // If vehicle isn't local to the client, switch client running towing simulation - if(!local _vehicle) then { - [_this,"SA_Simulate_Towing",_vehicle] call SA_RemoteExec; - _doExit = true; - }; - - // If the vehicle isn't towing anything, stop the towing simulation - SA_Get_Cargo(_vehicle,_currentCargo); - if(isNull _currentCargo) then { - _doExit = true; - }; - - sleep 0.01; - - }; -}; - -SA_Get_Corner_Points = { - params ["_vehicle"]; - private ["_centerOfMass","_bbr","_p1","_p2","_rearCorner","_rearCorner2","_frontCorner","_frontCorner2"]; - private ["_maxWidth","_widthOffset","_maxLength","_lengthOffset","_widthFactor","_lengthFactor"]; - - // Correct width and length factor for air - _widthFactor = 0.75; - _lengthFactor = 0.75; - 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; - _rearCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) - _lengthOffset, _centerOfMass select 2]; - _rearCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) - _lengthOffset, _centerOfMass select 2]; - _frontCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) + _lengthOffset, _centerOfMass select 2]; - _frontCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) + _lengthOffset, _centerOfMass select 2]; - - if(missionNamespace getVariable ["SA_TOW_DEBUG_ENABLED", false]) then { - if(isNil "sa_tow_debug_arrow_1") then { - sa_tow_debug_arrow_1 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; - sa_tow_debug_arrow_2 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; - sa_tow_debug_arrow_3 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; - sa_tow_debug_arrow_4 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; - }; - sa_tow_debug_arrow_1 setPosASL AGLToASL (_vehicle modelToWorldVisual _rearCorner); - sa_tow_debug_arrow_2 setPosASL AGLToASL (_vehicle modelToWorldVisual _rearCorner2); - sa_tow_debug_arrow_3 setPosASL AGLToASL (_vehicle modelToWorldVisual _frontCorner); - sa_tow_debug_arrow_4 setPosASL AGLToASL (_vehicle modelToWorldVisual _frontCorner2); - }; - - [_rearCorner,_rearCorner2,_frontCorner,_frontCorner2]; -}; - -SA_Get_Hitch_Points = { - params ["_vehicle"]; - private ["_cornerPoints","_rearCorner","_rearCorner2","_frontCorner","_frontCorner2","_rearHitchPoint"]; - private ["_frontHitchPoint","_sideLeftPoint","_sideRightPoint"]; - _cornerPoints = [_vehicle] call SA_Get_Corner_Points; - _rearCorner = _cornerPoints select 0; - _rearCorner2 = _cornerPoints select 1; - _frontCorner = _cornerPoints select 2; - _frontCorner2 = _cornerPoints select 3; - _rearHitchPoint = ((_rearCorner vectorDiff _rearCorner2) vectorMultiply 0.5) vectorAdd _rearCorner2; - _frontHitchPoint = ((_frontCorner vectorDiff _frontCorner2) vectorMultiply 0.5) vectorAdd _frontCorner2; - //_sideLeftPoint = ((_frontCorner vectorDiff _rearCorner) vectorMultiply 0.5) vectorAdd _frontCorner; - //_sideRightPoint = ((_frontCorner2 vectorDiff _rearCorner2) vectorMultiply 0.5) vectorAdd _frontCorner2; - [_frontHitchPoint,_rearHitchPoint]; -}; - -SA_Attach_Tow_Ropes = { - params ["_cargo","_player"]; - _vehicle = _player getVariable ["SA_Tow_Ropes_Vehicle", objNull]; - if(!isNull _vehicle) then { - if(local _vehicle) then { - private ["_towRopes","_vehicleHitch","_cargoHitch","_objDistance","_ropeLength"]; - _towRopes = _vehicle getVariable ["SA_Tow_Ropes",[]]; - if(count _towRopes == 1) then { - - - private ["_cargoHitchPoints","_distanceToFrontHitch","_distanceToRearHitch","_isRearCargoHitch"]; - _cargoHitchPoints = [_cargo] call SA_Get_Hitch_Points; - _distanceToFrontHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 0)); - _distanceToRearHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 1)); - if( _distanceToFrontHitch < _distanceToRearHitch ) then { - _cargoHitch = _cargoHitchPoints select 0; - _isRearCargoHitch = false; - } else { - _cargoHitch = _cargoHitchPoints select 1; - _isRearCargoHitch = true; - }; - - - _cargoHitch = ([_cargo] call SA_Get_Hitch_Points) select 0; - - _vehicleHitch = ([_vehicle] call SA_Get_Hitch_Points) select 1; - _ropeLength = (ropeLength (_towRopes select 0)); - _objDistance = ((_vehicle modelToWorld _vehicleHitch) distance (_cargo modelToWorld _cargoHitch)); - if( _objDistance > _ropeLength ) then { - [["The tow ropes are too short. Move vehicle closer.", false],"SA_Hint",_player] call SA_RemoteExec; - } else { - [_vehicle,_player] call SA_Drop_Tow_Ropes; - _helper = "Land_Can_V2_F" createVehicle position _cargo; - _helper attachTo [_cargo, _cargoHitch]; - _helper setVariable ["SA_Cargo",_cargo,true]; - hideObject _helper; - [[_helper],"SA_Hide_Object_Global"] call SA_RemoteExecServer; - [_helper, [0,0,0], [0,0,-1]] ropeAttachTo (_towRopes select 0); - [_vehicle,_vehicleHitch,_cargo,_cargoHitch,_ropeLength] spawn SA_Simulate_Towing; - }; - }; - } else { - [_this,"SA_Attach_Tow_Ropes",_vehicle,true] call SA_RemoteExec; - }; - }; -}; - -SA_Take_Tow_Ropes = { - params ["_vehicle","_player"]; - if(local _vehicle) then { - INFO_1("Take Tow Ropes Called %1",_this); - private ["_existingTowRopes","_hitchPoint","_rope"]; - _existingTowRopes = _vehicle getVariable ["SA_Tow_Ropes",[]]; - if(count _existingTowRopes == 0) then { - _hitchPoint = [_vehicle] call SA_Get_Hitch_Points select 1; - _rope = ropeCreate [_vehicle, _hitchPoint, 10]; - _vehicle setVariable ["SA_Tow_Ropes",[_rope],true]; - call SA_Pickup_Tow_Ropes; - }; - } else { - [_this,"SA_Take_Tow_Ropes",_vehicle,true] call SA_RemoteExec; - }; -}; - -SA_Pickup_Tow_Ropes = { - params ["_vehicle","_player"]; - if(local _vehicle) then { - private ["_attachedObj","_helper"]; - { - _attachedObj = _x; - { - _attachedObj ropeDetach _x; - } forEach (_vehicle getVariable ["SA_Tow_Ropes",[]]); - detach _attachedObj; - deleteVehicle _attachedObj; - } forEach ropeAttachedObjects _vehicle; - _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 (_vehicle getVariable ["SA_Tow_Ropes",[]]); - hideObject _helper; - [[_helper],"SA_Hide_Object_Global"] call SA_RemoteExecServer; - _player setVariable ["SA_Tow_Ropes_Vehicle", _vehicle,true]; - _player setVariable ["SA_Tow_Ropes_Pick_Up_Helper", _helper,true]; - } else { - [_this,"SA_Pickup_Tow_Ropes",_vehicle,true] call SA_RemoteExec; - }; -}; - -SA_Drop_Tow_Ropes = { - params ["_vehicle","_player"]; - if(local _vehicle) then { - private ["_helper"]; - _helper = (_player getVariable ["SA_Tow_Ropes_Pick_Up_Helper", objNull]); - if(!isNull _helper) then { - { - _helper ropeDetach _x; - } forEach (_vehicle getVariable ["SA_Tow_Ropes",[]]); - detach _helper; - deleteVehicle _helper; - }; - _player setVariable ["SA_Tow_Ropes_Vehicle", nil,true]; - _player setVariable ["SA_Tow_Ropes_Pick_Up_Helper", nil,true]; - } else { - [_this,"SA_Drop_Tow_Ropes",_vehicle,true] call SA_RemoteExec; - }; -}; - -SA_Put_Away_Tow_Ropes = { - params ["_vehicle","_player"]; - if(local _vehicle) then { - private ["_existingTowRopes","_hitchPoint","_rope"]; - _existingTowRopes = _vehicle getVariable ["SA_Tow_Ropes",[]]; - if(count _existingTowRopes > 0) then { - call SA_Pickup_Tow_Ropes; - call SA_Drop_Tow_Ropes; - { - ropeDestroy _x; - } forEach _existingTowRopes; - _vehicle setVariable ["SA_Tow_Ropes",nil,true]; - }; - } else { - [_this,"SA_Put_Away_Tow_Ropes",_vehicle,true] call SA_RemoteExec; - }; -}; - -SA_Attach_Tow_Ropes_Action = { - private ["_vehicle","_cargo","_canBeTowed"]; - _cargo = cursorTarget; - _vehicle = player getVariable ["SA_Tow_Ropes_Vehicle", objNull]; - if([_vehicle,_cargo] call SA_Can_Attach_Tow_Ropes) then { - - _canBeTowed = true; - - if!(missionNamespace getVariable ["SA_TOW_LOCKED_VEHICLES_ENABLED",false]) then { - if( locked _cargo > 1 ) then { - ["Cannot attach tow ropes to locked vehicle",false] call SA_Hint; - _canBeTowed = false; - }; - }; - - if!(missionNamespace getVariable ["SA_TOW_IN_EXILE_SAFEZONE_ENABLED",false]) then { - if(!isNil "ExilePlayerInSafezone") then { - if( ExilePlayerInSafezone ) then { - ["Cannot attach tow ropes in safe zone",false] call SA_Hint; - _canBeTowed = false; - }; - }; - }; - - if(_canBeTowed) then { - [_cargo,player] call SA_Attach_Tow_Ropes; - }; - - }; -}; - -SA_Attach_Tow_Ropes_Action_Check = { - private ["_vehicle","_cargo"]; - _vehicle = player getVariable ["SA_Tow_Ropes_Vehicle", objNull]; - _cargo = cursorTarget; - [_vehicle,_cargo] call SA_Can_Attach_Tow_Ropes; -}; - -SA_Can_Attach_Tow_Ropes = { - params ["_vehicle","_cargo"]; - if(!isNull _vehicle && !isNull _cargo) then { - [_vehicle,_cargo] call SA_Is_Supported_Cargo && isNull objectParent player && player distance _cargo < 10 && _vehicle != _cargo; - } else { - false; - }; -}; - -SA_Take_Tow_Ropes_Action = { - private ["_vehicle","_canTakeTowRopes"]; - _vehicle = cursorTarget; - if([_vehicle] call SA_Can_Take_Tow_Ropes) then { - - _canTakeTowRopes = true; - - if!(missionNamespace getVariable ["SA_TOW_LOCKED_VEHICLES_ENABLED",false]) then { - if( locked _vehicle > 1 ) then { - ["Cannot take tow ropes from locked vehicle",false] call SA_Hint; - _canTakeTowRopes = false; - }; - }; - - if!(missionNamespace getVariable ["SA_TOW_IN_EXILE_SAFEZONE_ENABLED",false]) then { - if(!isNil "ExilePlayerInSafezone") then { - if( ExilePlayerInSafezone ) then { - ["Cannot take tow ropes in safe zone",false] call SA_Hint; - _canTakeTowRopes = false; - }; - }; - }; - - if(_canTakeTowRopes) then { - [_vehicle,player] call SA_Take_Tow_Ropes; - }; - - }; -}; - -SA_Take_Tow_Ropes_Action_Check = { - [cursorTarget] call SA_Can_Take_Tow_Ropes; -}; - -SA_Can_Take_Tow_Ropes = { - params ["_vehicle"]; - if([_vehicle] call SA_Is_Supported_Vehicle) then { - private ["_existingVehicle","_existingTowRopes"]; - _existingTowRopes = _vehicle getVariable ["SA_Tow_Ropes",[]]; - _existingVehicle = player getVariable ["SA_Tow_Ropes_Vehicle", objNull]; - isNull objectParent player && player distance _vehicle < 10 && (count _existingTowRopes) == 0 && isNull _existingVehicle; - } else { - false; - }; -}; - -SA_Put_Away_Tow_Ropes_Action = { - private ["_vehicle","_canPutAwayTowRopes"]; - _vehicle = cursorTarget; - if([_vehicle] call SA_Can_Put_Away_Tow_Ropes) then { - - _canPutAwayTowRopes = true; - - if!(missionNamespace getVariable ["SA_TOW_LOCKED_VEHICLES_ENABLED",false]) then { - if( locked _vehicle > 1 ) then { - ["Cannot put away tow ropes in locked vehicle",false] call SA_Hint; - _canPutAwayTowRopes = false; - }; - }; - - if!(missionNamespace getVariable ["SA_TOW_IN_EXILE_SAFEZONE_ENABLED",false]) then { - if(!isNil "ExilePlayerInSafezone") then { - if( ExilePlayerInSafezone ) then { - ["Cannot put away tow ropes in safe zone",false] call SA_Hint; - _canPutAwayTowRopes = false; - }; - }; - }; - - if(_canPutAwayTowRopes) then { - [_vehicle,player] call SA_Put_Away_Tow_Ropes; - }; - - }; -}; - -SA_Put_Away_Tow_Ropes_Action_Check = { - [cursorTarget] call SA_Can_Put_Away_Tow_Ropes; -}; - -SA_Can_Put_Away_Tow_Ropes = { - params ["_vehicle"]; - private ["_existingTowRopes"]; - if([_vehicle] call SA_Is_Supported_Vehicle) then { - _existingTowRopes = _vehicle getVariable ["SA_Tow_Ropes",[]]; - isNull objectParent player && player distance _vehicle < 10 && (count _existingTowRopes) > 0; - } else { - false; - }; -}; - - -SA_Drop_Tow_Ropes_Action = { - private ["_vehicle"]; - _vehicle = player getVariable ["SA_Tow_Ropes_Vehicle", objNull]; - if([] call SA_Can_Drop_Tow_Ropes) then { - [_vehicle, player] call SA_Drop_Tow_Ropes; - }; -}; - -SA_Drop_Tow_Ropes_Action_Check = { - [] call SA_Can_Drop_Tow_Ropes; -}; - -SA_Can_Drop_Tow_Ropes = { - !isNull (player getVariable ["SA_Tow_Ropes_Vehicle", objNull]) && isNull objectParent player; -}; - - - -SA_Pickup_Tow_Ropes_Action = { - private ["_nearbyTowVehicles","_canPickupTowRopes","_vehicle"]; - _nearbyTowVehicles = missionNamespace getVariable ["SA_Nearby_Tow_Vehicles",[]]; - if([] call SA_Can_Pickup_Tow_Ropes) then { - - _vehicle = _nearbyTowVehicles select 0; - _canPickupTowRopes = true; - - if!(missionNamespace getVariable ["SA_TOW_LOCKED_VEHICLES_ENABLED",false]) then { - if( locked _vehicle > 1 ) then { - ["Cannot pick up tow ropes from locked vehicle",false] call SA_Hint; - _canPickupTowRopes = false; - }; - }; - - if!(missionNamespace getVariable ["SA_TOW_IN_EXILE_SAFEZONE_ENABLED",false]) then { - if(!isNil "ExilePlayerInSafezone") then { - if( ExilePlayerInSafezone ) then { - ["Cannot pick up tow ropes in safe zone",false] call SA_Hint; - _canPickupTowRopes = false; - }; - }; - }; - - if(_canPickupTowRopes) then { - [_nearbyTowVehicles select 0, player] call SA_Pickup_Tow_Ropes; - }; - - }; -}; - -SA_Pickup_Tow_Ropes_Action_Check = { - [] call SA_Can_Pickup_Tow_Ropes; -}; - -SA_Can_Pickup_Tow_Ropes = { - isNull (player getVariable ["SA_Tow_Ropes_Vehicle", objNull]) && count (missionNamespace getVariable ["SA_Nearby_Tow_Vehicles",[]]) > 0 && isNull objectParent player; -}; - -SA_tow_supported_vehicles = [ - //"Tank", "Car", "Ship" -]; - -SA_Is_Supported_Vehicle = { - params ["_vehicle","_isSupported"]; - _isSupported = false; - if(not isNull _vehicle) then { - { - if(_vehicle isKindOf _x) then { - _isSupported = true; - }; - } forEach (missionNamespace getVariable ["SA_TOW_SUPPORTED_VEHICLES_OVERRIDE", SA_tow_supported_vehicles]); - }; - _isSupported; -}; - -/* SA_Is_Supported_Vehicle = { - params ["_vehicle","_isSupported"]; - _isSupported = false; - if(not isNull _vehicle) then { - { - if((typeOf _vehicle == "rsr_bergepanzer_flecktarn") or (typeOf _vehicle == "rsr_wisent_repair_flecktarn") or - (typeOf _vehicle == "rsr_bergepanzer_tropentarn") or (typeOf _vehicle == "rsr_wisent_repair_tropentarn") or (typeOf _vehicle == "B_APC_Tracked_01_CRV_F")) then { - _isSupported = true; - }; - } forEach (missionNamespace getVariable ["SA_TOW_SUPPORTED_VEHICLES_OVERRIDE",SA_tow_supported_vehicles]); - }; - _isSupported; -}; */ - -SA_TOW_RULES = [ - ["Tank","CAN_TOW","Tank"], - ["Tank","CAN_TOW","Car"], - ["Tank","CAN_TOW","Ship"], - ["Tank","CAN_TOW","Air"], - //["Car","CAN_TOW","Tank"], - ["Car","CAN_TOW","Car"], - ["Car","CAN_TOW","Ship"], - ["Car","CAN_TOW","Air"], - ["Ship","CAN_TOW","Ship"] -]; - -SA_Is_Supported_Cargo = { - params ["_vehicle","_cargo"]; - private ["_canTow"]; - _canTow = 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_TOW" ) then { - _canTow = true; - } else { - _canTow = false; - }; - }; - }; - } forEach (missionNamespace getVariable ["SA_TOW_RULES_OVERRIDE",SA_Tow_Rules]); - }; - _canTow; -}; - -SA_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; - }; - }; -}; - -SA_Hide_Object_Global = { - params ["_obj"]; - if( _obj isKindOf "Land_Can_V2_F" ) then { - hideObjectGlobal _obj; - }; -}; - -SA_Set_Owner = { - params ["_obj","_client"]; - _obj setOwner _client; -}; - -SA_Add_Player_Tow_Actions = { - - player addAction ["Deploy Tow Ropes", { - [] call SA_Take_Tow_Ropes_Action; - }, nil, 0, false, true, "", "call SA_Take_Tow_Ropes_Action_Check"]; - - player addAction ["Put Away Tow Ropes", { - [] call SA_Put_Away_Tow_Ropes_Action; - }, nil, 0, false, true, "", "call SA_Put_Away_Tow_Ropes_Action_Check"]; - - player addAction ["Attach To Tow Ropes", { - [] call SA_Attach_Tow_Ropes_Action; - }, nil, 0, false, true, "", "call SA_Attach_Tow_Ropes_Action_Check"]; - - player addAction ["Drop Tow Ropes", { - [] call SA_Drop_Tow_Ropes_Action; - }, nil, 0, false, true, "", "call SA_Drop_Tow_Ropes_Action_Check"]; - - player addAction ["Pickup Tow Ropes", { - [] call SA_Pickup_Tow_Ropes_Action; - }, nil, 0, false, true, "", "call SA_Pickup_Tow_Ropes_Action_Check"]; - - player addEventHandler ["Respawn", { - player setVariable ["SA_Tow_Actions_Loaded",false]; - }]; - -}; - -SA_Find_Nearby_Tow_Vehicles = { - private ["_nearVehicles","_nearVehiclesWithTowRopes","_vehicle","_ends","_end1","_end2"]; - _nearVehicles = []; - { - _nearVehicles append (position player nearObjects [_x, 30]); - } forEach (missionNamespace getVariable ["SA_TOW_SUPPORTED_VEHICLES_OVERRIDE", SA_tow_supported_vehicles]); - _nearVehiclesWithTowRopes = []; - { - _vehicle = _x; - { - _ends = ropeEndPosition _x; - if(count _ends == 2) then { - _end1 = _ends select 0; - _end2 = _ends select 1; - if(((position player) distance _end1) < 5 || ((position player) distance _end2) < 5 ) then { - _nearVehiclesWithTowRopes pushBack _vehicle; - } - }; - } forEach (_vehicle getVariable ["SA_Tow_Ropes",[]]); - } forEach _nearVehicles; - _nearVehiclesWithTowRopes; -}; - -if(!isDedicated) then { - [] spawn { - while {true} do { - if(!isNull player && isPlayer player) then { - if!( player getVariable ["SA_Tow_Actions_Loaded",false] ) then { - [] call SA_Add_Player_Tow_Actions; - player setVariable ["SA_Tow_Actions_Loaded",true]; - }; - }; - missionNamespace setVariable ["SA_Nearby_Tow_Vehicles", (call SA_Find_Nearby_Tow_Vehicles)]; - sleep 2; - }; - }; -}; - -SA_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 { - ["AdvancedTowingRemoteExecClient",[_params,_functionName,_target,_isCall]] call ExileClient_system_network_send; - }; -}; - -SA_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]; - }; - } else { - ["AdvancedTowingRemoteExecServer",[_params,_functionName,_isCall]] call ExileClient_system_network_send; - }; -}; - -if(isServer) then { - - // Adds support for exile network calls (Only used when running exile) // - - SA_Supported_RemoteExecServer_Functions = ["SA_Set_Owner","SA_Hide_Object_Global"]; - - ExileServer_AdvancedTowing_network_AdvancedTowingRemoteExecServer = { - params ["_sessionId", "_messageParameters",["_isCall",false]]; - _messageParameters params ["_params","_functionName"]; - if(_functionName in SA_Supported_RemoteExecServer_Functions) then { - if(_isCall) then { - _params call (missionNamespace getVariable [_functionName,{}]); - } else { - _params spawn (missionNamespace getVariable [_functionName,{}]); - }; - }; - }; - - SA_Supported_RemoteExecClient_Functions = ["SA_Simulate_Towing","SA_Attach_Tow_Ropes","SA_Take_Tow_Ropes","SA_Put_Away_Tow_Ropes","SA_Pickup_Tow_Ropes","SA_Drop_Tow_Ropes","SA_Hint"]; - - ExileServer_AdvancedTowing_network_AdvancedTowingRemoteExecClient = { - params ["_sessionId", "_messageParameters"]; - _messageParameters params ["_params","_functionName","_target",["_isCall",false]]; - if(_functionName in SA_Supported_RemoteExecClient_Functions) then { - if(_isCall) then { - _params remoteExecCall [_functionName, _target]; - } else { - _params remoteExec [_functionName, _target]; - }; - }; - }; - - // Install Advanced Towing on all clients (plus JIP) // - - publicVariable "SA_Advanced_Towing_Install"; - remoteExecCall ["SA_Advanced_Towing_Install", -2,true]; - -}; - -INFO("Advanced Towing Loaded"); - -}; - -if(isServer) then { - [] call SA_Advanced_Towing_Install; -}; diff --git a/addons/advancedtowing/functions/fnc_install.sqf b/addons/advancedtowing/functions/fnc_install.sqf new file mode 100644 index 000000000..10675af42 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_install.sqf @@ -0,0 +1,19 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_install + * + * Public: No + */ + +if(!isNil QGVAR(INIT)) exitWith {}; +SA_TOW_INIT = true; diff --git a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf new file mode 100644 index 000000000..50d2f5111 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_isSupportedCargo + * + * Public: No + */ + +params ["_vehicle","_cargo"]; + +private _canTow = false; + +if(!isNull _vehicle && !isNull _cargo) then { + { + if(_vehicle isKindOf (_x select 0)) then { + if(_cargo isKindOf (_x select 2)) then { + if( (toUpper (_x select 1)) == "CAN_TOW" ) then { + _canTow = true; + } else { + _canTow = false; + }; + }; + }; + } forEach (missionNamespace getVariable [QGVAR(RULES_OVERRIDE), SA_Tow_Rules]); +}; +_canTow; diff --git a/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf b/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf new file mode 100644 index 000000000..74950a06f --- /dev/null +++ b/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf @@ -0,0 +1,28 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_isSupportedVehicle + * + * Public: No + */ + +params ["_vehicle", "_isSupported"]; + +_isSupported = false; +if(!isNull _vehicle) then { + { + if(_vehicle isKindOf _x) then { + _isSupported = true; + }; + } forEach (missionNamespace getVariable [QGVAR(SUPPORTED_VEHICLES_OVERRIDE), SA_tow_supported_vehicles]); +}; +_isSupported; diff --git a/addons/advancedtowing/functions/fnc_pickupTowRopes.sqf b/addons/advancedtowing/functions/fnc_pickupTowRopes.sqf new file mode 100644 index 000000000..6c543ef01 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_pickupTowRopes.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_pickupTowRopes + * + * Public: No + */ + +params ["_vehicle", "_player"]; + +if(local _vehicle) then { + private ["_attachedObj", "_helper"]; + { + _attachedObj = _x; + { + _attachedObj ropeDetach _x; + } forEach (_vehicle getVariable [QGVAR(Ropes), []]); + detach _attachedObj; + deleteVehicle _attachedObj; + } forEach ropeAttachedObjects _vehicle; + + _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 (_vehicle getVariable [QGVAR(Ropes), []]); + hideObject _helper; + [[_helper], QFUNC(customHideObjectGlobal)] call FUNC(customRemoteExecServer); + + _player setVariable [QGVAR(Ropes_Vehicle), _vehicle, true]; + _player setVariable [QGVAR(Ropes_Pick_Up_Helper), _helper, true]; +} else { + [_this, QFUNC(pickupTowRopes), _vehicle, true] call SA_RemoteExec; +}; diff --git a/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf new file mode 100644 index 000000000..4dad8e110 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_pickupTowRopesAction + * + * Public: No + */ + +private _nearbyTowVehicles = missionNamespace getVariable [QGVAR(Nearby_Tow_Vehicles), []]; + +if([] call SA_Can_Pickup_Tow_Ropes) then { + + private _vehicle = _nearbyTowVehicles select 0; + private _canPickupTowRopes = true; + + if!(missionNamespace getVariable [QGVAR(LOCKED_VEHICLES_ENABLED),false]) then { + if( locked _vehicle > 1 ) then { + ["Cannot pick up tow ropes from locked vehicle", false] call FUNC(customHint); //ToDo Localize + _canPickupTowRopes = false; + }; + }; + + if(_canPickupTowRopes) then { + [_nearbyTowVehicles select 0, player] call FUNC(pickupTowRopes); + }; + +}; diff --git a/addons/advancedtowing/functions/fnc_pickupTowRopesActionCheck.sqf b/addons/advancedtowing/functions/fnc_pickupTowRopesActionCheck.sqf new file mode 100644 index 000000000..6d64c19ab --- /dev/null +++ b/addons/advancedtowing/functions/fnc_pickupTowRopesActionCheck.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_pickupTowRopesActionCheck + * + * Public: No + */ + +[] call FUNC(canPickupTowRopes); diff --git a/addons/advancedtowing/functions/fnc_putAwayTowRopes.sqf b/addons/advancedtowing/functions/fnc_putAwayTowRopes.sqf new file mode 100644 index 000000000..51214367e --- /dev/null +++ b/addons/advancedtowing/functions/fnc_putAwayTowRopes.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_putAwayTowRopes + * + * Public: No + */ + +params ["_vehicle", "_player"]; + +if(local _vehicle) then { + private ["_hitchPoint", "_rope"]; + + private _existingTowRopes = _vehicle getVariable [QGVAR(Ropes), []]; + if(count _existingTowRopes > 0) then { + call FUNC(pickUpTowRopes); + call FUNC(dropTowRopes); + { + ropeDestroy _x; + } forEach _existingTowRopes; + _vehicle setVariable [QGVAR(Ropes), nil, true]; + }; +} else { + [_this, QFUNC(putAwayTowRopes), _vehicle, true] call FUNC(customRemoteExec); +}; diff --git a/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf new file mode 100644 index 000000000..cbde82fc9 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf @@ -0,0 +1,35 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_putAwayTowRopesAction + * + * Public: No + */ + +private _vehicle = cursorTarget; + +if([_vehicle] call FUNC(canPutAwayTowRopes)) then { + + private _canPutAwayTowRopes = true; + + if!(missionNamespace getVariable [QGVAR(LOCKED_VEHICLES_ENABLED), false]) then { + if( locked _vehicle > 1 ) then { + ["Cannot put away tow ropes in locked vehicle", false] call FUNC(customHint); //ToDo Localize + _canPutAwayTowRopes = false; + }; + }; + + if(_canPutAwayTowRopes) then { + [_vehicle, player] call FUNC(putAwayTowRopes); + }; + +}; diff --git a/addons/advancedtowing/functions/fnc_putAwayTowRopesActionCheck.sqf b/addons/advancedtowing/functions/fnc_putAwayTowRopesActionCheck.sqf new file mode 100644 index 000000000..f07ba9461 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_putAwayTowRopesActionCheck.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_putawayTowRopesActionCheck + * + * Public: No + */ + +[cursorTarget] call FUNC(canPutAwayTowRopes); diff --git a/addons/advancedtowing/functions/fnc_simulateTowing.sqf b/addons/advancedtowing/functions/fnc_simulateTowing.sqf new file mode 100644 index 000000000..931bd7ec8 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_simulateTowing.sqf @@ -0,0 +1,168 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_simulateTowing + * + * Public: No + */ + +params ["_vehicle", "_vehicleHitchModelPos", "_cargo", "_cargoHitchModelPos", "_ropeLength"]; + +private ["_lastCargoHitchPosition","_lastCargoVectorDir","_lastMovedCargoPosition","_cargoHitchPoints"]; +private ["_vehicleHitchPosition","_cargoHitchPosition","_newCargoHitchPosition","_cargoVector","_movedCargoVector","_currentCargo"]; +private ["_newCargoDir","_lastCargoVectorDir","_newCargoPosition","_cargoPosition","_vehiclePosition","_vehicleMass","_cargoMass"]; +private ["_cargoCorner1AGL","_cargoCorner1ASL","_cargoCorner2AGL","_cargoCorner2ASL","_cargoCorner3AGL","_cargoCorner3ASL","_cargoCorner4AGL","_cargoCorner4ASL","_surfaceNormal1","_surfaceNormal2","_surfaceNormal"]; +private ["_cargoCenterASL","_surfaceHeight","_surfaceHeight2","_maxSurfaceHeight"]; + +private _maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); +private _cargoCanFloat = [false, true] select (getNumber ((configOf _cargo) >> "canFloat") == 1); + +private _cargoCenterOfMassAGL; +SA_Find_Surface_AGL_Under_Model(_cargo, getCenterOfMass _cargo, _cargoCenterOfMassAGL, _cargoCanFloat); + +private _cargoModelCenterGroundPosition = _cargo worldToModelVisual _cargoCenterOfMassAGL; +_cargoModelCenterGroundPosition set [0, 0]; +_cargoModelCenterGroundPosition set [1, 0]; +_cargoModelCenterGroundPosition set [2, (_cargoModelCenterGroundPosition select 2) - 0.05]; // Adjust height so that it doesn't ride directly on ground + +// Calculate cargo model corner points +private _cargoCornerPoints = [_cargo] call FUNC(getCornerPoints); +_corner1 = _cargoCornerPoints select 0; +_corner2 = _cargoCornerPoints select 1; +_corner3 = _cargoCornerPoints select 2; +_corner4 = _cargoCornerPoints select 3; + + +// Try to set cargo owner if the towing client doesn't own the cargo +if(local _vehicle && !local _cargo) then { + [[_cargo, clientOwner], QFUNC(customSetOwner)] call FUNC(customRemoteExecServer); +}; + +_vehicleHitchModelPos set [2, 0]; +_cargoHitchModelPos set [2, 0]; + +_lastCargoHitchPosition = _cargo modelToWorld _cargoHitchModelPos; +_lastCargoVectorDir = vectorDir _cargo; +_lastMovedCargoPosition = getPos _cargo; + +_cargoHitchPoints = [_cargo] call FUNC(getHitchPoints); +private _cargoLength = (_cargoHitchPoints select 0) distance (_cargoHitchPoints select 1); + +_vehicleMass = 1 max (getMass _vehicle); +_cargoMass = getMass _cargo; +if(_cargoMass == 0) then { + _cargoMass = _vehicleMass; +}; + +private _maxDistanceToCargo = _ropeLength; + +private _doExit = false; + +// Start vehicle speed simulation +[_vehicle] spawn FUNC(simulateTowingSpeed); + +while {!_doExit} do { + + _vehicleHitchPosition = _vehicle modelToWorld _vehicleHitchModelPos; + _vehicleHitchPosition set [2,0]; + _cargoHitchPosition = _lastCargoHitchPosition; + _cargoHitchPosition set [2,0]; + + _cargoPosition = getPos _cargo; + _vehiclePosition = getPos _vehicle; + + if(_vehicleHitchPosition distance _cargoHitchPosition > _maxDistanceToCargo) then { + + // Calculated simulated towing position + direction + _newCargoHitchPosition = _vehicleHitchPosition vectorAdd ((_vehicleHitchPosition vectorFromTo _cargoHitchPosition) vectorMultiply _ropeLength); + _cargoVector = _lastCargoVectorDir vectorMultiply _cargoLength; + _movedCargoVector = _newCargoHitchPosition vectorDiff _lastCargoHitchPosition; + _newCargoDir = vectorNormalized (_cargoVector vectorAdd _movedCargoVector); + //if(_isRearCargoHitch) then { + // _newCargoDir = _newCargoDir vectorMultiply -1; + //}; + _lastCargoVectorDir = _newCargoDir; + _newCargoPosition = _newCargoHitchPosition vectorAdd (_newCargoDir vectorMultiply -(vectorMagnitude (_cargoHitchModelPos))); + + SA_Find_Surface_ASL_Under_Position(_cargo,_newCargoPosition,_newCargoPosition,_cargoCanFloat); + + // Calculate surface normal (up) (more realistic than surfaceNormal function) + SA_Find_Surface_ASL_Under_Model(_cargo,_corner1,_cargoCorner1ASL,_cargoCanFloat); + SA_Find_Surface_ASL_Under_Model(_cargo,_corner2,_cargoCorner2ASL,_cargoCanFloat); + SA_Find_Surface_ASL_Under_Model(_cargo,_corner3,_cargoCorner3ASL,_cargoCanFloat); + SA_Find_Surface_ASL_Under_Model(_cargo,_corner4,_cargoCorner4ASL,_cargoCanFloat); + _surfaceNormal1 = (_cargoCorner1ASL vectorFromTo _cargoCorner3ASL) vectorCrossProduct (_cargoCorner1ASL vectorFromTo _cargoCorner2ASL); + _surfaceNormal2 = (_cargoCorner4ASL vectorFromTo _cargoCorner2ASL) vectorCrossProduct (_cargoCorner4ASL vectorFromTo _cargoCorner3ASL); + _surfaceNormal = _surfaceNormal1 vectorAdd _surfaceNormal2; + + if(missionNamespace getVariable [QGVAR(DEBUG_ENABLED), false]) then { + if(isNil "sa_tow_debug_arrow_1") then { + sa_tow_debug_arrow_1 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; + sa_tow_debug_arrow_2 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; + sa_tow_debug_arrow_3 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; + sa_tow_debug_arrow_4 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; + }; + sa_tow_debug_arrow_1 setPosASL _cargoCorner1ASL; + sa_tow_debug_arrow_1 setVectorUp _surfaceNormal; + sa_tow_debug_arrow_2 setPosASL _cargoCorner2ASL; + sa_tow_debug_arrow_2 setVectorUp _surfaceNormal; + sa_tow_debug_arrow_3 setPosASL _cargoCorner3ASL; + sa_tow_debug_arrow_3 setVectorUp _surfaceNormal; + sa_tow_debug_arrow_4 setPosASL _cargoCorner4ASL; + sa_tow_debug_arrow_4 setVectorUp _surfaceNormal; + }; + + // Calculate adjusted surface height based on surface normal (prevents vehicle from clipping into ground) + _cargoCenterASL = AGLToASL (_cargo modelToWorldVisual [0,0,0]); + _cargoCenterASL set [2,0]; + _surfaceHeight = ((_cargoCorner1ASL vectorAdd ( _cargoCenterASL vectorMultiply -1)) vectorDotProduct _surfaceNormal1) / ([0,0,1] vectorDotProduct _surfaceNormal1); + _surfaceHeight2 = ((_cargoCorner1ASL vectorAdd ( _cargoCenterASL vectorMultiply -1)) vectorDotProduct _surfaceNormal2) / ([0,0,1] vectorDotProduct _surfaceNormal2); + _maxSurfaceHeight = (_newCargoPosition select 2) max _surfaceHeight max _surfaceHeight2; + _newCargoPosition set [2, _maxSurfaceHeight ]; + + _newCargoPosition = _newCargoPosition vectorAdd ( _cargoModelCenterGroundPosition vectorMultiply -1 ); + + _cargo setVectorDir _newCargoDir; + _cargo setVectorUp _surfaceNormal; + _cargo setPosWorld _newCargoPosition; + + _lastCargoHitchPosition = _newCargoHitchPosition; + _maxDistanceToCargo = _vehicleHitchPosition distance _newCargoHitchPosition; + _lastMovedCargoPosition = _cargoPosition; + + _massAdjustedMaxSpeed = _vehicle getVariable [QGVAR(Max_Tow_Speed), _maxVehicleSpeed]; + if(speed _vehicle > (_massAdjustedMaxSpeed) + 0.1) then { + _vehicle setVelocity ((vectorNormalized (velocity _vehicle)) vectorMultiply (_massAdjustedMaxSpeed / 3.6)); + }; + + } else { + + if(_lastMovedCargoPosition distance _cargoPosition > 2) then { + _lastCargoHitchPosition = _cargo modelToWorld _cargoHitchModelPos; + _lastCargoVectorDir = vectorDir _cargo; + }; + + }; + + // If vehicle isn't local to the client, switch client running towing simulation + if(!local _vehicle) then { + [_this, QFUNC(simulateTowing), _vehicle] call FUNC(customRemoteExec); + _doExit = true; + }; + + // If the vehicle isn't towing anything, stop the towing simulation + SA_Get_Cargo(_vehicle,_currentCargo); + if(isNull _currentCargo) then { + _doExit = true; + }; + sleep 0.01; +}; diff --git a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf new file mode 100644 index 000000000..c9f80822b --- /dev/null +++ b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf @@ -0,0 +1,80 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_simulateTowingSpeed + * + * Public: No + */ + + + +params ["_vehicle"]; + +private _currentCargo; +"_maxVehicleSpeed","_vehicleMass"]; + +_maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); +_vehicleMass = 1000 max (getMass _vehicle); +private _maxTowedCargo = missionNamespace getVariable ["SA_MAX_TOWED_CARGO",2]; +private _runSimulation = true; + +while {_runSimulation} do { + + // Calculate total mass and count of cargo being towed (only takes into account + // cargo that's actively being towed (e.g. there's no slack in the rope) + + private _currentVehicle = _vehicle; + private _totalCargoMass = 0; + private _totalCargoCount = 0; + private _findNextCargo = true; + while {_findNextCargo} do { + + _findNextCargo = false; + SA_Get_Cargo(_currentVehicle,_currentCargo); + + if(!isNull _currentCargo) then { + + private _towRopes = _currentVehicle getVariable [QGVAR(Tow_Ropes), []]; + + if(count _towRopes > 0) then { + + private _ropeLength = ropeLength (_towRopes select 0); + private _ends = ropeEndPosition (_towRopes select 0); + private _endsDistance = (_ends select 0) distance (_ends select 1); + + if( _endsDistance >= _ropeLength - 2 ) then { + _totalCargoMass = _totalCargoMass + (1000 max (getMass _currentCargo)); + _totalCargoCount = _totalCargoCount + 1; + _currentVehicle = _currentCargo; + _findNextCargo = true; + }; + }; + }; + }; + + private _newMaxSpeed = _maxVehicleSpeed / (1 max ((_totalCargoMass / _vehicleMass) * 2)); + _newMaxSpeed = (_maxVehicleSpeed * 0.75) min _newMaxSpeed; + + // Prevent vehicle from moving if trying to move more cargo than pre-defined max + if(_totalCargoCount > _maxTowedCargo) then { + _newMaxSpeed = 0; + }; + + private _currentMaxSpeed = _vehicle getVariable [QGVAR(Max_Tow_Speed), _maxVehicleSpeed]; + + if(_currentMaxSpeed != _newMaxSpeed) then { + _vehicle setVariable [QGVAR(Max_Tow_Speed),_newMaxSpeed]; + }; + + sleep 0.1; + +}; diff --git a/addons/advancedtowing/functions/fnc_takeTowRopes.sqf b/addons/advancedtowing/functions/fnc_takeTowRopes.sqf new file mode 100644 index 000000000..fc0b5556f --- /dev/null +++ b/addons/advancedtowing/functions/fnc_takeTowRopes.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_takeTowRopes + * + * Public: No + */ + +params ["_vehicle","_player"]; + +if(local _vehicle) then { + + INFO_1("Take Tow Ropes Called %1", _this); + + private _existingTowRopes = _vehicle getVariable [QGVAR(Ropes), []]; + + if(count _existingTowRopes == 0) then { + private _hitchPoint = [_vehicle] call FUNC(getHitchPoints) select 1; + private _rope = ropeCreate [_vehicle, _hitchPoint, 10]; + _vehicle setVariable [QGVAR(Ropes), [_rope], true]; + call FUNC(pickUpTowRopes); + }; +} else { + [_this, QFUNC(takwTowRopes), _vehicle, true] call FUNC(CustomRemoteExec); +}; diff --git a/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf new file mode 100644 index 000000000..8062d7344 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf @@ -0,0 +1,36 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_takeTowRopesAction + * + * Public: No + */ + + +private _vehicle = cursorTarget; + +if([_vehicle] call FUNC(canTakeTowRopes)) then { + + private _canTakeTowRopes = true; + + if!(missionNamespace getVariable [QGVAR(LOCKED_VEHICLES_ENABLED), false]) then { + if( locked _vehicle > 1 ) then { + ["Cannot take tow ropes from locked vehicle", false] call FUNC(customHint); //ToDo Localize + _canTakeTowRopes = false; + }; + }; + + if(_canTakeTowRopes) then { + [_vehicle, player] call FUNC(takeTowRopes); + }; + +}; diff --git a/addons/advancedtowing/functions/fnc_takeTowRopesActionCheck.sqf b/addons/advancedtowing/functions/fnc_takeTowRopesActionCheck.sqf new file mode 100644 index 000000000..af2991d30 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_takeTowRopesActionCheck.sqf @@ -0,0 +1,18 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_takeTowRopesActionCheck + * + * Public: No + */ + +[cursorTarget] call FUNC(canTakeTowRopes); From 6c1734763942aa606e0030e92c8e7225d41139b1 Mon Sep 17 00:00:00 2001 From: Andx Date: Sat, 4 Oct 2025 17:26:38 +0200 Subject: [PATCH 02/20] move marco to script component --- addons/advancedtowing/functions/fnc_init.sqf | 39 +------------------- addons/advancedtowing/script_component.hpp | 39 ++++++++++++++++++++ 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/addons/advancedtowing/functions/fnc_init.sqf b/addons/advancedtowing/functions/fnc_init.sqf index 644d0311a..8b60e56f4 100644 --- a/addons/advancedtowing/functions/fnc_init.sqf +++ b/addons/advancedtowing/functions/fnc_init.sqf @@ -18,44 +18,7 @@ SA_TOW_LOCKED_VEHICLES_ENABLED = true; _isRearCargoHitch = 0; -#define SA_Find_Surface_ASL_Under_Position(_object,_positionAGL,_returnSurfaceASL,_canFloat) \ -_objectASL = AGLToASL (_object modelToWorldVisual (getCenterOfMass _object)); \ -_surfaceIntersectStartASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) + 1]; \ -_surfaceIntersectEndASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) - 5]; \ -_surfaces = lineIntersectsSurfaces [_surfaceIntersectStartASL, _surfaceIntersectEndASL, _object, objNull, true, 5]; \ -_returnSurfaceASL = AGLToASL _positionAGL; \ -{ \ - scopeName "surfaceLoop"; \ - if( isNull (_x select 2) ) then { \ - _returnSurfaceASL = _x select 0; \ - breakOut "surfaceLoop"; \ - } else { \ - if!((_x select 2) isKindOf "RopeSegment") then { \ - _objectFileName = str (_x select 2); \ - if((_objectFileName find " t_") == -1 && (_objectFileName find " b_") == -1) then { \ - _returnSurfaceASL = _x select 0; \ - breakOut "surfaceLoop"; \ - }; \ - }; \ - }; \ -} forEach _surfaces; \ -if(_canFloat && (_returnSurfaceASL select 2) < 0) then { \ - _returnSurfaceASL set [2,0]; \ -}; \ -#define SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceASL,_canFloat) \ -SA_Find_Surface_ASL_Under_Position(_object,(_object modelToWorldVisual _modelOffset),_returnSurfaceASL,_canFloat); - -#define SA_Find_Surface_AGL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat) \ -SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat); \ -_returnSurfaceAGL = ASLtoAGL _returnSurfaceAGL; - -#define SA_Get_Cargo(_vehicle,_cargo) \ -if( count (ropeAttachedObjects _vehicle) == 0 ) then { \ - _cargo = objNull; \ -} else { \ - _cargo = ((ropeAttachedObjects _vehicle) select 0) getVariable ["SA_Cargo",objNull]; \ -}; SA_tow_supported_vehicles = [ //"Tank", "Car", "Ship" @@ -78,7 +41,7 @@ if(!isDedicated) then { while {true} do { if(!isNull player && isPlayer player) then { if!( player getVariable [QGVAR(Actions_Loaded), false] ) then { - [] callFUNC(addPlayerTowActions); + [] call FUNC(addPlayerTowActions); player setVariable [QGVAR(Actions_Loaded), true]; }; }; diff --git a/addons/advancedtowing/script_component.hpp b/addons/advancedtowing/script_component.hpp index a79a42098..601447e25 100644 --- a/addons/advancedtowing/script_component.hpp +++ b/addons/advancedtowing/script_component.hpp @@ -3,3 +3,42 @@ #include "\z\ttt\addons\main\script_mod.hpp" #include "\z\ttt\addons\main\script_macros.hpp" + +#define SA_Find_Surface_ASL_Under_Position(_object,_positionAGL,_returnSurfaceASL,_canFloat) \ +_objectASL = AGLToASL (_object modelToWorldVisual (getCenterOfMass _object)); \ +_surfaceIntersectStartASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) + 1]; \ +_surfaceIntersectEndASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) - 5]; \ +_surfaces = lineIntersectsSurfaces [_surfaceIntersectStartASL, _surfaceIntersectEndASL, _object, objNull, true, 5]; \ +_returnSurfaceASL = AGLToASL _positionAGL; \ +{ \ + scopeName "surfaceLoop"; \ + if( isNull (_x select 2) ) then { \ + _returnSurfaceASL = _x select 0; \ + breakOut "surfaceLoop"; \ + } else { \ + if!((_x select 2) isKindOf "RopeSegment") then { \ + _objectFileName = str (_x select 2); \ + if((_objectFileName find " t_") == -1 && (_objectFileName find " b_") == -1) then { \ + _returnSurfaceASL = _x select 0; \ + breakOut "surfaceLoop"; \ + }; \ + }; \ + }; \ +} forEach _surfaces; \ +if(_canFloat && (_returnSurfaceASL select 2) < 0) then { \ + _returnSurfaceASL set [2,0]; \ +}; \ + +#define SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceASL,_canFloat) \ +SA_Find_Surface_ASL_Under_Position(_object,(_object modelToWorldVisual _modelOffset),_returnSurfaceASL,_canFloat); + +#define SA_Find_Surface_AGL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat) \ +SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat); \ +_returnSurfaceAGL = ASLtoAGL _returnSurfaceAGL; + +#define SA_Get_Cargo(_vehicle,_cargo) \ +if( count (ropeAttachedObjects _vehicle) == 0 ) then { \ + _cargo = objNull; \ +} else { \ + _cargo = ((ropeAttachedObjects _vehicle) select 0) getVariable ["SA_Cargo",objNull]; \ +}; From 2976e748df1a2fdb85153e840fa27ff2154ca593 Mon Sep 17 00:00:00 2001 From: Andx Date: Sat, 4 Oct 2025 17:28:57 +0200 Subject: [PATCH 03/20] fix hemtt warnings --- addons/advancedtowing/XEH_PREP.hpp | 3 ++- addons/advancedtowing/XEH_postInit.sqf | 2 +- .../functions/fnc_addPlayerTowActions.sqf | 10 +++++----- addons/advancedtowing/functions/fnc_simulateTowing.sqf | 2 +- .../functions/fnc_simulateTowingSpeed.sqf | 5 ++--- addons/advancedtowing/functions/fnc_takeTowRopes.sqf | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/addons/advancedtowing/XEH_PREP.hpp b/addons/advancedtowing/XEH_PREP.hpp index 4e2ee41da..a88e90132 100644 --- a/addons/advancedtowing/XEH_PREP.hpp +++ b/addons/advancedtowing/XEH_PREP.hpp @@ -19,7 +19,7 @@ PREP(findNearbyTowVehicles); PREP(getCornerPoints); PREP(getHitchPoints); PREP(init); -PREP(initAdvancedTowing); +PREP(install); PREP(isSupportedCargo); PREP(isSupportedVehicle); PREP(pickupTowRopes); @@ -28,6 +28,7 @@ PREP(pickupTowRopesActionCheck); PREP(putAwayTowRopes); PREP(putAwayTowRopesAction); PREP(putAwayTowRopesActionCheck); +PREP(simulateTowing); PREP(simulateTowingSpeed); PREP(takeTowRopes); PREP(takeTowRopesAction); diff --git a/addons/advancedtowing/XEH_postInit.sqf b/addons/advancedtowing/XEH_postInit.sqf index c2fd87c5d..4d9c3082f 100644 --- a/addons/advancedtowing/XEH_postInit.sqf +++ b/addons/advancedtowing/XEH_postInit.sqf @@ -1,3 +1,3 @@ #include "script_component.hpp" -[] call FUNC(initAdvancedTowing); +[] call FUNC(init); diff --git a/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf b/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf index 8838ab70b..6e2321806 100644 --- a/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf +++ b/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf @@ -17,23 +17,23 @@ player addAction ["Deploy Tow Ropes", { //ToDo Localize call FUNC(takeTowRopesAction); -}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(deployTowRopesActionCheck), _this)] call CBA_fnc_directCall)]; +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(deployTowRopesActionCheck),_this)] call CBA_fnc_directCall)]; player addAction ["Put Away Tow Ropes", { //ToDo Localize call FUNC(putAwayTowRopesAction); -}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(putAwayTowRopesActionCheck), _this)] call CBA_fnc_directCall)]; +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(putAwayTowRopesActionCheck),_this)] call CBA_fnc_directCall)]; player addAction ["Attach To Tow Ropes", { //ToDo Localize call FUNC(attachTowRopesAction); -}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(attachTowRopesActionCheck), _this)] call CBA_fnc_directCall)]; +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(attachTowRopesActionCheck),_this)] call CBA_fnc_directCall)]; player addAction ["Drop Tow Ropes", { //ToDo Localize call FUNC(dropTowRopesAction); -}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(dropTowRopesActionCheck), _this)] call CBA_fnc_directCall)]; +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(dropTowRopesActionCheck),_this)] call CBA_fnc_directCall)]; player addAction ["Pickup Tow Ropes", { //ToDo Localize call FUNC(pickupTowRopesAction); -}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(pickupTowRopesActionCheck), _this)] call CBA_fnc_directCall)]; +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(pickupTowRopesActionCheck),_this)] call CBA_fnc_directCall)]; player addEventHandler ["Respawn", { player setVariable [QGVAR(Actions_Loaded), false]; diff --git a/addons/advancedtowing/functions/fnc_simulateTowing.sqf b/addons/advancedtowing/functions/fnc_simulateTowing.sqf index 931bd7ec8..6cf782067 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowing.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowing.sqf @@ -27,7 +27,7 @@ private _maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); private _cargoCanFloat = [false, true] select (getNumber ((configOf _cargo) >> "canFloat") == 1); private _cargoCenterOfMassAGL; -SA_Find_Surface_AGL_Under_Model(_cargo, getCenterOfMass _cargo, _cargoCenterOfMassAGL, _cargoCanFloat); +SA_Find_Surface_AGL_Under_Model(_cargo,getCenterOfMass _cargo,_cargoCenterOfMassAGL,_cargoCanFloat); private _cargoModelCenterGroundPosition = _cargo worldToModelVisual _cargoCenterOfMassAGL; _cargoModelCenterGroundPosition set [0, 0]; diff --git a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf index c9f80822b..774fcfc12 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf @@ -20,10 +20,9 @@ params ["_vehicle"]; private _currentCargo; -"_maxVehicleSpeed","_vehicleMass"]; -_maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); -_vehicleMass = 1000 max (getMass _vehicle); +private _maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); +private _vehicleMass = 1000 max (getMass _vehicle); private _maxTowedCargo = missionNamespace getVariable ["SA_MAX_TOWED_CARGO",2]; private _runSimulation = true; diff --git a/addons/advancedtowing/functions/fnc_takeTowRopes.sqf b/addons/advancedtowing/functions/fnc_takeTowRopes.sqf index fc0b5556f..fa2a6506b 100644 --- a/addons/advancedtowing/functions/fnc_takeTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_takeTowRopes.sqf @@ -19,7 +19,7 @@ params ["_vehicle","_player"]; if(local _vehicle) then { - INFO_1("Take Tow Ropes Called %1", _this); + INFO_1("Take Tow Ropes Called %1",_this); private _existingTowRopes = _vehicle getVariable [QGVAR(Ropes), []]; From f3dafdf097d0c8a3a0970c773cb8f1bccd65f9cb Mon Sep 17 00:00:00 2001 From: Andx <17100110+Andx667@users.noreply.github.com> Date: Sat, 4 Oct 2025 18:24:15 +0200 Subject: [PATCH 04/20] Update addons/advancedtowing/functions/fnc_install.sqf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/advancedtowing/functions/fnc_install.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/advancedtowing/functions/fnc_install.sqf b/addons/advancedtowing/functions/fnc_install.sqf index 10675af42..3b7c0a2bf 100644 --- a/addons/advancedtowing/functions/fnc_install.sqf +++ b/addons/advancedtowing/functions/fnc_install.sqf @@ -16,4 +16,4 @@ */ if(!isNil QGVAR(INIT)) exitWith {}; -SA_TOW_INIT = true; +GVAR(INIT) = true; From ad4f632edeb624ee1178d99e8b8a0918c99ec21d Mon Sep 17 00:00:00 2001 From: Andx <17100110+Andx667@users.noreply.github.com> Date: Sat, 4 Oct 2025 18:25:53 +0200 Subject: [PATCH 05/20] Update addons/advancedtowing/functions/fnc_takeTowRopes.sqf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/advancedtowing/functions/fnc_takeTowRopes.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/advancedtowing/functions/fnc_takeTowRopes.sqf b/addons/advancedtowing/functions/fnc_takeTowRopes.sqf index fa2a6506b..bea541d61 100644 --- a/addons/advancedtowing/functions/fnc_takeTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_takeTowRopes.sqf @@ -27,8 +27,8 @@ if(local _vehicle) then { private _hitchPoint = [_vehicle] call FUNC(getHitchPoints) select 1; private _rope = ropeCreate [_vehicle, _hitchPoint, 10]; _vehicle setVariable [QGVAR(Ropes), [_rope], true]; - call FUNC(pickUpTowRopes); + call FUNC(pickupTowRopes); }; } else { - [_this, QFUNC(takwTowRopes), _vehicle, true] call FUNC(CustomRemoteExec); + [_this, QFUNC(takeTowRopes), _vehicle, true] call FUNC(customRemoteExec); }; From 33f7a45de887ff0fafe6e6a0fc2297f4e7b214a5 Mon Sep 17 00:00:00 2001 From: Andx <17100110+Andx667@users.noreply.github.com> Date: Sat, 4 Oct 2025 18:26:14 +0200 Subject: [PATCH 06/20] Update addons/advancedtowing/functions/fnc_putAwayTowRopes.sqf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/advancedtowing/functions/fnc_putAwayTowRopes.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/advancedtowing/functions/fnc_putAwayTowRopes.sqf b/addons/advancedtowing/functions/fnc_putAwayTowRopes.sqf index 51214367e..d817329f8 100644 --- a/addons/advancedtowing/functions/fnc_putAwayTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_putAwayTowRopes.sqf @@ -22,7 +22,7 @@ if(local _vehicle) then { private _existingTowRopes = _vehicle getVariable [QGVAR(Ropes), []]; if(count _existingTowRopes > 0) then { - call FUNC(pickUpTowRopes); + call FUNC(pickupTowRopes); call FUNC(dropTowRopes); { ropeDestroy _x; From 60423f963d407bb2e201a14f64fae74443ac6a4b Mon Sep 17 00:00:00 2001 From: Andx <17100110+Andx667@users.noreply.github.com> Date: Sat, 4 Oct 2025 18:26:22 +0200 Subject: [PATCH 07/20] Update addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf index 774fcfc12..befa7d34f 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf @@ -42,7 +42,7 @@ while {_runSimulation} do { if(!isNull _currentCargo) then { - private _towRopes = _currentVehicle getVariable [QGVAR(Tow_Ropes), []]; + private _towRopes = _currentVehicle getVariable [QGVAR(Ropes), []]; if(count _towRopes > 0) then { From 0de4b0bf8fdb4783980f587aefd8576c902d7ebd Mon Sep 17 00:00:00 2001 From: Andx <17100110+Andx667@users.noreply.github.com> Date: Sat, 4 Oct 2025 18:26:53 +0200 Subject: [PATCH 08/20] Update addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf index 8062d7344..990465cd9 100644 --- a/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf +++ b/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf @@ -22,8 +22,10 @@ if([_vehicle] call FUNC(canTakeTowRopes)) then { private _canTakeTowRopes = true; - if!(missionNamespace getVariable [QGVAR(LOCKED_VEHICLES_ENABLED), false]) then { - if( locked _vehicle > 1 ) then { + if (missionNamespace getVariable [QGVAR(LOCKED_VEHICLES_ENABLED), false]) then { + // Locked vehicles are enabled, so do nothing special + } else { + if (locked _vehicle > 1) then { ["Cannot take tow ropes from locked vehicle", false] call FUNC(customHint); //ToDo Localize _canTakeTowRopes = false; }; From 27beb0e0e0b0530dc0f3773ff7320b95bf937a10 Mon Sep 17 00:00:00 2001 From: Andx <17100110+Andx667@users.noreply.github.com> Date: Sat, 4 Oct 2025 18:27:19 +0200 Subject: [PATCH 09/20] Update addons/advancedtowing/functions/fnc_isSupportedCargo.sqf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/advancedtowing/functions/fnc_isSupportedCargo.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf index 50d2f5111..3f129825f 100644 --- a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf +++ b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf @@ -30,6 +30,6 @@ if(!isNull _vehicle && !isNull _cargo) then { }; }; }; - } forEach (missionNamespace getVariable [QGVAR(RULES_OVERRIDE), SA_Tow_Rules]); + } forEach (missionNamespace getVariable [QGVAR(RULES_OVERRIDE), SA_TOW_RULES]); }; _canTow; From bb3335dabe65f98a8847f1e23650d0f0eb755429 Mon Sep 17 00:00:00 2001 From: Andx <17100110+Andx667@users.noreply.github.com> Date: Sat, 4 Oct 2025 18:27:38 +0200 Subject: [PATCH 10/20] Update addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf b/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf index 6e2321806..62086f475 100644 --- a/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf +++ b/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf @@ -17,7 +17,7 @@ player addAction ["Deploy Tow Ropes", { //ToDo Localize call FUNC(takeTowRopesAction); -}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(deployTowRopesActionCheck),_this)] call CBA_fnc_directCall)]; +}, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(takeTowRopesActionCheck),_this)] call CBA_fnc_directCall)]; player addAction ["Put Away Tow Ropes", { //ToDo Localize call FUNC(putAwayTowRopesAction); From 3f1ddfab74037cdd73fd1952254a2e1d9be637f8 Mon Sep 17 00:00:00 2001 From: Andx <17100110+Andx667@users.noreply.github.com> Date: Sat, 4 Oct 2025 18:27:50 +0200 Subject: [PATCH 11/20] Update addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf index 4dad8e110..781302a6f 100644 --- a/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf +++ b/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf @@ -17,7 +17,7 @@ private _nearbyTowVehicles = missionNamespace getVariable [QGVAR(Nearby_Tow_Vehicles), []]; -if([] call SA_Can_Pickup_Tow_Ropes) then { +if([] call FUNC(canPickupTowRopes)) then { private _vehicle = _nearbyTowVehicles select 0; private _canPickupTowRopes = true; From 9bbc849cd15fd0b7f7fe20f08f921fa6e04ed208 Mon Sep 17 00:00:00 2001 From: Andx <17100110+Andx667@users.noreply.github.com> Date: Sat, 4 Oct 2025 18:36:25 +0200 Subject: [PATCH 12/20] Update addons/advancedtowing/functions/fnc_dropTowRopesActionCheck.sqf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/advancedtowing/functions/fnc_dropTowRopesActionCheck.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/advancedtowing/functions/fnc_dropTowRopesActionCheck.sqf b/addons/advancedtowing/functions/fnc_dropTowRopesActionCheck.sqf index 0141020bf..5c1819208 100644 --- a/addons/advancedtowing/functions/fnc_dropTowRopesActionCheck.sqf +++ b/addons/advancedtowing/functions/fnc_dropTowRopesActionCheck.sqf @@ -15,4 +15,4 @@ * Public: No */ -[] call SA_Can_Drop_Tow_Ropes; +[] call FUNC(canDropTowRopes); From 59c4b8a84f9540430bcbb8964c78cde6ce619bf9 Mon Sep 17 00:00:00 2001 From: Andx <17100110+Andx667@users.noreply.github.com> Date: Sat, 4 Oct 2025 18:36:34 +0200 Subject: [PATCH 13/20] Update addons/advancedtowing/functions/fnc_attachTowRopes.sqf Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- addons/advancedtowing/functions/fnc_attachTowRopes.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf index 85452d4e3..a0e0d2497 100644 --- a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf @@ -17,7 +17,7 @@ params ["_cargo", "_player"]; -_vehicle = _player getVariable [QGVAR(ropes_vehicle), objNull]; +_vehicle = _player getVariable [QGVAR(Ropes_Vehicle), objNull]; if(!isNull _vehicle) then { if(local _vehicle) then { From 1d439160150471f3e3a4f01100a975876fb98bb3 Mon Sep 17 00:00:00 2001 From: Andx Date: Sat, 4 Oct 2025 20:09:32 +0200 Subject: [PATCH 14/20] wip --- addons/advancedtowing/XEH_PREP.hpp | 4 ++ .../functions/fnc_attachTowRopes.sqf | 3 +- .../fnc_findSurfaceAGLUnderModel.sqf | 22 +++++++++ .../fnc_findSurfaceASLUnderModel.sqf | 20 ++++++++ .../fnc_findSurfaceASLUnderPosition.sqf | 46 +++++++++++++++++++ .../advancedtowing/functions/fnc_getCargo.sqf | 24 ++++++++++ addons/advancedtowing/functions/fnc_init.sqf | 9 ++-- .../advancedtowing/functions/fnc_install.sqf | 6 +++ .../functions/fnc_isSupportedCargo.sqf | 2 +- .../functions/fnc_simulateTowing.sqf | 17 +++---- .../functions/fnc_simulateTowingSpeed.sqf | 6 +-- addons/advancedtowing/script_component.hpp | 39 ---------------- 12 files changed, 139 insertions(+), 59 deletions(-) create mode 100644 addons/advancedtowing/functions/fnc_findSurfaceAGLUnderModel.sqf create mode 100644 addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf create mode 100644 addons/advancedtowing/functions/fnc_findSurfaceASLUnderPosition.sqf create mode 100644 addons/advancedtowing/functions/fnc_getCargo.sqf diff --git a/addons/advancedtowing/XEH_PREP.hpp b/addons/advancedtowing/XEH_PREP.hpp index a88e90132..f181c62f5 100644 --- a/addons/advancedtowing/XEH_PREP.hpp +++ b/addons/advancedtowing/XEH_PREP.hpp @@ -16,6 +16,10 @@ PREP(dropTowRopes); PREP(dropTowRopesAction); PREP(dropTowRopesActionCheck); PREP(findNearbyTowVehicles); +PREP(findSurfaceAGLUnderModel); +PREP(findSurfaceASLUnderModel); +PREP(findSurfaceASLUnderPosition); +PREP(getCargo); PREP(getCornerPoints); PREP(getHitchPoints); PREP(init); diff --git a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf index a0e0d2497..dcc7fe586 100644 --- a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf @@ -17,7 +17,8 @@ params ["_cargo", "_player"]; -_vehicle = _player getVariable [QGVAR(Ropes_Vehicle), objNull]; +private _vehicle = _player getVariable [QGVAR(Ropes_Vehicle), objNull]; +private _isRearCargoHitch = 0; if(!isNull _vehicle) then { if(local _vehicle) then { diff --git a/addons/advancedtowing/functions/fnc_findSurfaceAGLUnderModel.sqf b/addons/advancedtowing/functions/fnc_findSurfaceAGLUnderModel.sqf new file mode 100644 index 000000000..4fabd4a04 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_findSurfaceAGLUnderModel.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_findSurfaceAGLUnderModel + * + * Public: No + */ + +params ["_object", "_modelOffset", "_returnSurfaceAGL", "_canFloat"]; + +_returnSurfaceAGL = [_object, _modelOffset, _canFloat] call FUNC(findSurfaceASLUnderModel); + +_returnSurfaceAGL = ASLToAGL _returnSurfaceAGL; diff --git a/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf new file mode 100644 index 000000000..66fc9d997 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_findSurfaceASLUnderModel + * + * Public: No + */ + +params ["_object", "_modelOffset", "_canFloat"]; + +[_object, (_object modelToWorldVisual _modelOffset), _canFloat] call FUNC(findSurfaceASLUnderPosition) diff --git a/addons/advancedtowing/functions/fnc_findSurfaceASLUnderPosition.sqf b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderPosition.sqf new file mode 100644 index 000000000..e3ae43194 --- /dev/null +++ b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderPosition.sqf @@ -0,0 +1,46 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_findSurfaceASLUnderPosition + * + * Public: No + */ + +params ["_object", "_positionAGL", "_canFloat"]; + +private _objectASL = AGLToASL (_object modelToWorldVisual (getCenterOfMass _object)); +private _surfaceIntersectStartASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) + 1]; +private _surfaceIntersectEndASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) - 5]; +private _surfaces = lineIntersectsSurfaces [_surfaceIntersectStartASL, _surfaceIntersectEndASL, _object, objNull, true, 5]; +private _returnSurfaceASL = AGLToASL _positionAGL; + +{ + scopeName "surfaceLoop"; + if( isNull (_x select 2) ) then { + _returnSurfaceASL = _x select 0; + breakOut "surfaceLoop"; + } else { + if!((_x select 2) isKindOf "RopeSegment") then { + _objectFileName = str (_x select 2); + if((_objectFileName find " t_") == -1 && (_objectFileName find " b_") == -1) then { + _returnSurfaceASL = _x select 0; + breakOut "surfaceLoop"; + }; + }; + }; +} forEach _surfaces; + +if(_canFloat && (_returnSurfaceASL select 2) < 0) then { + _returnSurfaceASL set [2,0]; +}; + +_returnSurfaceASL diff --git a/addons/advancedtowing/functions/fnc_getCargo.sqf b/addons/advancedtowing/functions/fnc_getCargo.sqf new file mode 100644 index 000000000..9e31d6f4d --- /dev/null +++ b/addons/advancedtowing/functions/fnc_getCargo.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Authors: You + * Description. + * + * Arguments: + * 0: Argument (optional, default: value) + * + * Return Value: + * Return description + * + * Example: + * [params] call PREFIX_advancedtowing_fnc_getCargo + * + * Public: No + */ + +params ["_vehicle", "_cargo"]; + +if( ropeAttachedObjects _vehicle isEqualTo [] ) then { + _cargo = objNull; +} else { + _cargo = ((ropeAttachedObjects _vehicle) select 0) getVariable [QGVAR(Cargo), objNull]; +}; diff --git a/addons/advancedtowing/functions/fnc_init.sqf b/addons/advancedtowing/functions/fnc_init.sqf index 8b60e56f4..784c01696 100644 --- a/addons/advancedtowing/functions/fnc_init.sqf +++ b/addons/advancedtowing/functions/fnc_init.sqf @@ -17,14 +17,11 @@ SA_TOW_LOCKED_VEHICLES_ENABLED = true; -_isRearCargoHitch = 0; - - SA_tow_supported_vehicles = [ - //"Tank", "Car", "Ship" + "Tank", "Car", "Ship" ]; -SA_TOW_RULES = [ +GVAR(TOW_RULES) = [ ["Tank","CAN_TOW","Tank"], ["Tank","CAN_TOW","Car"], ["Tank","CAN_TOW","Ship"], @@ -52,5 +49,5 @@ if(!isDedicated) then { }; if(isServer) then { - [] call FUNC(Install); + call FUNC(Install); }; diff --git a/addons/advancedtowing/functions/fnc_install.sqf b/addons/advancedtowing/functions/fnc_install.sqf index 3b7c0a2bf..7b1915f0b 100644 --- a/addons/advancedtowing/functions/fnc_install.sqf +++ b/addons/advancedtowing/functions/fnc_install.sqf @@ -16,4 +16,10 @@ */ if(!isNil QGVAR(INIT)) exitWith {}; + GVAR(INIT) = true; + +// Install Advanced Towing on all clients (plus JIP) // + +publicVariable FUNC(install); +remoteExecCall [FUNC(install), -2, true]; diff --git a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf index 3f129825f..4f99a5a80 100644 --- a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf +++ b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf @@ -30,6 +30,6 @@ if(!isNull _vehicle && !isNull _cargo) then { }; }; }; - } forEach (missionNamespace getVariable [QGVAR(RULES_OVERRIDE), SA_TOW_RULES]); + } forEach (missionNamespace getVariable [QGVAR(RULES_OVERRIDE), GVAR(TOW_RULES)]); }; _canTow; diff --git a/addons/advancedtowing/functions/fnc_simulateTowing.sqf b/addons/advancedtowing/functions/fnc_simulateTowing.sqf index 6cf782067..b03de8a1e 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowing.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowing.sqf @@ -26,8 +26,7 @@ private ["_cargoCenterASL","_surfaceHeight","_surfaceHeight2","_maxSurfaceHeight private _maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); private _cargoCanFloat = [false, true] select (getNumber ((configOf _cargo) >> "canFloat") == 1); -private _cargoCenterOfMassAGL; -SA_Find_Surface_AGL_Under_Model(_cargo,getCenterOfMass _cargo,_cargoCenterOfMassAGL,_cargoCanFloat); +private _cargoCenterOfMassAGL = [_cargo, getCenterOfMass _cargo, _cargoCanFloat] call FUNC(findSurfaceAGLUnderModel); private _cargoModelCenterGroundPosition = _cargo worldToModelVisual _cargoCenterOfMassAGL; _cargoModelCenterGroundPosition set [0, 0]; @@ -93,13 +92,14 @@ while {!_doExit} do { _lastCargoVectorDir = _newCargoDir; _newCargoPosition = _newCargoHitchPosition vectorAdd (_newCargoDir vectorMultiply -(vectorMagnitude (_cargoHitchModelPos))); - SA_Find_Surface_ASL_Under_Position(_cargo,_newCargoPosition,_newCargoPosition,_cargoCanFloat); + _newCargoPosition = [_cargo, _newCargoPosition, _cargoCanFloat] call FUNC(findSurfaceASLUnderPosition); // Calculate surface normal (up) (more realistic than surfaceNormal function) - SA_Find_Surface_ASL_Under_Model(_cargo,_corner1,_cargoCorner1ASL,_cargoCanFloat); - SA_Find_Surface_ASL_Under_Model(_cargo,_corner2,_cargoCorner2ASL,_cargoCanFloat); - SA_Find_Surface_ASL_Under_Model(_cargo,_corner3,_cargoCorner3ASL,_cargoCanFloat); - SA_Find_Surface_ASL_Under_Model(_cargo,_corner4,_cargoCorner4ASL,_cargoCanFloat); + private _cargoCorner1ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); + private _cargoCorner2ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); + private _cargoCorner2ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); + private _cargoCorner3ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); + _surfaceNormal1 = (_cargoCorner1ASL vectorFromTo _cargoCorner3ASL) vectorCrossProduct (_cargoCorner1ASL vectorFromTo _cargoCorner2ASL); _surfaceNormal2 = (_cargoCorner4ASL vectorFromTo _cargoCorner2ASL) vectorCrossProduct (_cargoCorner4ASL vectorFromTo _cargoCorner3ASL); _surfaceNormal = _surfaceNormal1 vectorAdd _surfaceNormal2; @@ -160,7 +160,8 @@ while {!_doExit} do { }; // If the vehicle isn't towing anything, stop the towing simulation - SA_Get_Cargo(_vehicle,_currentCargo); + [_Vehicle, _currentCargo] call FUNC(getCargo); + if(isNull _currentCargo) then { _doExit = true; }; diff --git a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf index befa7d34f..63f13b134 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf @@ -19,11 +19,9 @@ params ["_vehicle"]; -private _currentCargo; - private _maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); private _vehicleMass = 1000 max (getMass _vehicle); -private _maxTowedCargo = missionNamespace getVariable ["SA_MAX_TOWED_CARGO",2]; +private _maxTowedCargo = missionNamespace getVariable [QGVAR(MAX_TOWED_CARGO), 2]; private _runSimulation = true; while {_runSimulation} do { @@ -38,7 +36,7 @@ while {_runSimulation} do { while {_findNextCargo} do { _findNextCargo = false; - SA_Get_Cargo(_currentVehicle,_currentCargo); + private _currentCargo = [_currentVehicle, _currentCargo] call FUNC(getCargo); if(!isNull _currentCargo) then { diff --git a/addons/advancedtowing/script_component.hpp b/addons/advancedtowing/script_component.hpp index 601447e25..a79a42098 100644 --- a/addons/advancedtowing/script_component.hpp +++ b/addons/advancedtowing/script_component.hpp @@ -3,42 +3,3 @@ #include "\z\ttt\addons\main\script_mod.hpp" #include "\z\ttt\addons\main\script_macros.hpp" - -#define SA_Find_Surface_ASL_Under_Position(_object,_positionAGL,_returnSurfaceASL,_canFloat) \ -_objectASL = AGLToASL (_object modelToWorldVisual (getCenterOfMass _object)); \ -_surfaceIntersectStartASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) + 1]; \ -_surfaceIntersectEndASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) - 5]; \ -_surfaces = lineIntersectsSurfaces [_surfaceIntersectStartASL, _surfaceIntersectEndASL, _object, objNull, true, 5]; \ -_returnSurfaceASL = AGLToASL _positionAGL; \ -{ \ - scopeName "surfaceLoop"; \ - if( isNull (_x select 2) ) then { \ - _returnSurfaceASL = _x select 0; \ - breakOut "surfaceLoop"; \ - } else { \ - if!((_x select 2) isKindOf "RopeSegment") then { \ - _objectFileName = str (_x select 2); \ - if((_objectFileName find " t_") == -1 && (_objectFileName find " b_") == -1) then { \ - _returnSurfaceASL = _x select 0; \ - breakOut "surfaceLoop"; \ - }; \ - }; \ - }; \ -} forEach _surfaces; \ -if(_canFloat && (_returnSurfaceASL select 2) < 0) then { \ - _returnSurfaceASL set [2,0]; \ -}; \ - -#define SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceASL,_canFloat) \ -SA_Find_Surface_ASL_Under_Position(_object,(_object modelToWorldVisual _modelOffset),_returnSurfaceASL,_canFloat); - -#define SA_Find_Surface_AGL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat) \ -SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat); \ -_returnSurfaceAGL = ASLtoAGL _returnSurfaceAGL; - -#define SA_Get_Cargo(_vehicle,_cargo) \ -if( count (ropeAttachedObjects _vehicle) == 0 ) then { \ - _cargo = objNull; \ -} else { \ - _cargo = ((ropeAttachedObjects _vehicle) select 0) getVariable ["SA_Cargo",objNull]; \ -}; From 17ce00d6cafb7ea3dfec508ba0770105f91c698f Mon Sep 17 00:00:00 2001 From: Andx Date: Sat, 4 Oct 2025 20:19:09 +0200 Subject: [PATCH 15/20] unify gvars --- addons/advancedtowing/config.cpp | 3 +-- .../advancedtowing/functions/fnc_attachTowRopesAction.sqf | 2 +- addons/advancedtowing/functions/fnc_customHint.sqf | 2 +- .../advancedtowing/functions/fnc_findNearbyTowVehicles.sqf | 2 +- addons/advancedtowing/functions/fnc_getCornerPoints.sqf | 2 +- addons/advancedtowing/functions/fnc_init.sqf | 6 +++--- addons/advancedtowing/functions/fnc_install.sqf | 4 ++-- addons/advancedtowing/functions/fnc_isSupportedCargo.sqf | 2 +- addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf | 2 +- .../advancedtowing/functions/fnc_pickupTowRopesAction.sqf | 2 +- .../advancedtowing/functions/fnc_putAwayTowRopesAction.sqf | 2 +- addons/advancedtowing/functions/fnc_simulateTowing.sqf | 2 +- addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf | 2 +- addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf | 2 +- 14 files changed, 17 insertions(+), 18 deletions(-) diff --git a/addons/advancedtowing/config.cpp b/addons/advancedtowing/config.cpp index f0b0f55c8..044b61f5e 100644 --- a/addons/advancedtowing/config.cpp +++ b/addons/advancedtowing/config.cpp @@ -12,7 +12,7 @@ class CfgPatches { requiredVersion = REQUIRED_VERSION; // Required addons, used for setting load order. (CfgPatches classname NOT PBO filename!) // When any of the addons are missing, a pop-up warning will appear when launching the game. - requiredAddons[] = {"ttt_common"}; + requiredAddons[] = {"ttt_common", "ace_common"}; // List of objects (CfgVehicles classes) contained in the addon. Important also for Zeus content (units and groups) unlocking. units[] = {}; // List of weapons (CfgWeapons classes) contained in the addon. @@ -25,4 +25,3 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" - diff --git a/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf index 14622f916..4550f4d14 100644 --- a/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf +++ b/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf @@ -22,7 +22,7 @@ if([_vehicle, _cargo] call FUNC(canAttachTowRopes)) then { private _canBeTowed = true; - if!(missionNamespace getVariable [QGVAR(LOCKED_VEHICLES_ENABLED), false]) then { + if!(missionNamespace getVariable [QGVAR(Locked_Vehicles_Enabled), false]) then { if( locked _cargo > 1 ) then { ["Cannot attach tow ropes to locked vehicle", false] call FUNC(customHint);//ToDo Localize _canBeTowed = false; diff --git a/addons/advancedtowing/functions/fnc_customHint.sqf b/addons/advancedtowing/functions/fnc_customHint.sqf index 0c043557a..608a512fb 100644 --- a/addons/advancedtowing/functions/fnc_customHint.sqf +++ b/addons/advancedtowing/functions/fnc_customHint.sqf @@ -17,4 +17,4 @@ params ["_msg",["_isSuccess",true]]; -hint _msg; +[_msg, true] call ace_common_fnc_displayText; diff --git a/addons/advancedtowing/functions/fnc_findNearbyTowVehicles.sqf b/addons/advancedtowing/functions/fnc_findNearbyTowVehicles.sqf index c832c468e..b9a74ef0a 100644 --- a/addons/advancedtowing/functions/fnc_findNearbyTowVehicles.sqf +++ b/addons/advancedtowing/functions/fnc_findNearbyTowVehicles.sqf @@ -19,7 +19,7 @@ private _nearVehicles = []; { _nearVehicles append (position player nearObjects [_x, 30]); -} forEach (missionNamespace getVariable [QGVAR(SUPPORTED_VEHICLES_OVERRIDE), SA_tow_supported_vehicles]); +} forEach (missionNamespace getVariable [QGVAR(Supported_Vehicles_Override), GVAR(Supported_Vehicles)]); private _nearVehiclesWithTowRopes = []; { diff --git a/addons/advancedtowing/functions/fnc_getCornerPoints.sqf b/addons/advancedtowing/functions/fnc_getCornerPoints.sqf index 4a04b0324..2f415d5d0 100644 --- a/addons/advancedtowing/functions/fnc_getCornerPoints.sqf +++ b/addons/advancedtowing/functions/fnc_getCornerPoints.sqf @@ -42,7 +42,7 @@ private _rearCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass private _frontCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) + _lengthOffset, _centerOfMass select 2]; private _frontCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) + _lengthOffset, _centerOfMass select 2]; -if(missionNamespace getVariable [QGVAR(DEBUG_ENABLED), false]) then { +if(missionNamespace getVariable [QGVAR(Debug_Enabled), false]) then { if(isNil "sa_tow_debug_arrow_1") then { sa_tow_debug_arrow_1 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; sa_tow_debug_arrow_2 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; diff --git a/addons/advancedtowing/functions/fnc_init.sqf b/addons/advancedtowing/functions/fnc_init.sqf index 784c01696..7bcad87ed 100644 --- a/addons/advancedtowing/functions/fnc_init.sqf +++ b/addons/advancedtowing/functions/fnc_init.sqf @@ -15,13 +15,13 @@ * Public: No */ - SA_TOW_LOCKED_VEHICLES_ENABLED = true; +GVAR(Locked_Vehicles_Enabled) = true; -SA_tow_supported_vehicles = [ +GVAR(Supported_Vehicles) = [ "Tank", "Car", "Ship" ]; -GVAR(TOW_RULES) = [ +GVAR(Tow_Rules) = [ ["Tank","CAN_TOW","Tank"], ["Tank","CAN_TOW","Car"], ["Tank","CAN_TOW","Ship"], diff --git a/addons/advancedtowing/functions/fnc_install.sqf b/addons/advancedtowing/functions/fnc_install.sqf index 7b1915f0b..381e1f708 100644 --- a/addons/advancedtowing/functions/fnc_install.sqf +++ b/addons/advancedtowing/functions/fnc_install.sqf @@ -15,9 +15,9 @@ * Public: No */ -if(!isNil QGVAR(INIT)) exitWith {}; +if(!isNil QGVAR(Init)) exitWith {}; -GVAR(INIT) = true; +GVAR(Init) = true; // Install Advanced Towing on all clients (plus JIP) // diff --git a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf index 4f99a5a80..6640f695c 100644 --- a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf +++ b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf @@ -30,6 +30,6 @@ if(!isNull _vehicle && !isNull _cargo) then { }; }; }; - } forEach (missionNamespace getVariable [QGVAR(RULES_OVERRIDE), GVAR(TOW_RULES)]); + } forEach (missionNamespace getVariable [QGVAR(Rules_Override, GVAR(Tow_Rules)]); }; _canTow; diff --git a/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf b/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf index 74950a06f..a9cbf85ca 100644 --- a/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf +++ b/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf @@ -23,6 +23,6 @@ if(!isNull _vehicle) then { if(_vehicle isKindOf _x) then { _isSupported = true; }; - } forEach (missionNamespace getVariable [QGVAR(SUPPORTED_VEHICLES_OVERRIDE), SA_tow_supported_vehicles]); + } forEach (missionNamespace getVariable [QGVAR(Supported_Vehicles_Override), GVAR(Supported_Vehicles)]); }; _isSupported; diff --git a/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf index 781302a6f..d39a01410 100644 --- a/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf +++ b/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf @@ -22,7 +22,7 @@ if([] call FUNC(canPickupTowRopes)) then { private _vehicle = _nearbyTowVehicles select 0; private _canPickupTowRopes = true; - if!(missionNamespace getVariable [QGVAR(LOCKED_VEHICLES_ENABLED),false]) then { + if!(missionNamespace getVariable [QGVAR(Locked_Vehicles_Enabled),false]) then { if( locked _vehicle > 1 ) then { ["Cannot pick up tow ropes from locked vehicle", false] call FUNC(customHint); //ToDo Localize _canPickupTowRopes = false; diff --git a/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf index cbde82fc9..d9391ebcd 100644 --- a/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf +++ b/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf @@ -21,7 +21,7 @@ if([_vehicle] call FUNC(canPutAwayTowRopes)) then { private _canPutAwayTowRopes = true; - if!(missionNamespace getVariable [QGVAR(LOCKED_VEHICLES_ENABLED), false]) then { + if!(missionNamespace getVariable [QGVAR(Locked_Vehicles_Enabled), false]) then { if( locked _vehicle > 1 ) then { ["Cannot put away tow ropes in locked vehicle", false] call FUNC(customHint); //ToDo Localize _canPutAwayTowRopes = false; diff --git a/addons/advancedtowing/functions/fnc_simulateTowing.sqf b/addons/advancedtowing/functions/fnc_simulateTowing.sqf index b03de8a1e..a5f9af4b2 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowing.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowing.sqf @@ -104,7 +104,7 @@ while {!_doExit} do { _surfaceNormal2 = (_cargoCorner4ASL vectorFromTo _cargoCorner2ASL) vectorCrossProduct (_cargoCorner4ASL vectorFromTo _cargoCorner3ASL); _surfaceNormal = _surfaceNormal1 vectorAdd _surfaceNormal2; - if(missionNamespace getVariable [QGVAR(DEBUG_ENABLED), false]) then { + if(missionNamespace getVariable [QGVAR(Debug_Enabled), false]) then { if(isNil "sa_tow_debug_arrow_1") then { sa_tow_debug_arrow_1 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; sa_tow_debug_arrow_2 = "Sign_Arrow_F" createVehicleLocal [0,0,0]; diff --git a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf index 63f13b134..891dbb0bd 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf @@ -21,7 +21,7 @@ params ["_vehicle"]; private _maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); private _vehicleMass = 1000 max (getMass _vehicle); -private _maxTowedCargo = missionNamespace getVariable [QGVAR(MAX_TOWED_CARGO), 2]; +private _maxTowedCargo = missionNamespace getVariable [QGVAR(Max_Towed_Cargo), 2]; private _runSimulation = true; while {_runSimulation} do { diff --git a/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf index 990465cd9..6dab36292 100644 --- a/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf +++ b/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf @@ -22,7 +22,7 @@ if([_vehicle] call FUNC(canTakeTowRopes)) then { private _canTakeTowRopes = true; - if (missionNamespace getVariable [QGVAR(LOCKED_VEHICLES_ENABLED), false]) then { + if (missionNamespace getVariable [QGVAR(Locked_Vehicles_Enabled), false]) then { // Locked vehicles are enabled, so do nothing special } else { if (locked _vehicle > 1) then { From 4cde2130188126fb731dee5dfeb84507764b2691 Mon Sep 17 00:00:00 2001 From: Andx Date: Sat, 4 Oct 2025 20:51:40 +0200 Subject: [PATCH 16/20] wip --- .../functions/fnc_attachTowRopes.sqf | 2 +- .../advancedtowing/functions/fnc_getCargo.sqf | 10 +++++--- addons/advancedtowing/functions/fnc_init.sqf | 8 +++--- .../advancedtowing/functions/fnc_install.sqf | 25 ------------------- .../functions/fnc_isSupportedCargo.sqf | 2 +- .../functions/fnc_simulateTowingSpeed.sqf | 2 +- 6 files changed, 13 insertions(+), 36 deletions(-) delete mode 100644 addons/advancedtowing/functions/fnc_install.sqf diff --git a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf index dcc7fe586..0158c757a 100644 --- a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf @@ -27,7 +27,7 @@ if(!isNull _vehicle) then { if(count _towRopes == 1) then { - private ["_cargoHitchPoints","_distanceToFrontHitch","_distanceToRearHitch","_isRearCargoHitch"]; + private ["_cargoHitchPoints", "_distanceToFrontHitch", "_distanceToRearHitch", "_isRearCargoHitch"]; _cargoHitchPoints = [_cargo] call FUNC(getHitchPoints); _distanceToFrontHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 0)); diff --git a/addons/advancedtowing/functions/fnc_getCargo.sqf b/addons/advancedtowing/functions/fnc_getCargo.sqf index 9e31d6f4d..f2527f786 100644 --- a/addons/advancedtowing/functions/fnc_getCargo.sqf +++ b/addons/advancedtowing/functions/fnc_getCargo.sqf @@ -15,10 +15,12 @@ * Public: No */ -params ["_vehicle", "_cargo"]; +params ["_vehicle"]; -if( ropeAttachedObjects _vehicle isEqualTo [] ) then { - _cargo = objNull; -} else { +private _cargo = objNull; + +if( ropeAttachedObjects _vehicle isNotEqualTo [] ) then { _cargo = ((ropeAttachedObjects _vehicle) select 0) getVariable [QGVAR(Cargo), objNull]; }; + +_cargo diff --git a/addons/advancedtowing/functions/fnc_init.sqf b/addons/advancedtowing/functions/fnc_init.sqf index 7bcad87ed..b889682d0 100644 --- a/addons/advancedtowing/functions/fnc_init.sqf +++ b/addons/advancedtowing/functions/fnc_init.sqf @@ -15,6 +15,10 @@ * Public: No */ +if(!isNil QGVAR(Init)) exitWith {}; + +GVAR(Init) = true; + GVAR(Locked_Vehicles_Enabled) = true; GVAR(Supported_Vehicles) = [ @@ -47,7 +51,3 @@ if(!isDedicated) then { }; }; }; - -if(isServer) then { - call FUNC(Install); -}; diff --git a/addons/advancedtowing/functions/fnc_install.sqf b/addons/advancedtowing/functions/fnc_install.sqf deleted file mode 100644 index 381e1f708..000000000 --- a/addons/advancedtowing/functions/fnc_install.sqf +++ /dev/null @@ -1,25 +0,0 @@ -#include "..\script_component.hpp" -/* - * Authors: You - * Description. - * - * Arguments: - * 0: Argument (optional, default: value) - * - * Return Value: - * Return description - * - * Example: - * [params] call PREFIX_advancedtowing_fnc_install - * - * Public: No - */ - -if(!isNil QGVAR(Init)) exitWith {}; - -GVAR(Init) = true; - -// Install Advanced Towing on all clients (plus JIP) // - -publicVariable FUNC(install); -remoteExecCall [FUNC(install), -2, true]; diff --git a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf index 6640f695c..009c47f6b 100644 --- a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf +++ b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf @@ -30,6 +30,6 @@ if(!isNull _vehicle && !isNull _cargo) then { }; }; }; - } forEach (missionNamespace getVariable [QGVAR(Rules_Override, GVAR(Tow_Rules)]); + } forEach (missionNamespace getVariable [QGVAR(Rules_Override), GVAR(Tow_Rules)]); }; _canTow; diff --git a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf index 891dbb0bd..66a878ed9 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf @@ -36,7 +36,7 @@ while {_runSimulation} do { while {_findNextCargo} do { _findNextCargo = false; - private _currentCargo = [_currentVehicle, _currentCargo] call FUNC(getCargo); + private _currentCargo = [_currentVehicle] call FUNC(getCargo); if(!isNull _currentCargo) then { From 0edaf40f593949a125316db523fa01ba331ac179 Mon Sep 17 00:00:00 2001 From: Andx Date: Sat, 4 Oct 2025 21:32:17 +0200 Subject: [PATCH 17/20] fix errors --- addons/advancedtowing/XEH_PREP.hpp | 1 - .../functions/fnc_attachTowRopes.sqf | 11 +++++------ .../functions/fnc_findSurfaceAGLUnderModel.sqf | 6 ++++-- .../functions/fnc_findSurfaceASLUnderModel.sqf | 4 +++- .../functions/fnc_simulateTowing.sqf | 17 ++++++++--------- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/addons/advancedtowing/XEH_PREP.hpp b/addons/advancedtowing/XEH_PREP.hpp index f181c62f5..a7d347cd0 100644 --- a/addons/advancedtowing/XEH_PREP.hpp +++ b/addons/advancedtowing/XEH_PREP.hpp @@ -23,7 +23,6 @@ PREP(getCargo); PREP(getCornerPoints); PREP(getHitchPoints); PREP(init); -PREP(install); PREP(isSupportedCargo); PREP(isSupportedVehicle); PREP(pickupTowRopes); diff --git a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf index 0158c757a..7612ad00f 100644 --- a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf @@ -18,7 +18,7 @@ params ["_cargo", "_player"]; private _vehicle = _player getVariable [QGVAR(Ropes_Vehicle), objNull]; -private _isRearCargoHitch = 0; +private _isRearCargoHitch = false; if(!isNull _vehicle) then { if(local _vehicle) then { @@ -27,11 +27,10 @@ if(!isNull _vehicle) then { if(count _towRopes == 1) then { - private ["_cargoHitchPoints", "_distanceToFrontHitch", "_distanceToRearHitch", "_isRearCargoHitch"]; - _cargoHitchPoints = [_cargo] call FUNC(getHitchPoints); - _distanceToFrontHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 0)); - _distanceToRearHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 1)); + private _cargoHitchPoints = [_cargo] call FUNC(getHitchPoints); + private _distanceToFrontHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 0)); + private _distanceToRearHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 1)); if( _distanceToFrontHitch < _distanceToRearHitch ) then { _cargoHitch = _cargoHitchPoints select 0; _isRearCargoHitch = false; @@ -47,7 +46,7 @@ if(!isNull _vehicle) then { _ropeLength = (ropeLength (_towRopes select 0)); _objDistance = ((_vehicle modelToWorld _vehicleHitch) distance (_cargo modelToWorld _cargoHitch)); if( _objDistance > _ropeLength ) then { - [["The tow ropes are too short. Move vehicle closer.", false],FUNC(customHint), _player] call FUNC(customRemoteExec); //ToDo Localize + [["The tow ropes are too short. Move vehicle closer.", false], QFUNC(customHint), _player] call FUNC(customRemoteExec); //ToDo Localize } else { [_vehicle,_player] call FUNC(dropTowRopes); _helper = "Land_Can_V2_F" createVehicle position _cargo; diff --git a/addons/advancedtowing/functions/fnc_findSurfaceAGLUnderModel.sqf b/addons/advancedtowing/functions/fnc_findSurfaceAGLUnderModel.sqf index 4fabd4a04..084f3fd6d 100644 --- a/addons/advancedtowing/functions/fnc_findSurfaceAGLUnderModel.sqf +++ b/addons/advancedtowing/functions/fnc_findSurfaceAGLUnderModel.sqf @@ -15,8 +15,10 @@ * Public: No */ -params ["_object", "_modelOffset", "_returnSurfaceAGL", "_canFloat"]; +params ["_object", "_modelOffset", "_canFloat"]; -_returnSurfaceAGL = [_object, _modelOffset, _canFloat] call FUNC(findSurfaceASLUnderModel); +private _returnSurfaceAGL = [_object, _modelOffset, _canFloat] call FUNC(findSurfaceASLUnderModel); _returnSurfaceAGL = ASLToAGL _returnSurfaceAGL; + +_returnSurfaceAGL diff --git a/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf index 66fc9d997..7fe688bb2 100644 --- a/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf +++ b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf @@ -17,4 +17,6 @@ params ["_object", "_modelOffset", "_canFloat"]; -[_object, (_object modelToWorldVisual _modelOffset), _canFloat] call FUNC(findSurfaceASLUnderPosition) +private _return = [_object, (_object modelToWorldVisual _modelOffset), _canFloat] call FUNC(findSurfaceASLUnderPosition); + +return diff --git a/addons/advancedtowing/functions/fnc_simulateTowing.sqf b/addons/advancedtowing/functions/fnc_simulateTowing.sqf index a5f9af4b2..df861fb94 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowing.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowing.sqf @@ -17,9 +17,8 @@ params ["_vehicle", "_vehicleHitchModelPos", "_cargo", "_cargoHitchModelPos", "_ropeLength"]; -private ["_lastCargoHitchPosition","_lastCargoVectorDir","_lastMovedCargoPosition","_cargoHitchPoints"]; private ["_vehicleHitchPosition","_cargoHitchPosition","_newCargoHitchPosition","_cargoVector","_movedCargoVector","_currentCargo"]; -private ["_newCargoDir","_lastCargoVectorDir","_newCargoPosition","_cargoPosition","_vehiclePosition","_vehicleMass","_cargoMass"]; +private ["_newCargoDir","_newCargoPosition","_cargoPosition","_vehiclePosition"]; private ["_cargoCorner1AGL","_cargoCorner1ASL","_cargoCorner2AGL","_cargoCorner2ASL","_cargoCorner3AGL","_cargoCorner3ASL","_cargoCorner4AGL","_cargoCorner4ASL","_surfaceNormal1","_surfaceNormal2","_surfaceNormal"]; private ["_cargoCenterASL","_surfaceHeight","_surfaceHeight2","_maxSurfaceHeight"]; @@ -49,15 +48,15 @@ if(local _vehicle && !local _cargo) then { _vehicleHitchModelPos set [2, 0]; _cargoHitchModelPos set [2, 0]; -_lastCargoHitchPosition = _cargo modelToWorld _cargoHitchModelPos; -_lastCargoVectorDir = vectorDir _cargo; -_lastMovedCargoPosition = getPos _cargo; +private _lastCargoHitchPosition = _cargo modelToWorld _cargoHitchModelPos; +private _lastCargoVectorDir = vectorDir _cargo; +private _lastMovedCargoPosition = getPos _cargo; -_cargoHitchPoints = [_cargo] call FUNC(getHitchPoints); +private _cargoHitchPoints = [_cargo] call FUNC(getHitchPoints); private _cargoLength = (_cargoHitchPoints select 0) distance (_cargoHitchPoints select 1); -_vehicleMass = 1 max (getMass _vehicle); -_cargoMass = getMass _cargo; +private _vehicleMass = 1 max (getMass _vehicle); +private _cargoMass = getMass _cargo; if(_cargoMass == 0) then { _cargoMass = _vehicleMass; }; @@ -92,7 +91,7 @@ while {!_doExit} do { _lastCargoVectorDir = _newCargoDir; _newCargoPosition = _newCargoHitchPosition vectorAdd (_newCargoDir vectorMultiply -(vectorMagnitude (_cargoHitchModelPos))); - _newCargoPosition = [_cargo, _newCargoPosition, _cargoCanFloat] call FUNC(findSurfaceASLUnderPosition); + [_cargo, _newCargoPosition, _cargoCanFloat] call FUNC(findSurfaceASLUnderPosition); // Calculate surface normal (up) (more realistic than surfaceNormal function) private _cargoCorner1ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); From b1145088f6fc85ce4c31ce4f88c4a0fb37561544 Mon Sep 17 00:00:00 2001 From: Andx Date: Sat, 4 Oct 2025 23:33:57 +0200 Subject: [PATCH 18/20] wip --- addons/advancedtowing/functions/fnc_simulateTowing.sqf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/advancedtowing/functions/fnc_simulateTowing.sqf b/addons/advancedtowing/functions/fnc_simulateTowing.sqf index df861fb94..bf3f28e81 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowing.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowing.sqf @@ -17,7 +17,7 @@ params ["_vehicle", "_vehicleHitchModelPos", "_cargo", "_cargoHitchModelPos", "_ropeLength"]; -private ["_vehicleHitchPosition","_cargoHitchPosition","_newCargoHitchPosition","_cargoVector","_movedCargoVector","_currentCargo"]; +private ["_vehicleHitchPosition","_cargoHitchPosition","_newCargoHitchPosition","_cargoVector","_movedCargoVector"]; private ["_newCargoDir","_newCargoPosition","_cargoPosition","_vehiclePosition"]; private ["_cargoCorner1AGL","_cargoCorner1ASL","_cargoCorner2AGL","_cargoCorner2ASL","_cargoCorner3AGL","_cargoCorner3ASL","_cargoCorner4AGL","_cargoCorner4ASL","_surfaceNormal1","_surfaceNormal2","_surfaceNormal"]; private ["_cargoCenterASL","_surfaceHeight","_surfaceHeight2","_maxSurfaceHeight"]; @@ -159,7 +159,7 @@ while {!_doExit} do { }; // If the vehicle isn't towing anything, stop the towing simulation - [_Vehicle, _currentCargo] call FUNC(getCargo); + private _currentCargo = [_vehicle] call FUNC(getCargo); if(isNull _currentCargo) then { _doExit = true; From cbf17f953907ddd23dc82df3ada5f71b5a058e58 Mon Sep 17 00:00:00 2001 From: Andx Date: Sun, 5 Oct 2025 00:53:08 +0200 Subject: [PATCH 19/20] wip --- .hemtt/missions/ttt_test.VR/init.sqf | 2 +- .hemtt/missions/ttt_test.VR/mission.sqm | 43 +++++++++++++++---- .../functions/fnc_attachTowRopes.sqf | 2 +- .../fnc_findSurfaceASLUnderModel.sqf | 2 +- .../functions/fnc_simulateTowing.sqf | 14 +++--- 5 files changed, 44 insertions(+), 19 deletions(-) diff --git a/.hemtt/missions/ttt_test.VR/init.sqf b/.hemtt/missions/ttt_test.VR/init.sqf index 91ce0f4f0..c476e8c37 100644 --- a/.hemtt/missions/ttt_test.VR/init.sqf +++ b/.hemtt/missions/ttt_test.VR/init.sqf @@ -1 +1 @@ -//missionNamespace setVariable ["SA_TOW_SUPPORTED_VEHICLES_OVERRIDE", ["rsr_bergepanzer_flecktarn", "rsr_wisent_repair_flecktarn"]]; +missionNamespace setVariable ["ttt_advancedtowing_Debug_Enabled", true]; diff --git a/.hemtt/missions/ttt_test.VR/mission.sqm b/.hemtt/missions/ttt_test.VR/mission.sqm index 7ffb5eb57..1eda930d9 100644 --- a/.hemtt/missions/ttt_test.VR/mission.sqm +++ b/.hemtt/missions/ttt_test.VR/mission.sqm @@ -8,7 +8,7 @@ class EditorData toggles=1; class ItemIDProvider { - nextID=166; + nextID=169; }; class MarkerIDProvider { @@ -16,10 +16,10 @@ class EditorData }; class Camera { - pos[]={5936.7441,7.6433673,4801.0391}; - dir[]={-0.89370924,-0.33833593,0.29490581}; - up[]={-0.32131693,0.94100124,0.10602826}; - aside[]={0.31338173,-1.6821286e-07,0.94969994}; + pos[]={5920.6519,26.137703,4824.4634}; + dir[]={0.17568986,-0.44796935,-0.87670892}; + up[]={0.088023543,0.89402485,-0.43924835}; + aside[]={-0.98057401,-2.1158485e-07,-0.19650301}; }; }; binarizationWanted=0; @@ -44,13 +44,14 @@ addons[]= "ace_vehicle_damage", "acre_sys_intercom", "A3_Structures_F_Civ_Camping", - "ace_dragging" + "ace_dragging", + "A3_Soft_F_Exp_LSV_01" }; class AddonsMetaData { class List { - items=17; + items=19; class Item0 { className="A3_Soft_F_Gamma"; @@ -177,11 +178,19 @@ class AddonsMetaData author="ACE-Team"; url="https://ace3.acemod.org/"; }; + class Item18 + { + className="A3_Soft_F_Exp"; + name="Arma 3 Apex - Unarmored Land Vehicles"; + author="Bohemia Interactive"; + url="https://www.arma3.com"; + }; }; }; dlcs[]= { - "Heli" + "Heli", + "Expansion" }; randomSeed=2912351; class ScenarioData @@ -232,7 +241,7 @@ class Mission }; class Entities { - items=68; + items=69; class Item0 { dataType="Object"; @@ -1658,5 +1667,21 @@ class Mission id=139; type="EmptyDetectorAreaR50"; }; + class Item68 + { + dataType="Object"; + class PositionInfo + { + position[]={5926.4302,7.1761513,4784.0415}; + angles[]={-0,1.7638763,0}; + }; + side="Empty"; + flags=4; + class Attributes + { + }; + id=167; + type="B_CTRG_LSV_01_light_F"; + }; }; }; diff --git a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf index 7612ad00f..5c7f37091 100644 --- a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf @@ -51,7 +51,7 @@ if(!isNull _vehicle) then { [_vehicle,_player] call FUNC(dropTowRopes); _helper = "Land_Can_V2_F" createVehicle position _cargo; _helper attachTo [_cargo, _cargoHitch]; - _helper setVariable [GVAR(Cargo), _cargo, true]; + _helper setVariable [QGVAR(Cargo), _cargo, true]; hideObject _helper; [[_helper], QFUNC(customHideObjectGlobal)] call FUNC(customRemoteExecServer); [_helper, [0, 0, 0], [0, 0, -1]] ropeAttachTo (_towRopes select 0); diff --git a/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf index 7fe688bb2..d8c5edab9 100644 --- a/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf +++ b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf @@ -19,4 +19,4 @@ params ["_object", "_modelOffset", "_canFloat"]; private _return = [_object, (_object modelToWorldVisual _modelOffset), _canFloat] call FUNC(findSurfaceASLUnderPosition); -return +_return diff --git a/addons/advancedtowing/functions/fnc_simulateTowing.sqf b/addons/advancedtowing/functions/fnc_simulateTowing.sqf index bf3f28e81..a49aa7650 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowing.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowing.sqf @@ -25,7 +25,7 @@ private ["_cargoCenterASL","_surfaceHeight","_surfaceHeight2","_maxSurfaceHeight private _maxVehicleSpeed = getNumber (configOf _vehicle >> "maxSpeed"); private _cargoCanFloat = [false, true] select (getNumber ((configOf _cargo) >> "canFloat") == 1); -private _cargoCenterOfMassAGL = [_cargo, getCenterOfMass _cargo, _cargoCanFloat] call FUNC(findSurfaceAGLUnderModel); +private _cargoCenterOfMassAGL = [_cargo, getCenterOfMass _cargo, _cargoCanFloat] call FUNC(findSurfaceAGLUnderModel); private _cargoModelCenterGroundPosition = _cargo worldToModelVisual _cargoCenterOfMassAGL; _cargoModelCenterGroundPosition set [0, 0]; @@ -96,8 +96,8 @@ while {!_doExit} do { // Calculate surface normal (up) (more realistic than surfaceNormal function) private _cargoCorner1ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); private _cargoCorner2ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); - private _cargoCorner2ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); private _cargoCorner3ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); + private _cargoCorner4ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); _surfaceNormal1 = (_cargoCorner1ASL vectorFromTo _cargoCorner3ASL) vectorCrossProduct (_cargoCorner1ASL vectorFromTo _cargoCorner2ASL); _surfaceNormal2 = (_cargoCorner4ASL vectorFromTo _cargoCorner2ASL) vectorCrossProduct (_cargoCorner4ASL vectorFromTo _cargoCorner3ASL); @@ -121,12 +121,12 @@ while {!_doExit} do { }; // Calculate adjusted surface height based on surface normal (prevents vehicle from clipping into ground) - _cargoCenterASL = AGLToASL (_cargo modelToWorldVisual [0,0,0]); - _cargoCenterASL set [2,0]; - _surfaceHeight = ((_cargoCorner1ASL vectorAdd ( _cargoCenterASL vectorMultiply -1)) vectorDotProduct _surfaceNormal1) / ([0,0,1] vectorDotProduct _surfaceNormal1); - _surfaceHeight2 = ((_cargoCorner1ASL vectorAdd ( _cargoCenterASL vectorMultiply -1)) vectorDotProduct _surfaceNormal2) / ([0,0,1] vectorDotProduct _surfaceNormal2); + _cargoCenterASL = AGLToASL (_cargo modelToWorldVisual [0, 0, 0]); + _cargoCenterASL set [2, 0]; + _surfaceHeight = ((_cargoCorner1ASL vectorAdd ( _cargoCenterASL vectorMultiply -1)) vectorDotProduct _surfaceNormal1) / ([0, 0, 1] vectorDotProduct _surfaceNormal1); + _surfaceHeight2 = ((_cargoCorner1ASL vectorAdd ( _cargoCenterASL vectorMultiply -1)) vectorDotProduct _surfaceNormal2) / ([0, 0, 1] vectorDotProduct _surfaceNormal2); _maxSurfaceHeight = (_newCargoPosition select 2) max _surfaceHeight max _surfaceHeight2; - _newCargoPosition set [2, _maxSurfaceHeight ]; + _newCargoPosition set [2, _maxSurfaceHeight]; _newCargoPosition = _newCargoPosition vectorAdd ( _cargoModelCenterGroundPosition vectorMultiply -1 ); From 37666e121e69fa9b8955f6b8f83ffec756e0eef0 Mon Sep 17 00:00:00 2001 From: Andx Date: Sun, 5 Oct 2025 09:36:18 +0200 Subject: [PATCH 20/20] minor refactor --- .../advancedtowing/functions/fnc_addPlayerTowActions.sqf | 2 +- addons/advancedtowing/functions/fnc_attachTowRopes.sqf | 7 ++++--- .../advancedtowing/functions/fnc_attachTowRopesAction.sqf | 2 +- .../advancedtowing/functions/fnc_canPutAwayTowRopes.sqf | 2 +- .../functions/fnc_findSurfaceASLUnderModel.sqf | 4 ++-- .../functions/fnc_findSurfaceASLUnderPosition.sqf | 2 +- addons/advancedtowing/functions/fnc_getCornerPoints.sqf | 2 +- addons/advancedtowing/functions/fnc_getHitchPoints.sqf | 6 +++--- addons/advancedtowing/functions/fnc_isSupportedCargo.sqf | 3 ++- .../advancedtowing/functions/fnc_isSupportedVehicle.sqf | 8 +++++--- addons/advancedtowing/functions/fnc_pickupTowRopes.sqf | 2 +- .../advancedtowing/functions/fnc_pickupTowRopesAction.sqf | 3 +-- .../functions/fnc_putAwayTowRopesAction.sqf | 1 - addons/advancedtowing/functions/fnc_simulateTowing.sqf | 2 +- .../advancedtowing/functions/fnc_simulateTowingSpeed.sqf | 1 - addons/advancedtowing/functions/fnc_takeTowRopes.sqf | 3 --- .../advancedtowing/functions/fnc_takeTowRopesAction.sqf | 5 +---- 17 files changed, 25 insertions(+), 30 deletions(-) diff --git a/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf b/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf index 62086f475..2d758f0f2 100644 --- a/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf +++ b/addons/advancedtowing/functions/fnc_addPlayerTowActions.sqf @@ -15,7 +15,7 @@ * Public: No */ -player addAction ["Deploy Tow Ropes", { //ToDo Localize +player addAction ["Take Tow Ropes", { //ToDo Localize call FUNC(takeTowRopesAction); }, nil, 0, false, true, "", QUOTE([ARR_2(FUNC(takeTowRopesActionCheck),_this)] call CBA_fnc_directCall)]; diff --git a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf index 5c7f37091..9cff85592 100644 --- a/addons/advancedtowing/functions/fnc_attachTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_attachTowRopes.sqf @@ -22,15 +22,15 @@ private _isRearCargoHitch = false; if(!isNull _vehicle) then { if(local _vehicle) then { - private ["_cargoHitch","_objDistance","_ropeLength"]; + private ["_cargoHitch", "_objDistance", "_ropeLength"]; private _towRopes = _vehicle getVariable [QGVAR(Ropes), []]; if(count _towRopes == 1) then { - private _cargoHitchPoints = [_cargo] call FUNC(getHitchPoints); private _distanceToFrontHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 0)); private _distanceToRearHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 1)); + if( _distanceToFrontHitch < _distanceToRearHitch ) then { _cargoHitch = _cargoHitchPoints select 0; _isRearCargoHitch = false; @@ -39,12 +39,13 @@ if(!isNull _vehicle) then { _isRearCargoHitch = true; }; - _cargoHitch = ([_cargo] call FUNC(getHitchPoints)) select 0; private _vehicleHitch = ([_vehicle] call FUNC(getHitchPoints)) select 1; + _ropeLength = (ropeLength (_towRopes select 0)); _objDistance = ((_vehicle modelToWorld _vehicleHitch) distance (_cargo modelToWorld _cargoHitch)); + if( _objDistance > _ropeLength ) then { [["The tow ropes are too short. Move vehicle closer.", false], QFUNC(customHint), _player] call FUNC(customRemoteExec); //ToDo Localize } else { diff --git a/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf index 4550f4d14..6e1ddc027 100644 --- a/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf +++ b/addons/advancedtowing/functions/fnc_attachTowRopesAction.sqf @@ -15,7 +15,7 @@ * Public: No */ -private _cargo = cursorTarget; +private _cargo = cursorTarget; private _vehicle = player getVariable [QGVAR(Ropes_Vehicle), objNull]; if([_vehicle, _cargo] call FUNC(canAttachTowRopes)) then { diff --git a/addons/advancedtowing/functions/fnc_canPutAwayTowRopes.sqf b/addons/advancedtowing/functions/fnc_canPutAwayTowRopes.sqf index 5ec726cd0..6c90870b0 100644 --- a/addons/advancedtowing/functions/fnc_canPutAwayTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_canPutAwayTowRopes.sqf @@ -18,7 +18,7 @@ params ["_vehicle"]; if([_vehicle] call FUNC(isSupportedVehicle)) then { - private _existingTowRopes = _vehicle getVariable [QGVAR(Ropes),[]]; + private _existingTowRopes = _vehicle getVariable [QGVAR(Ropes), []]; isNull objectParent player && player distance _vehicle < 10 && (count _existingTowRopes) > 0; } else { false; diff --git a/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf index d8c5edab9..0fd08770d 100644 --- a/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf +++ b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderModel.sqf @@ -17,6 +17,6 @@ params ["_object", "_modelOffset", "_canFloat"]; -private _return = [_object, (_object modelToWorldVisual _modelOffset), _canFloat] call FUNC(findSurfaceASLUnderPosition); +private _returnSurfaceASL = [_object, (_object modelToWorldVisual _modelOffset), _canFloat] call FUNC(findSurfaceASLUnderPosition); -_return +_returnSurfaceASL diff --git a/addons/advancedtowing/functions/fnc_findSurfaceASLUnderPosition.sqf b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderPosition.sqf index e3ae43194..e210ce14f 100644 --- a/addons/advancedtowing/functions/fnc_findSurfaceASLUnderPosition.sqf +++ b/addons/advancedtowing/functions/fnc_findSurfaceASLUnderPosition.sqf @@ -40,7 +40,7 @@ private _returnSurfaceASL = AGLToASL _positionAGL; } forEach _surfaces; if(_canFloat && (_returnSurfaceASL select 2) < 0) then { - _returnSurfaceASL set [2,0]; + _returnSurfaceASL set [2, 0]; }; _returnSurfaceASL diff --git a/addons/advancedtowing/functions/fnc_getCornerPoints.sqf b/addons/advancedtowing/functions/fnc_getCornerPoints.sqf index 2f415d5d0..28ecc40f3 100644 --- a/addons/advancedtowing/functions/fnc_getCornerPoints.sqf +++ b/addons/advancedtowing/functions/fnc_getCornerPoints.sqf @@ -55,4 +55,4 @@ if(missionNamespace getVariable [QGVAR(Debug_Enabled), false]) then { sa_tow_debug_arrow_4 setPosASL AGLToASL (_vehicle modelToWorldVisual _frontCorner2); }; -[_rearCorner,_rearCorner2,_frontCorner,_frontCorner2]; +[_rearCorner, _rearCorner2, _frontCorner, _frontCorner2] diff --git a/addons/advancedtowing/functions/fnc_getHitchPoints.sqf b/addons/advancedtowing/functions/fnc_getHitchPoints.sqf index 4afb3ec13..920b70a52 100644 --- a/addons/advancedtowing/functions/fnc_getHitchPoints.sqf +++ b/addons/advancedtowing/functions/fnc_getHitchPoints.sqf @@ -18,13 +18,13 @@ params ["_vehicle"]; private _cornerPoints = [_vehicle] call FUNC(getCornerPoints); + private _rearCorner = _cornerPoints select 0; private _rearCorner2 = _cornerPoints select 1; private _frontCorner = _cornerPoints select 2; private _frontCorner2 = _cornerPoints select 3; + private _rearHitchPoint = ((_rearCorner vectorDiff _rearCorner2) vectorMultiply 0.5) vectorAdd _rearCorner2; private _frontHitchPoint = ((_frontCorner vectorDiff _frontCorner2) vectorMultiply 0.5) vectorAdd _frontCorner2; -//_sideLeftPoint = ((_frontCorner vectorDiff _rearCorner) vectorMultiply 0.5) vectorAdd _frontCorner; -//_sideRightPoint = ((_frontCorner2 vectorDiff _rearCorner2) vectorMultiply 0.5) vectorAdd _frontCorner2; -[_frontHitchPoint,_rearHitchPoint]; +[_frontHitchPoint, _rearHitchPoint] diff --git a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf index 009c47f6b..f3b80cde4 100644 --- a/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf +++ b/addons/advancedtowing/functions/fnc_isSupportedCargo.sqf @@ -32,4 +32,5 @@ if(!isNull _vehicle && !isNull _cargo) then { }; } forEach (missionNamespace getVariable [QGVAR(Rules_Override), GVAR(Tow_Rules)]); }; -_canTow; + +_canTow diff --git a/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf b/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf index a9cbf85ca..40e19e11a 100644 --- a/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf +++ b/addons/advancedtowing/functions/fnc_isSupportedVehicle.sqf @@ -15,9 +15,10 @@ * Public: No */ -params ["_vehicle", "_isSupported"]; +params ["_vehicle"]; + +private _isSupported = false; -_isSupported = false; if(!isNull _vehicle) then { { if(_vehicle isKindOf _x) then { @@ -25,4 +26,5 @@ if(!isNull _vehicle) then { }; } forEach (missionNamespace getVariable [QGVAR(Supported_Vehicles_Override), GVAR(Supported_Vehicles)]); }; -_isSupported; + +_isSupported diff --git a/addons/advancedtowing/functions/fnc_pickupTowRopes.sqf b/addons/advancedtowing/functions/fnc_pickupTowRopes.sqf index 6c543ef01..ac0102514 100644 --- a/addons/advancedtowing/functions/fnc_pickupTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_pickupTowRopes.sqf @@ -40,5 +40,5 @@ if(local _vehicle) then { _player setVariable [QGVAR(Ropes_Vehicle), _vehicle, true]; _player setVariable [QGVAR(Ropes_Pick_Up_Helper), _helper, true]; } else { - [_this, QFUNC(pickupTowRopes), _vehicle, true] call SA_RemoteExec; + [_this, QFUNC(pickupTowRopes), _vehicle, true] call FUNC(customRemoteExec); }; diff --git a/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf index d39a01410..b3982cf80 100644 --- a/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf +++ b/addons/advancedtowing/functions/fnc_pickupTowRopesAction.sqf @@ -22,7 +22,7 @@ if([] call FUNC(canPickupTowRopes)) then { private _vehicle = _nearbyTowVehicles select 0; private _canPickupTowRopes = true; - if!(missionNamespace getVariable [QGVAR(Locked_Vehicles_Enabled),false]) then { + if!(missionNamespace getVariable [QGVAR(Locked_Vehicles_Enabled), false]) then { if( locked _vehicle > 1 ) then { ["Cannot pick up tow ropes from locked vehicle", false] call FUNC(customHint); //ToDo Localize _canPickupTowRopes = false; @@ -32,5 +32,4 @@ if([] call FUNC(canPickupTowRopes)) then { if(_canPickupTowRopes) then { [_nearbyTowVehicles select 0, player] call FUNC(pickupTowRopes); }; - }; diff --git a/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf index d9391ebcd..d3ce6f811 100644 --- a/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf +++ b/addons/advancedtowing/functions/fnc_putAwayTowRopesAction.sqf @@ -31,5 +31,4 @@ if([_vehicle] call FUNC(canPutAwayTowRopes)) then { if(_canPutAwayTowRopes) then { [_vehicle, player] call FUNC(putAwayTowRopes); }; - }; diff --git a/addons/advancedtowing/functions/fnc_simulateTowing.sqf b/addons/advancedtowing/functions/fnc_simulateTowing.sqf index a49aa7650..363a27a22 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowing.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowing.sqf @@ -91,7 +91,7 @@ while {!_doExit} do { _lastCargoVectorDir = _newCargoDir; _newCargoPosition = _newCargoHitchPosition vectorAdd (_newCargoDir vectorMultiply -(vectorMagnitude (_cargoHitchModelPos))); - [_cargo, _newCargoPosition, _cargoCanFloat] call FUNC(findSurfaceASLUnderPosition); + _newCargoPosition = [_cargo, _newCargoPosition, _cargoCanFloat] call FUNC(findSurfaceASLUnderPosition); // Calculate surface normal (up) (more realistic than surfaceNormal function) private _cargoCorner1ASL = [_cargo, _corner1, _cargoCanFloat] call FUNC(findSurfaceASLUnderModel); diff --git a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf index 66a878ed9..3c8b4c786 100644 --- a/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf +++ b/addons/advancedtowing/functions/fnc_simulateTowingSpeed.sqf @@ -73,5 +73,4 @@ while {_runSimulation} do { }; sleep 0.1; - }; diff --git a/addons/advancedtowing/functions/fnc_takeTowRopes.sqf b/addons/advancedtowing/functions/fnc_takeTowRopes.sqf index bea541d61..e9992cc0c 100644 --- a/addons/advancedtowing/functions/fnc_takeTowRopes.sqf +++ b/addons/advancedtowing/functions/fnc_takeTowRopes.sqf @@ -18,9 +18,6 @@ params ["_vehicle","_player"]; if(local _vehicle) then { - - INFO_1("Take Tow Ropes Called %1",_this); - private _existingTowRopes = _vehicle getVariable [QGVAR(Ropes), []]; if(count _existingTowRopes == 0) then { diff --git a/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf b/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf index 6dab36292..9905cb9aa 100644 --- a/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf +++ b/addons/advancedtowing/functions/fnc_takeTowRopesAction.sqf @@ -22,9 +22,7 @@ if([_vehicle] call FUNC(canTakeTowRopes)) then { private _canTakeTowRopes = true; - if (missionNamespace getVariable [QGVAR(Locked_Vehicles_Enabled), false]) then { - // Locked vehicles are enabled, so do nothing special - } else { + if (!missionNamespace getVariable [QGVAR(Locked_Vehicles_Enabled), false]) then { if (locked _vehicle > 1) then { ["Cannot take tow ropes from locked vehicle", false] call FUNC(customHint); //ToDo Localize _canTakeTowRopes = false; @@ -34,5 +32,4 @@ if([_vehicle] call FUNC(canTakeTowRopes)) then { if(_canTakeTowRopes) then { [_vehicle, player] call FUNC(takeTowRopes); }; - };