mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Fix Underwater interactions (magrepack, loading, refuel, medical legs, dragging) (#5521)
* Fix Magazine Repack underwater - fix #5513 Also prevent common goKneeling function underwater * Fix loading patients underwater - fix #5515 * Fix load object underwater * Fix take nozzle on jerry can underwater * Fix refuel underwater conditions further * Use isTouchingGround, Make refuel semi-compatible reports false if head is out of the water, we want true even if we are not diving * Less interact exceptions duplication * Use animationState to determine if unit is swimming, create common function and use it instead of isTouchingGround * Fix condition * Support dragging underwater No carrying due to animation timing issues and other misc things * Allow Medical Legs SelfActions underwater * Fix fixPosition function underwater (use getPosATL instead of getPos) * Fix fixPosition's slope adjustment for non-gravity objects, Do the same for objects without simulation as well
This commit is contained in:
parent
ef25aaff02
commit
711e1fc026
@ -53,7 +53,7 @@ private _condition = {
|
||||
{(_target getVariable [QGVAR(canLoad), getNumber (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(canLoad))]) in [true, 1]} &&
|
||||
{locked _target < 2} &&
|
||||
{alive _target} &&
|
||||
{[_player, _target, []] call EFUNC(common,canInteractWith)} &&
|
||||
{[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} &&
|
||||
{0 < {
|
||||
private _type = typeOf _x;
|
||||
private _hasCargoPublic = _x getVariable [QGVAR(hasCargo), false];
|
||||
|
@ -42,7 +42,9 @@ if ([_object, _vehicle] call FUNC(canLoadItemIn)) then {
|
||||
[_object,_vehicle],
|
||||
{["ace_loadCargo", _this select 0] call CBA_fnc_localEvent},
|
||||
{},
|
||||
localize LSTRING(LoadingItem)
|
||||
localize LSTRING(LoadingItem),
|
||||
{true},
|
||||
["isNotSwimming"]
|
||||
] call EFUNC(common,progressBar);
|
||||
_return = true;
|
||||
} else {
|
||||
|
@ -104,6 +104,7 @@ PREP(isInBuilding);
|
||||
PREP(isMedic);
|
||||
PREP(isModLoaded);
|
||||
PREP(isPlayer);
|
||||
PREP(isSwimming);
|
||||
PREP(isUnderwater);
|
||||
PREP(lightIntensityFromObject);
|
||||
PREP(loadPerson);
|
||||
|
@ -1,6 +1,5 @@
|
||||
/*
|
||||
* Author: commy2
|
||||
*
|
||||
* Author: commy2, Jonpas
|
||||
* Fixes position of an object. E.g. moves object above ground and adjusts to terrain slope. Requires local object.
|
||||
*
|
||||
* Arguments:
|
||||
@ -10,7 +9,7 @@
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [bob] call ace_common_fnc_fixPosition
|
||||
* bob call ace_common_fnc_fixPosition
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
@ -19,25 +18,28 @@
|
||||
// setVectorUp requires local object
|
||||
if (!local _this) exitWith {};
|
||||
|
||||
if ((getText (configFile >> "CfgVehicles" >> (typeOf _this) >> "simulation")) == "house") then {
|
||||
//Houses don't have gravity/physics, so make sure they are not floating
|
||||
private _posAbove = (getPos _this) select 2;
|
||||
// Objects with disabled simulation and objects with simulation type "house" don't have gravity/physics, so make sure they are not floating
|
||||
private _hasGravity = simulationEnabled _this && {!(getText (configFile >> "CfgVehicles" >> typeOf _this >> "simulation") == "house")};
|
||||
|
||||
if (!_hasGravity) then {
|
||||
private _posAbove = (getPosATL _this) select 2;
|
||||
TRACE_2("house",_this,_posAbove);
|
||||
if (_posAbove > 0.1) then {
|
||||
private _newPosASL = (getPosASL _this) vectorDiff [0,0,_posAbove];
|
||||
_this setPosASL _newPosASL;
|
||||
private _newPosATL = (getPosATL _this) vectorDiff [0, 0, _posAbove];
|
||||
_this setPosATL _newPosATL;
|
||||
};
|
||||
};
|
||||
|
||||
private _position = getPos _this;
|
||||
private _position = getPosATL _this;
|
||||
|
||||
// don't place the object below the ground
|
||||
// Don't place the object below the ground
|
||||
if (_position select 2 < -0.1) then {
|
||||
_position set [2, -0.1];
|
||||
_this setPos _position;
|
||||
_this setPosATL _position;
|
||||
};
|
||||
|
||||
// adjust position to sloped terrain, if placed on ground
|
||||
if (getPosATL _this select 2 == _position select 2) then {
|
||||
// Adjust position to sloped terrain, if placed on ground
|
||||
// Object without gravity/physics may have negative height when placed on slope, but those objects are definitely on the ground
|
||||
if (!_hasGravity || {getPosATL _this select 2 == _position select 2}) then {
|
||||
_this setVectorUp surfaceNormal _position;
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Author: commy2
|
||||
* Move unit to kneeling position (only if not yet prone).
|
||||
* Move unit to kneeling position (only if not yet prone and not underwater).
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
@ -18,7 +18,7 @@
|
||||
params ["_unit"];
|
||||
|
||||
// Animation changes even inside vehicle post-1.60
|
||||
if (stance _unit == "PRONE" || {vehicle ACE_player != ACE_player}) exitWith {};
|
||||
if (stance _unit == "PRONE" || {vehicle _unit != _unit} || {_unit call EFUNC(common,isSwimming)}) exitWith {};
|
||||
|
||||
[
|
||||
_unit,
|
||||
|
20
addons/common/functions/fnc_isSwimming.sqf
Normal file
20
addons/common/functions/fnc_isSwimming.sqf
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Author: das attorney, Jonpas
|
||||
* Check if unit is swimming (surface swimming or diving).
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* If unit is swimming <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [bob] call ace_common_fnc_isSwimming
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params [["_unit", objNull, [objNull]]];
|
||||
|
||||
((animationState _unit) select [1, 3]) in ["bdv","bsw","dve","sdv","ssw","swm"]
|
@ -21,7 +21,7 @@
|
||||
|
||||
params ["_caller", "_unit", ["_vehicle", objNull]];
|
||||
|
||||
if (!([_caller, _unit, ["isNotDragging", "isNotCarrying"]] call FUNC(canInteractWith)) || {_caller == _unit}) exitWith {_vehicle};
|
||||
if (!([_caller, _unit, ["isNotDragging", "isNotCarrying", "isNotSwimming"]] call FUNC(canInteractWith)) || {_caller == _unit}) exitWith {_vehicle};
|
||||
|
||||
// Try to use nearest vehicle if a vehicle hasn't been supplied
|
||||
if (isNull _vehicle) then {
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
params ["_unit", "_target"];
|
||||
|
||||
if !([_unit, _target, []] 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)
|
||||
if ((typeOf _target) isKindOf "StaticWeapon" && {{(getText (configFile >> "CfgVehicles" >> (typeOf _x) >> "simulation")) != "UAVPilot"} count crew _target > 0}) exitWith {false};
|
||||
|
@ -18,6 +18,6 @@
|
||||
|
||||
params ["_unit", "_target"];
|
||||
|
||||
if !([_unit, _target, ["isNotDragging"]] call EFUNC(common,canInteractWith)) exitWith {false};
|
||||
if !([_unit, _target, ["isNotDragging", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false};
|
||||
|
||||
_unit getVariable [QGVAR(draggedObject), objNull] == _target
|
||||
|
@ -58,7 +58,7 @@ if (_inBuilding) then {
|
||||
_unit setVariable [QGVAR(isDragging), false, true];
|
||||
_unit setVariable [QGVAR(draggedObject), objNull, true];
|
||||
|
||||
// make object accesable for other units
|
||||
// make object accessible for other units
|
||||
[objNull, _target, true] call EFUNC(common,claim);
|
||||
|
||||
if !(_target isKindOf "CAManBase") then {
|
||||
|
@ -31,6 +31,7 @@ private _totalWeight = 0;
|
||||
} forEach _item;
|
||||
true
|
||||
} count [
|
||||
//IGNORE_PRIVATE_WARNING ["_x"];
|
||||
[getMagazineCargo _object, {configFile >> "CfgMagazines" >> _x}],
|
||||
[getBackpackCargo _object, {configFile >> "CfgVehicles" >> _x}],
|
||||
[getItemCargo _object, {configFile >> "CfgWeapons" >> _x >> "ItemInfo"}],
|
||||
|
@ -30,7 +30,7 @@ if (_unit != _realUnit) exitWith {
|
||||
if (_unit getVariable [QGVAR(isDragging), false]) then {
|
||||
|
||||
// drop dragged object when not in valid animation
|
||||
if !(_anim in DRAG_ANIMATIONS) then {
|
||||
if (!(_anim in DRAG_ANIMATIONS) && {!(_unit call EFUNC(common,isSwimming))}) then {
|
||||
private _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull];
|
||||
|
||||
if (!isNull _draggedObject) then {
|
||||
|
@ -39,9 +39,11 @@ _unit selectWeapon primaryWeapon _unit;
|
||||
[_unit, _target, true] call EFUNC(common,claim);
|
||||
|
||||
// can't play action that depends on weapon if it was added the same frame
|
||||
[{
|
||||
[_this, "grabDrag"] call EFUNC(common,doGesture);
|
||||
}, _unit] call CBA_fnc_execNextFrame;
|
||||
if !(_unit call EFUNC(common,isSwimming)) then {
|
||||
[{
|
||||
[_this, "grabDrag"] call EFUNC(common,doGesture);
|
||||
}, _unit] call CBA_fnc_execNextFrame;
|
||||
};
|
||||
|
||||
// move a bit closer and adjust direction when trying to pick up a person
|
||||
if (_target isKindOf "CAManBase") then {
|
||||
|
@ -50,7 +50,7 @@ if (CBA_missionTime > _timeOut) exitWith {
|
||||
};
|
||||
|
||||
// unit is ready to start dragging
|
||||
if (animationState _unit in DRAG_ANIMATIONS) exitWith {
|
||||
if (animationState _unit in DRAG_ANIMATIONS || {_unit call EFUNC(common,isSwimming)}) exitWith {
|
||||
TRACE_4("Start Dragging",_unit,_target,_timeOut,CBA_missionTime);
|
||||
[_unit, _target] call FUNC(dragObject);
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define COMPONENT_BEAUTIFIED Dragging
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
//#define DEBUG_ENABLED_DRAGGING
|
||||
// #define DEBUG_ENABLED_DRAGGING
|
||||
// #define DEBUG_MODE_FULL
|
||||
// #define DISABLE_COMPILE_CACHE
|
||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||
|
@ -106,7 +106,7 @@ GVAR(isOpeningDoor) = false;
|
||||
{false},
|
||||
[20, [true, false, false]], false] call CBA_fnc_addKeybind;
|
||||
|
||||
["isNotSwimming", {!underwater (_this select 0)}] call EFUNC(common,addCanInteractWithCondition);
|
||||
["isNotSwimming", {!(_this call EFUNC(common,isSwimming))}] call EFUNC(common,addCanInteractWithCondition);
|
||||
["isNotOnLadder", {getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> animationState (_this select 0) >> "ACE_isLadder") != 1}] call EFUNC(common,addCanInteractWithCondition);
|
||||
|
||||
["ace_settingsInitialized", {
|
||||
|
@ -25,7 +25,7 @@ if (_unit != ACE_player) exitWith {};
|
||||
|
||||
_timeToCut = if ([_unit] call EFUNC(common,isEngineer)) then {7.5} else {11};
|
||||
|
||||
if (!underwater _unit) then {
|
||||
if !(_unit call EFUNC(common,isSwimming)) then {
|
||||
[_unit, "AinvPknlMstpSnonWnonDr_medic5", 0] call EFUNC(common,doAnimation);
|
||||
};
|
||||
|
||||
@ -33,7 +33,7 @@ _onCompletion = {
|
||||
TRACE_1("_onCompletion",_this);
|
||||
(_this select 0) params ["_fenceObject", "", "_unit"];
|
||||
_fenceObject setdamage 1;
|
||||
if (!underwater _unit) then {
|
||||
if !(_unit call EFUNC(common,isSwimming)) then {
|
||||
[_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation);
|
||||
};
|
||||
};
|
||||
@ -41,7 +41,7 @@ _onCompletion = {
|
||||
_onFail = {
|
||||
TRACE_1("_onFail", _this);
|
||||
(_this select 0) params ["", "", "_unit"];
|
||||
if (!underwater _unit) then {
|
||||
if !(_unit call EFUNC(common,isSwimming)) then {
|
||||
[_unit, "AmovPknlMstpSrasWrflDnon", 1] call EFUNC(common,doAnimation);
|
||||
};
|
||||
};
|
||||
|
@ -25,7 +25,7 @@ _args params ["_magazineClassname", "_lastAmmoCount"];
|
||||
private _fullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "count");
|
||||
|
||||
// Don't show anything if player can't interact
|
||||
if (!([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNowSwimming"]] call EFUNC(common,canInteractWith))) exitWith {};
|
||||
if (!([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith))) exitWith {};
|
||||
|
||||
// Count mags
|
||||
private _fullMags = 0;
|
||||
|
@ -351,7 +351,7 @@ class Medical {
|
||||
class ACE_LegLeft {
|
||||
displayName = ECSTRING(interaction,LegLeft);
|
||||
runOnHover = 1;
|
||||
exceptions[] = {"isNotInside", "isNotSitting"};
|
||||
exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"};
|
||||
statement = QUOTE([ARR_3(_target, true, 4)] call DFUNC(displayPatientInformation));
|
||||
modifierFunction = QUOTE([ARR_4(_target,_player,4,_this select 3)] call FUNC(modifyMedicalAction));
|
||||
condition = "true";
|
||||
@ -443,7 +443,7 @@ class Medical {
|
||||
class ACE_LegRight {
|
||||
displayName = ECSTRING(interaction,LegRight);
|
||||
runOnHover = 1;
|
||||
exceptions[] = {"isNotInside", "isNotSitting"};
|
||||
exceptions[] = {"isNotInside", "isNotSwimming", "isNotSitting"};
|
||||
statement = QUOTE([ARR_3(_target, true, 5)] call DFUNC(displayPatientInformation));
|
||||
modifierFunction = QUOTE([ARR_4(_target,_player,5,_this select 3)] call FUNC(modifyMedicalAction));
|
||||
condition = "true";
|
||||
|
@ -176,7 +176,7 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then {
|
||||
_caller selectWeapon (primaryWeapon _caller); // unit always has a primary weapon here
|
||||
};
|
||||
|
||||
if (!underwater _caller) then {
|
||||
if !(_caller call EFUNC(common,isSwimming)) then {
|
||||
// Weapon on back also does not work underwater
|
||||
if (isWeaponDeployed _caller) then {
|
||||
TRACE_1("Weapon Deployed, breaking out first",(stance _caller));
|
||||
|
@ -26,7 +26,7 @@ _args params ["_caller", "_target", "_selectionName", "_className", "_items", "_
|
||||
if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then {
|
||||
_caller removeWeapon "ACE_FakePrimaryWeapon";
|
||||
};
|
||||
if (vehicle _caller == _caller && {!underwater _caller}) then {
|
||||
if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then {
|
||||
private _lastAnim = _caller getVariable [QGVAR(treatmentPrevAnimCaller), ""];
|
||||
//Don't play another medic animation (when player is rapidily treating)
|
||||
TRACE_2("Reseting to old animation", animationState player, _lastAnim);
|
||||
|
@ -26,7 +26,7 @@ _args params ["_caller", "_target", "_selectionName", "_className", "_items", "_
|
||||
if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then {
|
||||
_caller removeWeapon "ACE_FakePrimaryWeapon";
|
||||
};
|
||||
if (vehicle _caller == _caller && {!underwater _caller}) then {
|
||||
if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then {
|
||||
private _lastAnim = _caller getVariable [QGVAR(treatmentPrevAnimCaller), ""];
|
||||
//Don't play another medic animation (when player is rapidily treating)
|
||||
TRACE_2("Reseting to old animation", animationState player, _lastAnim);
|
||||
|
@ -14,7 +14,7 @@
|
||||
displayName = CSTRING(TakeNozzle); \
|
||||
condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeNozzle)); \
|
||||
statement = QUOTE([ARR_2(_player,_target)] call FUNC(takeNozzle)); \
|
||||
exceptions[] = {"isNotInside", "isNotOnLadder"}; \
|
||||
exceptions[] = {INTERACT_EXCEPTIONS_REFUELING}; \
|
||||
icon = QPATHTOF(ui\icon_refuel_interact.paa); \
|
||||
}; \
|
||||
class GVAR(TurnOn) { \
|
||||
@ -35,7 +35,7 @@
|
||||
displayName = CSTRING(Disconnect); \
|
||||
condition = QUOTE([ARR_2(_player,_target)] call FUNC(canDisconnect)); \
|
||||
statement = QUOTE([ARR_2(_player,_target)] call DFUNC(disconnect)); \
|
||||
exceptions[] = {"isNotInside", "isNotOnLadder"}; \
|
||||
exceptions[] = {INTERACT_EXCEPTIONS_REFUELING}; \
|
||||
icon = QPATHTOF(ui\icon_refuel_interact.paa); \
|
||||
}; \
|
||||
}; \
|
||||
|
@ -44,7 +44,7 @@ private _action = [QGVAR(Refuel),
|
||||
_action = [QGVAR(PickUpNozzle),
|
||||
localize LSTRING(TakeNozzle),
|
||||
QPATHTOF(ui\icon_refuel_interact.paa),
|
||||
{[_player, _target] call FUNC(TakeNozzle)},
|
||||
{[_player, _target] call FUNC(takeNozzle)},
|
||||
{[_player, _target] call FUNC(canTakeNozzle)},
|
||||
{},
|
||||
[],
|
||||
|
@ -35,7 +35,7 @@ TRACE_2("start",_unit,_nozzle);
|
||||
|
||||
if !(
|
||||
alive _unit
|
||||
&& {"" isEqualTo currentWeapon _unit}
|
||||
&& {"" isEqualTo currentWeapon _unit || {_unit call EFUNC(common,isSwimming)}}
|
||||
&& {[_unit, objNull, [INTERACT_EXCEPTIONS, "notOnMap"]] call EFUNC(common,canInteractWith)}
|
||||
&& {!("unconscious" isEqualTo toLower animationState _unit)}
|
||||
&& {!(_unit getVariable ["ACE_isUnconscious", false])}
|
||||
|
@ -94,5 +94,5 @@ params [
|
||||
{},
|
||||
localize LSTRING(TakeNozzleAction),
|
||||
{true},
|
||||
["isNotInside", "isNotOnLadder"]
|
||||
[INTERACT_EXCEPTIONS_REFUELING]
|
||||
] call EFUNC(common,progressBar);
|
||||
|
@ -30,4 +30,5 @@
|
||||
#define TIME_PROGRESSBAR(X) (X)
|
||||
#endif
|
||||
|
||||
#define INTERACT_EXCEPTIONS "isNotInside", "isNotOnLadder", "isNotRefueling"
|
||||
#define INTERACT_EXCEPTIONS_REFUELING "isNotInside", "isNotOnLadder", "isNotSwimming"
|
||||
#define INTERACT_EXCEPTIONS INTERACT_EXCEPTIONS_REFUELING, "isNotRefueling"
|
||||
|
@ -169,7 +169,7 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then {
|
||||
_caller selectWeapon (primaryWeapon _caller); // unit always has a primary weapon here
|
||||
};
|
||||
|
||||
if (!underwater _caller) then {
|
||||
if !(_caller call EFUNC(common,isSwimming)) then {
|
||||
if (stance _caller == "STAND") then {
|
||||
_caller setVariable [QGVAR(repairPrevAnimCaller), "amovpknlmstpsraswrfldnon"];
|
||||
} else {
|
||||
|
@ -31,7 +31,7 @@ private ["_config","_callback", "_usersOfItems", "_weaponSelect"];
|
||||
if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then {
|
||||
_caller removeWeapon "ACE_FakePrimaryWeapon";
|
||||
};
|
||||
if (vehicle _caller == _caller && {!underwater _caller}) then {
|
||||
if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then {
|
||||
[_caller, _caller getVariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation);
|
||||
};
|
||||
_caller setVariable [QGVAR(repairPrevAnimCaller), nil];
|
||||
|
@ -31,7 +31,7 @@ private ["_config","_callback", "_weaponSelect"];
|
||||
if (primaryWeapon _caller == "ACE_FakePrimaryWeapon") then {
|
||||
_caller removeWeapon "ACE_FakePrimaryWeapon";
|
||||
};
|
||||
if (vehicle _caller == _caller && {!underwater _caller}) then {
|
||||
if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) then {
|
||||
[_caller, _caller getVariable [QGVAR(repairPrevAnimCaller), ""], 2] call EFUNC(common,doAnimation);
|
||||
};
|
||||
_caller setVariable [QGVAR(repairPrevAnimCaller), nil];
|
||||
|
Loading…
Reference in New Issue
Block a user