Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dragging - Corpse carrying and dragging - continued #9273

Merged
merged 59 commits into from
Sep 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
b00977e
Create clones for corpse carrying/dragging
BaerMitUmlaut Oct 4, 2020
905e8ca
Fix doccomment for dropClone
BaerMitUmlaut Oct 5, 2020
3fa5b69
Remove duplicate clone
BaerMitUmlaut Oct 5, 2020
28e0491
Add comment with reasoning for detach before delete
BaerMitUmlaut Oct 11, 2020
efd71c6
Bury corpse to prevent desecration
BaerMitUmlaut Oct 11, 2020
2d30be4
Prevent screams of agony from dragged corpse
BaerMitUmlaut Oct 11, 2020
ccbf480
Merge remote-tracking branch 'upstream/master' into corpse-carry-cont…
johnb432 Jul 20, 2023
fb065d1
Continue corpse carry
johnb432 Jul 20, 2023
cbc7748
Update XEH_postInit.sqf
johnb432 Jul 20, 2023
b32ad48
Potential fix for duplicating
johnb432 Jul 21, 2023
4969f48
Merge branch 'master' into corpse-carry-continued2
johnb432 Jul 22, 2023
d40346d
Merge branch 'master' into corpse-carry-continued2
johnb432 Jul 24, 2023
1ad961c
Merge remote-tracking branch 'upstream/master' into corpse-carry-cont…
LinkIsGrim Sep 6, 2023
98e516b
Merge branch 'master' into corpse-carry-continued2
johnb432 Oct 3, 2023
897ca7a
Update fnc_handleAnimChanged.sqf
johnb432 Oct 3, 2023
52cd637
Merge branch 'corpse-carry-continued2' of https://github.com/johnb432…
johnb432 Oct 3, 2023
1ccd2b4
New script_component
johnb432 Oct 3, 2023
29881bc
Update fnc_createClone.sqf
johnb432 Oct 21, 2023
04238fd
Merge branch 'master' into pr/9273
johnb432 Jan 7, 2024
4a5f056
Fixed/improved checks
johnb432 Jan 7, 2024
573bfbb
Fix not hidden
johnb432 Jan 7, 2024
3387898
Check correct ragdoll state
johnb432 Jan 7, 2024
d1755af
Remove body moving under terrain
johnb432 Jan 7, 2024
68f9ea2
Merge remote-tracking branch 'upstream/master' into corpse-carry-cont…
LinkIsGrim Jan 8, 2024
884bccf
add wound texture handling
LinkIsGrim Jan 8, 2024
594e118
Readd body moving under terrain
johnb432 Jan 9, 2024
c8b3c15
Update dragging.md
johnb432 Jan 10, 2024
097b3e8
Merge remote-tracking branch 'upstream/master' into corpse-carry-cont…
LinkIsGrim Jan 11, 2024
15b581b
Update fnc_createClone.sqf
johnb432 Jan 11, 2024
ceb940a
Merged master
johnb432 Jan 14, 2024
c4b29e6
Merge branch 'master' into pr/9273
johnb432 Jan 21, 2024
85f138f
Merge branch 'master' into pr/9273
johnb432 Feb 2, 2024
824a9f6
Another attempt
johnb432 Feb 2, 2024
f805604
Update addons/dragging/functions/fnc_dropClone.sqf
johnb432 Feb 2, 2024
43fb261
Update addons/dragging/functions/fnc_createClone.sqf
johnb432 Feb 2, 2024
2d8dc01
Cleanup
johnb432 Feb 2, 2024
58e220b
Update XEH_preInit.sqf
johnb432 Feb 3, 2024
a627dfd
Merge branch 'master' into pr/9273
johnb432 Mar 2, 2024
1a20df8
Merge branch 'master' into pr/9273
johnb432 Apr 1, 2024
fdbaeab
Try syncing individually on each client
johnb432 Apr 1, 2024
04564b4
`setPosATL` globally
johnb432 Apr 9, 2024
9c65030
Merge branch 'master' into pr/9273
johnb432 Jun 29, 2024
28560b9
Sync corpses when JIP to avoid weird hitbox collision, renamed functi…
johnb432 Jul 1, 2024
b5205c1
Update addons/dragging/XEH_postInit.sqf
johnb432 Jul 1, 2024
471d33a
More cleanup
johnb432 Jul 1, 2024
5ee6478
Merge branch 'master' into pr/9273
johnb432 Jul 16, 2024
de1c2a5
Update docs/wiki/framework/events-framework.md
johnb432 Jul 20, 2024
7a26177
Merge branch 'master' into pr/9273
johnb432 Jul 20, 2024
5b87267
Merge branch 'corpse-carry-continued2' of https://github.com/johnb432…
johnb432 Jul 20, 2024
f93ac13
Remove ; in headers
johnb432 Jul 20, 2024
78adfdf
Merge branch 'master' into pr/9273
PabstMirror Aug 25, 2024
a5d047c
Update addons/dragging/functions/fnc_canCarry.sqf
johnb432 Aug 28, 2024
5ea5330
Update fnc_canDrag.sqf
johnb432 Aug 28, 2024
0a6ec07
Fix opening backpack of clone while dragging and patient moved warning
PabstMirror Aug 29, 2024
b3abb78
Update addons/dragging/functions/fnc_canCarry.sqf
johnb432 Sep 5, 2024
b5579eb
Update addons/dragging/functions/fnc_canDrag.sqf
johnb432 Sep 5, 2024
7529931
Update addons/medical_status/functions/fnc_addInventoryActions.sqf
johnb432 Sep 5, 2024
46bf462
Merge branch 'master' into pr/9273
johnb432 Sep 5, 2024
ba1bda8
Improve corpse dragging
johnb432 Sep 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions addons/dragging/CfgVehicles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
class CBA_Extended_EventHandlers;

class CfgVehicles {
class C_man_1;
class GVAR(clone): C_man_1 {};

// Static weapons
class LandVehicle;
class StaticWeapon: LandVehicle {
Expand Down
2 changes: 2 additions & 0 deletions addons/dragging/XEH_PREP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ PREP(canDrop_carry);
PREP(canRun_carry);
PREP(carryObject);
PREP(carryObjectPFH);
PREP(createClone);
PREP(deleteClone);
PREP(dragObject);
PREP(dragObjectPFH);
PREP(dropObject);
Expand Down
66 changes: 66 additions & 0 deletions addons/dragging/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -1,9 +1,62 @@
// by PabstMirror, commy2
#include "script_component.hpp"

[QGVAR(moveCorpse), {
params ["_corpse", "_dir", "_posATL"];

if (isNull _corpse) exitWith {};

// Check if the corpse is already close to the target
// If so, don't teleport
if ((getPosATL _corpse) distance _posATL > 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 {};
Expand All @@ -20,6 +73,11 @@ if (isNil QGVAR(maxWeightCarryRun)) then {
GVAR(maxWeightCarryRun) = 50;
};

// Extended EH doesn't fire for dead units, so add interactions manually
{
_x call FUNC(initPerson);
} forEach allDeadMen;

["isNotDragging", {!((_this select 0) getVariable [QGVAR(isDragging), false])}] call EFUNC(common,addCanInteractWithCondition);
["isNotCarrying", {!((_this select 0) getVariable [QGVAR(isCarrying), false])}] call EFUNC(common,addCanInteractWithCondition);

Expand Down Expand Up @@ -57,6 +115,14 @@ if (isNil QGVAR(maxWeightCarryRun)) then {
// 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"];
Expand Down
20 changes: 12 additions & 8 deletions addons/dragging/functions/fnc_canCarry.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,30 @@

params ["_unit", "_target"];

if !(alive _target && {_target getVariable [QGVAR(canCarry), false]} && {isNull objectParent _target}) exitWith {false};
private _alive = alive _target;
private _isPerson = _target isKindOf "CAManBase";

if !((_alive || _isPerson) && {_target getVariable [QGVAR(canCarry), false]} && {isNull objectParent _target}) exitWith {false};

if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false};

// #2644 - Units with injured legs cannot bear the extra weight of carrying an object
// The fireman carry animation does not slow down for injured legs, so you could carry and run
if ((_unit getHitPointDamage "HitLegs") >= 0.5) exitWith {false};

// Units need to be unconscious or limping; Units also need to not be in ragdoll if alive, as that causes desync issues
if (_isPerson) exitWith {
((!_alive) && {missionNamespace getVariable [QGVAR(canMoveDead), true]}) ||
{(isAwake _target) && // not ragdolled if alive
{!(_target call EFUNC(common,isAwake)) ||
{_target getHitPointDamage "HitLegs" >= 0.5}}}
LinkIsGrim marked this conversation as resolved.
Show resolved Hide resolved
};

// Static weapons need to be empty for carrying (ignore UAV AI)
if (_target isKindOf "StaticWeapon") exitWith {
(crew _target) findIf {!unitIsUAV _x} == -1
};

// Units need to be unconscious or limping; Units also need to not be in ragdoll, as that causes desync issues
if (_target isKindOf "CAManBase") exitWith {
isAwake _target && // not ragdolled
{lifeState _target == "INCAPACITATED" ||
{_target getHitPointDamage "HitLegs" >= 0.5}}
};

// Check max items for WeaponHolders
if (["WeaponHolder", "WeaponHolderSimulated"] findIf {_target isKindOf _x} != -1) exitWith {
(count (weaponCargo _target + magazineCargo _target + itemCargo _target)) <= MAX_DRAGGED_ITEMS
Expand Down
20 changes: 12 additions & 8 deletions addons/dragging/functions/fnc_canDrag.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,26 @@

params ["_unit", "_target"];

if !(alive _target && {_target getVariable [QGVAR(canDrag), false]} && {isNull objectParent _target}) exitWith {false};
private _alive = alive _target;
private _isPerson = _target isKindOf "CAManBase";

if !((_alive || _isPerson) && {_target getVariable [QGVAR(canDrag), false]} && {isNull objectParent _target}) exitWith {false};

if !([_unit, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false};

// Units need to be unconscious or limping; Units also need to not be in ragdoll if alive, as that causes desync issues
if (_isPerson) exitWith {
((!_alive) && {missionNamespace getVariable [QGVAR(canMoveDead), true]}) ||
{(isAwake _target) && // not ragdolled if alive
{!(_target call EFUNC(common,isAwake)) ||
{_target getHitPointDamage "HitLegs" >= 0.5}}}
};

// Static weapons need to be empty for dragging (ignore UAV AI)
if (_target isKindOf "StaticWeapon") exitWith {
(crew _target) findIf {!unitIsUAV _x} == -1
};

// Units need to be unconscious or limping; Units also need to not be in ragdoll, as that causes desync issues
if (_target isKindOf "CAManBase") exitWith {
isAwake _target && // not ragdolled
{lifeState _target == "INCAPACITATED" ||
{_target getHitPointDamage "HitLegs" >= 0.5}}
};

// Check max items for WeaponHolders
if (["WeaponHolder", "WeaponHolderSimulated"] findIf {_target isKindOf _x} != -1) exitWith {
(count (weaponCargo _target + magazineCargo _target + itemCargo _target)) <= MAX_DRAGGED_ITEMS
Expand Down
101 changes: 101 additions & 0 deletions addons/dragging/functions/fnc_createClone.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "..\script_component.hpp"
/*
* Author: BaerMitUmlaut, johnb43
* Creates a draggable / carryable clone of a dead unit.
*
* Arguments:
* 0: Unit dragging/carrying <OBJECT>
* 1: Dead unit <OBJECT>
*
* Return Value:
* Cloned unit <OBJECT>
*
* Example:
* [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
private _clone = createVehicle [[configOf _target >> QGVAR(cloneClass), "TEXT", QGVAR(clone)] call CBA_fnc_getConfigEntry, _posATL, [], 0, "CAN_COLLIDE"];

// Claim the clone
[_unit, _clone] call EFUNC(common,claim);

// Move unit -10 m below terrain in order to hide it and remove its inventory access
_posATL set [2, -10];

// Corpse is desynced, but it doesn't matter here
_target setPosATL _posATL;

// Hide unit until it can be moved below terrain
private _isObjectHidden = isObjectHidden _target;

if (!_isObjectHidden) then {
[QEGVAR(common,hideObjectGlobal), [_target, true]] call CBA_fnc_serverEvent;
};

// Prevents unit from falling when below terrain
private _simulationEnabled = simulationEnabled _target;

if (_simulationEnabled) then {
[QEGVAR(common,enableSimulationGlobal), [_target, false]] call CBA_fnc_serverEvent;
};

private _isInRemainsCollector = isInRemainsCollector _target;

// Make sure corpse isn't deleted by engine's garbage collector
if (_isInRemainsCollector) then {
removeFromRemainsCollector [_target];
};

// Make sure clone has the same wound textures as the corpse
_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

// Disable all damage
_clone allowDamage false;
_clone setVariable [QGVAR(original), [_target, _isInRemainsCollector, _isObjectHidden, _simulationEnabled], true];

[_clone, _target call CBA_fnc_getLoadout] call CBA_fnc_setLoadout;

// Sets the facial expression
[[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"];

// Remove clone from all zeuses
if (["ace_zeus"] call EFUNC(common,isModLoaded)) then {
[QEGVAR(zeus,removeObjects), [[_clone]]] call CBA_fnc_serverEvent;
};

// Release claim on corpse
[objNull, _target] call EFUNC(common,claim);
}, [_clone, _target], 0.25] call CBA_fnc_waitAndExecute;

// Save which curators had this object as editable
if (["ace_zeus"] call EFUNC(common,isModLoaded)) then {
private _objectCurators = objectCurators _target;

_target setVariable [QGVAR(objectCurators), _objectCurators, true];

if (_objectCurators isEqualTo []) exitWith {};

[QEGVAR(zeus,removeObjects), [[_target], _objectCurators]] call CBA_fnc_serverEvent;
};

_clone
80 changes: 80 additions & 0 deletions addons/dragging/functions/fnc_deleteClone.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include "..\script_component.hpp"
/*
* Author: BaerMitUmlaut, johnb43
* Drops a draggable / carryable clone of a dead unit.
*
* Arguments:
* 0: Unit dragging / carrying <OBJECT>
* 1: Clone <OBJECT>
* 2: If unit is in building <BOOL>
*
* Return Value:
* Original unit <OBJECT>
*
* Example:
* [player, cursorObject, false] call ace_dragging_fnc_deleteClone;
*
* Public: No
*/

params ["_unit", "_clone", "_inBuilding"];

(_clone getVariable [QGVAR(original), []]) params [
["_target", objNull],
["_isInRemainsCollector", true],
["_isObjectHidden", false],
["_simulationEnabled", true]
];

// API
[QGVAR(cloneDeleted), [_clone, _target]] call CBA_fnc_localEvent;

// Check if unit was deleted
if (!isNull _target) then {
private _posATL = getPosATL _clone;

if (_inBuilding) then {
_posATL = _posATL vectorAdd [0, 0, 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 desyncs the corpse position otherwise)
[QGVAR(moveCorpse), [_target, getDir _unit + 180, _posATL]] call CBA_fnc_globalEvent;

// Unhide unit
if (!_isObjectHidden) then {
[QEGVAR(common,hideObjectGlobal), [_target, false]] call CBA_fnc_serverEvent;
};

// Enable simulation again
if (_simulationEnabled) then {
[QEGVAR(common,enableSimulationGlobal), [_target, true]] call CBA_fnc_serverEvent;
};

// Detach first to prevent objNull in attachedObjects
detach _clone;
deleteVehicle _clone;

// Get which curators had this object as editable
if (["ace_zeus"] call EFUNC(common,isModLoaded)) then {
private _objectCurators = _target getVariable [QGVAR(objectCurators), []];

if (_objectCurators isEqualTo []) exitWith {};

[QEGVAR(zeus,addObjects), [[_target], _objectCurators]] call CBA_fnc_serverEvent;
};

if (_isInRemainsCollector) then {
addToRemainsCollector [_target];
};
} else {
// Detach first to prevent objNull in attachedObjects
detach _clone;
deleteVehicle _clone;
};

_target
5 changes: 5 additions & 0 deletions addons/dragging/functions/fnc_dragObjectPFH.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,8 @@ if (_target isKindOf "StaticWeapon" && {((crew _target) - (_target getVariable [

_idPFH call CBA_fnc_removePerFrameHandler;
};

// Clones can die of drowning if oxygen is under 0.5, so refill their oxygen from time to time
if (_target isKindOf QGVAR(clone) && {getOxygenRemaining _target < 0.8}) then {
_target setOxygenRemaining 1;
};
8 changes: 7 additions & 1 deletion addons/dragging/functions/fnc_dropObject.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ if (!GVAR(dragAndFire)) then {
};

private _inBuilding = _unit call FUNC(isObjectOnObject);
private _isClone = _target isKindOf QGVAR(clone);

// Drop cloned dead units
if (_isClone) then {
_target = [_unit, _target, _inBuilding] call FUNC(deleteClone);
};

// Play release animation
if (_unit call EFUNC(common,isAwake)) then {
Expand All @@ -57,7 +63,7 @@ _unit removeWeapon "ACE_FakePrimaryWeapon";
[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);

// Prevent object from flipping inside buildings
if (_inBuilding) then {
if (_inBuilding && {!_isClone}) then {
_target setPosASL (getPosASL _target vectorAdd [0, 0, 0.05]);
TRACE_2("setPos",getPosASL _unit,getPosASL _target);
};
Expand Down
Loading
Loading