Interaction - Add actions to access and allow carrying inventory holders (#6029)

* Add interaction to inventory holders

* Add Take Weapon action

* Add Drag/Carry actions

* Fix menu position

* Add Inventory action also to unconscious

* Underwater: Fix menu position, disable gear action

* Add dead body weapons carrying with workaround

* Disable man gear action in water

* Optimize position code

* Fix macro using

* Use macro and power

* Restrict max dragged items count

* Remove superfluous condition, Add Take action to all holders

* Cleanup XEH

* Remove weapon carry-drop workaround

* code style changes

* code style changes

* brackets, isEqualTo, vehicle check

* code style changes

* brackets, isEqualTo, vehicle check

---------

Co-authored-by: Salluci <salluci.lovi@gmail.com>
This commit is contained in:
Dystopian 2023-07-10 05:49:37 +03:00 committed by GitHub
parent e181ba5aa1
commit 1b8c56f0be
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 132 additions and 10 deletions

View File

@ -40,6 +40,11 @@ class Extended_Init_EventHandlers {
init = QUOTE(_this call DFUNC(initObject)); init = QUOTE(_this call DFUNC(initObject));
}; };
}; };
class WeaponHolder {
class ADDON {
init = QUOTE(_this call DFUNC(initObject));
};
};
class Land_Camping_Light_F { class Land_Camping_Light_F {
class ADDON { class ADDON {
init = QUOTE(_this call DFUNC(initObject)); init = QUOTE(_this call DFUNC(initObject));

View File

@ -226,6 +226,32 @@ class CfgVehicles {
GVAR(canCarry) = 1; 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 Lamps_base_F;
class Land_PortableLight_single_F: Lamps_base_F { class Land_PortableLight_single_F: Lamps_base_F {
GVAR(canCarry) = 1; GVAR(canCarry) = 1;

View File

@ -1,6 +1,6 @@
#include "script_component.hpp" #include "script_component.hpp"
/* /*
* Author: commy2 * Author: commy2, Dystopian
* Check if unit can carry the object. Doesn't check weight. * Check if unit can carry the object. Doesn't check weight.
* *
* Arguments: * Arguments:
@ -11,20 +11,35 @@
* Can the unit carry the object? <BOOL> * Can the unit carry the object? <BOOL>
* *
* Example: * Example:
* [player, cursorTarget] call ace_dragging_fnc_canCarry; * [player, cursorTarget] call ace_dragging_fnc_canCarry
* *
* Public: No * Public: No
*/ */
params ["_unit", "_target"]; 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}; if !([_unit, _target, []] call EFUNC(common,canInteractWith)) exitWith {false};
//#2644 - Units with injured legs cannot bear the extra weight of carrying an object //#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 //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}; if ((_unit getHitPointDamage "HitLegs") >= 0.5) exitWith {false};
// a static weapon has to be empty for dragging (ignore UAV AI) // Static weapons need to be empty for carrying (ignore UAV AI)
if (((typeOf _target) isKindOf "StaticWeapon") && {{(getText (configOf _x >> "simulation")) != "UAVPilot"} count crew _target > 0}) exitWith {false}; 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

View File

@ -1,6 +1,6 @@
#include "script_component.hpp" #include "script_component.hpp"
/* /*
* Author: commy2 * Author: commy2, Dystopian
* Check if unit can drag the object. Doesn't check weight. * Check if unit can drag the object. Doesn't check weight.
* *
* Arguments: * Arguments:
@ -11,16 +11,31 @@
* Can the unit drag the object? <BOOL> * Can the unit drag the object? <BOOL>
* *
* Example: * Example:
* [player, cursorTarget] call ace_dragging_fnc_canDrag; * [player, cursorTarget] call ace_dragging_fnc_canDrag
* *
* Public: No * Public: No
*/ */
params ["_unit", "_target"]; 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}; if !([_unit, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false};
// a static weapon has to be empty for dragging (ignore UAV AI) // Static weapons need to be empty for dragging (ignore UAV AI)
if ((typeOf _target) isKindOf "StaticWeapon" && {{(getText (configOf _x >> "simulation")) != "UAVPilot"} count crew _target > 0}) exitWith {false}; 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

View File

@ -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 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 CARRY_ANIMATIONS ["acinpercmstpsnonwnondnon", "acinpknlmstpsnonwnondnon_acinpercmrunsnonwnondnon"]
#define MAX_DRAGGED_ITEMS 3

View File

@ -162,6 +162,12 @@ class CfgVehicles {
exceptions[] = {"isNotSwimming"}; exceptions[] = {"isNotSwimming"};
icon = "\a3\ui_f\data\IGUI\Cfg\simpleTasks\types\getout_ca.paa"; 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 { class ACE_Torso {
@ -693,6 +699,41 @@ class CfgVehicles {
class ACE_SelfActions {}; 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 Lamps_base_F;
class Land_PortableLight_single_F: Lamps_base_F { class Land_PortableLight_single_F: Lamps_base_F {
class EventHandlers { class EventHandlers {

View File

@ -161,3 +161,21 @@ GVAR(isOpeningDoor) = false;
[QGVAR(clearWeaponAttachmentsActionsCache)] call CBA_fnc_localEvent; [QGVAR(clearWeaponAttachmentsActionsCache)] call CBA_fnc_localEvent;
}] call CBA_fnc_addPlayerEventHandler; }] call CBA_fnc_addPlayerEventHandler;
} forEach ["loadout", "weapon"]; } 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"];