From 493e57d749514cccfd1f01cc89785a35e703f3e1 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Tue, 3 Feb 2026 20:29:09 +0100 Subject: [PATCH 1/6] Sandbag refactor --- addons/sandbag/CfgEventHandlers.hpp | 23 +------ addons/sandbag/CfgVehicles.hpp | 37 ++++------- addons/sandbag/CfgWeapons.hpp | 14 ---- addons/sandbag/XEH_PREP.hpp | 7 +- addons/sandbag/XEH_missionDisplayLoad.sqf | 7 +- addons/sandbag/XEH_postInit.sqf | 65 +++++++++++++++---- addons/sandbag/functions/fnc_canDeploy.sqf | 6 +- addons/sandbag/functions/fnc_deploy.sqf | 24 +++---- addons/sandbag/functions/fnc_deployCancel.sqf | 29 ++++----- .../sandbag/functions/fnc_deployConfirm.sqf | 60 ++++++++--------- .../functions/fnc_handleDeployInterrupt.sqf | 31 +++++++++ .../fnc_handleInteractMenuOpened.sqf | 22 ------- addons/sandbag/functions/fnc_handleKilled.sqf | 22 ------- .../functions/fnc_handlePlayerChanged.sqf | 27 -------- .../fnc_handlePlayerInventoryChanged.sqf | 25 ------- .../functions/fnc_handleScrollWheel.sqf | 33 +++++++--- .../functions/fnc_handleUnconscious.sqf | 24 ------- addons/sandbag/functions/fnc_pickup.sqf | 21 +++--- addons/sandbag/stringtable.xml | 30 ++++----- 19 files changed, 217 insertions(+), 290 deletions(-) create mode 100644 addons/sandbag/functions/fnc_handleDeployInterrupt.sqf delete mode 100644 addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf delete mode 100644 addons/sandbag/functions/fnc_handleKilled.sqf delete mode 100644 addons/sandbag/functions/fnc_handlePlayerChanged.sqf delete mode 100644 addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf delete mode 100644 addons/sandbag/functions/fnc_handleUnconscious.sqf diff --git a/addons/sandbag/CfgEventHandlers.hpp b/addons/sandbag/CfgEventHandlers.hpp index fc20af2e083..d17adf2696d 100644 --- a/addons/sandbag/CfgEventHandlers.hpp +++ b/addons/sandbag/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); @@ -6,9 +5,9 @@ class Extended_PreStart_EventHandlers { }; class Extended_PreInit_EventHandlers { - class ADDON { - init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); - }; + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; }; class Extended_PostInit_EventHandlers { @@ -17,22 +16,6 @@ class Extended_PostInit_EventHandlers { }; }; -class Extended_Init_EventHandlers { - class ACE_SandbagObject { - class ADDON { - init = QUOTE(call EFUNC(dragging,initObject)); - }; - }; -}; - -class Extended_Killed_EventHandlers { - class CAManBase { - class ADDON { - killed = QUOTE(call FUNC(handleKilled)); - }; - }; -}; - class Extended_DisplayLoad_EventHandlers { class RscDisplayMission { ADDON = QUOTE(call COMPILE_SCRIPT(XEH_missionDisplayLoad)); diff --git a/addons/sandbag/CfgVehicles.hpp b/addons/sandbag/CfgVehicles.hpp index 3fce474c247..46c54aacfeb 100644 --- a/addons/sandbag/CfgVehicles.hpp +++ b/addons/sandbag/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CBA_Extended_EventHandlers_base; class CfgVehicles { @@ -6,10 +5,10 @@ class CfgVehicles { class CAManBase: Man { class ACE_SelfActions { class GVAR(place) { - displayName = CSTRING(DeploySandbag); + displayName = CSTRING(deploySandbag); condition = QUOTE(call FUNC(canDeploy)); - //wait a frame to handle "Do When releasing action menu key" option - statement = QUOTE([ARR_2({_this call FUNC(deploy)},_this)] call CBA_fnc_execNextFrame); + // Wait a frame to handle "Do When releasing action menu key" option + statement = QUOTE([ARR_2(LINKFUNC(deploy),_this)] call CBA_fnc_execNextFrame); exceptions[] = {"isNotSwimming"}; showDisabled = 0; icon = QPATHTOF(UI\icon_sandbag_ca.paa); @@ -32,20 +31,6 @@ class CfgVehicles { }; }; - /*class ACE_Item_Sandbag: Item_Base_F { - author = ECSTRING(common,ACETeam); - scope = 2; - scopeCurator = 2; - displayName = CSTRING(sandbag_displayName); - vehicleClass = "Items"; - class TransportItems { - class ACE_Sandbag { - name = "ACE_Sandbag"; - count = 1; - }; - }; - };*/ - class ThingX; class ACE_SandbagObject: ThingX { class EventHandlers { @@ -66,14 +51,16 @@ class CfgVehicles { accuracy = 1000; destrType = "DestructDefault"; + EGVAR(dragging,canCarry) = 1; + class DestructionEffects {}; class Damage { tex[] = {}; mat[] = { - "z\ace\addons\sandbag\data\bag_destruct.rvmat", - "z\ace\addons\sandbag\data\bag_destruct.rvmat", - "z\ace\addons\sandbag\data\bag_destruct.rvmat" + QPATHTOF(data\bag_destruct.rvmat), + QPATHTOF(data\bag_destruct.rvmat), + QPATHTOF(data\bag_destruct.rvmat) }; }; @@ -81,13 +68,13 @@ class CfgVehicles { class ACE_MainActions { selection = ""; distance = 5; - condition = "(true)"; + condition = "true"; class ACE_PickUp { selection = ""; displayName = CSTRING(PICKUPSB); distance = 4; - condition = QUOTE(!(_player getVariable [ARR_2(QUOTE(QGVAR(isUsingSandbag)),false)])); + condition = QUOTE(!(_player getVariable [ARR_2(QQGVAR(isUsingSandbag),false)])); statement = QUOTE([ARR_2(_player,_target)] call FUNC(pickup)); showDisabled = 0; exceptions[] = {}; @@ -104,6 +91,10 @@ class CfgVehicles { class ACE_SandbagObject_NoGeo: ACE_SandbagObject { scope = 1; model = QPATHTOF(data\ace_sandbag_nogeo.p3d); + + class EventHandlers: EventHandlers { + class CBA_Extended_EventHandlers {}; + }; }; class Box_NATO_Support_F; diff --git a/addons/sandbag/CfgWeapons.hpp b/addons/sandbag/CfgWeapons.hpp index 72336e8bbfe..f76bcac1fa9 100644 --- a/addons/sandbag/CfgWeapons.hpp +++ b/addons/sandbag/CfgWeapons.hpp @@ -1,4 +1,3 @@ - class CfgWeapons { class ACE_ItemCore; class CBA_MiscItem_ItemInfo; @@ -14,17 +13,4 @@ class CfgWeapons { mass = 8; }; }; - /* - class ACE_Sandbag: ACE_ItemCore { - author = ECSTRING(common,ACETeam); - scope = 2; - displayName = CSTRING(sandbag_displayName); - model = QPATHTOF(data\ace_sandbag_build.p3d); - picture = QPATHTOF(data\m_sandbag_ca.paa); - - class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 160; - }; - }; - */ }; diff --git a/addons/sandbag/XEH_PREP.hpp b/addons/sandbag/XEH_PREP.hpp index 399655a8914..273fb262aaf 100644 --- a/addons/sandbag/XEH_PREP.hpp +++ b/addons/sandbag/XEH_PREP.hpp @@ -1,12 +1,7 @@ - PREP(canDeploy); PREP(deploy); PREP(deployCancel); PREP(deployConfirm); -PREP(handleInteractMenuOpened); -PREP(handleKilled); -PREP(handlePlayerChanged); -PREP(handlePlayerInventoryChanged); +PREP(handleDeployInterrupt); PREP(handleScrollWheel); -PREP(handleUnconscious); PREP(pickup); diff --git a/addons/sandbag/XEH_missionDisplayLoad.sqf b/addons/sandbag/XEH_missionDisplayLoad.sqf index cb85ffb9fbf..7bdea7571fe 100644 --- a/addons/sandbag/XEH_missionDisplayLoad.sqf +++ b/addons/sandbag/XEH_missionDisplayLoad.sqf @@ -3,4 +3,9 @@ params ["_display"]; _display displayAddEventHandler ["MouseZChanged", {(_this select 1) call FUNC(handleScrollWheel)}]; -_display displayAddEventHandler ["MouseButtonDown", {[ACE_player, _this select 1] call FUNC(deployCancel)}]; +_display displayAddEventHandler ["MouseButtonDown", { + // Right clicking cancels deployment + if (_this select 1 == 1) then { + ACE_player call FUNC(handleDeployInterrupt); + }; +}]; diff --git a/addons/sandbag/XEH_postInit.sqf b/addons/sandbag/XEH_postInit.sqf index 8185bb31074..3bb6bea7d5d 100644 --- a/addons/sandbag/XEH_postInit.sqf +++ b/addons/sandbag/XEH_postInit.sqf @@ -1,25 +1,68 @@ #include "script_component.hpp" if (isServer) then { - // Cancel deploy on hard disconnection. Function is identical to killed - addMissionEventHandler ["HandleDisconnect", {call FUNC(handleKilled)}]; + // Cancel deploy on hard disconnection. Function is identical to interrupted + addMissionEventHandler ["HandleDisconnect", {(_this select 0) call FUNC(handleDeployInterrupt)}]; }; if (!hasInterface) exitWith {}; GVAR(sandBag) = objNull; GVAR(deployPFH) = -1; +GVAR(deployDistance) = -1; GVAR(deployDirection) = 0; +GVAR(deployHeight) = 0; -// Cancel deploy sandbag if interact menu opened -["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; +// Cancel object deployment if interact menu opened +["ace_interactMenuOpened", {ACE_player call FUNC(handleDeployInterrupt)}] call CBA_fnc_addEventHandler; -// Cancel deploy on player change. This does work when returning to lobby, but not when hard disconnecting. -["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; -["loadout", LINKFUNC(handlePlayerInventoryChanged)] call CBA_fnc_addPlayerEventHandler; -["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; +// Cancel deploy on player change. This does work when returning to lobby, but not when hard disconnecting +["unit", LINKFUNC(handleDeployInterrupt)] call CBA_fnc_addPlayerEventHandler; +["vehicle", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; +["weapon", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; +["loadout", {[_this select 0, objNull, false] call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; -// handle waking up dragged unit and falling unconscious while dragging -["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; +// When changing feature cameras, stop deployment +["featureCamera", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; -//@todo Captivity? +// Handle falling unconscious while trying to deploy +["ace_unconscious", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addEventHandler; + +// Handle death +[QGVAR(killedEH), "Killed", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addBISPlayerEventHandler; + +// Handle surrendering and handcuffing +["ace_captiveStatusChanged", { + params ["_unit", "_state"]; + + // If surrendered or handcuffed, stop deployment + if (_state) then { + _unit call FUNC(handleDeployInterrupt); + }; +}] call CBA_fnc_addEventHandler; + +if (["ace_dragging"] call EFUNC(common,isModLoaded)) then { + // When carrying starts, update surrounding sandbags + [QEGVAR(dragging,setupCarry), { + params ["", "_target"]; + + if !(_target isKindOf "ACE_SandbagObject") exitWith {}; + + // Force PhysX update + { + [QEGVAR(common,awake), [_x, true]] call CBA_fnc_globalEvent; + } forEach ((_target nearObjects ["ACE_SandbagObject", 5]) - [_target]); + }] call CBA_fnc_addEventHandler; + + // When carrying stops, update surrounding sandbags + [QEGVAR(dragging,stoppedCarry), { + params ["", "_target", "_loadCargo"]; + + if (_loadCargo || {!(_target isKindOf "ACE_SandbagObject")}) exitWith {}; + + // Force PhysX update + { + [QEGVAR(common,awake), [_x, true]] call CBA_fnc_globalEvent; + } forEach ((_target nearObjects ["ACE_SandbagObject", 5]) - [_target]); + }] call CBA_fnc_addEventHandler; +}; diff --git a/addons/sandbag/functions/fnc_canDeploy.sqf b/addons/sandbag/functions/fnc_canDeploy.sqf index bc0751d6b08..803a9db9b21 100644 --- a/addons/sandbag/functions/fnc_canDeploy.sqf +++ b/addons/sandbag/functions/fnc_canDeploy.sqf @@ -10,13 +10,11 @@ * Can deploy * * Example: - * [ACE_player] call ace_sandbag_fnc_canDeploy + * player call ace_sandbag_fnc_canDeploy * * Public: No */ params ["_unit"]; -if !("ACE_Sandbag_empty" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; - -_unit call EFUNC(common,canDig) +([_unit, "ACE_Sandbag_empty"] call EFUNC(common,hasItem)) && {!(_unit getVariable [QGVAR(isUsingSandbag), false])} && {_unit call EFUNC(common,canDig)} // return diff --git a/addons/sandbag/functions/fnc_deploy.sqf b/addons/sandbag/functions/fnc_deploy.sqf index dd055504631..41cb16d3c23 100644 --- a/addons/sandbag/functions/fnc_deploy.sqf +++ b/addons/sandbag/functions/fnc_deploy.sqf @@ -1,50 +1,52 @@ #include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support - * Starts the deploy process for sandbags. + * Starts the deployment process for sandbags. * * Arguments: - * 0: unit + * 0: Unit * * Return Value: * None * * Example: - * [ACE_player] call ace_sandbag_fnc_deploy + * player call ace_sandbag_fnc_deploy * * Public: No */ params ["_unit"]; -// prevent the placing unit from running +// Prevent the placing unit from running [_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); [_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); -// create the sandbag +// Create the sandbag private _sandBag = createVehicle ["ACE_SandbagObject_NoGeo", [0, 0, 0], [], 0, "NONE"]; GVAR(sandBag) = _sandBag; -// prevent collisions with sandbag +// Prevent collisions with sandbag [QEGVAR(common,enableSimulationGlobal), [_sandBag, false]] call CBA_fnc_serverEvent; +GVAR(deployDistance) = 1; GVAR(deployDirection) = 0; +GVAR(deployHeight) = 0; -// pfh that runs while the deployment is in progress +// PFH that runs while the deployment is in progress GVAR(deployPFH) = [{ (_this select 0) params ["_unit", "_sandBag"]; if (isNull _sandBag) exitWith { - [_unit] call FUNC(deployCancel); + _unit call FUNC(deployCancel); }; - _sandBag setPosASL (eyePos _unit vectorAdd (positionCameraToWorld [0, 0, 1] vectorDiff positionCameraToWorld [0, 0, 0])); + _sandBag setPosASL (eyePos _unit vectorAdd (positionCameraToWorld [0, GVAR(deployHeight), GVAR(deployDistance)] vectorDiff positionCameraToWorld [0, 0, 0])); _sandBag setDir (GVAR(deployDirection) + getDir _unit); }, 0, [_unit, _sandBag]] call CBA_fnc_addPerFrameHandler; -// add mouse button action and hint -[localize LSTRING(ConfirmDeployment), localize LSTRING(CancelDeployment), localize LSTRING(ScrollAction)] call EFUNC(interaction,showMouseHint); +// Add mouse button action and hint +[LLSTRING(confirmDeployment), LLSTRING(cancelDeployment), LLSTRING(scrollAction)] call EFUNC(interaction,showMouseHint); _unit setVariable [QGVAR(Deploy), [ _unit, "DefaultAction", diff --git a/addons/sandbag/functions/fnc_deployCancel.sqf b/addons/sandbag/functions/fnc_deployCancel.sqf index eff3400577c..f1b3caef1f3 100644 --- a/addons/sandbag/functions/fnc_deployCancel.sqf +++ b/addons/sandbag/functions/fnc_deployCancel.sqf @@ -1,40 +1,39 @@ #include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support - * Cancels sandbag deployment + * Cancels sandbag deployment. * * Arguments: * 0: Unit - * 1: Key (1 for left mouse button) (default: 1) * * Return Value: * None * * Example: - * [ACE_player] call ace_sandbag_fnc_deployCancel + * player call ace_sandbag_fnc_deployCancel * * Public: No */ -params ["_unit", ["_key", 1]]; +if (GVAR(deployPFH) == -1) exitWith {}; -if (_key != 1 || {GVAR(deployPFH) == -1}) exitWith {}; +// Remove deployment PFH +GVAR(deployPFH) call CBA_fnc_removePerFrameHandler; +GVAR(deployPFH) = -1; + +params ["_unit"]; -// enable running again +// Enable running again [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); -// delete placement dummy +// Delete placement dummy deleteVehicle GVAR(sandBag); -// remove deployment pfh -[GVAR(deployPFH)] call CBA_fnc_removePerFrameHandler; -GVAR(deployPFH) = -1; - -// remove mouse button actions +// Remove mouse button actions call EFUNC(interaction,hideMouseHint); -[_unit, "DefaultAction", _unit getVariable [QGVAR(Deploy), -1]] call EFUNC(common,removeActionEventHandler); -[_unit, "zoomtemp", _unit getVariable [QGVAR(Cancel), -1]] call EFUNC(common,removeActionEventHandler); +[_unit, "DefaultAction", _unit getVariable [QGVAR(deploy), -1]] call EFUNC(common,removeActionEventHandler); +_unit setVariable [QGVAR(deploy), nil]; -_unit setVariable [QGVAR(isDeploying), false, true]; +_unit setVariable [QGVAR(isDeploying), nil, true]; diff --git a/addons/sandbag/functions/fnc_deployConfirm.sqf b/addons/sandbag/functions/fnc_deployConfirm.sqf index ef2aafd97c7..04ea807c0cf 100644 --- a/addons/sandbag/functions/fnc_deployConfirm.sqf +++ b/addons/sandbag/functions/fnc_deployConfirm.sqf @@ -1,57 +1,53 @@ #include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet, Ruthberg, edited by commy2 for better MP and eventual AI support - * Confirms sandbag deployment + * Confirms sandbag deployment. * * Arguments: - * 0: unit + * 0: Unit * * Return Value: * None * * Example: - * [ACE_player] call ace_sandbag_fnc_deployConfirm + * player call ace_sandbag_fnc_deployConfirm * * Public: No */ -params ["_unit"]; - -// enable running again -[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); -[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); +if (GVAR(deployPFH) == -1) exitWith {}; -// remove sandbag from inventory -_unit removeItem "ACE_Sandbag_empty"; - -// delete placement dummy and create real sandbag -[{ - if (isNull GVAR(sandBag)) exitWith {}; +// Save placement dummy data +private _position = getPosASL GVAR(sandBag); +private _direction = getDir GVAR(sandBag); - params ["_unit"]; +params ["_unit"]; - private _position = getPosASL GVAR(sandBag); - private _direction = getDir GVAR(sandBag); +// Clean up hints and dummy +_unit call FUNC(deployCancel); - deleteVehicle GVAR(sandBag); +// Make sure unit still has empty sandbag, otherwise quit +if (!alive _unit || {!([_unit, "ACE_Sandbag_empty"] call EFUNC(common,hasItem))}) exitWith {}; - private _sandBag = createVehicle ["ACE_SandbagObject", [0, 0, 0], [], 0, "NONE"]; - _sandBag setPosASL _position; - _sandBag setDir _direction; +// Play animation +[_unit, "PutDown"] call EFUNC(common,doGesture); - GVAR(sandBag) = objNull; -}, [_unit], 1] call CBA_fnc_waitAndExecute; +[{ + params ["_unit", "_direction", "_position"]; -// remove deployment pfh -[GVAR(deployPFH)] call CBA_fnc_removePerFrameHandler; -GVAR(deployPFH) = -1; + // Make sure unit still has empty sandbag, otherwise quit + if (!alive _unit || {!([_unit, "ACE_Sandbag_empty"] call EFUNC(common,hasItem))}) exitWith {}; -// remove mouse button actions -call EFUNC(interaction,hideMouseHint); + // Remove sandbag from inventory + _unit removeItem "ACE_Sandbag_empty"; -[_unit, "DefaultAction", _unit getVariable [QGVAR(Deploy), -1]] call EFUNC(common,removeActionEventHandler); + // Create real sandbag + private _sandBag = createVehicle ["ACE_SandbagObject", [0, 0, 0], [], 0, "NONE"]; -// play animation -[_unit, "PutDown"] call EFUNC(common,doGesture); + _sandBag setDir _direction; + _sandBag setPosASL _position; -_unit setVariable [QGVAR(isDeploying), false, true]; + // Prevent collision damage + [QEGVAR(common,fixCollision), _unit] call CBA_fnc_localEvent; + [QEGVAR(common,fixCollision), _sandBag] call CBA_fnc_localEvent; +}, [_unit, _direction, _position], 0.5] call CBA_fnc_waitAndExecute; diff --git a/addons/sandbag/functions/fnc_handleDeployInterrupt.sqf b/addons/sandbag/functions/fnc_handleDeployInterrupt.sqf new file mode 100644 index 00000000000..0301e333ac7 --- /dev/null +++ b/addons/sandbag/functions/fnc_handleDeployInterrupt.sqf @@ -0,0 +1,31 @@ +#include "..\script_component.hpp" +/* + * Author: commy2 + * Handles various interruption types. + * + * Arguments: + * 0: (New) unit + * 1: Old unit (for player change) (default: objNull) + * 2: Ignore item check (default: true) + * + * Return Value: + * None + * + * Example: + * player call ace_sandbag_fnc_handleDeployInterrupt + * + * Public: No +*/ + +params ["_newPlayer", ["_oldPlayer", objNull], ["_ignoreItemCheck", true]]; +TRACE_3("params",_newPlayer,_oldPlayer,_ignoreItemCheck); + +if (!local _newPlayer) exitWith {}; + +if (_newPlayer getVariable [QGVAR(isDeploying), false] && {_ignoreItemCheck || {!([_newPlayer, "ACE_Sandbag_empty"] call EFUNC(common,hasItem))}}) then { + _newPlayer call FUNC(deployCancel); +}; + +if (_oldPlayer getVariable [QGVAR(isDeploying), false]) then { + _oldPlayer call FUNC(deployCancel); +}; diff --git a/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf b/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf deleted file mode 100644 index cb6cb4ddf14..00000000000 --- a/addons/sandbag/functions/fnc_handleInteractMenuOpened.sqf +++ /dev/null @@ -1,22 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Handle opening of interaction menu. - * - * Arguments: - * 0: Unit - * - * Return Value: - * None - * - * Example: - * [bob] call ace_sandbag_fnc_handleInteractMenuOpened - * - * Public: No -*/ - -params ["_unit"]; - -if (_unit getVariable [QGVAR(isDeploying), false]) then { - [_unit] call FUNC(deployCancel); -}; diff --git a/addons/sandbag/functions/fnc_handleKilled.sqf b/addons/sandbag/functions/fnc_handleKilled.sqf deleted file mode 100644 index 100ed2e930c..00000000000 --- a/addons/sandbag/functions/fnc_handleKilled.sqf +++ /dev/null @@ -1,22 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Handle death. - * - * Arguments: - * 0: Unit - * - * Return Value: - * None - * - * Example: - * [bob] call ace_sandbag_fnc_handleKilled - * - * Public: No -*/ - -params ["_unit"]; - -if (_unit getVariable [QGVAR(isDeploying), false]) then { - [_unit] call FUNC(deployCancel); -}; diff --git a/addons/sandbag/functions/fnc_handlePlayerChanged.sqf b/addons/sandbag/functions/fnc_handlePlayerChanged.sqf deleted file mode 100644 index 6882ed553e9..00000000000 --- a/addons/sandbag/functions/fnc_handlePlayerChanged.sqf +++ /dev/null @@ -1,27 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Handle player changes. - * - * Arguments: - * 0: New Player Unit - * 1: Old Player Unit - * - * Return Value: - * None - * - * Example: - * [bob, kevin] call ace_sandbag_fnc_handlePlayerChanged - * - * Public: No -*/ - -params ["_newPlayer", "_oldPlayer"]; - -if (_newPlayer getVariable [QGVAR(isDeploying), false]) then { - [_newPlayer] call FUNC(deployCancel); -}; - -if (_oldPlayer getVariable [QGVAR(isDeploying), false]) then { - [_oldPlayer] call FUNC(deployCancel); -}; diff --git a/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf b/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf deleted file mode 100644 index 1e557cba1f5..00000000000 --- a/addons/sandbag/functions/fnc_handlePlayerInventoryChanged.sqf +++ /dev/null @@ -1,25 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Handle the InventoryChanged event. - * - * Arguments: - * 0: Unit - * 1: Weapon - * - * Return Value: - * None - * - * Example: - * [bob, "weapon"] call ace_sandbag_fnc_handlePlayerInventoryChanged - * - * Public: No -*/ - -params ["_unit"]; - -if (_unit getVariable [QGVAR(isDeploying), false]) then { - if !("ACE_Sandbag_empty" in (_unit call EFUNC(common,uniqueItems))) then { - [_unit] call FUNC(deployCancel); - }; -}; diff --git a/addons/sandbag/functions/fnc_handleScrollWheel.sqf b/addons/sandbag/functions/fnc_handleScrollWheel.sqf index 3a4f00a502e..74164f3c82d 100644 --- a/addons/sandbag/functions/fnc_handleScrollWheel.sqf +++ b/addons/sandbag/functions/fnc_handleScrollWheel.sqf @@ -1,24 +1,41 @@ #include "..\script_component.hpp" /* - * Author: Garth 'L-H' de Wet, Ruthberg - * Handles sandbag rotation + * Author: Garth 'L-H' de Wet, Ruthberg, Smith + * Handles sandbag rotation. * * Arguments: - * 0: scroll amount + * 0: Scroll amount * * Return Value: - * handled + * If the scroll was handled * * Example: - * [1.2] call ace_sandbag_fnc_handleScrollWheel + * 1.2 call ace_sandbag_fnc_handleScrollWheel * * Public: No */ -if (GVAR(deployPFH) == -1) exitWith {false}; +if (GVAR(deployPFH) == -1) exitWith { + false // return +}; params ["_scroll"]; -GVAR(deployDirection) = GVAR(deployDirection) + (_scroll * 5); +// Change direction +if (CBA_events_control) exitWith { + GVAR(deployDirection) = GVAR(deployDirection) + (_scroll * 5); -true + true // return +}; + +// Change height +if (CBA_events_alt) exitWith { + GVAR(deployHeight) = 1.5 min (-1.5 max GVAR(deployHeight) + (_scroll * 0.1)); + + true // return +}; + +// Change distance +GVAR(deployDistance) = 1.5 min (0.36 max GVAR(deployDistance) + (_scroll * 0.1)); + +true // return diff --git a/addons/sandbag/functions/fnc_handleUnconscious.sqf b/addons/sandbag/functions/fnc_handleUnconscious.sqf deleted file mode 100644 index 3ad90a0cc50..00000000000 --- a/addons/sandbag/functions/fnc_handleUnconscious.sqf +++ /dev/null @@ -1,24 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Handle unconsciousness. - * - * Arguments: - * 0: Unit - * - * Return Value: - * None - * - * Example: - * [bob] call ace_sandbag_fnc_handleUnconscious - * - * Public: No -*/ - -params ["_unit"]; - -if (!local _unit) exitWith {}; - -if (_unit getVariable [QGVAR(isDeploying), false]) then { - [_unit] call FUNC(deployCancel); -}; diff --git a/addons/sandbag/functions/fnc_pickup.sqf b/addons/sandbag/functions/fnc_pickup.sqf index 07a6285e685..f16292f8895 100644 --- a/addons/sandbag/functions/fnc_pickup.sqf +++ b/addons/sandbag/functions/fnc_pickup.sqf @@ -1,17 +1,17 @@ #include "..\script_component.hpp" /* * Author: Ruthberg - * Pick up sandbag + * Picks up a sandbag. * * Arguments: - * 0: unit - * 1: sandbag + * 0: Unit + * 1: Sandbag * * Return Value: * None * * Example: - * [_unit, _sandbag] call ace_sandbag_fnc_pickup + * [player, cursorObject] call ace_sandbag_fnc_pickup * * Public: No */ @@ -27,14 +27,17 @@ _unit setVariable [QGVAR(isUsingSandbag), true]; _unit setVariable [QGVAR(isUsingSandbag), false]; - if (isNull _sandbag) exitWith {}; + // If another unit picked up the sandbag or otherwise sandbag no longer present, exit + if (!alive _unit || {!alive _sandbag}) exitWith {}; + + private _nearSandbags = (_sandbag nearObjects ["ACE_SandbagObject", 5]) - [_sandbag]; deleteVehicle _sandbag; - // Force physx update + // Force PhysX update { - _x setPosASL (getPosASL _x); - } forEach (_unit nearObjects ["ACE_SandbagObject", 5]); + [QEGVAR(common,awake), [_x, true]] call CBA_fnc_globalEvent; + } forEach _nearSandbags; [_unit, "ACE_Sandbag_empty"] call EFUNC(common,addToInventory); -}, [_unit, _sandbag], 1.5] call CBA_fnc_waitAndExecute; +}, [_unit, _sandbag], 1] call CBA_fnc_waitAndExecute; diff --git a/addons/sandbag/stringtable.xml b/addons/sandbag/stringtable.xml index 8aadb390e88..e0f1122acd7 100644 --- a/addons/sandbag/stringtable.xml +++ b/addons/sandbag/stringtable.xml @@ -182,22 +182,20 @@ Ящик мішків із піском - Rotate - Otočit - Tourner - Girar - Rotazione - Obrót - Rotaciona - Bращать - Drehen - 돌리기 - 回転 - 旋轉 - 旋转 - Yönlendir - Forgatás - Обертати + Distance | (Ctrl + Scroll) Rotate | (Alt + Scroll) Height + Vzdálenost | (Ctrl + Kolečko myši) Otáčet | (Alt + Kolečko myši) Výška + Distance | (Ctrl + Scroll) Rotation | (Alt + Scroll) Hauteur + Distancia | (Ctrl + Scroll) Rotar | (Alt + Scroll) Altura + Distanza | (Ctrl + Rotellina) Ruota | (Alt + Rotellina) Altezza + Odległość | (Ctrl + Kółko myszy) obracanie | (Alt + Kółko myszy) Wysokość + Distância | (Ctrl + Scroll) Rotacionar | (Alt + Scroll) Altura + Дистанция | (Ctrl + Скролл) Крутить | (Alt + Скролл) Высота + Entfernung | (Strg + Scrollen) Drehen | (Alt + Scrollen) Höhe + 거리 | (컨트롤 + 스크롤) 회전 | (Alt + 스크롤) 고도 + 距離 | (Ctrl + スクロール) 回転 | (Alt + スクロール) 高さ + 距离 |(Ctrl + 鼠标滚轮)旋转 |(Alt + 鼠标滚轮)高度 + Mesafe | (Ctrl + Tekerlek) Döndür | (Alt + Tekerlek) Yükseklik + Дистанція | (Ctrl + Скрол) Крутити | (Alt + Скрол) Висота Sandbag (empty) From c61769e704cd4f74ed80f65996c2ba8c9511d796 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 7 Feb 2026 09:49:28 +0100 Subject: [PATCH 2/6] Handle locality better --- addons/sandbag/XEH_postInit.sqf | 22 +++++++---- addons/sandbag/functions/fnc_deploy.sqf | 12 +++--- addons/sandbag/functions/fnc_deployCancel.sqf | 37 ++++++++++++------- .../sandbag/functions/fnc_deployConfirm.sqf | 17 ++++++--- .../functions/fnc_handleDeployInterrupt.sqf | 6 +-- 5 files changed, 57 insertions(+), 37 deletions(-) diff --git a/addons/sandbag/XEH_postInit.sqf b/addons/sandbag/XEH_postInit.sqf index 3bb6bea7d5d..a6bd205e018 100644 --- a/addons/sandbag/XEH_postInit.sqf +++ b/addons/sandbag/XEH_postInit.sqf @@ -7,7 +7,6 @@ if (isServer) then { if (!hasInterface) exitWith {}; -GVAR(sandBag) = objNull; GVAR(deployPFH) = -1; GVAR(deployDistance) = -1; GVAR(deployDirection) = 0; @@ -25,20 +24,27 @@ GVAR(deployHeight) = 0; // When changing feature cameras, stop deployment ["featureCamera", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; -// Handle falling unconscious while trying to deploy -["ace_unconscious", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addEventHandler; - // Handle death [QGVAR(killedEH), "Killed", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addBISPlayerEventHandler; +// Handle falling unconscious while trying to deploy +["ace_unconscious", { + params ["_unit", "_isUnconscious"]; + + // Since global event, let clients handle local objects themselves + if !(_isUnconscious && local _unit) exitWith {}; + + _unit call FUNC(handleDeployInterrupt); +}] call CBA_fnc_addEventHandler; + // Handle surrendering and handcuffing ["ace_captiveStatusChanged", { params ["_unit", "_state"]; - // If surrendered or handcuffed, stop deployment - if (_state) then { - _unit call FUNC(handleDeployInterrupt); - }; + // If surrendered or handcuffed, stop deployment; Since global event, let clients handle local objects themselves + if !(_state && local _unit) exitWith {}; + + _unit call FUNC(handleDeployInterrupt); }] call CBA_fnc_addEventHandler; if (["ace_dragging"] call EFUNC(common,isModLoaded)) then { diff --git a/addons/sandbag/functions/fnc_deploy.sqf b/addons/sandbag/functions/fnc_deploy.sqf index 41cb16d3c23..431ecc94f47 100644 --- a/addons/sandbag/functions/fnc_deploy.sqf +++ b/addons/sandbag/functions/fnc_deploy.sqf @@ -24,8 +24,6 @@ params ["_unit"]; // Create the sandbag private _sandBag = createVehicle ["ACE_SandbagObject_NoGeo", [0, 0, 0], [], 0, "NONE"]; -GVAR(sandBag) = _sandBag; - // Prevent collisions with sandbag [QEGVAR(common,enableSimulationGlobal), [_sandBag, false]] call CBA_fnc_serverEvent; @@ -48,10 +46,12 @@ GVAR(deployPFH) = [{ // Add mouse button action and hint [LLSTRING(confirmDeployment), LLSTRING(cancelDeployment), LLSTRING(scrollAction)] call EFUNC(interaction,showMouseHint); -_unit setVariable [QGVAR(Deploy), [ - _unit, "DefaultAction", +// Intercept left mouse button to confirm sandbag deployment +_unit setVariable [QGVAR(deploy), [ + _unit, + "DefaultAction", {GVAR(deployPFH) != -1}, - {[_this select 1] call FUNC(deployConfirm)} + {(_this select 1) call FUNC(deployConfirm)} ] call EFUNC(common,addActionEventHandler)]; -_unit setVariable [QGVAR(isDeploying), true, true]; +_unit setVariable [QGVAR(sandbag), _sandBag, true]; diff --git a/addons/sandbag/functions/fnc_deployCancel.sqf b/addons/sandbag/functions/fnc_deployCancel.sqf index f1b3caef1f3..5b8954f6bac 100644 --- a/addons/sandbag/functions/fnc_deployCancel.sqf +++ b/addons/sandbag/functions/fnc_deployCancel.sqf @@ -15,25 +15,36 @@ * Public: No */ -if (GVAR(deployPFH) == -1) exitWith {}; - -// Remove deployment PFH -GVAR(deployPFH) call CBA_fnc_removePerFrameHandler; -GVAR(deployPFH) = -1; - params ["_unit"]; // Enable running again [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); -// Delete placement dummy -deleteVehicle GVAR(sandBag); +private _sandbag = _unit getVariable [QGVAR(sandBag), objNull]; -// Remove mouse button actions -call EFUNC(interaction,hideMouseHint); +// Delete placement dummy, if present (don't early exit, in case dummy was deleted by something else) +if (!isNull _sandbag) then { + deleteVehicle _sandbag; + + _unit setVariable [QGVAR(sandbag), nil, true]; +}; + +// Stop intercepting left mouse button +private _ehID = _unit getVariable [QGVAR(deploy), -1]; -[_unit, "DefaultAction", _unit getVariable [QGVAR(deploy), -1]] call EFUNC(common,removeActionEventHandler); -_unit setVariable [QGVAR(deploy), nil]; +if (_ehID != -1) then { + [_unit, "DefaultAction", _ehID] call EFUNC(common,removeActionEventHandler); -_unit setVariable [QGVAR(isDeploying), nil, true]; + _unit setVariable [QGVAR(deploy), nil]; +}; + +// Only remove deployment PFH if unit is current player +if (_unit != ACE_player || {GVAR(deployPFH) == -1}) exitWith {}; + +// Remove deployment PFH +GVAR(deployPFH) call CBA_fnc_removePerFrameHandler; +GVAR(deployPFH) = -1; + +// Remove mouse button actions +call EFUNC(interaction,hideMouseHint); diff --git a/addons/sandbag/functions/fnc_deployConfirm.sqf b/addons/sandbag/functions/fnc_deployConfirm.sqf index 04ea807c0cf..e4b34aef085 100644 --- a/addons/sandbag/functions/fnc_deployConfirm.sqf +++ b/addons/sandbag/functions/fnc_deployConfirm.sqf @@ -15,19 +15,22 @@ * Public: No */ -if (GVAR(deployPFH) == -1) exitWith {}; +params ["_unit"]; -// Save placement dummy data -private _position = getPosASL GVAR(sandBag); -private _direction = getDir GVAR(sandBag); +private _sandbag = _unit getVariable [QGVAR(sandBag), objNull]; -params ["_unit"]; +// Save placement dummy data; Need to check now, as it's deleted later +private _dummyDeleted = isNull _sandbag; +private _position = getPosASL _sandbag; +private _direction = getDir _sandbag; // Clean up hints and dummy _unit call FUNC(deployCancel); // Make sure unit still has empty sandbag, otherwise quit -if (!alive _unit || {!([_unit, "ACE_Sandbag_empty"] call EFUNC(common,hasItem))}) exitWith {}; +if (_dummyDeleted || {!alive _unit} || {!([_unit, "ACE_Sandbag_empty"] call EFUNC(common,hasItem))}) exitWith {}; + +_unit setVariable [QGVAR(isUsingSandbag), true]; // Play animation [_unit, "PutDown"] call EFUNC(common,doGesture); @@ -35,6 +38,8 @@ if (!alive _unit || {!([_unit, "ACE_Sandbag_empty"] call EFUNC(common,hasItem))} [{ params ["_unit", "_direction", "_position"]; + _unit setVariable [QGVAR(isUsingSandbag), false]; + // Make sure unit still has empty sandbag, otherwise quit if (!alive _unit || {!([_unit, "ACE_Sandbag_empty"] call EFUNC(common,hasItem))}) exitWith {}; diff --git a/addons/sandbag/functions/fnc_handleDeployInterrupt.sqf b/addons/sandbag/functions/fnc_handleDeployInterrupt.sqf index 0301e333ac7..ee46ce9e3c6 100644 --- a/addons/sandbag/functions/fnc_handleDeployInterrupt.sqf +++ b/addons/sandbag/functions/fnc_handleDeployInterrupt.sqf @@ -20,12 +20,10 @@ params ["_newPlayer", ["_oldPlayer", objNull], ["_ignoreItemCheck", true]]; TRACE_3("params",_newPlayer,_oldPlayer,_ignoreItemCheck); -if (!local _newPlayer) exitWith {}; - -if (_newPlayer getVariable [QGVAR(isDeploying), false] && {_ignoreItemCheck || {!([_newPlayer, "ACE_Sandbag_empty"] call EFUNC(common,hasItem))}}) then { +if (_ignoreItemCheck || {!([_newPlayer, "ACE_Sandbag_empty"] call EFUNC(common,hasItem))}) then { _newPlayer call FUNC(deployCancel); }; -if (_oldPlayer getVariable [QGVAR(isDeploying), false]) then { +if (!isNull _oldPlayer) then { _oldPlayer call FUNC(deployCancel); }; From 4b85c5fb71d99965e821dd39ed4029ea2b7a1694 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 7 Feb 2026 10:07:21 +0100 Subject: [PATCH 3/6] Fix bad path --- addons/sandbag/CfgVehicles.hpp | 6 +++--- addons/sandbag/XEH_postInit.sqf | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/sandbag/CfgVehicles.hpp b/addons/sandbag/CfgVehicles.hpp index 46c54aacfeb..25ce2e37a41 100644 --- a/addons/sandbag/CfgVehicles.hpp +++ b/addons/sandbag/CfgVehicles.hpp @@ -58,9 +58,9 @@ class CfgVehicles { class Damage { tex[] = {}; mat[] = { - QPATHTOF(data\bag_destruct.rvmat), - QPATHTOF(data\bag_destruct.rvmat), - QPATHTOF(data\bag_destruct.rvmat) + QPATHTO_R(data\bag_destruct.rvmat), + QPATHTO_R(data\bag_destruct.rvmat), + QPATHTO_R(data\bag_destruct.rvmat) }; }; diff --git a/addons/sandbag/XEH_postInit.sqf b/addons/sandbag/XEH_postInit.sqf index a6bd205e018..d1fe26b314b 100644 --- a/addons/sandbag/XEH_postInit.sqf +++ b/addons/sandbag/XEH_postInit.sqf @@ -32,7 +32,7 @@ GVAR(deployHeight) = 0; params ["_unit", "_isUnconscious"]; // Since global event, let clients handle local objects themselves - if !(_isUnconscious && local _unit) exitWith {}; + if !(_isUnconscious && {local _unit}) exitWith {}; _unit call FUNC(handleDeployInterrupt); }] call CBA_fnc_addEventHandler; @@ -42,7 +42,7 @@ GVAR(deployHeight) = 0; params ["_unit", "_state"]; // If surrendered or handcuffed, stop deployment; Since global event, let clients handle local objects themselves - if !(_state && local _unit) exitWith {}; + if !(_state && {local _unit}) exitWith {}; _unit call FUNC(handleDeployInterrupt); }] call CBA_fnc_addEventHandler; From 72c794f2c71a169461d9f4dd958de44c1ee990a9 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sat, 7 Feb 2026 10:47:06 +0100 Subject: [PATCH 4/6] Remove unnecessary function --- addons/sandbag/XEH_PREP.hpp | 1 - addons/sandbag/XEH_missionDisplayLoad.sqf | 2 +- addons/sandbag/XEH_postInit.sqf | 45 ++++++++++++------- addons/sandbag/functions/fnc_deployCancel.sqf | 4 +- .../functions/fnc_handleDeployInterrupt.sqf | 29 ------------ 5 files changed, 34 insertions(+), 47 deletions(-) delete mode 100644 addons/sandbag/functions/fnc_handleDeployInterrupt.sqf diff --git a/addons/sandbag/XEH_PREP.hpp b/addons/sandbag/XEH_PREP.hpp index 273fb262aaf..891b21e24f3 100644 --- a/addons/sandbag/XEH_PREP.hpp +++ b/addons/sandbag/XEH_PREP.hpp @@ -2,6 +2,5 @@ PREP(canDeploy); PREP(deploy); PREP(deployCancel); PREP(deployConfirm); -PREP(handleDeployInterrupt); PREP(handleScrollWheel); PREP(pickup); diff --git a/addons/sandbag/XEH_missionDisplayLoad.sqf b/addons/sandbag/XEH_missionDisplayLoad.sqf index 7bdea7571fe..c4966178335 100644 --- a/addons/sandbag/XEH_missionDisplayLoad.sqf +++ b/addons/sandbag/XEH_missionDisplayLoad.sqf @@ -6,6 +6,6 @@ _display displayAddEventHandler ["MouseZChanged", {(_this select 1) call FUNC(ha _display displayAddEventHandler ["MouseButtonDown", { // Right clicking cancels deployment if (_this select 1 == 1) then { - ACE_player call FUNC(handleDeployInterrupt); + ACE_player call FUNC(deployCancel); }; }]; diff --git a/addons/sandbag/XEH_postInit.sqf b/addons/sandbag/XEH_postInit.sqf index d1fe26b314b..1bcb3a90685 100644 --- a/addons/sandbag/XEH_postInit.sqf +++ b/addons/sandbag/XEH_postInit.sqf @@ -2,30 +2,45 @@ if (isServer) then { // Cancel deploy on hard disconnection. Function is identical to interrupted - addMissionEventHandler ["HandleDisconnect", {(_this select 0) call FUNC(handleDeployInterrupt)}]; + addMissionEventHandler ["HandleDisconnect", {(_this select 0) call FUNC(deployCancel)}]; }; +// To be safe for FUNC(deployCancel) if called by dedicated server +GVAR(deployPFH) = -1; + if (!hasInterface) exitWith {}; -GVAR(deployPFH) = -1; GVAR(deployDistance) = -1; GVAR(deployDirection) = 0; GVAR(deployHeight) = 0; -// Cancel object deployment if interact menu opened -["ace_interactMenuOpened", {ACE_player call FUNC(handleDeployInterrupt)}] call CBA_fnc_addEventHandler; - // Cancel deploy on player change. This does work when returning to lobby, but not when hard disconnecting -["unit", LINKFUNC(handleDeployInterrupt)] call CBA_fnc_addPlayerEventHandler; -["vehicle", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; -["weapon", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; -["loadout", {[_this select 0, objNull, false] call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; +["unit", { + params ["_newPlayer", "_oldPlayer"]; + + _newPlayer call FUNC(deployCancel); + _oldPlayer call FUNC(deployCancel); +}] call CBA_fnc_addPlayerEventHandler; -// When changing feature cameras, stop deployment -["featureCamera", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; +// Handle loadout change +["loadout", { + params ["_unit"]; + + // If the unit still has a sandbag, don't cancel deployment + if ([_unit, "ACE_Sandbag_empty"] call EFUNC(common,hasItem)) exitWith {}; + + _unit call FUNC(deployCancel); +}] call CBA_fnc_addPlayerEventHandler; + +["vehicle", {(_this select 0) call FUNC(deployCancel)}] call CBA_fnc_addPlayerEventHandler; +["weapon", {(_this select 0) call FUNC(deployCancel)}] call CBA_fnc_addPlayerEventHandler; +["featureCamera", {(_this select 0) call FUNC(deployCancel)}] call CBA_fnc_addPlayerEventHandler; // Handle death -[QGVAR(killedEH), "Killed", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addBISPlayerEventHandler; +[QGVAR(killedEH), "Killed", {(_this select 0) call FUNC(deployCancel)}] call CBA_fnc_addBISPlayerEventHandler; + +// Cancel object deployment if interact menu opened +["ace_interactMenuOpened", {ACE_player call FUNC(deployCancel)}] call CBA_fnc_addEventHandler; // Handle falling unconscious while trying to deploy ["ace_unconscious", { @@ -34,17 +49,17 @@ GVAR(deployHeight) = 0; // Since global event, let clients handle local objects themselves if !(_isUnconscious && {local _unit}) exitWith {}; - _unit call FUNC(handleDeployInterrupt); + _unit call FUNC(deployCancel); }] call CBA_fnc_addEventHandler; // Handle surrendering and handcuffing ["ace_captiveStatusChanged", { params ["_unit", "_state"]; - // If surrendered or handcuffed, stop deployment; Since global event, let clients handle local objects themselves + // Since global event, let clients handle local objects themselves if !(_state && {local _unit}) exitWith {}; - _unit call FUNC(handleDeployInterrupt); + _unit call FUNC(deployCancel); }] call CBA_fnc_addEventHandler; if (["ace_dragging"] call EFUNC(common,isModLoaded)) then { diff --git a/addons/sandbag/functions/fnc_deployCancel.sqf b/addons/sandbag/functions/fnc_deployCancel.sqf index 5b8954f6bac..76923a65535 100644 --- a/addons/sandbag/functions/fnc_deployCancel.sqf +++ b/addons/sandbag/functions/fnc_deployCancel.sqf @@ -17,13 +17,15 @@ params ["_unit"]; +if (isNull _unit) exitWith {}; + // Enable running again [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); [_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); private _sandbag = _unit getVariable [QGVAR(sandBag), objNull]; -// Delete placement dummy, if present (don't early exit, in case dummy was deleted by something else) +// Delete placement dummy, if present (don't early exit, in case dummy was deleted by something else, as still need to clean up) if (!isNull _sandbag) then { deleteVehicle _sandbag; diff --git a/addons/sandbag/functions/fnc_handleDeployInterrupt.sqf b/addons/sandbag/functions/fnc_handleDeployInterrupt.sqf deleted file mode 100644 index ee46ce9e3c6..00000000000 --- a/addons/sandbag/functions/fnc_handleDeployInterrupt.sqf +++ /dev/null @@ -1,29 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Handles various interruption types. - * - * Arguments: - * 0: (New) unit - * 1: Old unit (for player change) (default: objNull) - * 2: Ignore item check (default: true) - * - * Return Value: - * None - * - * Example: - * player call ace_sandbag_fnc_handleDeployInterrupt - * - * Public: No -*/ - -params ["_newPlayer", ["_oldPlayer", objNull], ["_ignoreItemCheck", true]]; -TRACE_3("params",_newPlayer,_oldPlayer,_ignoreItemCheck); - -if (_ignoreItemCheck || {!([_newPlayer, "ACE_Sandbag_empty"] call EFUNC(common,hasItem))}) then { - _newPlayer call FUNC(deployCancel); -}; - -if (!isNull _oldPlayer) then { - _oldPlayer call FUNC(deployCancel); -}; From 509671c087ddc9720cb29119e33b376734b52693 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 8 Feb 2026 09:52:01 -0800 Subject: [PATCH 5/6] Update addons/sandbag/functions/fnc_handleScrollWheel.sqf Co-authored-by: PabstMirror --- addons/sandbag/functions/fnc_handleScrollWheel.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sandbag/functions/fnc_handleScrollWheel.sqf b/addons/sandbag/functions/fnc_handleScrollWheel.sqf index 74164f3c82d..fa22785e4ff 100644 --- a/addons/sandbag/functions/fnc_handleScrollWheel.sqf +++ b/addons/sandbag/functions/fnc_handleScrollWheel.sqf @@ -30,7 +30,7 @@ if (CBA_events_control) exitWith { // Change height if (CBA_events_alt) exitWith { - GVAR(deployHeight) = 1.5 min (-1.5 max GVAR(deployHeight) + (_scroll * 0.1)); + GVAR(deployHeight) = 1.5 min (-1.5 max (GVAR(deployHeight) + (_scroll * 0.1))); true // return }; From ebf191b8dbe4876e63c7f7bd0088239fb429fce6 Mon Sep 17 00:00:00 2001 From: johnb432 <58661205+johnb432@users.noreply.github.com> Date: Sun, 8 Feb 2026 09:52:06 -0800 Subject: [PATCH 6/6] Update addons/sandbag/functions/fnc_handleScrollWheel.sqf Co-authored-by: PabstMirror --- addons/sandbag/functions/fnc_handleScrollWheel.sqf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/sandbag/functions/fnc_handleScrollWheel.sqf b/addons/sandbag/functions/fnc_handleScrollWheel.sqf index fa22785e4ff..86d48586275 100644 --- a/addons/sandbag/functions/fnc_handleScrollWheel.sqf +++ b/addons/sandbag/functions/fnc_handleScrollWheel.sqf @@ -36,6 +36,6 @@ if (CBA_events_alt) exitWith { }; // Change distance -GVAR(deployDistance) = 1.5 min (0.36 max GVAR(deployDistance) + (_scroll * 0.1)); +GVAR(deployDistance) = 1.5 min (0.36 max (GVAR(deployDistance) + (_scroll * 0.1))); true // return