Skip to content

Commit

Permalink
Towing - Fix some issues (acemod#9007)
Browse files Browse the repository at this point in the history
Co-authored-by: johnb432 <[email protected]>
Co-authored-by: LinkIsGrim <[email protected]>
  • Loading branch information
3 people authored Feb 5, 2024
1 parent a3aef6a commit b54992b
Show file tree
Hide file tree
Showing 16 changed files with 350 additions and 197 deletions.
101 changes: 39 additions & 62 deletions addons/towing/CfgVehicles.hpp
Original file line number Diff line number Diff line change
@@ -1,84 +1,61 @@
#define TOW_ACTION \
class ACE_Actions {\
class ACE_MainActions {\
class ADDON {\
displayName = CSTRING(displayName);\
distance = TOW_ACTION_DISTANCE;\
condition = QUOTE([ARR_1(_target)] call FUNC(isSuitableSimulation));\
statement = "";\
exceptions[] = { INTERACTION_EXCEPTIONS };\
showDisabled = 0;\
icon = "";\
class GVAR(startTow3) {\
displayName = CSTRING(start3);\
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope3')] call EFUNC(common,hasItem));\
statement = QUOTE([ARR_3(_player,_target,'ACE_rope3')] call FUNC(startTow));\
exceptions[] = { INTERACTION_EXCEPTIONS };\
};\
class GVAR(startTow6) {\
displayName = CSTRING(start6);\
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope6')] call EFUNC(common,hasItem));\
statement = QUOTE([ARR_3(_player,_target,'ACE_rope6')] call FUNC(startTow));\
exceptions[] = { INTERACTION_EXCEPTIONS };\
};\
class GVAR(startTow12) {\
displayName = CSTRING(start12);\
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope12')] call EFUNC(common,hasItem));\
statement = QUOTE([ARR_3(_player,_target,'ACE_rope12')] call FUNC(startTow));\
exceptions[] = { INTERACTION_EXCEPTIONS };\
};\
class GVAR(startTow15) {\
displayName = CSTRING(start15);\
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope15')] call EFUNC(common,hasItem));\
statement = QUOTE([ARR_3(_player,_target,'ACE_rope15')] call FUNC(startTow));\
exceptions[] = { INTERACTION_EXCEPTIONS };\
};\
class GVAR(startTow18) {\
displayName = CSTRING(start18);\
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope18')] call EFUNC(common,hasItem));\
statement = QUOTE([ARR_3(_player,_target,'ACE_rope18')] call FUNC(startTow));\
exceptions[] = { INTERACTION_EXCEPTIONS };\
};\
class GVAR(startTow27) {\
displayName = CSTRING(start27);\
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope27')] call EFUNC(common,hasItem));\
statement = QUOTE([ARR_3(_player,_target,'ACE_rope27')] call FUNC(startTow));\
exceptions[] = { INTERACTION_EXCEPTIONS };\
};\
class GVAR(startTow36) {\
displayName = CSTRING(start36);\
condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope36')] call EFUNC(common,hasItem));\
statement = QUOTE([ARR_3(_player,_target,'ACE_rope36')] call FUNC(startTow));\
#define CONCAT(a,b) a##b
#define TOW_ACTION(length) \
class GVAR(CONCAT(startTow,length)) {\
displayName = CSTRING(CONCAT(start,length));\
condition = QUOTE([ARR_2(_player,'CONCAT(ACE_rope,length)')] call DEFUNC(common,hasItem));\
statement = QUOTE([ARR_3(_player,_target,'CONCAT(ACE_rope,length)')] call DFUNC(startTow));\
exceptions[] = { INTERACTION_EXCEPTIONS };\
}
#define TOW_ACTIONS \
class ACE_Actions {\
class ACE_MainActions {\
class ADDON {\
displayName = CSTRING(displayName);\
distance = TOW_ACTION_DISTANCE;\
condition = QUOTE(alive _target && {_target call DFUNC(isSuitableSimulation)});\
exceptions[] = { INTERACTION_EXCEPTIONS };\
insertChildren = QUOTE(_target call DFUNC(getDetachActions));\
TOW_ACTION(3);\
TOW_ACTION(6);\
TOW_ACTION(12);\
TOW_ACTION(15);\
TOW_ACTION(18);\
TOW_ACTION(27);\
TOW_ACTION(36);\
};\
};\
};\
}
}

class CfgVehicles {
class LandVehicle;
class Car: LandVehicle {
TOW_ACTION;
TOW_ACTIONS;
};

class Tank: LandVehicle {
TOW_ACTION;
TOW_ACTIONS;
};

class Ship;
class Ship_F: Ship {
TOW_ACTIONS;
};

class ThingX;
class GVAR(hook): ThingX {
displayName = "hook"; // not publicly visible, no stringtable needed
class GVAR(helper): ThingX {
displayName = "helper"; // not publicly visible, no stringtable needed
scope = 1;
scopeCurator = 1;
model = "\a3\Structures_F_Orange\VR\Helpers\Sign_sphere10cm_Geometry_F.p3d";
model = "\A3\Weapons_f\empty";
destrType = "DestructNo";

};
class GVAR(hook): GVAR(helper) {
displayName = "hook";
class ACE_Actions {
class ACE_MainActions {
displayName = CSTRING(detach);
condition = "true";
statement = QUOTE(private _parent = _target getVariable [ARR_2(QQGVAR(parent),objNull)]; private _child = _target getVariable [ARR_2(QQGVAR(child),objNull)]; [ARR_3(_player,_parent,_child)] call FUNC(detach));
distance = 2;
statement = QUOTE([ARR_2(_player,_target)] call DFUNC(detachRope));
distance = TOW_ACTION_DISTANCE;
};
};
};
Expand Down
6 changes: 4 additions & 2 deletions addons/towing/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
PREP(addRopeToVehicle);
PREP(attachRopePFH);
PREP(canStartTow);
PREP(detach);
PREP(attachVehicles);
PREP(detachChild);
PREP(detachRope);
PREP(getDetachActions);
PREP(isSuitableSimulation);
PREP(onMouseButtonDown);
PREP(onMouseButtonUp);
Expand Down
38 changes: 32 additions & 6 deletions addons/towing/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -1,14 +1,40 @@
#include "script_component.hpp"
["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler;

["MouseButtonUp", LINKFUNC(onMouseButtonUp)] call CBA_fnc_addDisplayHandler;
GVAR(mouseLeft) = false;
GVAR(mouseRight) = false;
GVAR(blockFireEHID) = -1;

GVAR(cancel) = false;
GVAR(canAttach) = false;
[QGVAR(ropeAttachTo), {
params ["_child", "_relativeAttachPos", "_rope", "_helper"];
TRACE_4("ropeAttachTo",_child,_relativeAttachPos,_rope,_helper);
_helper ropeDetach _rope;
[_child, _relativeAttachPos] ropeAttachTo _rope;
deleteVehicle _helper;
}] call CBA_fnc_addEventHandler;

[QGVAR(attachVehicles), LINKFUNC(attachVehicles)] call CBA_fnc_addEventHandler;
[QGVAR(detachChild), LINKFUNC(detachChild)] call CBA_fnc_addEventHandler;

[QGVAR(setTowParent), {
params ["_parent", "_child"];
_child setTowParent _parent;
if (!isServer) exitWith {};

[QGVAR(cleanupParent), {
params ["_parent"];
TRACE_1("cleanupParent",_parent);
_parent removeEventHandler ["RopeBreak", _parent getVariable [QGVAR(RopeBreakEHID), -1]];
_parent setVariable [QGVAR(RopeBreakEHID), -1];
private _parentParentHooks = _parent getVariable [QGVAR(parentHooks), []];
if (_parentParentHooks isEqualTo []) then {
TRACE_1("remove Deleted EH",_parent);
_parent removeEventHandler ["Deleted", _parent getVariable [QGVAR(DeletedEHID), -1]];
_parent setVariable [QGVAR(DeletedEHID), -1];
};
}] call CBA_fnc_addEventHandler;

addMissionEventHandler ["PlayerConnected", {
if (GVAR(allChildren) isEqualTo []) exitWith {};
params ["", "", "", "_jip", "_owner"];
if (!_jip) exitWith {};
TRACE_2("pushing children",_owner,GVAR(allChildren));
[QGVAR(setTowParentAllChildren), [GVAR(allChildren)], _owner] call CBA_fnc_ownerEvent;
}];
16 changes: 16 additions & 0 deletions addons/towing/XEH_preInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,20 @@ PREP_RECOMPILE_END;

#include "initSettings.inc.sqf"

// handle JIP
if (isServer) then {
GVAR(allChildren) = [];
} else {
// can't use CBA EH in postInit because too late for server PlayerConnected EH
[QGVAR(setTowParentAllChildren), {
params ["_children"];
TRACE_1("setTowParentAllChildren",_children);
{
private _parent = _x getVariable QGVAR(parent);
TRACE_2("setTowParent",_x,_parent);
_x setTowParent _parent;
} forEach _children;
}] call CBA_fnc_addEventHandler;
};

ADDON = true;
28 changes: 23 additions & 5 deletions addons/towing/functions/fnc_attachRopePFH.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,32 @@ if (_intersections isNotEqualTo []) then {

_intersectionToUse params ["_intersectPosition", "", "_intersectObject"];

// if we have a target object, we assume we are attaching to the parent. If no target object, we are attaching to child
GVAR(canAttach) = (_intersectObject isNotEqualTo _ignoreParent) && { (!isNull _target && { _intersectObject isEqualTo _target }) || { isNull _target && { [_intersectObject] call FUNC(isSuitableSimulation) }}} && { !(_intersectObject getVariable [QGVAR(towing), false]) };
GVAR(canAttach) =
_intersectObject isNotEqualTo _ignoreParent
&& {
// if we have a target object, we assume we are attaching to the parent. If no target object, we are attaching to child
if (!isNull _target) then {
_intersectObject isEqualTo _target
} else {
[_intersectObject] call FUNC(isSuitableSimulation)
&& { // ignore _intersectObject which has parent != _ignoreParent
private _intersectObjectParent = _intersectObject getVariable [QGVAR(parent), objNull];
isNull _intersectObjectParent || {_intersectObjectParent == _ignoreParent}
} && { // arma prevents making rings (ropeAttachTo silently fails)
private _ancestor = _ignoreParent getVariable [QGVAR(parent), objNull];
while {!isNull _ancestor && {_ancestor != _intersectObject}} do {
_ancestor = _ancestor getVariable [QGVAR(parent), objNull];
};
isNull _ancestor
}
}
}
;

if (GVAR(canAttach)) then {
TRACE_4("can attach",_target,_intersectObject,_ignoreParent,_ignoreRope);
// TRACE_4("can attach",_target,_intersectObject,_ignoreParent,_ignoreRope);
GVAR(attachHelper) setPosASL _intersectPosition;
_hintLMB = localize LSTRING(attach);
_hintLMB = LLSTRING(attach);

GVAR(attachHelper) setVariable [QGVAR(object), _intersectObject];
};
Expand Down Expand Up @@ -76,4 +95,3 @@ if (_hint isNotEqualTo (_unit getVariable [QGVAR(hint), []])) then {
_unit setVariable [QGVAR(hint), _hint];
_hint call EFUNC(interaction,showMouseHint);
};

65 changes: 65 additions & 0 deletions addons/towing/functions/fnc_attachVehicles.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "..\script_component.hpp"
/*
* Author: Dystopian
* Attaches child to parent vehicle.
* Run globally.
*
* Arguments:
* 0: Vehicle to tow from <OBJECT>
* 1: Vehicle to tow <OBJECT>
* 2: Rope End Position <ARRAY>
* 3: Rope <OBJECT>
* 4: Attached Helper Object <OBJECT>
*
* Return Value:
* None
*
* Example:
* [parent, cursorObject, [0,0,0], ropes parent select 0] call ace_towing_fnc_attachVehicles
*
* Public: No
*/
params ["_parent", "_child", "_relativeAttachPos", "_rope", "_helper"];
TRACE_5("attachVehicles",_parent,_child,_relativeAttachPos,_rope,_helper);

if (local _parent) then {
_helper ropeDetach _rope;
[_child, _relativeAttachPos] ropeAttachTo _rope;
deleteVehicle _helper;
};

_child setTowParent _parent;
if (!isServer) exitWith {};

_child setVariable [QGVAR(parent), _parent, true];
GVAR(allChildren) pushBack _child;

{
if (-1 == _x getVariable [QGVAR(DeletedEHID), -1]) then {
_x setVariable [QGVAR(DeletedEHID), _x addEventHandler ["Deleted", {
params ["_entity"];
private _childHooks = _entity getVariable [QGVAR(childHooks), []];
private _parentHooks = _entity getVariable [QGVAR(parentHooks), []];
TRACE_3("Deleted EH",_entity,_childHooks,_parentHooks);
{
[objNull, _x, _entity] call FUNC(detachRope);
} forEach (_childHooks + _parentHooks);
if (_childHooks isNotEqualTo []) then { // only for parent
// because deleting lasts for several frames we have to delete RB EH to fix double cleanup
_entity removeEventHandler ["RopeBreak", _entity getVariable QGVAR(RopeBreakEHID)];
};
}]];
};
} forEach [_parent, _child];

if (-1 == _parent getVariable [QGVAR(RopeBreakEHID), -1]) then {
_parent setVariable [QGVAR(RopeBreakEHID), _parent addEventHandler ["RopeBreak", {
params ["_parent", "_rope", "_child"];
if (isNull _rope) exitWith {}; // happens
private _hook = _rope getVariable [QGVAR(hook), objNull];
private _hookChild = _hook getVariable [QGVAR(vars), []] param [1, objNull];
if (isNull _hook || {_child != _hookChild}) exitWith {}; // handle helper detach
TRACE_4("RopeBreak EH",_parent,_rope,_child,_hook);
[objNull, _hook] call FUNC(detachRope);
}]];
};
21 changes: 0 additions & 21 deletions addons/towing/functions/fnc_canStartTow.sqf

This file was deleted.

48 changes: 0 additions & 48 deletions addons/towing/functions/fnc_detach.sqf

This file was deleted.

Loading

0 comments on commit b54992b

Please sign in to comment.