diff --git a/addons/dragging/CfgVehicles.hpp b/addons/dragging/CfgVehicles.hpp index 89721efd97..37196b270f 100644 --- a/addons/dragging/CfgVehicles.hpp +++ b/addons/dragging/CfgVehicles.hpp @@ -3,25 +3,34 @@ class CfgVehicles { class ThingX; class ReammoBox_F: ThingX { XEH_ENABLED; + GVAR(canCarry) = 0; + GVAR(carryPosition[]) = {0,1,1}; + GVAR(carryDirection) = 0; + GVAR(canDrag) = 0; GVAR(dragPosition[]) = {0,1.2,0}; GVAR(dragDirection) = 0; }; class Slingload_base_F: ReammoBox_F { + GVAR(canCarry) = 0; GVAR(canDrag) = 0; }; class EAST_Box_Base: ReammoBox_F { + GVAR(canCarry) = 1; GVAR(canDrag) = 1; }; class IND_Box_Base: ReammoBox_F { + GVAR(canCarry) = 1; GVAR(canDrag) = 1; }; /*class FIA_Box_Base_F: ReammoBox_F { + GVAR(canCarry) = 1; GVAR(canDrag) = 1; };*/ class NATO_Box_Base: ReammoBox_F { + GVAR(canCarry) = 1; GVAR(canDrag) = 1; }; @@ -31,14 +40,17 @@ class CfgVehicles { // in order to move the bigger ones. Currently simply remove support. // I believe these crates are currently broken (hitbox doesn't work or something) in 1.22 (2014-07-04) class Box_East_AmmoVeh_F: EAST_Box_Base { + GVAR(canCarry) = 0; GVAR(canDrag) = 0; }; class Box_NATO_AmmoVeh_F: NATO_Box_Base { + GVAR(canCarry) = 0; GVAR(canDrag) = 0; }; class Box_IND_AmmoVeh_F: IND_Box_Base { + GVAR(canCarry) = 0; GVAR(canDrag) = 0; }; }; diff --git a/addons/dragging/XEH_clientInit.sqf b/addons/dragging/XEH_clientInit.sqf index a8ae492c6f..98da043742 100644 --- a/addons/dragging/XEH_clientInit.sqf +++ b/addons/dragging/XEH_clientInit.sqf @@ -10,6 +10,7 @@ if (isNil QGVAR(maxWeight)) then { }; ["isNotDragging", {!((_this select 0) getVariable [QGVAR(isDragging), false])}] call EFUNC(common,addCanInteractWithCondition); +["isNotCarrying", {!((_this select 0) getVariable [QGVAR(isCarrying), false])}] call EFUNC(common,addCanInteractWithCondition); // release object on player change. This does work when returning to lobby, but not when hard disconnecting. ["playerChanged", { diff --git a/addons/dragging/XEH_preInit.sqf b/addons/dragging/XEH_preInit.sqf index 46c3ebecb1..5428cebcd5 100644 --- a/addons/dragging/XEH_preInit.sqf +++ b/addons/dragging/XEH_preInit.sqf @@ -2,13 +2,19 @@ ADDON = false; +PREP(canCarry); PREP(canDrag); PREP(canDrop); +PREP(canDrop_carry); +PREP(carryObject); +PREP(carryObjectPFH); PREP(dragObject); PREP(dragObjectPFH); PREP(dropObject); +PREP(dropObject_carry); PREP(initObject); PREP(isObjectOnObject); +PREP(setCarryable); PREP(setDraggable); PREP(startDrag); PREP(startDragPFH); diff --git a/addons/dragging/functions/fnc_canCarry.sqf b/addons/dragging/functions/fnc_canCarry.sqf new file mode 100644 index 0000000000..6d3210776b --- /dev/null +++ b/addons/dragging/functions/fnc_canCarry.sqf @@ -0,0 +1,25 @@ +/* + * Author: commy2 + * + * Check if unit can carry the object. Doesn't check weight. + * + * Argument: + * 0: Unit that should do the carrying (Object) + * 1: Object to carry (Object) + * + * Return value: + * Can the unit carry the object? (Bool) + */ +#include "script_component.hpp" + +private ["_unit", "_target"]; + +_unit = _this select 0; +_target = _this select 1; + +if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; + +// a static weapon has to be empty for dragging +if ((typeOf _target) isKindOf "StaticWeapon" && {count crew _target > 0}) exitWith {false}; + +_target getVariable [QGVAR(canCarry), false] diff --git a/addons/dragging/functions/fnc_canDrag.sqf b/addons/dragging/functions/fnc_canDrag.sqf index 17c2ffb901..5b0c578699 100644 --- a/addons/dragging/functions/fnc_canDrag.sqf +++ b/addons/dragging/functions/fnc_canDrag.sqf @@ -21,3 +21,5 @@ if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false}; // a static weapon has to be empty for dragging if ((typeOf _target) isKindOf "StaticWeapon" && {count crew _target > 0}) exitWith {false}; + +_target getVariable [QGVAR(canDrag), false] diff --git a/addons/dragging/functions/fnc_canDrop_carry.sqf b/addons/dragging/functions/fnc_canDrop_carry.sqf new file mode 100644 index 0000000000..9efbbe9b0f --- /dev/null +++ b/addons/dragging/functions/fnc_canDrop_carry.sqf @@ -0,0 +1,22 @@ +/* + * Author: commy2 + * + * Check if unit can drop the carried object. + * + * Argument: + * 0: Unit that currently carries a object (Object) + * 1: Object that is carried (Object) + * + * Return value: + * Can the unit drop the object? (Bool) + */ +#include "script_component.hpp" + +private ["_unit", "_target"]; + +_unit = _this select 0; +_target = _this select 1; + +if !([_unit, _target, ["isNotCarrying"]] call EFUNC(common,canInteractWith)) exitWith {false}; + +_unit getVariable [QGVAR(carriedObject), objNull] == _target diff --git a/addons/dragging/functions/fnc_carryObject.sqf b/addons/dragging/functions/fnc_carryObject.sqf new file mode 100644 index 0000000000..8ebf015800 --- /dev/null +++ b/addons/dragging/functions/fnc_carryObject.sqf @@ -0,0 +1,66 @@ +/* + * Author: commy2 + * + * Carry an object. + * + * Argument: + * 0: Unit that should do the carrying (Object) + * 1: Object to carry (Object) + * + * Return value: + * NONE. + */ +#include "script_component.hpp" + +private ["_unit", "_target"]; + +_unit = _this select 0; +_target = _this select 1; + +// select no weapon and stop sprinting +_unit action ["SwitchWeapon", _unit, _unit, 99]; + +[_unit, "isDragging", true] call EFUNC(common,setforceWalkStatus); + +// prevent multiple players from accessing the same object +[_unit, _target, true] call EFUNC(common,claim); + +// get attachTo offset and direction. +private ["_position", "_direction"]; + +_position = _target getVariable [QGVAR(carryPosition), [0, 0, 0]]; +_direction = _target getVariable [QGVAR(carryDirection), 0]; + +// attach object +_target attachTo [_unit, _position]; +_target setDir _direction; + +_unit setVariable [QGVAR(isCarrying), true, true]; +_unit setVariable [QGVAR(carriedObject), _target, true]; + +// add scrollwheel action to release object +private "_actionID"; +_actionID = _unit getVariable [QGVAR(ReleaseActionID), -1]; + +if (_actionID != -1) then { + _unit removeAction _actionID; +}; + +_actionID = _unit addAction [ + format ["%1", localize "STR_ACE_Dragging_Drop"], + QUOTE([ARR_2(_this select 0, (_this select 0) getVariable [ARR_2(QUOTE(QGVAR(carriedObject)),objNull)])] call FUNC(dropObject_carry)), + nil, + 20, + false, + true, + "", + QUOTE(!isNull (_this getVariable [ARR_2(QUOTE(QGVAR(carriedObject)),objNull)])) +]; + +_unit setVariable [QGVAR(ReleaseActionID), _actionID]; + +// check everything +[FUNC(carryObjectPFH), 0, [_unit, _target]] call CBA_fnc_addPerFrameHandler; + +// reset current dragging height. +GVAR(currentHeightChange) = 0; diff --git a/addons/dragging/functions/fnc_carryObjectPFH.sqf b/addons/dragging/functions/fnc_carryObjectPFH.sqf new file mode 100644 index 0000000000..b89719c688 --- /dev/null +++ b/addons/dragging/functions/fnc_carryObjectPFH.sqf @@ -0,0 +1,30 @@ +// by commy2 +#include "script_component.hpp" + +private ["_unit", "_target"]; + +_unit = _this select 0 select 0; +_target = _this select 0 select 1; + +// drop if the player is dead +if !([_unit] call EFUNC(common,isAlive)) exitWith { + [_unit, _target] call FUNC(dropObject_carry); + [_this select 1] call CBA_fnc_removePerFrameHandler; +}; + +// drop if the crate is destroyed +if !([_target] call EFUNC(common,isAlive)) exitWith { + [_unit, _target] call FUNC(dropObject_carry); + [_this select 1] call CBA_fnc_removePerFrameHandler; +}; + +// drop if not in carrying anim. +if (currentWeapon _unit != "") exitWith { + [_unit, _target] call FUNC(dropObject_carry); + [_this select 1] call CBA_fnc_removePerFrameHandler; +}; + +if !([_unit] call EFUNC(common,isPlayer)) exitWith { + [_unit, _target] call FUNC(dropObject_carry); + [_this select 1] call CBA_fnc_removePerFrameHandler; +}; diff --git a/addons/dragging/functions/fnc_dragObjectPFH.sqf b/addons/dragging/functions/fnc_dragObjectPFH.sqf index cf8e710474..5c78f9d24b 100644 --- a/addons/dragging/functions/fnc_dragObjectPFH.sqf +++ b/addons/dragging/functions/fnc_dragObjectPFH.sqf @@ -24,6 +24,11 @@ if !(animationState _unit in DRAG_ANIMATIONS) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; }; +if (currentWeapon _unit != primaryWeapon _unit) exitWith { + [_unit, _target] call FUNC(dropObject); + [_this select 1] call CBA_fnc_removePerFrameHandler; +}; + if !([_unit] call EFUNC(common,isPlayer)) exitWith { [_unit, _target] call FUNC(dropObject); [_this select 1] call CBA_fnc_removePerFrameHandler; diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf new file mode 100644 index 0000000000..0751936f88 --- /dev/null +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -0,0 +1,49 @@ +/* + * Author: commy2 + * + * Drop a carried object. + * + * Argument: + * 0: Unit that carries the other object (Object) + * 1: Carried object to drop (Object) + * + * Return value: + * NONE. + */ +#include "script_component.hpp" + +private ["_unit", "_target"]; + +_unit = _this select 0; +_target = _this select 1; + +// remove scroll wheel action +_unit removeAction (_unit getVariable [QGVAR(ReleaseActionID), -1]); + +private "_inBuilding"; +_inBuilding = [_unit] call FUNC(isObjectOnObject); + +// prevent collision damage +["fixCollision", _unit, _unit] call EFUNC(common,targetEvent); +["fixCollision", _target, _target] call EFUNC(common,targetEvent); + +// release object +detach _target; + +// reselect weapon and re-enable sprint +_unit selectWeapon primaryWeapon _unit; + +[_unit, "isDragging", false] call EFUNC(common,setforceWalkStatus); + +// prevent object from flipping inside buildings +if (_inBuilding) then { + _target setPosASL (getPosASL _target vectorAdd [0, 0, 0.05]); +}; + +_unit setVariable [QGVAR(isCarrying), false, true]; +_unit setVariable [QGVAR(carriedObject), objNull, true]; + +// make object accesable for other units +[objNull, _target, true] call EFUNC(common,claim); + +["fixPosition", _target, _target] call EFUNC(common,targetEvent); diff --git a/addons/dragging/functions/fnc_initObject.sqf b/addons/dragging/functions/fnc_initObject.sqf index 3d1f51ad21..65866bd028 100644 --- a/addons/dragging/functions/fnc_initObject.sqf +++ b/addons/dragging/functions/fnc_initObject.sqf @@ -1,7 +1,7 @@ /* * Author: commy2 * - * Initialize variables for dragable objects. Called from init EH. + * Initialize variables for drag or carryable objects. Called from init EH. * * Argument: * 0: Any object (Object) @@ -15,11 +15,23 @@ private "_object"; _object = _this select 0; -if (getNumber (configFile >> "CfgVehicles" >> typeOf _object >> QGVAR(canDrag)) == 1) then { +private "_config"; +_config = configFile >> "CfgVehicles" >> typeOf _object; + +if (getNumber (_config >> QGVAR(canDrag)) == 1) then { private ["_position", "_direction"]; - _position = getArray (configFile >> "CfgVehicles" >> typeOf _object >> QGVAR(dragPosition)); - _direction = getNumber (configFile >> "CfgVehicles" >> typeOf _object >> QGVAR(dragDirection)); + _position = getArray (_config >> QGVAR(dragPosition)); + _direction = getNumber (_config >> QGVAR(dragDirection)); [_object, true, _position, _direction] call FUNC(setDraggable); }; + +if (getNumber (_config >> QGVAR(canCarry)) == 1) then { + private ["_position", "_direction"]; + + _position = getArray (_config >> QGVAR(carryPosition)); + _direction = getNumber (_config >> QGVAR(carryDirection)); + + [_object, true, _position, _direction] call FUNC(setCarryable); +}; diff --git a/addons/dragging/functions/fnc_setCarryable.sqf b/addons/dragging/functions/fnc_setCarryable.sqf new file mode 100644 index 0000000000..52de076982 --- /dev/null +++ b/addons/dragging/functions/fnc_setCarryable.sqf @@ -0,0 +1,52 @@ +/* + * Author: commy2 + * + * Enable the object to be carried. + * + * Argument: + * 0: Any object (Object) + * 1: true to enable carrying, false to disable (Bool) + * 2: Position offset for attachTo command (Array, optinal; default: [0,0,0]) + * 3: Direction in degree to rotate the object after attachTo (Number, optional; default: 0) + * + * Return value: + * NONE. + */ +#include "script_component.hpp" + +private ["_object", "_enableCarry", "_position", "_direction"]; + +_this resize 4; + +_object = _this select 0; +_enableCarry = _this select 1; +_position = _this select 2; +_direction = _this select 3; + +if (isNil "_position") then { + _position = _object getVariable [QGVAR(carryPosition), [0,0,0]]; +}; + +if (isNil "_direction") then { + _direction = _object getVariable [QGVAR(carryDirection), 0]; +}; + +// update variables +_object setVariable [QGVAR(canCarry), _enableCarry]; +_object setVariable [QGVAR(carryPosition), _position]; +_object setVariable [QGVAR(carryDirection), _direction]; + +// add action to class if it is not already present +private ["_type", "_initializedClasses"]; + +_type = typeOf _object; +_initializedClasses = GETGVAR(initializedClasses_carry,[]); + +// do nothing if the class is already initialized +if (_type in _initializedClasses) exitWith {}; + +_initializedClasses pushBack _type; +GVAR(initializedClasses_carry) = _initializedClasses; + +[_type, 0, ["ACE_MainActions", QGVAR(carry)], localize "STR_ACE_Dragging_Carry", "", "", {[_player, _target] call FUNC(carryObject)}, {[_player, _target] call FUNC(canCarry)}, 2] call EFUNC(interact_menu,addClassAction); +[_type, 0, ["ACE_MainActions", QGVAR(drop_carry)], localize "STR_ACE_Dragging_Drop", "", "", {[_player, _target] call FUNC(dropObject_carry)}, {[_player, _target] call FUNC(canDrop_carry)}, 2] call EFUNC(interact_menu,addClassAction);