diff --git a/addons/dragging/XEH_PREP.hpp b/addons/dragging/XEH_PREP.hpp index a5afd0367e..aeba3135ab 100644 --- a/addons/dragging/XEH_PREP.hpp +++ b/addons/dragging/XEH_PREP.hpp @@ -6,9 +6,9 @@ PREP(canRun_carry); PREP(carryObject); PREP(carryObjectPFH); PREP(createClone); +PREP(deleteClone); PREP(dragObject); PREP(dragObjectPFH); -PREP(dropClone); PREP(dropObject); PREP(dropObject_carry); PREP(getWeight); diff --git a/addons/dragging/XEH_postInit.sqf b/addons/dragging/XEH_postInit.sqf index 745803bf33..942fffd4b8 100644 --- a/addons/dragging/XEH_postInit.sqf +++ b/addons/dragging/XEH_postInit.sqf @@ -1,9 +1,72 @@ // by PabstMirror, commy2 #include "script_component.hpp" +[QGVAR(moveCorpse), { + params ["_corpse", "_dir", "_posATL"]; + _posATL params ["_xPos", "_yPos", "_zPos"]; + + if (isNull _corpse) exitWith {}; + + private _currentPos = getPosATL _corpse; + + // Check if the corpse is already close to the target + // If so, don't teleport + if !( + (_currentPos select 0 <= _xPos + 0.25) && + {_currentPos select 0 >= _xPos - 0.25} && + {_currentPos select 1 <= _yPos + 0.25} && + {_currentPos select 1 >= _yPos - 0.25} && + {_currentPos select 2 <= _zPos + 0.25} && + {_currentPos select 2 >= _zPos - 0.25} + ) then { + // Set direction before position + _corpse setDir _dir; + + // Bring corpse back to clone's position + _corpse setPosATL _posATL; + }; + + // Sync the corpse with its position + [{ + _this awake true; + + [{ + _this awake false; + }, _this] call CBA_fnc_execNextFrame; + }, _corpse] call CBA_fnc_execNextFrame; + + // Allow the corpse to be synced for JIP players + if (isServer) exitWith { + GVAR(movedCorpses) pushBackUnique _corpse; + }; +}] call CBA_fnc_addEventHandler; + if (isServer) then { // Release object on disconnection. Function is identical to killed addMissionEventHandler ["HandleDisconnect", LINKFUNC(handleKilled)]; + + GVAR(movedCorpses) = []; + + ["CAManBase", "Deleted", { + GVAR(movedCorpses) deleteAt (GVAR(movedCorpses) find (_this select 0)); + }, true, [], true] call CBA_fnc_addClassEventHandler; + + [QGVAR(disableSyncMovedCorpseOnJIP), { + params ["_corpse"]; + + GVAR(movedCorpses) deleteAt (GVAR(movedCorpses) find _corpse); + }] call CBA_fnc_addEventHandler; + + // Sync position of dead corpse for JIP unit (prevents weird invisible hitboxes on corpses) + [QGVAR(requestSyncMovedCorpsesJIP), { + params ["_clientOwner"]; + + { + [QGVAR(moveCorpse), [_x, getDir _x, getPosATL _x], _clientOwner] call CBA_fnc_ownerEvent; + } forEach GVAR(movedCorpses); + }] call CBA_fnc_addEventHandler; +} else { + [QGVAR(requestSyncMovedCorpsesJIP), clientOwner] call CBA_fnc_serverEvent; }; if (!hasInterface) exitWith {}; @@ -59,50 +122,17 @@ if (isNil QGVAR(maxWeightCarryRun)) then { // Handle waking up dragged unit and falling unconscious while dragging ["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; -// Handle local effect commands for clones -[QGVAR(cloneCreated), { - params ["_unit", "_clone"]; - - _clone setFace face _unit; - _clone setMimic "unconscious"; -}] call CBA_fnc_addEventHandler; - -[QGVAR(moveCorpse), { - params ["_corpse", "_dir", "_pos"]; - _pos params ["_xPos", "_yPos", "_zPos"]; - - private _currentPos = getPosATL _corpse; - - // Check if the corpse is already close to the target - // If so, don't teleport - if !( - (_currentPos select 0 <= _xPos + 0.25) && - {_currentPos select 0 >= _xPos - 0.25} && - {_currentPos select 1 <= _yPos + 0.25} && - {_currentPos select 1 >= _yPos - 0.25} && - {_currentPos select 2 <= _zPos + 0.25} && - {_currentPos select 2 >= _zPos - 0.25} - ) then { - // Set direction before position - _corpse setDir _dir; - - // Bring corpse back to clone's position - _corpse setPosATL _pos; - }; - - // Sync the corpse with its position - [{ - _this awake true; - - [{ - _this awake false; - }, _this] call CBA_fnc_execNextFrame; - }, _corpse] call CBA_fnc_execNextFrame; -}] call CBA_fnc_addEventHandler; - // Display event handler ["MouseZChanged", {(_this select 1) call FUNC(handleScrollWheel)}] call CBA_fnc_addDisplayHandler; +// Handle local effect commands for clones +[QGVAR(setCloneFace), { + params ["_clone", "_corpse"]; + + _clone setFace face _corpse; + _clone setMimic "unconscious"; +}] call CBA_fnc_addEventHandler; + // Handle surrendering and handcuffing ["ace_captiveStatusChanged", { params ["_unit", "_state"]; diff --git a/addons/dragging/functions/fnc_createClone.sqf b/addons/dragging/functions/fnc_createClone.sqf index e80724682b..5c0ffb4d76 100644 --- a/addons/dragging/functions/fnc_createClone.sqf +++ b/addons/dragging/functions/fnc_createClone.sqf @@ -11,13 +11,16 @@ * Cloned unit * * Example: - * [player] call ace_dragging_fnc_createClone; + * [player, cursorObject] call ace_dragging_fnc_createClone; * * Public: No */ params ["_unit", "_target"]; +// Don't sync corpse when a player joins in progress until the corpse is in its proper position +[QGVAR(disableSyncMovedCorpseOnJIP), _target] call CBA_fnc_serverEvent; + private _posATL = getPosATL _target; // Create clone @@ -54,11 +57,11 @@ if (_isInRemainsCollector) then { }; // Make sure clone has the same wound textures as the corpse -_clone setDamage ((damage _target) min 0.99); // don't kill the clone +_clone setDamage ((damage _target) min 0.99); // Don't kill the clone { _clone setHitPointDamage [_x, (_target getHitPointDamage _x) min 0.99]; -} forEach ["HitHead", "HitBody", "HitHands", "HitLegs"]; // relevant hitpoints +} forEach ["HitHead", "HitBody", "HitHands", "HitLegs"]; // Relevant hitpoints // Disable all damage _clone allowDamage false; @@ -67,7 +70,10 @@ _clone setVariable [QGVAR(original), [_target, _isInRemainsCollector, _isObjectH [_clone, _target call CBA_fnc_getLoadout] call CBA_fnc_setLoadout; // Sets the facial expression -[[QGVAR(cloneCreated), [_target, _clone]] call CBA_fnc_globalEventJIP, _clone] call CBA_fnc_removeGlobalEventJIP; +[[QGVAR(setCloneFace), [_clone, _target]] call CBA_fnc_globalEventJIP, _clone] call CBA_fnc_removeGlobalEventJIP; + +// API +[QGVAR(cloneCreated), [_clone, _target]] call CBA_fnc_localEvent; [{ params ["_clone", "_target"]; diff --git a/addons/dragging/functions/fnc_dropClone.sqf b/addons/dragging/functions/fnc_deleteClone.sqf similarity index 75% rename from addons/dragging/functions/fnc_dropClone.sqf rename to addons/dragging/functions/fnc_deleteClone.sqf index 0f00609e8c..148b88a3a3 100644 --- a/addons/dragging/functions/fnc_dropClone.sqf +++ b/addons/dragging/functions/fnc_deleteClone.sqf @@ -12,7 +12,7 @@ * Original unit * * Example: - * [player, cursorObject, false] call ace_dragging_fnc_dropClone; + * [player, cursorObject, false] call ace_dragging_fnc_deleteClone; * * Public: No */ @@ -26,21 +26,24 @@ params ["_unit", "_clone", "_inBuilding"]; ["_simulationEnabled", true] ]; +// API +[QGVAR(cloneDeleted), [_clone, _target]] call CBA_fnc_localEvent; + // Check if unit was deleted if (!isNull _target) then { - private _pos = getPosATL _clone; + private _posATL = getPosATL _clone; if (_inBuilding) then { - _pos = _pos vectorAdd [0, 0, 0.05]; + _posATL = _posATL vectorAdd [0, 0, 0.05]; }; - // Make sure position is not underground - if (_pos select 2 < 0.05) then { - _pos set [2, 0.05]; + // Make sure position isn't underground + if (_posATL select 2 < 0.05) then { + _posATL set [2, 0.05]; }; - // Move the unit globally (important, as it doesn't work otherwise) - [QGVAR(moveCorpse), [_target, getDir _unit + 180, _pos]] call CBA_fnc_globalEvent; + // Move the unit globally (important, as it desyncs the corpse position otherwise) + [QGVAR(moveCorpse), [_target, getDir _unit + 180, _posATL]] call CBA_fnc_globalEvent; // Unhide unit if (!_isObjectHidden) then { diff --git a/addons/dragging/functions/fnc_dropObject.sqf b/addons/dragging/functions/fnc_dropObject.sqf index 5b59f7d900..c5b0dff489 100644 --- a/addons/dragging/functions/fnc_dropObject.sqf +++ b/addons/dragging/functions/fnc_dropObject.sqf @@ -35,7 +35,7 @@ private _isClone = _target isKindOf QGVAR(clone); // Drop cloned dead units if (_isClone) then { - _target = [_unit, _target, _inBuilding] call FUNC(dropClone); + _target = [_unit, _target, _inBuilding] call FUNC(deleteClone); }; // Play release animation diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf index 960a42e74f..9a96515223 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -29,7 +29,7 @@ private _isClone = _target isKindOf QGVAR(clone); // Drop cloned dead units if (_isClone) then { - _target = [_unit, _target, _inBuilding] call FUNC(dropClone); + _target = [_unit, _target, _inBuilding] call FUNC(deleteClone); }; // Prevent collision damage diff --git a/docs/wiki/framework/events-framework.md b/docs/wiki/framework/events-framework.md index 5155cf7593..956048e801 100644 --- a/docs/wiki/framework/events-framework.md +++ b/docs/wiki/framework/events-framework.md @@ -167,6 +167,13 @@ MenuType: 0 = Interaction, 1 = Self Interaction | `ace_headless_groupTransferPre` | [_group, _HC (OBJECT), _previousOwner, _idHC] | Target | Listen | Called just before a group is transferred from any machine to a HC. Called where group currently is local and on the HC, where group is going to be local. | `ace_headless_groupTransferPost` | [_group, _HC (OBJECT), _previousOwner, _idHC, _transferredSuccessfully] | Target | Listen | Called just after a group is transferred from a machine to a HC. Called where group was local and on the HC, where group is now local. `_transferredSuccessfully` is passed so mods can actually check if the locality was properly transferred, as ownership transfer is not guaranteed. +### 2.18 Interaction (`ace_dragging`) + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_dragging_cloneCreated` | [_clone, _corpse] | Local | Listen | Called when a clone used for dragging/carrying corpses is created +| `ace_dragging_cloneDeleted` | [_clone, _corpse] | Local | Listen | Called when a clone used for dragging/carrying corpses is deleted + ## 3. Usage Also Reference [CBA Events System](https://github.com/CBATeam/CBA_A3/wiki/Custom-Events-System){:target="_blank"} documentation.