diff --git a/addons/dragging/CfgEventHandlers.hpp b/addons/dragging/CfgEventHandlers.hpp index d1f8a87636..8903f2ded8 100644 --- a/addons/dragging/CfgEventHandlers.hpp +++ b/addons/dragging/CfgEventHandlers.hpp @@ -40,6 +40,11 @@ class Extended_Init_EventHandlers { init = QUOTE(_this call DFUNC(initObject)); }; }; + class WeaponHolder { + class ADDON { + init = QUOTE(_this call DFUNC(initObject)); + }; + }; class Land_Camping_Light_F { class ADDON { init = QUOTE(_this call DFUNC(initObject)); diff --git a/addons/dragging/CfgVehicles.hpp b/addons/dragging/CfgVehicles.hpp index cea1675565..c972a6514f 100644 --- a/addons/dragging/CfgVehicles.hpp +++ b/addons/dragging/CfgVehicles.hpp @@ -226,6 +226,32 @@ class CfgVehicles { GVAR(canCarry) = 1; }; + // weapons dropped from dead body + class WeaponHolderSimulated: ThingX { + GVAR(canCarry) = 1; + GVAR(carryPosition[]) = {0,0.5,1.3}; + GVAR(carryDirection) = 0; + + // z-position floats from -1.2 to >0 + // it's OK for carrying but odd for dragging + // needs workaround to drag correctly. Disabled ATM + GVAR(canDrag) = 0; + GVAR(dragPosition[]) = {0,1,0}; + GVAR(dragDirection) = 0; + }; + + class ReammoBox; + // dropped weapons/gear + class WeaponHolder: ReammoBox { + GVAR(canCarry) = 1; + GVAR(carryPosition[]) = {0,0.5,1}; + GVAR(carryDirection) = 0; + + GVAR(canDrag) = 1; + GVAR(dragPosition[]) = {0,1,0}; + GVAR(dragDirection) = 0; + }; + class Lamps_base_F; class Land_PortableLight_single_F: Lamps_base_F { GVAR(canCarry) = 1; diff --git a/addons/dragging/functions/fnc_canCarry.sqf b/addons/dragging/functions/fnc_canCarry.sqf index 2483903eef..41fc983ba7 100644 --- a/addons/dragging/functions/fnc_canCarry.sqf +++ b/addons/dragging/functions/fnc_canCarry.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: commy2 + * Author: commy2, Dystopian * Check if unit can carry the object. Doesn't check weight. * * Arguments: @@ -11,20 +11,35 @@ * Can the unit carry the object? * * Example: - * [player, cursorTarget] call ace_dragging_fnc_canCarry; + * [player, cursorTarget] call ace_dragging_fnc_canCarry * * Public: No */ params ["_unit", "_target"]; +if !(alive _target && {_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}; -// a static weapon has to be empty for dragging (ignore UAV AI) -if (((typeOf _target) isKindOf "StaticWeapon") && {{(getText (configOf _x >> "simulation")) != "UAVPilot"} count crew _target > 0}) exitWith {false}; +// Static weapons need to be empty for carrying (ignore UAV AI) +if (_target isKindOf "StaticWeapon") exitWith { + crew _target findIf {getText (configOf _x >> "simulation") != "UAVPilot"} == -1 +}; -alive _target && {vehicle _target isEqualto _target} && {_target getVariable [QGVAR(canCarry), false]} && {animationState _target in ["", "unconscious"] || (_target getVariable ["ACE_isUnconscious", false]) || (_target isKindOf "CAManBase" && {(_target getHitPointDamage "HitLegs") > 0.4})} +// Units need to be unconscious or be limping +if (_target isKindOf "CAManBase") exitWith { + lifeState _target isEqualTo "INCAPACITATED" + || {_target getHitPointDamage "HitLegs" > 0.4} +}; + +// Check max items for WeaponHolders +if (["WeaponHolder", "WeaponHolderSimulated"] findIf {_target isKindOf _x} != -1) exitWith { + (count (weaponCargo _target + magazineCargo _target + itemCargo _target)) <= MAX_DRAGGED_ITEMS +}; + +true // return diff --git a/addons/dragging/functions/fnc_canDrag.sqf b/addons/dragging/functions/fnc_canDrag.sqf index afc679e375..82cb33068b 100644 --- a/addons/dragging/functions/fnc_canDrag.sqf +++ b/addons/dragging/functions/fnc_canDrag.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" /* - * Author: commy2 + * Author: commy2, Dystopian * Check if unit can drag the object. Doesn't check weight. * * Arguments: @@ -11,16 +11,31 @@ * Can the unit drag the object? * * Example: - * [player, cursorTarget] call ace_dragging_fnc_canDrag; + * [player, cursorTarget] call ace_dragging_fnc_canDrag * * Public: No */ params ["_unit", "_target"]; +if !(alive _target && {_target getVariable [QGVAR(canDrag), false]} && {isNull objectParent _target}) exitWith {false}; + if !([_unit, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; -// a static weapon has to be empty for dragging (ignore UAV AI) -if ((typeOf _target) isKindOf "StaticWeapon" && {{(getText (configOf _x >> "simulation")) != "UAVPilot"} count crew _target > 0}) exitWith {false}; +// Static weapons need to be empty for dragging (ignore UAV AI) +if (_target isKindOf "StaticWeapon") exitWith { + crew _target findIf {getText (configOf _x >> "simulation") != "UAVPilot"} == -1 +}; -alive _target && {vehicle _target isEqualto _target} && {_target getVariable [QGVAR(canDrag), false]} && {animationState _target in ["", "unconscious"] || (_target getVariable ["ACE_isUnconscious", false]) || (_target isKindOf "CAManBase" && {(_target getHitPointDamage "HitLegs") > 0.4})} +// Units need to be unconscious or be limping +if (_target isKindOf "CAManBase") exitWith { + lifeState _target isEqualTo "INCAPACITATED" + || {_target getHitPointDamage "HitLegs" > 0.4} +}; + +// Check max items for WeaponHolders +if (["WeaponHolder", "WeaponHolderSimulated"] findIf {_target isKindOf _x} != -1) exitWith { + (count (weaponCargo _target + magazineCargo _target + itemCargo _target)) <= MAX_DRAGGED_ITEMS +}; + +true // return diff --git a/addons/dragging/script_component.hpp b/addons/dragging/script_component.hpp index 5befaede9c..ed1ad0fb37 100644 --- a/addons/dragging/script_component.hpp +++ b/addons/dragging/script_component.hpp @@ -20,3 +20,5 @@ #define DRAG_ANIMATIONS ["amovpercmstpslowwrfldnon_acinpknlmwlkslowwrfldb_2", "amovpercmstpsraswpstdnon_acinpknlmwlksnonwpstdb_2", "amovpercmstpsnonwnondnon_acinpknlmwlksnonwnondb_2", "acinpknlmstpsraswrfldnon", "acinpknlmstpsnonwpstdnon", "acinpknlmstpsnonwnondnon", "acinpknlmwlksraswrfldb", "acinpknlmwlksnonwnondb", "ace_dragging", "ace_dragging_static", "ace_dragging_drop"] #define CARRY_ANIMATIONS ["acinpercmstpsnonwnondnon", "acinpknlmstpsnonwnondnon_acinpercmrunsnonwnondnon"] + +#define MAX_DRAGGED_ITEMS 3 diff --git a/addons/interaction/CfgVehicles.hpp b/addons/interaction/CfgVehicles.hpp index c88e93c095..57753dfaff 100644 --- a/addons/interaction/CfgVehicles.hpp +++ b/addons/interaction/CfgVehicles.hpp @@ -162,6 +162,12 @@ class CfgVehicles { exceptions[] = {"isNotSwimming"}; icon = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\getout_ca.paa"; }; + class GVAR(Gear) { + displayName = "$STR_ACTION_GEAR"; + condition = QUOTE(!(lifeState _target in [ARR_2('HEALTHY','INJURED')]) && {isNull objectParent _target}); + statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)),_target)]); + icon = "\A3\ui_f\data\igui\cfg\actions\gear_ca.paa"; + }; }; class ACE_Torso { @@ -693,6 +699,41 @@ class CfgVehicles { class ACE_SelfActions {}; }; + // weapons dropped from dead body + class WeaponHolderSimulated: ThingX { + class ACE_Actions { + class ACE_MainActions { + displayName = CSTRING(MainAction); + distance = 3; + position = QUOTE(_target worldToModel ASLToAGL getPosASL _target); + + class GVAR(Gear) { + displayName = "$STR_ACTION_GEAR"; + statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)),_target)]); + icon = "\A3\ui_f\data\igui\cfg\actions\gear_ca.paa"; + }; + }; + }; + }; + + class ReammoBox; + // dropped weapons/gear + class WeaponHolder: ReammoBox { + class ACE_Actions { + class ACE_MainActions { + displayName = CSTRING(MainAction); + distance = 3; + position = QUOTE(_target worldToModel ASLToAGL getPosASL _target); + + class GVAR(Gear) { + displayName = "$STR_ACTION_GEAR"; + statement = QUOTE(_player action [ARR_2(QUOTE(QUOTE(Gear)),_target)]); + icon = "\A3\ui_f\data\igui\cfg\actions\gear_ca.paa"; + }; + }; + }; + }; + class Lamps_base_F; class Land_PortableLight_single_F: Lamps_base_F { class EventHandlers { diff --git a/addons/interaction/XEH_postInit.sqf b/addons/interaction/XEH_postInit.sqf index 6d7d96713c..75e92c02c9 100644 --- a/addons/interaction/XEH_postInit.sqf +++ b/addons/interaction/XEH_postInit.sqf @@ -161,3 +161,21 @@ GVAR(isOpeningDoor) = false; [QGVAR(clearWeaponAttachmentsActionsCache)] call CBA_fnc_localEvent; }] call CBA_fnc_addPlayerEventHandler; } forEach ["loadout", "weapon"]; + + +// add "Take _weapon_" action to dropped weapons +private _action = [ + // action display name will be overwritten in modifier function + QGVAR(takeWeapon), "take", "\A3\ui_f\data\igui\cfg\actions\take_ca.paa", + {_player action ["TakeWeapon", _target, weaponCargo _target select 0]}, + {count weaponCargo _target == 1}, + nil, nil, nil, nil, nil, + { + params ["_target", "", "", "_actionData"]; + _actionData set [1, format [localize "STR_ACTION_TAKE_BAG", getText (configfile >> "CfgWeapons" >> weaponCargo _target select 0 >> "displayName")]]; + } +] call EFUNC(interact_menu,createAction); + +{ + [_x, 0, ["ACE_MainActions"], _action, true] call EFUNC(interact_menu,addActionToClass); +} forEach ["WeaponHolder", "WeaponHolderSimulated"];