Advertisement
Guest User

Untitled

a guest
May 25th, 2018
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 30.66 KB | None | 0 0
  1. #define SA_Find_Surface_ASL_Under_Position(_object,_positionAGL,_returnSurfaceASL,_canFloat) \
  2. _objectASL = AGLToASL (_object modelToWorldVisual (getCenterOfMass _object)); \
  3. _surfaceIntersectStartASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) + 1]; \
  4. _surfaceIntersectEndASL = [_positionAGL select 0, _positionAGL select 1, (_objectASL select 2) - 5]; \
  5. _surfaces = lineIntersectsSurfaces [_surfaceIntersectStartASL, _surfaceIntersectEndASL, _object, objNull, true, 5]; \
  6. _returnSurfaceASL = AGLToASL _positionAGL; \
  7. { \
  8. scopeName "surfaceLoop"; \
  9. if( isNull (_x select 2) ) then { \
  10. _returnSurfaceASL = _x select 0; \
  11. breakOut "surfaceLoop"; \
  12. } else { \
  13. if!((_x select 2) isKindOf "RopeSegment") then { \
  14. _objectFileName = str (_x select 2); \
  15. if((_objectFileName find " t_") == -1 && (_objectFileName find " b_") == -1) then { \
  16. _returnSurfaceASL = _x select 0; \
  17. breakOut "surfaceLoop"; \
  18. }; \
  19. }; \
  20. }; \
  21. } forEach _surfaces; \
  22. if(_canFloat && (_returnSurfaceASL select 2) < 0) then { \
  23. _returnSurfaceASL set [2,0]; \
  24. }; \
  25.  
  26. #define SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceASL,_canFloat) \
  27. SA_Find_Surface_ASL_Under_Position(_object, (_object modelToWorldVisual _modelOffset), _returnSurfaceASL,_canFloat);
  28.  
  29. #define SA_Find_Surface_AGL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat) \
  30. SA_Find_Surface_ASL_Under_Model(_object,_modelOffset,_returnSurfaceAGL,_canFloat); \
  31. _returnSurfaceAGL = ASLtoAGL _returnSurfaceAGL;
  32.  
  33. #define SA_Get_Cargo(_vehicle,_cargo) \
  34. if( count (ropeAttachedObjects _vehicle) == 0 ) then { \
  35. _cargo = objNull; \
  36. } else { \
  37. _cargo = ((ropeAttachedObjects _vehicle) select 0) getVariable ["SA_Cargo",objNull]; \
  38. };
  39.  
  40. SA_Advanced_Towing_Install = {
  41.  
  42. // Prevent advanced towing from installing twice
  43. if(!isNil "SA_TOW_INIT") exitWith {};
  44. SA_TOW_INIT = true;
  45.  
  46. diag_log "RJ: Guincho Avançado - Inicializando...";
  47.  
  48. SA_Simulate_Towing_Speed = {
  49.  
  50. params ["_vehicle"];
  51.  
  52. private ["_runSimulation","_currentCargo","_maxVehicleSpeed","_maxTowedVehicles","_vehicleMass"];
  53.  
  54. _maxVehicleSpeed = getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "maxSpeed");
  55. _vehicleMass = 1000 max (getMass _vehicle);
  56. _maxTowedCargo = missionNamespace getVariable ["SA_MAX_TOWED_CARGO",2];
  57. _runSimulation = true;
  58.  
  59. private ["_currentVehicle","_totalCargoMass","_totalCargoCount","_findNextCargo","_towRopes","_ropeLength"];
  60. private ["_ends","_endsDistance","_currentMaxSpeed","_newMaxSpeed"];
  61.  
  62. while {_runSimulation} do {
  63.  
  64. // Calculate total mass and count of cargo being towed (only takes into account
  65. // cargo that's actively being towed (e.g. there's no slack in the rope)
  66.  
  67. _currentVehicle = _vehicle;
  68. _totalCargoMass = 0;
  69. _totalCargoCount = 0;
  70. _findNextCargo = true;
  71. while {_findNextCargo} do {
  72. _findNextCargo = false;
  73. SA_Get_Cargo(_currentVehicle,_currentCargo);
  74. if(!isNull _currentCargo) then {
  75. _towRopes = _currentVehicle getVariable ["SA_Tow_Ropes",[]];
  76. if(count _towRopes > 0) then {
  77. _ropeLength = ropeLength (_towRopes select 0);
  78. _ends = ropeEndPosition (_towRopes select 0);
  79. _endsDistance = (_ends select 0) distance (_ends select 1);
  80. if( _endsDistance >= _ropeLength - 2 ) then {
  81. _totalCargoMass = _totalCargoMass + (1000 max (getMass _currentCargo));
  82. _totalCargoCount = _totalCargoCount + 1;
  83. _currentVehicle = _currentCargo;
  84. _findNextCargo = true;
  85. };
  86. };
  87. };
  88. };
  89.  
  90. _newMaxSpeed = _maxVehicleSpeed / (1 max ((_totalCargoMass / _vehicleMass) * 2));
  91. _newMaxSpeed = (_maxVehicleSpeed * 0.75) min _newMaxSpeed;
  92.  
  93. // Prevent vehicle from moving if trying to move more cargo than pre-defined max
  94. if(_totalCargoCount > _maxTowedCargo) then {
  95. _newMaxSpeed = 0;
  96. };
  97.  
  98. _currentMaxSpeed = _vehicle getVariable ["SA_Max_Tow_Speed",_maxVehicleSpeed];
  99.  
  100. if(_currentMaxSpeed != _newMaxSpeed) then {
  101. _vehicle setVariable ["SA_Max_Tow_Speed",_newMaxSpeed];
  102. };
  103.  
  104. sleep 0.1;
  105.  
  106. };
  107. };
  108.  
  109. SA_Simulate_Towing = {
  110.  
  111. params ["_vehicle","_vehicleHitchModelPos","_cargo","_cargoHitchModelPos","_ropeLength"];
  112.  
  113. private ["_lastCargoHitchPosition","_lastCargoVectorDir","_cargoLength","_maxDistanceToCargo","_lastMovedCargoPosition","_cargoHitchPoints"];
  114. private ["_vehicleHitchPosition","_cargoHitchPosition","_newCargoHitchPosition","_cargoVector","_movedCargoVector","_attachedObjects","_currentCargo"];
  115. private ["_newCargoDir","_lastCargoVectorDir","_newCargoPosition","_doExit","_cargoPosition","_vehiclePosition","_maxVehicleSpeed","_vehicleMass","_cargoMass","_cargoCanFloat"];
  116. private ["_cargoCorner1AGL","_cargoCorner1ASL","_cargoCorner2AGL","_cargoCorner2ASL","_cargoCorner3AGL","_cargoCorner3ASL","_cargoCorner4AGL","_cargoCorner4ASL","_surfaceNormal1","_surfaceNormal2","_surfaceNormal"];
  117. private ["_cargoCenterASL","_surfaceHeight","_surfaceHeight2","_maxSurfaceHeight"];
  118.  
  119. _maxVehicleSpeed = getNumber (configFile >> "CfgVehicles" >> typeOf _vehicle >> "maxSpeed");
  120. _cargoCanFloat = if( getNumber (configFile >> "CfgVehicles" >> typeOf _cargo >> "canFloat") == 1 ) then { true } else { false };
  121.  
  122. private ["_cargoCenterOfMassAGL","_cargoModelCenterGroundPosition"];
  123. SA_Find_Surface_AGL_Under_Model(_cargo,getCenterOfMass _cargo,_cargoCenterOfMassAGL,_cargoCanFloat);
  124. _cargoModelCenterGroundPosition = _cargo worldToModelVisual _cargoCenterOfMassAGL;
  125. _cargoModelCenterGroundPosition set [0,0];
  126. _cargoModelCenterGroundPosition set [1,0];
  127. _cargoModelCenterGroundPosition set [2, (_cargoModelCenterGroundPosition select 2) - 0.05]; // Adjust height so that it doesn't ride directly on ground
  128.  
  129. // Calculate cargo model corner points
  130. private ["_cargoCornerPoints"];
  131. _cargoCornerPoints = [_cargo] call SA_Get_Corner_Points;
  132. _corner1 = _cargoCornerPoints select 0;
  133. _corner2 = _cargoCornerPoints select 1;
  134. _corner3 = _cargoCornerPoints select 2;
  135. _corner4 = _cargoCornerPoints select 3;
  136.  
  137.  
  138. // Try to set cargo owner if the towing client doesn't own the cargo
  139. if(local _vehicle && !local _cargo) then {
  140. [[_cargo, clientOwner],"SA_Set_Owner"] call SA_RemoteExecServer;
  141. };
  142.  
  143. _vehicleHitchModelPos set [2,0];
  144. _cargoHitchModelPos set [2,0];
  145.  
  146. _lastCargoHitchPosition = _cargo modelToWorld _cargoHitchModelPos;
  147. _lastCargoVectorDir = vectorDir _cargo;
  148. _lastMovedCargoPosition = getPos _cargo;
  149.  
  150. _cargoHitchPoints = [_cargo] call SA_Get_Hitch_Points;
  151. _cargoLength = (_cargoHitchPoints select 0) distance (_cargoHitchPoints select 1);
  152.  
  153. _vehicleMass = 1 max (getMass _vehicle);
  154. _cargoMass = getMass _cargo;
  155. if(_cargoMass == 0) then {
  156. _cargoMass = _vehicleMass;
  157. };
  158.  
  159. _maxDistanceToCargo = _ropeLength;
  160.  
  161. _doExit = false;
  162.  
  163. // Start vehicle speed simulation
  164. [_vehicle] spawn SA_Simulate_Towing_Speed;
  165.  
  166. while {!_doExit} do {
  167.  
  168. _vehicleHitchPosition = _vehicle modelToWorld _vehicleHitchModelPos;
  169. _vehicleHitchPosition set [2,0];
  170. _cargoHitchPosition = _lastCargoHitchPosition;
  171. _cargoHitchPosition set [2,0];
  172.  
  173. _cargoPosition = getPos _cargo;
  174. _vehiclePosition = getPos _vehicle;
  175.  
  176. if(_vehicleHitchPosition distance _cargoHitchPosition > _maxDistanceToCargo) then {
  177.  
  178. // Calculated simulated towing position + direction
  179. _newCargoHitchPosition = _vehicleHitchPosition vectorAdd ((_vehicleHitchPosition vectorFromTo _cargoHitchPosition) vectorMultiply _ropeLength);
  180. _cargoVector = _lastCargoVectorDir vectorMultiply _cargoLength;
  181. _movedCargoVector = _newCargoHitchPosition vectorDiff _lastCargoHitchPosition;
  182. _newCargoDir = vectorNormalized (_cargoVector vectorAdd _movedCargoVector);
  183. //if(_isRearCargoHitch) then {
  184. // _newCargoDir = _newCargoDir vectorMultiply -1;
  185. //};
  186. _lastCargoVectorDir = _newCargoDir;
  187. _newCargoPosition = _newCargoHitchPosition vectorAdd (_newCargoDir vectorMultiply -(vectorMagnitude (_cargoHitchModelPos)));
  188.  
  189. SA_Find_Surface_ASL_Under_Position(_cargo,_newCargoPosition,_newCargoPosition,_cargoCanFloat);
  190.  
  191. // Calculate surface normal (up) (more realistic than surfaceNormal function)
  192. SA_Find_Surface_ASL_Under_Model(_cargo,_corner1,_cargoCorner1ASL,_cargoCanFloat);
  193. SA_Find_Surface_ASL_Under_Model(_cargo,_corner2,_cargoCorner2ASL,_cargoCanFloat);
  194. SA_Find_Surface_ASL_Under_Model(_cargo,_corner3,_cargoCorner3ASL,_cargoCanFloat);
  195. SA_Find_Surface_ASL_Under_Model(_cargo,_corner4,_cargoCorner4ASL,_cargoCanFloat);
  196. _surfaceNormal1 = (_cargoCorner1ASL vectorFromTo _cargoCorner3ASL) vectorCrossProduct (_cargoCorner1ASL vectorFromTo _cargoCorner2ASL);
  197. _surfaceNormal2 = (_cargoCorner4ASL vectorFromTo _cargoCorner2ASL) vectorCrossProduct (_cargoCorner4ASL vectorFromTo _cargoCorner3ASL);
  198. _surfaceNormal = _surfaceNormal1 vectorAdd _surfaceNormal2;
  199.  
  200. if(missionNamespace getVariable ["SA_TOW_DEBUG_ENABLED", false]) then {
  201. if(isNil "sa_tow_debug_arrow_1") then {
  202. sa_tow_debug_arrow_1 = "Sign_Arrow_F" createVehicleLocal [0,0,0];
  203. sa_tow_debug_arrow_2 = "Sign_Arrow_F" createVehicleLocal [0,0,0];
  204. sa_tow_debug_arrow_3 = "Sign_Arrow_F" createVehicleLocal [0,0,0];
  205. sa_tow_debug_arrow_4 = "Sign_Arrow_F" createVehicleLocal [0,0,0];
  206. };
  207. sa_tow_debug_arrow_1 setPosASL _cargoCorner1ASL;
  208. sa_tow_debug_arrow_1 setVectorUp _surfaceNormal;
  209. sa_tow_debug_arrow_2 setPosASL _cargoCorner2ASL;
  210. sa_tow_debug_arrow_2 setVectorUp _surfaceNormal;
  211. sa_tow_debug_arrow_3 setPosASL _cargoCorner3ASL;
  212. sa_tow_debug_arrow_3 setVectorUp _surfaceNormal;
  213. sa_tow_debug_arrow_4 setPosASL _cargoCorner4ASL;
  214. sa_tow_debug_arrow_4 setVectorUp _surfaceNormal;
  215. };
  216.  
  217. // Calculate adjusted surface height based on surface normal (prevents vehicle from clipping into ground)
  218. _cargoCenterASL = AGLtoASL (_cargo modelToWorldVisual [0,0,0]);
  219. _cargoCenterASL set [2,0];
  220. _surfaceHeight = ((_cargoCorner1ASL vectorAdd ( _cargoCenterASL vectorMultiply -1)) vectorDotProduct _surfaceNormal1) / ([0,0,1] vectorDotProduct _surfaceNormal1);
  221. _surfaceHeight2 = ((_cargoCorner1ASL vectorAdd ( _cargoCenterASL vectorMultiply -1)) vectorDotProduct _surfaceNormal2) / ([0,0,1] vectorDotProduct _surfaceNormal2);
  222. _maxSurfaceHeight = (_newCargoPosition select 2) max _surfaceHeight max _surfaceHeight2;
  223. _newCargoPosition set [2, _maxSurfaceHeight ];
  224.  
  225. _newCargoPosition = _newCargoPosition vectorAdd ( _cargoModelCenterGroundPosition vectorMultiply -1 );
  226.  
  227. _cargo setVectorDir _newCargoDir;
  228. _cargo setVectorUp _surfaceNormal;
  229. _cargo setPosWorld _newCargoPosition;
  230.  
  231. _lastCargoHitchPosition = _newCargoHitchPosition;
  232. _maxDistanceToCargo = _vehicleHitchPosition distance _newCargoHitchPosition;
  233. _lastMovedCargoPosition = _cargoPosition;
  234.  
  235. _massAdjustedMaxSpeed = _vehicle getVariable ["SA_Max_Tow_Speed",_maxVehicleSpeed];
  236. if(speed _vehicle > (_massAdjustedMaxSpeed)+0.1) then {
  237. _vehicle setVelocity ((vectorNormalized (velocity _vehicle)) vectorMultiply (_massAdjustedMaxSpeed/3.6));
  238. };
  239.  
  240. } else {
  241.  
  242. if(_lastMovedCargoPosition distance _cargoPosition > 2) then {
  243. _lastCargoHitchPosition = _cargo modelToWorld _cargoHitchModelPos;
  244. _lastCargoVectorDir = vectorDir _cargo;
  245. };
  246.  
  247. };
  248.  
  249. // If vehicle isn't local to the client, switch client running towing simulation
  250. if(!local _vehicle) then {
  251. [_this,"SA_Simulate_Towing",_vehicle] call SA_RemoteExec;
  252. _doExit = true;
  253. };
  254.  
  255. // If the vehicle isn't towing anything, stop the towing simulation
  256. SA_Get_Cargo(_vehicle,_currentCargo);
  257. if(isNull _currentCargo) then {
  258. _doExit = true;
  259. };
  260.  
  261. sleep 0.01;
  262.  
  263. };
  264. };
  265.  
  266. SA_Get_Corner_Points = {
  267. params ["_vehicle"];
  268. private ["_centerOfMass","_bbr","_p1","_p2","_rearCorner","_rearCorner2","_frontCorner","_frontCorner2"];
  269. private ["_maxWidth","_widthOffset","_maxLength","_lengthOffset","_widthFactor","_lengthFactor"];
  270.  
  271. // Correct width and length factor for air
  272. _widthFactor = 0.75;
  273. _lengthFactor = 0.75;
  274. if(_vehicle isKindOf "Air") then {
  275. _widthFactor = 0.3;
  276. };
  277. if(_vehicle isKindOf "Helicopter") then {
  278. _widthFactor = 0.2;
  279. _lengthFactor = 0.45;
  280. };
  281.  
  282. _centerOfMass = getCenterOfMass _vehicle;
  283. _bbr = boundingBoxReal _vehicle;
  284. _p1 = _bbr select 0;
  285. _p2 = _bbr select 1;
  286. _maxWidth = abs ((_p2 select 0) - (_p1 select 0));
  287. _widthOffset = ((_maxWidth / 2) - abs ( _centerOfMass select 0 )) * _widthFactor;
  288. _maxLength = abs ((_p2 select 1) - (_p1 select 1));
  289. _lengthOffset = ((_maxLength / 2) - abs (_centerOfMass select 1 )) * _lengthFactor;
  290. _rearCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) - _lengthOffset, _centerOfMass select 2];
  291. _rearCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) - _lengthOffset, _centerOfMass select 2];
  292. _frontCorner = [(_centerOfMass select 0) + _widthOffset, (_centerOfMass select 1) + _lengthOffset, _centerOfMass select 2];
  293. _frontCorner2 = [(_centerOfMass select 0) - _widthOffset, (_centerOfMass select 1) + _lengthOffset, _centerOfMass select 2];
  294.  
  295. if(missionNamespace getVariable ["SA_TOW_DEBUG_ENABLED", false]) then {
  296. if(isNil "sa_tow_debug_arrow_1") then {
  297. sa_tow_debug_arrow_1 = "Sign_Arrow_F" createVehicleLocal [0,0,0];
  298. sa_tow_debug_arrow_2 = "Sign_Arrow_F" createVehicleLocal [0,0,0];
  299. sa_tow_debug_arrow_3 = "Sign_Arrow_F" createVehicleLocal [0,0,0];
  300. sa_tow_debug_arrow_4 = "Sign_Arrow_F" createVehicleLocal [0,0,0];
  301. };
  302. sa_tow_debug_arrow_1 setPosASL AGLtoASL (_vehicle modelToWorldVisual _rearCorner);
  303. sa_tow_debug_arrow_2 setPosASL AGLtoASL (_vehicle modelToWorldVisual _rearCorner2);
  304. sa_tow_debug_arrow_3 setPosASL AGLtoASL (_vehicle modelToWorldVisual _frontCorner);
  305. sa_tow_debug_arrow_4 setPosASL AGLtoASL (_vehicle modelToWorldVisual _frontCorner2);
  306. };
  307.  
  308. [_rearCorner,_rearCorner2,_frontCorner,_frontCorner2];
  309. };
  310.  
  311. SA_Get_Hitch_Points = {
  312. params ["_vehicle"];
  313. private ["_cornerPoints","_rearCorner","_rearCorner2","_frontCorner","_frontCorner2","_rearHitchPoint"];
  314. private ["_frontHitchPoint","_sideLeftPoint","_sideRightPoint"];
  315. _cornerPoints = [_vehicle] call SA_Get_Corner_Points;
  316. _rearCorner = _cornerPoints select 0;
  317. _rearCorner2 = _cornerPoints select 1;
  318. _frontCorner = _cornerPoints select 2;
  319. _frontCorner2 = _cornerPoints select 3;
  320. _rearHitchPoint = ((_rearCorner vectorDiff _rearCorner2) vectorMultiply 0.5) vectorAdd _rearCorner2;
  321. _frontHitchPoint = ((_frontCorner vectorDiff _frontCorner2) vectorMultiply 0.5) vectorAdd _frontCorner2;
  322. //_sideLeftPoint = ((_frontCorner vectorDiff _rearCorner) vectorMultiply 0.5) vectorAdd _frontCorner;
  323. //_sideRightPoint = ((_frontCorner2 vectorDiff _rearCorner2) vectorMultiply 0.5) vectorAdd _frontCorner2;
  324. [_frontHitchPoint,_rearHitchPoint];
  325. };
  326.  
  327. SA_Attach_Tow_Ropes = {
  328. params ["_cargo","_player"];
  329. _vehicle = _player getVariable ["SA_Tow_Ropes_Vehicle", objNull];
  330. if(!isNull _vehicle) then {
  331. if(local _vehicle) then {
  332. private ["_towRopes","_vehicleHitch","_cargoHitch","_objDistance","_ropeLength"];
  333. _towRopes = _vehicle getVariable ["SA_Tow_Ropes",[]];
  334. if(count _towRopes == 1) then {
  335.  
  336. /*
  337. private ["_cargoHitchPoints","_distanceToFrontHitch","_distanceToRearHitch","_isRearCargoHitch"];
  338. _cargoHitchPoints = [_cargo] call SA_Get_Hitch_Points;
  339. _distanceToFrontHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 0));
  340. _distanceToRearHitch = player distance (_cargo modelToWorld (_cargoHitchPoints select 1));
  341. if( _distanceToFrontHitch < _distanceToRearHitch ) then {
  342. _cargoHitch = _cargoHitchPoints select 0;
  343. _isRearCargoHitch = false;
  344. } else {
  345. _cargoHitch = _cargoHitchPoints select 1;
  346. _isRearCargoHitch = true;
  347. };
  348. */
  349.  
  350. _cargoHitch = ([_cargo] call SA_Get_Hitch_Points) select 0;
  351.  
  352. _vehicleHitch = ([_vehicle] call SA_Get_Hitch_Points) select 1;
  353. _ropeLength = (ropeLength (_towRopes select 0));
  354. _objDistance = ((_vehicle modelToWorld _vehicleHitch) distance (_cargo modelToWorld _cargoHitch));
  355. if( _objDistance > _ropeLength ) then {
  356. [["The tow ropes are too short. Move vehicle closer.", false],"SA_Hint",_player] call SA_RemoteExec;
  357. } else {
  358. [_vehicle,_player] call SA_Drop_Tow_Ropes;
  359. _helper = "Land_Can_V2_F" createVehicle position _cargo;
  360. _helper attachTo [_cargo, _cargoHitch];
  361. _helper setVariable ["SA_Cargo",_cargo,true];
  362. hideObject _helper;
  363. [[_helper],"SA_Hide_Object_Global"] call SA_RemoteExecServer;
  364. [_helper, [0,0,0], [0,0,-1]] ropeAttachTo (_towRopes select 0);
  365. [_vehicle,_vehicleHitch,_cargo,_cargoHitch,_ropeLength] spawn SA_Simulate_Towing;
  366. };
  367. };
  368. } else {
  369. [_this,"SA_Attach_Tow_Ropes",_vehicle,true] call SA_RemoteExec;
  370. };
  371. };
  372. };
  373.  
  374. SA_Take_Tow_Ropes = {
  375. params ["_vehicle","_player"];
  376. if(local _vehicle) then {
  377. diag_log format ["Take Tow Ropes Called %1", _this];
  378. private ["_existingTowRopes","_hitchPoint","_rope"];
  379. _existingTowRopes = _vehicle getVariable ["SA_Tow_Ropes",[]];
  380. if(count _existingTowRopes == 0) then {
  381. _hitchPoint = [_vehicle] call SA_Get_Hitch_Points select 1;
  382. _rope = ropeCreate [_vehicle, _hitchPoint, 10];
  383. _vehicle setVariable ["SA_Tow_Ropes",[_rope],true];
  384. _this call SA_Pickup_Tow_Ropes;
  385. };
  386. } else {
  387. [_this,"SA_Take_Tow_Ropes",_vehicle,true] call SA_RemoteExec;
  388. };
  389. };
  390.  
  391. SA_Pickup_Tow_Ropes = {
  392. params ["_vehicle","_player"];
  393. if(local _vehicle) then {
  394. private ["_attachedObj","_helper"];
  395. {
  396. _attachedObj = _x;
  397. {
  398. _attachedObj ropeDetach _x;
  399. } forEach (_vehicle getVariable ["SA_Tow_Ropes",[]]);
  400. deleteVehicle _attachedObj;
  401. } forEach ropeAttachedObjects _vehicle;
  402. _helper = "Land_Can_V2_F" createVehicle position _player;
  403. {
  404. [_helper, [0, 0, 0], [0,0,-1]] ropeAttachTo _x;
  405. _helper attachTo [_player, [-0.1, 0.1, 0.15], "Pelvis"];
  406. } forEach (_vehicle getVariable ["SA_Tow_Ropes",[]]);
  407. hideObject _helper;
  408. [[_helper],"SA_Hide_Object_Global"] call SA_RemoteExecServer;
  409. _player setVariable ["SA_Tow_Ropes_Vehicle", _vehicle,true];
  410. _player setVariable ["SA_Tow_Ropes_Pick_Up_Helper", _helper,true];
  411. } else {
  412. [_this,"SA_Pickup_Tow_Ropes",_vehicle,true] call SA_RemoteExec;
  413. };
  414. };
  415.  
  416. SA_Drop_Tow_Ropes = {
  417. params ["_vehicle","_player"];
  418. if(local _vehicle) then {
  419. private ["_helper"];
  420. _helper = (_player getVariable ["SA_Tow_Ropes_Pick_Up_Helper", objNull]);
  421. if(!isNull _helper) then {
  422. {
  423. _helper ropeDetach _x;
  424. } forEach (_vehicle getVariable ["SA_Tow_Ropes",[]]);
  425. detach _helper;
  426. deleteVehicle _helper;
  427. };
  428. _player setVariable ["SA_Tow_Ropes_Vehicle", nil,true];
  429. _player setVariable ["SA_Tow_Ropes_Pick_Up_Helper", nil,true];
  430. } else {
  431. [_this,"SA_Drop_Tow_Ropes",_vehicle,true] call SA_RemoteExec;
  432. };
  433. };
  434.  
  435. SA_Put_Away_Tow_Ropes = {
  436. params ["_vehicle","_player"];
  437. if(local _vehicle) then {
  438. private ["_existingTowRopes","_hitchPoint","_rope"];
  439. _existingTowRopes = _vehicle getVariable ["SA_Tow_Ropes",[]];
  440. if(count _existingTowRopes > 0) then {
  441. _this call SA_Pickup_Tow_Ropes;
  442. _this call SA_Drop_Tow_Ropes;
  443. {
  444. ropeDestroy _x;
  445. } forEach _existingTowRopes;
  446. _vehicle setVariable ["SA_Tow_Ropes",nil,true];
  447. };
  448. } else {
  449. [_this,"SA_Put_Away_Tow_Ropes",_vehicle,true] call SA_RemoteExec;
  450. };
  451. };
  452.  
  453. SA_Attach_Tow_Ropes_Action = {
  454. private ["_vehicle","_cargo","_canBeTowed"];
  455. _cargo = cursorTarget;
  456. _vehicle = player getVariable ["SA_Tow_Ropes_Vehicle", objNull];
  457. if([_vehicle,_cargo] call SA_Can_Attach_Tow_Ropes) then {
  458.  
  459. _canBeTowed = true;
  460.  
  461. if!(missionNamespace getVariable ["SA_TOW_LOCKED_VEHICLES_ENABLED",false]) then {
  462. if( locked _cargo > 1 ) then {
  463. ["Não é Possivel Guinchar Veiculos Fechados",false] call SA_Hint;
  464. _canBeTowed = false;
  465. };
  466. };
  467.  
  468. if!(missionNamespace getVariable ["SA_TOW_IN_EXILE_SAFEZONE_ENABLED",false]) then {
  469. if(!isNil "ExilePlayerInSafezone") then {
  470. if( ExilePlayerInSafezone ) then {
  471. ["Cannot attach tow ropes in safe zone",false] call SA_Hint;
  472. _canBeTowed = false;
  473. };
  474. };
  475. };
  476.  
  477. if(_canBeTowed) then {
  478. [_cargo,player] call SA_Attach_Tow_Ropes;
  479. };
  480.  
  481. };
  482. };
  483.  
  484. SA_Attach_Tow_Ropes_Action_Check = {
  485. private ["_vehicle","_cargo"];
  486. _vehicle = player getVariable ["SA_Tow_Ropes_Vehicle", objNull];
  487. _cargo = cursorTarget;
  488. [_vehicle,_cargo] call SA_Can_Attach_Tow_Ropes;
  489. };
  490.  
  491. SA_Can_Attach_Tow_Ropes = {
  492. params ["_vehicle","_cargo"];
  493. if(!isNull _vehicle && !isNull _cargo) then {
  494. [_vehicle,_cargo] call SA_Is_Supported_Cargo && vehicle player == player && player distance _cargo < 10 && _vehicle != _cargo;
  495. } else {
  496. false;
  497. };
  498. };
  499.  
  500. SA_Take_Tow_Ropes_Action = {
  501. private ["_vehicle","_canTakeTowRopes"];
  502. _vehicle = cursorTarget;
  503. if([_vehicle] call SA_Can_Take_Tow_Ropes) then {
  504.  
  505. _canTakeTowRopes = true;
  506.  
  507. if!(missionNamespace getVariable ["SA_TOW_LOCKED_VEHICLES_ENABLED",false]) then {
  508. if( locked _vehicle > 1 ) then {
  509. ["Cannot take tow ropes from locked vehicle",false] call SA_Hint;
  510. _canTakeTowRopes = false;
  511. };
  512. };
  513.  
  514. if!(missionNamespace getVariable ["SA_TOW_IN_EXILE_SAFEZONE_ENABLED",false]) then {
  515. if(!isNil "ExilePlayerInSafezone") then {
  516. if( ExilePlayerInSafezone ) then {
  517. ["Cannot take tow ropes in safe zone",false] call SA_Hint;
  518. _canTakeTowRopes = false;
  519. };
  520. };
  521. };
  522.  
  523. if(_canTakeTowRopes) then {
  524. [_vehicle,player] call SA_Take_Tow_Ropes;
  525. };
  526.  
  527. };
  528. };
  529.  
  530. SA_Take_Tow_Ropes_Action_Check = {
  531. [cursorTarget] call SA_Can_Take_Tow_Ropes;
  532. };
  533.  
  534. SA_Can_Take_Tow_Ropes = {
  535. params ["_vehicle"];
  536. if([_vehicle] call SA_Is_Supported_Vehicle) then {
  537. private ["_existingVehicle","_existingTowRopes"];
  538. _existingTowRopes = _vehicle getVariable ["SA_Tow_Ropes",[]];
  539. _existingVehicle = player getVariable ["SA_Tow_Ropes_Vehicle", objNull];
  540. vehicle player == player && player distance _vehicle < 10 && (count _existingTowRopes) == 0 && isNull _existingVehicle;
  541. } else {
  542. false;
  543. };
  544. };
  545.  
  546. SA_Put_Away_Tow_Ropes_Action = {
  547. private ["_vehicle","_canPutAwayTowRopes"];
  548. _vehicle = cursorTarget;
  549. if([_vehicle] call SA_Can_Put_Away_Tow_Ropes) then {
  550.  
  551. _canPutAwayTowRopes = true;
  552.  
  553. if!(missionNamespace getVariable ["SA_TOW_LOCKED_VEHICLES_ENABLED",false]) then {
  554. if( locked _vehicle > 1 ) then {
  555. ["Cannot put away tow ropes in locked vehicle",false] call SA_Hint;
  556. _canPutAwayTowRopes = false;
  557. };
  558. };
  559.  
  560. if!(missionNamespace getVariable ["SA_TOW_IN_EXILE_SAFEZONE_ENABLED",false]) then {
  561. if(!isNil "ExilePlayerInSafezone") then {
  562. if( ExilePlayerInSafezone ) then {
  563. ["Cannot put away tow ropes in safe zone",false] call SA_Hint;
  564. _canPutAwayTowRopes = false;
  565. };
  566. };
  567. };
  568.  
  569. if(_canPutAwayTowRopes) then {
  570. [_vehicle,player] call SA_Put_Away_Tow_Ropes;
  571. };
  572.  
  573. };
  574. };
  575.  
  576. SA_Put_Away_Tow_Ropes_Action_Check = {
  577. [cursorTarget] call SA_Can_Put_Away_Tow_Ropes;
  578. };
  579.  
  580. SA_Can_Put_Away_Tow_Ropes = {
  581. params ["_vehicle"];
  582. private ["_existingTowRopes"];
  583. if([_vehicle] call SA_Is_Supported_Vehicle) then {
  584. _existingTowRopes = _vehicle getVariable ["SA_Tow_Ropes",[]];
  585. vehicle player == player && player distance _vehicle < 10 && (count _existingTowRopes) > 0;
  586. } else {
  587. false;
  588. };
  589. };
  590.  
  591.  
  592. SA_Drop_Tow_Ropes_Action = {
  593. private ["_vehicle"];
  594. _vehicle = player getVariable ["SA_Tow_Ropes_Vehicle", objNull];
  595. if([] call SA_Can_Drop_Tow_Ropes) then {
  596. [_vehicle, player] call SA_Drop_Tow_Ropes;
  597. };
  598. };
  599.  
  600. SA_Drop_Tow_Ropes_Action_Check = {
  601. [] call SA_Can_Drop_Tow_Ropes;
  602. };
  603.  
  604. SA_Can_Drop_Tow_Ropes = {
  605. !isNull (player getVariable ["SA_Tow_Ropes_Vehicle", objNull]) && vehicle player == player;
  606. };
  607.  
  608.  
  609.  
  610. SA_Pickup_Tow_Ropes_Action = {
  611. private ["_nearbyTowVehicles","_canPickupTowRopes","_vehicle"];
  612. _nearbyTowVehicles = missionNamespace getVariable ["SA_Nearby_Tow_Vehicles",[]];
  613. if([] call SA_Can_Pickup_Tow_Ropes) then {
  614.  
  615. _vehicle = _nearbyTowVehicles select 0;
  616. _canPickupTowRopes = true;
  617.  
  618. if!(missionNamespace getVariable ["SA_TOW_LOCKED_VEHICLES_ENABLED",false]) then {
  619. if( locked _vehicle > 1 ) then {
  620. ["Cannot pick up tow ropes from locked vehicle",false] call SA_Hint;
  621. _canPickupTowRopes = false;
  622. };
  623. };
  624.  
  625. if!(missionNamespace getVariable ["SA_TOW_IN_EXILE_SAFEZONE_ENABLED",false]) then {
  626. if(!isNil "ExilePlayerInSafezone") then {
  627. if( ExilePlayerInSafezone ) then {
  628. ["Cannot pick up tow ropes in safe zone",false] call SA_Hint;
  629. _canPickupTowRopes = false;
  630. };
  631. };
  632. };
  633.  
  634. if(_canPickupTowRopes) then {
  635. [_nearbyTowVehicles select 0, player] call SA_Pickup_Tow_Ropes;
  636. };
  637.  
  638. };
  639. };
  640.  
  641. SA_Pickup_Tow_Ropes_Action_Check = {
  642. [] call SA_Can_Pickup_Tow_Ropes;
  643. };
  644.  
  645. SA_Can_Pickup_Tow_Ropes = {
  646. isNull (player getVariable ["SA_Tow_Ropes_Vehicle", objNull]) && count (missionNamespace getVariable ["SA_Nearby_Tow_Vehicles",[]]) > 0 && vehicle player == player;
  647. };
  648.  
  649. SA_TOW_SUPPORTED_VEHICLES = [
  650. "Tank", "Car", "Ship"
  651. ];
  652.  
  653. SA_Is_Supported_Vehicle = {
  654. params ["_vehicle","_isSupported"];
  655. _isSupported = false;
  656. if(not isNull _vehicle) then {
  657. {
  658. if(_vehicle isKindOf _x) then {
  659. _isSupported = true;
  660. };
  661. } forEach (missionNamespace getVariable ["SA_TOW_SUPPORTED_VEHICLES_OVERRIDE",SA_TOW_SUPPORTED_VEHICLES]);
  662. };
  663. _isSupported;
  664. };
  665.  
  666. SA_TOW_RULES = [
  667. ["Tank","CAN_TOW","Tank"],
  668. ["Tank","CAN_TOW","Car"],
  669. ["Tank","CAN_TOW","Ship"],
  670. ["Tank","CAN_TOW","Air"],
  671. ["Car","CAN_TOW","Tank"],
  672. ["Car","CAN_TOW","Car"],
  673. ["Car","CAN_TOW","Ship"],
  674. ["Car","CAN_TOW","Air"],
  675. ["Ship","CAN_TOW","Ship"]
  676. ];
  677.  
  678. SA_Is_Supported_Cargo = {
  679. params ["_vehicle","_cargo"];
  680. private ["_canTow"];
  681. _canTow = false;
  682. if(not isNull _vehicle && not isNull _cargo) then {
  683. {
  684. if(_vehicle isKindOf (_x select 0)) then {
  685. if(_cargo isKindOf (_x select 2)) then {
  686. if( (toUpper (_x select 1)) == "CAN_TOW" ) then {
  687. _canTow = true;
  688. } else {
  689. _canTow = false;
  690. };
  691. };
  692. };
  693. } forEach (missionNamespace getVariable ["SA_TOW_RULES_OVERRIDE",SA_TOW_RULES]);
  694. };
  695. _canTow;
  696. };
  697.  
  698. SA_Hint = {
  699. params ["_msg",["_isSuccess",true]];
  700. if(!isNil "ExileClient_gui_notification_event_addNotification") then {
  701. if(_isSuccess) then {
  702. ["Success", [_msg]] call ExileClient_gui_notification_event_addNotification;
  703. } else {
  704. ["Whoops", [_msg]] call ExileClient_gui_notification_event_addNotification;
  705. };
  706. } else {
  707. hint _msg;
  708. };
  709. };
  710.  
  711. SA_Hide_Object_Global = {
  712. params ["_obj"];
  713. if( _obj isKindOf "Land_Can_V2_F" ) then {
  714. hideObjectGlobal _obj;
  715. };
  716. };
  717.  
  718. SA_Set_Owner = {
  719. params ["_obj","_client"];
  720. _obj setOwner _client;
  721. };
  722.  
  723. SA_Add_Player_Tow_Actions = {
  724.  
  725. player addAction ["Implantar Cordas de Reboque", {
  726. [] call SA_Take_Tow_Ropes_Action;
  727. }, nil, 0, false, true, "", "call SA_Take_Tow_Ropes_Action_Check"];
  728.  
  729. player addAction ["Pegar Guincho", {
  730. [] call SA_Put_Away_Tow_Ropes_Action;
  731. }, nil, 0, false, true, "", "call SA_Put_Away_Tow_Ropes_Action_Check"];
  732.  
  733. player addAction ["Engatar Guincho", {
  734. [] call SA_Attach_Tow_Ropes_Action;
  735. }, nil, 0, false, true, "", "call SA_Attach_Tow_Ropes_Action_Check"];
  736.  
  737. player addAction ["Jogar Guincho", {
  738. [] call SA_Drop_Tow_Ropes_Action;
  739. }, nil, 0, false, true, "", "call SA_Drop_Tow_Ropes_Action_Check"];
  740.  
  741. player addAction ["Pegar Guincho Do Chao", {
  742. [] call SA_Pickup_Tow_Ropes_Action;
  743. }, nil, 0, false, true, "", "call SA_Pickup_Tow_Ropes_Action_Check"];
  744.  
  745. player addEventHandler ["Respawn", {
  746. player setVariable ["SA_Tow_Actions_Loaded",false];
  747. }];
  748.  
  749. };
  750.  
  751. SA_Find_Nearby_Tow_Vehicles = {
  752. private ["_nearVehicles","_nearVehiclesWithTowRopes","_vehicle","_ends","_end1","_end2"];
  753. _nearVehicles = [];
  754. {
  755. _nearVehicles append (position player nearObjects [_x, 30]);
  756. } forEach (missionNamespace getVariable ["SA_TOW_SUPPORTED_VEHICLES_OVERRIDE",SA_TOW_SUPPORTED_VEHICLES]);
  757. _nearVehiclesWithTowRopes = [];
  758. {
  759. _vehicle = _x;
  760. {
  761. _ends = ropeEndPosition _x;
  762. if(count _ends == 2) then {
  763. _end1 = _ends select 0;
  764. _end2 = _ends select 1;
  765. if(((position player) distance _end1) < 5 || ((position player) distance _end2) < 5 ) then {
  766. _nearVehiclesWithTowRopes pushBack _vehicle;
  767. }
  768. };
  769. } forEach (_vehicle getVariable ["SA_Tow_Ropes",[]]);
  770. } forEach _nearVehicles;
  771. _nearVehiclesWithTowRopes;
  772. };
  773.  
  774. if(!isDedicated) then {
  775. [] spawn {
  776. while {true} do {
  777. if(!isNull player && isPlayer player) then {
  778. if!( player getVariable ["SA_Tow_Actions_Loaded",false] ) then {
  779. [] call SA_Add_Player_Tow_Actions;
  780. player setVariable ["SA_Tow_Actions_Loaded",true];
  781. };
  782. };
  783. missionNamespace setVariable ["SA_Nearby_Tow_Vehicles", (call SA_Find_Nearby_Tow_Vehicles)];
  784. sleep 2;
  785. };
  786. };
  787. };
  788.  
  789. SA_RemoteExec = {
  790. params ["_params","_functionName","_target",["_isCall",false]];
  791. if(!isNil "ExileClient_system_network_send") then {
  792. ["AdvancedTowingRemoteExecClient",[_params,_functionName,_target,_isCall]] call ExileClient_system_network_send;
  793. } else {
  794. if(_isCall) then {
  795. _params remoteExecCall [_functionName, _target];
  796. } else {
  797. _params remoteExec [_functionName, _target];
  798. };
  799. };
  800. };
  801.  
  802. SA_RemoteExecServer = {
  803. params ["_params","_functionName",["_isCall",false]];
  804. if(!isNil "ExileClient_system_network_send") then {
  805. ["AdvancedTowingRemoteExecServer",[_params,_functionName,_isCall]] call ExileClient_system_network_send;
  806. } else {
  807. if(_isCall) then {
  808. _params remoteExecCall [_functionName, 2];
  809. } else {
  810. _params remoteExec [_functionName, 2];
  811. };
  812. };
  813. };
  814.  
  815. if(isServer) then {
  816.  
  817. // Adds support for exile network calls (Only used when running exile) //
  818.  
  819. SA_SUPPORTED_REMOTEEXECSERVER_FUNCTIONS = ["SA_Set_Owner","SA_Hide_Object_Global"];
  820.  
  821. ExileServer_AdvancedTowing_network_AdvancedTowingRemoteExecServer = {
  822. params ["_sessionId", "_messageParameters",["_isCall",false]];
  823. _messageParameters params ["_params","_functionName"];
  824. if(_functionName in SA_SUPPORTED_REMOTEEXECSERVER_FUNCTIONS) then {
  825. if(_isCall) then {
  826. _params call (missionNamespace getVariable [_functionName,{}]);
  827. } else {
  828. _params spawn (missionNamespace getVariable [_functionName,{}]);
  829. };
  830. };
  831. };
  832.  
  833. 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"];
  834.  
  835. ExileServer_AdvancedTowing_network_AdvancedTowingRemoteExecClient = {
  836. params ["_sessionId", "_messageParameters"];
  837. _messageParameters params ["_params","_functionName","_target",["_isCall",false]];
  838. if(_functionName in SA_SUPPORTED_REMOTEEXECCLIENT_FUNCTIONS) then {
  839. if(_isCall) then {
  840. _params remoteExecCall [_functionName, _target];
  841. } else {
  842. _params remoteExec [_functionName, _target];
  843. };
  844. };
  845. };
  846.  
  847. // Install Advanced Towing on all clients (plus JIP) //
  848.  
  849. publicVariable "SA_Advanced_Towing_Install";
  850. remoteExecCall ["SA_Advanced_Towing_Install", -2,true];
  851.  
  852. };
  853.  
  854. diag_log "RJ: Guincho Avançado - Carregado";
  855.  
  856. };
  857.  
  858. if(isServer) then {
  859. [] call SA_Advanced_Towing_Install;
  860. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement