Medical - Improve loading/unloading of unconc patients (#7109)

* Medical - Improve loading/unloading of unconc patients

* Update fnc_loadPersonLocal.sqf

* Multi-line

* Formating

* Update fnc_loadUnit.sqf
This commit is contained in:
PabstMirror 2019-09-05 15:56:53 -05:00 committed by GitHub
parent d6c39e661f
commit edd5c44853
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 112 additions and 95 deletions

View File

@ -121,8 +121,8 @@ if (isServer) then {
[QGVAR(fixFloating), FUNC(fixFloating)] call CBA_fnc_addEventHandler;
[QGVAR(fixPosition), FUNC(fixPosition)] call CBA_fnc_addEventHandler;
["ace_loadPersonEvent", FUNC(loadPersonLocal)] call CBA_fnc_addEventHandler;
["ace_unloadPersonEvent", FUNC(unloadPersonLocal)] call CBA_fnc_addEventHandler;
["ace_loadPersonEvent", LINKFUNC(loadPersonLocal)] call CBA_fnc_addEventHandler;
["ace_unloadPersonEvent", LINKFUNC(unloadPersonLocal)] call CBA_fnc_addEventHandler;
[QGVAR(lockVehicle), {
_this setVariable [QGVAR(lockStatus), locked _this];

View File

@ -20,8 +20,9 @@
#define GROUP_SWITCH_ID QFUNC(loadPerson)
params ["_caller", "_unit", ["_vehicle", objNull]];
TRACE_3("loadPerson",_caller,_unit,_vehicle);
if (!([_caller, _unit, ["isNotDragging", "isNotCarrying", "isNotSwimming"]] call FUNC(canInteractWith)) || {_caller == _unit}) exitWith {_vehicle};
if (!([_caller, _unit, ["isNotDragging", "isNotCarrying", "isNotSwimming"]] call FUNC(canInteractWith)) || {_caller == _unit}) exitWith { objNull };
// Try to use nearest vehicle if a vehicle hasn't been supplied
if (isNull _vehicle) then {
@ -30,6 +31,7 @@ if (isNull _vehicle) then {
if (!isNull _vehicle) then {
[_unit, true, GROUP_SWITCH_ID, side group _caller] call FUNC(switchToGroupSide);
TRACE_3("sending ace_loadPersonEvent",_unit,_vehicle,_caller);
["ace_loadPersonEvent", [_unit, _vehicle, _caller], _unit] call CBA_fnc_targetEvent;
};

View File

@ -17,15 +17,11 @@
* Public: Yes
*/
params ["_unit", "_vehicle", "_caller"];
// if (!alive _unit) then {
// _unit = [_unit, _caller] call makeCopyOfBody; //func does not exist
// };
params ["_unit", "_vehicle", ["_caller", objNull]];
TRACE_3("loadPersonLocal",_unit,_vehicle,_caller);
private _slotsOpen = false;
if (_vehicle emptyPositions "cargo" > 0) then {
if ((_vehicle emptyPositions "cargo" > 0) && {!(_unit getVariable ['ACE_isUnconscious', false])} || {(getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "ejectDeadCargo")) == 0}) then {
_unit moveInCargo _vehicle;
_slotsOpen = true;
} else {
@ -35,29 +31,16 @@ if (_vehicle emptyPositions "cargo" > 0) then {
};
};
if (_slotsOpen) then {
private _loaded = _vehicle getVariable [QGVAR(loaded_persons),[]];
_loaded pushBack _unit;
if (!_slotsOpen) exitWith { WARNING_2("no open seats %1->%2",_unit,_vehicle); };
_vehicle setVariable [QGVAR(loaded_persons), _loaded, true];
if !([_unit] call FUNC(isAwake)) then {
[{
(_this select 0) params ["_unit", "_vehicle"];
// wait until the unit is in the vehicle
if (vehicle _unit != _vehicle) exitWith {
// kill this pfh if either one is deleted
if (isNull _unit || isNull _vehicle) then {
[_this select 1] call CBA_fnc_removePerFrameHandler;
};
};
_unit setVariable [QEGVAR(medical,vehicleAwakeAnim), [_vehicle, animationState _unit]];
[_unit, [_unit] call FUNC(getDeathAnim), 1, true] call FUNC(doAnimation);
[_this select 1] call CBA_fnc_removePerFrameHandler;
}, 0.5, [_unit, _vehicle]] call CBA_fnc_addPerFrameHandler;
};
};
[{ // just for error reporting
params ["_unit", "_vehicle"];
(alive _unit) && {alive _vehicle} && {(vehicle _unit) == _vehicle}
}, {
params ["_unit", "_vehicle"];
TRACE_2("success",_unit,_vehicle);
}, [_unit, _vehicle], 2, {
params ["_unit", "_vehicle"];
if (!alive _unit) exitWith {};
WARNING_2("timeout %1->%2",_unit,_vehicle);
}] call CBA_fnc_waitUntilAndExecute;

View File

@ -19,4 +19,8 @@
params ["_unit", ["_distance", 10]];
private _nearVehicles = nearestObjects [_unit, ["Car", "Air", "Tank", "Ship_F", "Pod_Heli_Transport_04_crewed_base_F"], _distance];
_nearVehicles select {(_x emptyPositions "cargo" > 0) || {_x emptyPositions "gunner" > 0}}
_nearVehicles select {
// Filter cargo seats that will eject unconscious units (e.g. quad bike)
((_x emptyPositions "cargo" > 0) && {!(_unit getVariable ['ACE_isUnconscious', false])} || {(getNumber (configFile >> "CfgVehicles" >> (typeOf _x) >> "ejectDeadCargo")) == 0})
|| {_x emptyPositions "gunner" > 0}
}

View File

@ -15,18 +15,16 @@
* Public: No
*/
#define GROUP_SWITCH_ID QFUNC(loadPerson)
params ["_unit"];
TRACE_1("unloadPerson",_unit);
private _vehicle = vehicle _unit;
if (isNull _vehicle) exitWith {false};
if (_vehicle == _unit) exitWith {false};
if (speed _vehicle > 1 || {((getPos _vehicle) select 2) > 2}) exitWith {false};
if (!isNull _vehicle) then {
["ace_unloadPersonEvent", [_unit, _vehicle], [_unit]] call CBA_fnc_targetEvent;
};
["ace_unloadPersonEvent", [_unit, _vehicle], [_unit]] call CBA_fnc_targetEvent;
true

View File

@ -20,11 +20,19 @@
#define GROUP_SWITCH_ID QFUNC(loadPerson)
params ["_unit", "_vehicle", ["_unloader", objNull]];
TRACE_3("params",_unit,_vehicle,_unloader);
TRACE_3("unloadpersonLocal",_unit,_vehicle,_unloader);
//This covers testing vehicle stability and finding a safe position
private _emptyPos = [_vehicle, (typeOf _unit), _unloader] call EFUNC(common,findUnloadPosition);
TRACE_1("findUnloadPosition",_emptyPos);
if (_emptyPos isEqualTo []) then {
_emptyPos = [_vehicle, (typeOf _unit), _unloader] call EFUNC(common,findUnloadPosition);
TRACE_1("findUnloadPosition 2nd attempt",_emptyPos);
if (_emptyPos isEqualTo []) then {
_emptyPos = [_vehicle, (typeOf _unit), _unloader] call EFUNC(common,findUnloadPosition);
TRACE_1("findUnloadPosition 3rd attempt",_emptyPos);
};
};
if (count _emptyPos != 3) exitwith {
WARNING_4("Could not find unload pos %1-ASL: %2 isTouchingGround: %3 Speed: %4",_vehicle, getPosASL _vehicle, isTouchingGround _vehicle, speed _vehicle);
@ -38,57 +46,22 @@ if (count _emptyPos != 3) exitwith {
unassignVehicle _unit;
[_unit] orderGetIn false;
private _resetUncon = false;
if (lifeState _unit == "INCAPACITATED") then {
_resetUncon = true;
_unit setUnconscious false;
TRACE_1("pausing setUnconscious",_unit);
};
TRACE_1("Ejecting", alive _unit);
_unit action ["Eject", vehicle _unit];
[{
params ["_unit", "_emptyPos", "_resetUncon"];
if ((vehicle _unit) != _unit) then {
WARNING_2("Failed to unload in time [%1 - %2]",_unit, vehicle _unit);
};
params ["_unit", "_emptyPos"];
(alive _unit) && {(vehicle _unit) != _unit}
}, {
params ["_unit", "_emptyPos"];
TRACE_2("success",_unit,_emptyPos);
_unit setPosASL AGLToASL _emptyPos;
if (_resetUncon) then {
TRACE_1("resuming setUnconscious",_unit);
// This should reset the unit to an Unconscious animation
// Also has the hilarious effect of violently ragdolling the guy
_unit setUnconscious true;
};
// ToDo [medical-rewrite]: verify we can remove the following commented code
// if !([_unit] call FUNC(isAwake)) then {
// TRACE_1("Check if isAwake", [_unit] call FUNC(isAwake));
// if (driver _unit == _unit) then {
// private _anim = [_unit] call FUNC(getDeathAnim);
// [_unit, _anim, 1, true] call FUNC(doAnimation);
// [{
// params ["_unit", "_anim"];
// if ((_unit getVariable "ACE_isUnconscious") and (animationState _unit != _anim)) then {
// [_unit, _anim, 2, true] call FUNC(doAnimation);
// };
// }, [_unit, _anim], 0.5] call CBA_fnc_waitAndExecute;
// };
// };
}, [_unit, _emptyPos, _resetUncon], 0.5] call CBA_fnc_waitAndExecute;
}, [_unit, _emptyPos], 2, {
params ["_unit", "_emptyPos"];
if (!alive _unit) exitWith {};
WARNING_2("timeout %1->%2",_unit,vehicle _unit);
}] call CBA_fnc_waitUntilAndExecute;
[_unit, false, GROUP_SWITCH_ID, side group _unit] call FUNC(switchToGroupSide);
private _loaded = _vehicle getvariable [QGVAR(loaded_persons),[]];
_loaded deleteAt (_loaded find _unit);
_vehicle setvariable [QGVAR(loaded_persons), _loaded, true];
true

View File

@ -1,5 +1,8 @@
#include "\z\ace\addons\medical\script_component.hpp"
if (missionNamespace getVariable [QGVAR(dev_watchVariableRunning), false]) exitWith {};
GVAR(dev_watchVariableRunning) = true;
["medical", {
// Hide when patient display is up because they might overlap
@ -152,6 +155,8 @@
_return pushBack format ["ACE_setCustomAimCoef: %1", [missionNamespace, "ACE_setCustomAimCoef", "max"] call EFUNC(common,arithmeticGetResult)];
};
_return pushBack format ["%1 - %2",lifeState _unit, animationState _unit];
// Footer:
_return pushBack "</t>";

View File

@ -17,9 +17,10 @@
*/
params [["_unit", objNull, [objNull]], ["_isUnconscious", true, [false]]];
TRACE_2("setUnconsciousAnim",_unit,_isUnconscious);
if (!local _unit) exitWith {
ERROR("Unit not local or null");
ERROR_1("Unit %1 not local or null",_unit);
};
_unit setUnconscious _isUnconscious;
@ -27,21 +28,25 @@ _unit setUnconscious _isUnconscious;
if (_isUnconscious) then {
// eject from static weapon
if (vehicle _unit isKindOf "StaticWeapon") then {
TRACE_2("ejecting from static weapon",_unit,vehicle _unit);
[_unit] call EFUNC(common,unloadPerson);
};
// set animation inside vehicles
if (vehicle _unit != _unit) then {
private _unconAnim = _unit call EFUNC(common,getDeathAnim);
TRACE_2("inVehicle - playing death anim",_unit,_unconAnim);
[_unit, _unconAnim] call EFUNC(common,doAnimation);
};
} else {
// reset animation inside vehicles
if (vehicle _unit != _unit) then {
private _awakeAnim = _unit call EFUNC(common,getAwakeAnim);
TRACE_2("inVehicle - playing awake anim",_unit,_awakeAnim);
[_unit, _awakeAnim, 2] call EFUNC(common,doAnimation);
} else {
// and on foot
TRACE_1("onfoot - playing standard anim",_unit);
[_unit, "AmovPpneMstpSnonWnonDnon"] call EFUNC(common,doAnimation);
if (currentWeapon _unit == secondaryWeapon _unit && {currentWeapon _unit != ""}) then {
@ -50,9 +55,12 @@ if (_isUnconscious) then {
[{
params ["_unit"];
if (animationState _unit == "unconscious" && {lifeState _unit != "INCAPACITATED"}) then {
TRACE_3("after delay",_unit,animationState _unit,lifeState _unit);
if (!alive _unit) exitWith {};
// Fix unit being in locked animation with switchMove (If unit was unloaded from a vehicle, they may be in deadstate instead of unconscious)
if (((animationState _unit == "unconscious") || {animationState _unit == "deadstate"}) && {lifeState _unit != "INCAPACITATED"}) then {
[_unit, "AmovPpneMstpSnonWnonDnon", 2] call EFUNC(common,doAnimation);
TRACE_1("forcing SwitchMove",animationState _unit);
};
}, _unit, 0.5] call CBA_fnc_waitAndExecute;
};

View File

@ -18,6 +18,7 @@
*/
params ["_unit", "_active"];
TRACE_2("setUnconscious",_unit,_active);
// No change to make
if (_active isEqualTo IS_UNCONSCIOUS(_unit)) exitWith { TRACE_2("no change",_active,IS_UNCONSCIOUS(_unit)); };

View File

@ -18,6 +18,7 @@
*/
params ["_medic", "_patient", ["_vehicle", objNull]];
TRACE_3("loadUnit",_medic,_patient,_vehicle);
if (_patient call EFUNC(common,isAwake)) exitWith {
[[LSTRING(CanNotLoad), _patient call EFUNC(common,getName)]] call EFUNC(common,displayTextStructured);
@ -33,8 +34,19 @@ if (_patient call EFUNC(medical_status,isBeingDragged)) then {
private _vehicle = [_medic, _patient, _vehicle] call EFUNC(common,loadPerson);
if (!isNull _vehicle) then {
private _patientName = [_patient, false, true] call EFUNC(common,getName);
if (isNull _vehicle) exitWith { TRACE_1("no vehicle found",_vehicle); };
[{
params ["_unit", "_vehicle"];
(alive _unit) && {alive _vehicle} && {(vehicle _unit) == _vehicle}
}, {
params ["_unit", "_vehicle"];
TRACE_2("success",_unit,_vehicle);
private _patientName = [_unit, false, true] call EFUNC(common,getName);
private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName");
[[LSTRING(LoadedInto), _patientName, _vehicleName], 3] call EFUNC(common,displayTextStructured);
};
}, [_patient, _vehicle], 3, {
params ["_unit", "_emptyPos"];
WARNING_3("loadPerson failed to load %1[local %2] -> %3 ",_unit,local _unit,_vehicle);
}] call CBA_fnc_waitUntilAndExecute;

View File

@ -17,13 +17,28 @@
*/
params ["_medic", "_patient"];
TRACE_2("unloadUnit",_medic,_patient);
if (vehicle _patient == _patient) exitWith {
TRACE_1("Unit is not in a vehicle",_patient);
ERROR_1("Unit %1 is not in a vehicle",_patient);
};
if (_patient call EFUNC(common,isAwake)) exitWith {
TRACE_1("Unit is awake",_patient);
ERROR_1("Unit %1 is awake",_patient);
};
["ace_unloadPersonEvent", [_patient, vehicle _patient, _medic], _patient] call CBA_fnc_targetEvent;
[{
params ["_unit", "_vehicle"];
(alive _unit) && {alive _vehicle} && {(vehicle _unit) != _vehicle}
}, {
params ["_unit", "_vehicle"];
TRACE_2("success",_unit,_vehicle);
private _patientName = [_unit, false, true] call EFUNC(common,getName);
private _vehicleName = getText (configFile >> "CfgVehicles" >> typeOf _vehicle >> "displayName");
[[LSTRING(UnloadedFrom), _patientName, _vehicleName], 3] call EFUNC(common,displayTextStructured);
}, [_patient, vehicle _patient], 3, {
params ["_unit", "_vehicle"];
WARNING_3("unloadPerson failed to unload %1[local %2] -> %3 ",_unit,local _unit,_vehicle);
}] call CBA_fnc_waitUntilAndExecute;

View File

@ -3293,6 +3293,22 @@
<Chinese>%1&lt;br/&gt;裝載至&lt;br/&gt;%2</Chinese>
<Chinesesimp>%1&lt;br/&gt;装载至&lt;br/&gt;%2</Chinesesimp>
</Key>
<Key ID="STR_ACE_Medical_Treatment_UnloadedFrom">
<English>Unloaded&lt;br/&gt;%1 from&lt;br/&gt;%2</English>
<German>%1&lt;br/&gt;von&lt;br/&gt;%2 abgeladen</German>
<Spanish>Descargado/a&lt;br/&gt;%1 de&lt;br/&gt;%2</Spanish>
<French>Déchargé&lt;br/&gt;%1 de&lt;br/&gt;%2</French>
<Polish>%1&lt;br/&gt;rozładowano z&lt;br/&gt;%2</Polish>
<Czech>%1&lt;br/&gt;vyloženo z&lt;br/&gt;%2</Czech>
<Portuguese>%1&lt;br/&gt;descarregado de&lt;br/&gt;%2</Portuguese>
<Italian>Hai scaricato&lt;br/&gt;%1 da&lt;br/&gt;%2</Italian>
<Hungarian>1%&lt;br/&gt;kirakodva ebből:&lt;br/&gt;%2</Hungarian>
<Russian>%1&lt;br/&gt;разгружен из&lt;br/&gt;%2</Russian>
<Japanese>&lt;br/&gt;%1が&lt;br/&gt;%2から降ろされました</Japanese>
<Korean>%1&lt;br/&gt;&lt;br/&gt;%2 에서 내려짐</Korean>
<Chinese>&lt;br/&gt;%2卸載&lt;br/&gt;%1</Chinese>
<Chinesesimp>&lt;br/&gt;%2卸载&lt;br/&gt;%1</Chinesesimp>
</Key>
<Key ID="STR_ACE_Medical_Treatment_PlaceInBodyBag">
<English>Place body in bodybag</English>
<Spanish>Colocar cuerpo en bolsa para cadáveres</Spanish>