Merge pull request #2249 from acemod/captiveFFV

Captive ffv animation fix + cleanup
This commit is contained in:
PabstMirror 2015-08-29 15:39:23 -05:00
commit fa3a0213b7
19 changed files with 237 additions and 81 deletions

View File

@ -18,6 +18,11 @@ class CfgMovesBasic {
default = "ACE_AmovPercMstpSsurWnonDnon";
PutDown = "";
};
class ACE_CivilHandCuffedFFVActions: ACE_CivilStandHandcuffedActions {
stop = "ACE_HandcuffedFFV";
StopRelaxed = "ACE_HandcuffedFFV";
default = "ACE_HandcuffedFFV";
};
};
};
@ -55,6 +60,14 @@ class CfgMovesMaleSdr: CfgMovesBasic {
InterpolateTo[] = {"Unconscious",0.01,"ACE_AmovPercMstpSnonWnonDnon_AmovPercMstpScapWnonDnon",0.1};
};
//Handcuffed-FFV:
class ACE_HandcuffedFFV: ACE_AmovPercMstpScapWnonDnon {
file = "\A3\cargoposes_F_heli\anim\passenger_flatground_3idleunarmed.rtm";
actions = "ACE_CivilHandCuffedFFVActions";
ConnectTo[] = {};
};
//Surrender Anims:
class ACE_AmovPercMstpSnonWnonDnon_AmovPercMstpSsurWnonDnon: CutSceneAnimationBase {
actions = "ACE_CivilStandSurrenderActions";

View File

@ -12,17 +12,17 @@ class CfgVehicles {
exceptions[] = {};
icon = QUOTE(PATHTOF(UI\handcuff_ca.paa));
};
class ACE_RemoveHandcuffs {
displayName = CSTRING(ReleaseCaptive);
selection = "righthand";
distance = 2;
condition = QUOTE([ARR_2(_player, _target)] call FUNC(canRemoveHandcuffs));
statement = QUOTE([ARR_2(_player, _target)] call FUNC(doRemoveHandcuffs));
exceptions[] = {};
icon = QUOTE(PATHTOF(UI\handcuff_ca.paa));
};
class ACE_MainActions {
class ACE_RemoveHandcuffs {
displayName = CSTRING(ReleaseCaptive);
selection = "righthand";
distance = 2;
condition = QUOTE([ARR_2(_player, _target)] call FUNC(canRemoveHandcuffs));
statement = QUOTE([ARR_2(_player, _target)] call FUNC(doRemoveHandcuffs));
exceptions[] = {};
icon = QUOTE(PATHTOF(UI\handcuff_ca.paa));
};
class ACE_EscortCaptive {
displayName = CSTRING(EscortCaptive);
distance = 4;
@ -97,7 +97,7 @@ class CfgVehicles {
};
};
#define MACRO_LOADUNLOADCAPTIVE \
#define MACRO_LOADCAPTIVE \
class ACE_Actions { \
class ACE_MainActions { \
class GVAR(LoadCaptive) { \
@ -113,27 +113,27 @@ class CfgVehicles {
class LandVehicle;
class Car: LandVehicle {
MACRO_LOADUNLOADCAPTIVE
MACRO_LOADCAPTIVE
};
class Tank: LandVehicle {
MACRO_LOADUNLOADCAPTIVE
MACRO_LOADCAPTIVE
};
class Air;
class Helicopter: Air {
MACRO_LOADUNLOADCAPTIVE
MACRO_LOADCAPTIVE
};
class Plane: Air {
MACRO_LOADUNLOADCAPTIVE
MACRO_LOADCAPTIVE
};
class Ship;
class Ship_F: Ship {
MACRO_LOADUNLOADCAPTIVE
MACRO_LOADCAPTIVE
};
class StaticWeapon: LandVehicle {
MACRO_LOADUNLOADCAPTIVE
MACRO_LOADCAPTIVE
};
class Box_NATO_Support_F;

View File

@ -6,12 +6,11 @@
if (isServer) then {
addMissionEventHandler ["HandleDisconnect", {
PARAMS_1(_disconnectedPlayer);
params ["_disconnectedPlayer"];
private "_escortedUnit";
_escortedUnit = _disconnectedPlayer getVariable [QGVAR(escortedUnit), objNull];
if ((!isNull _escortedUnit) && {(attachedTo _escortedUnit) == _disconnectedPlayer}) then {
detach _escortedUnit;
//systemChat "debug: DC detach";
};
if (_disconnectedPlayer getVariable [QGVAR(isEscorting), false]) then {
_disconnectedPlayer setVariable [QGVAR(isEscorting), false, true];

View File

@ -16,6 +16,7 @@ PREP(doFriskPerson);
PREP(doLoadCaptive);
PREP(doRemoveHandcuffs);
PREP(doUnloadCaptive);
PREP(findEmptyNonFFVCargoSeat);
PREP(handleGetIn);
PREP(handleGetOut);
PREP(handleKilled);

View File

@ -11,28 +11,36 @@
* The return value <BOOL>
*
* Example:
* [player, bob] call ACE_captives_fnc_canLoadCaptive
* [player, bob, car] call ACE_captives_fnc_canLoadCaptive
*
* Public: No
*/
#include "script_component.hpp"
private ["_objects"];
params ["_unit", "_target","_vehicle"];
if (isNull _target) then {
_objects = attachedObjects _unit;
_objects = [_objects, {_this getVariable [QGVAR(isHandcuffed), false]}] call EFUNC(common,filter);
if ((count _objects) > 0) then {_target = _objects select 0;};
if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then {
//Looking at a vehicle while escorting, get target from attached objects:
{
if (_x getVariable [QGVAR(isHandcuffed), false]) exitWith {
_target = _x;
};
} forEach (attachedObjects _unit);
};
if ((isNull _target) || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {false};
if (isNull _vehicle) then {
_objects = nearestObjects [_unit, ["Car", "Tank", "Helicopter", "Plane", "Ship"], 10];
if ((count _objects) > 0) then {_vehicle = _objects select 0;};
//Looking at a captive unit, search for nearby vehicles with valid seats:
{
if ((_x emptyPositions "cargo") > 0) exitWith {
_vehicle = _x;
};
} forEach (nearestObjects [_unit, ["Car", "Tank", "Helicopter", "Plane", "Ship"], 10]);
} else {
//We have a vehicle picked, make sure it has empty seats:
if ((_vehicle emptyPositions "cargo") == 0) then {
_vehicle = objNull;
};
};
(!isNull _target)
&& {!isNull _vehicle}
&& {_unit getVariable [QGVAR(isEscorting), false]}
&& {_target getVariable [QGVAR(isHandcuffed), false]}
&& {_vehicle emptyPositions "cargo" > 0}
(!isNull _vehicle)

View File

@ -20,4 +20,5 @@ params ["_unit", "_target"];
//Unit is handcuffed and not currently being escorted
_target getVariable [QGVAR(isHandcuffed), false] &&
{isNull (attachedTo _target)}
{isNull (attachedTo _target)} &&
{(vehicle _target) == _target}

View File

@ -35,7 +35,9 @@ if (_state) then {
nil, 20, false, true, "", QUOTE(!isNull (GETVAR(_target,QGVAR(escortedUnit),objNull)))];
[{
EXPLODE_3_PVT((_this select 0),_unit,_target,_actionID);
params ["_args", "_pfID"];
_args params ["_unit", "_target", "_actionID"];
if (_unit getVariable [QGVAR(isEscorting), false]) then {
if (!alive _target || {!alive _unit} || {!canStand _target} || {!canStand _unit} || {_target getVariable ["ACE_isUnconscious", false]} || {_unit getVariable ["ACE_isUnconscious", false]} || {!isNull (attachedTo _unit)}) then {
_unit setVariable [QGVAR(isEscorting), false, true];

View File

@ -18,7 +18,6 @@
private ["_weapon", "_listedItemClasses", "_actions", "_allGear"];
PARAMS_2(_player,_unit);
params ["_player", "_unit"];
_weapon = currentWeapon _player;

View File

@ -1,6 +1,6 @@
/*
* Author: commy2
* Unit loads the target object into a vehicle.
* Unit loads the target object into a vehicle. (logic same as canLoadCaptive)
*
* Arguments:
* 0: Unit that wants to load a captive <OBJECT>
@ -17,24 +17,34 @@
*/
#include "script_component.hpp"
private "_objects";
params ["_unit", "_target","_vehicle"];
if (isNull _target) then {
_objects = attachedObjects _unit;
_objects = [_objects, {_this getVariable [QGVAR(isHandcuffed), false]}] call EFUNC(common,filter);
if ((count _objects) > 0) then {_target = _objects select 0;};
if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then {
//Looking at a vehicle while escorting, get target from attached objects:
{
if (_x getVariable [QGVAR(isHandcuffed), false]) exitWith {
_target = _x;
};
} forEach (attachedObjects _unit);
};
if (isNull _target) exitWith {};
if ((isNull _target) || {(vehicle _target) != _target} || {!(_target getVariable [QGVAR(isHandcuffed), false])}) exitWith {ERROR("");};
if (isNull _vehicle) then {
_objects = nearestObjects [_unit, ["Car", "Tank", "Helicopter", "Plane", "Ship"], 10];
if ((count _objects) > 0) then {_vehicle = _objects select 0;};
//Looking at a captive unit, search for nearby vehicles with valid seats:
{
// if (([_x] call FUNC(findEmptyNonFFVCargoSeat)) != -1) exitWith {
if ((_x emptyPositions "cargo") > 0) exitWith {
_vehicle = _x;
};
} forEach (nearestObjects [_unit, ["Car", "Tank", "Helicopter", "Plane", "Ship"], 10]);
} else {
// if (([_vehicle] call FUNC(findEmptyNonFFVCargoSeat)) == -1) then {
if ((_vehicle emptyPositions "cargo") == 0) then {
_vehicle = objNull;
};
};
if (isNull _vehicle) exitWith {};
if ((!isNil "_target") && {!isNil "_vehicle"}) then {
_unit setVariable [QGVAR(isEscorting), false, true];
["MoveInCaptive", [_target], [_target, _vehicle]] call EFUNC(common,targetEvent);
};
if (isNull _vehicle) exitWith {ERROR("");};
_unit setVariable [QGVAR(isEscorting), false, true];
["MoveInCaptive", [_target], [_target, _vehicle]] call EFUNC(common,targetEvent);

View File

@ -0,0 +1,67 @@
/*
* Author: PabstMirror
* Finds a free cargo seat, searching non FFV first
*
* Arguments:
* 0: The Vehicle <OBJECT>
*
* Return Value:
* ARRAY [seat index <NUMBER>, is FFV <BOOL>]
*
* Example:
* [car1] call ACE_captives_fnc_findEmptyNonFFVCargoSeat
*
* Public: No
*/
#include "script_component.hpp"
params ["_vehicle"];
TRACE_1("params", _vehicle);
_vehicleConfig = configFile >> "CfgVehicles" >> (typeOf _vehicle);
_proxyOrder = getArray (_vehicleConfig >> "getInProxyOrder");
_transportSoldier = getNumber (_vehicleConfig >> "transportSoldier");
_realCargoCount = if (isArray (_vehicleConfig >> "getInProxyOrder")) then {count _proxyOrder} else {_transportSoldier};
//Find FFV turrets:
_ffvCargoIndexes = [];
{
_turretConfig = [_vehicleConfig, _x] call EFUNC(common,getTurretConfigPath);
_isCargoProxy = ((getText (_turretConfig >> "proxyType")) == "CPCargo") && {isNumber (_turretConfig >> "proxyIndex")};
if (_isCargoProxy) then {
_proxyCargoIndex = getNumber (_turretConfig >> "proxyIndex");
_cargoIndex = _proxyOrder find _proxyCargoIndex;
_ffvCargoIndexes pushBack _cargoIndex;
};
} forEach (allTurrets [_vehicle, true]);
//Find Empty Seats:
_occupiedSeats = [];
{
_x params ["", "", "_xIndex"];
if (_xIndex > -1) then {_occupiedSeats pushBack _xIndex;};
} forEach (fullCrew _vehicle);
TRACE_3("Searching for empty seat",_realCargoCount,_ffvCargoIndexes,_occupiedSeats);
_emptyCargoSeatReturn = [-1, false];
//First seach for non-ffv seats:
for "_index" from 0 to (_realCargoCount - 1) do {
if ((!(_index in _ffvCargoIndexes)) && {!(_index in _occupiedSeats)}) exitWith {
_emptyCargoSeatReturn = [_index, false];
};
};
//Only use FFV if none found:
if (_emptyCargoSeatReturn isEqualTo [-1, false]) then {
for "_index" from 0 to (_realCargoCount - 1) do {
if (!(_index in _occupiedSeats)) exitWith {
_emptyCargoSeatReturn = [_index, true];
};
};
};
_emptyCargoSeatReturn

View File

@ -4,8 +4,8 @@
*
* Arguments:
* 0: _vehicle <OBJECT>
* 2: dunno <OBJECT>
* 1: _unit <OBJECT>
* 1: dunno <OBJECT>
* 2: _unit <OBJECT>
*
* Return Value:
* The return value <BOOL>
@ -17,7 +17,8 @@
*/
#include "script_component.hpp"
params ["_vehicle", "_dontcare","_unit"];
params ["_vehicle", "","_unit"];
TRACE_2("params",_vehicle,_unit);
if (local _unit) then {
if (_unit getVariable [QGVAR(isEscorting), false]) then {
@ -27,4 +28,18 @@ if (local _unit) then {
if (_unit getVariable [QGVAR(isSurrendering), false]) then {
[_unit, false] call FUNC(setSurrender);
};
if (_unit getVariable [QGVAR(isHandcuffed), false]) then {
//Need to force animation for FFV turrets
_turretPath = [];
{
_x params ["_xUnit", "", "", "_xTurretPath"];
if (_unit == _xUnit) exitWith {_turretPath = _xTurretPath};
} forEach (fullCrew (vehicle _unit));
if (!(_turretPath isEqualTo [])) then {
TRACE_1("Setting FFV Handcuffed Animation",_turretPath);
[_unit, "ACE_HandcuffedFFV", 2] call EFUNC(common,doAnimation);
[_unit, "ACE_HandcuffedFFV", 1] call EFUNC(common,doAnimation);
};
};
};

View File

@ -4,8 +4,8 @@
*
* Arguments:
* 0: _vehicle <OBJECT>
* 2: dunno <OBJECT>
* 1: _unit <OBJECT>
* 1: dunno <OBJECT>
* 2: _unit <OBJECT>
*
* Return Value:
* The return value <BOOL>
@ -17,17 +17,21 @@
*/
#include "script_component.hpp"
params ["_vehicle", "_dontcare","_unit"];
params ["_vehicle", "", "_unit"];
TRACE_2("params",_vehicle,_unit);
if ((local _unit) && {_unit getVariable [QGVAR(isHandcuffed), false]}) then {
private ["_cargoIndex"];
_cargoIndex = _unit getVariable [QGVAR(CargoIndex), -1];
//If captive was not "unloaded", then move them back into the vehicle.
if (_cargoIndex != -1) exitWith {
if (_cargoIndex != -1) then {
//If captive was not "unloaded", then move them back into the vehicle.
TRACE_1("forcing back into vehicle",_cargoIndex);
_unit moveInCargo [_vehicle, _cargoIndex];
} else {
//Getting out of vehicle:
[_unit, "ACE_AmovPercMstpScapWnonDnon", 2] call EFUNC(common,doAnimation);
[_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation);
};
[_unit, "ACE_AmovPercMstpScapWnonDnon", 2] call EFUNC(common,doAnimation);
};

View File

@ -18,7 +18,7 @@
params ["_unit"];
// prevent players from throwing grenades (added to all units)
[_unit, "Throw", {((_this select 1) getVariable [QGVAR(isHandcuffed), false]) || {(_this select 1) getVariable [QGVAR(isSurrendering), false]}}, {}] call EFUNC(common,addActionEventhandler);
// [_unit, "Throw", {systemChat "a"; ((_this select 1) getVariable [QGVAR(isHandcuffed), false]) || {(_this select 1) getVariable [QGVAR(isSurrendering), false]}; true}, {systemChat "b";}] call EFUNC(common,addActionEventhandler);
if (local _unit) then {
// reset status on mission start

View File

@ -26,11 +26,11 @@ if (!_activated) exitWith {};
if (local _logic) then {
//Modules run before postInit can instal the event handler, so we need to wait a little bit
[{
PARAMS_1(_units);
params ["_units"];
{
["SetSurrendered", [_x], [_x, true]] call EFUNC(common,targetEvent);
} forEach _units;
}, [_units], 0.05, 0.05]call EFUNC(common,waitAndExecute);
}, [_units], 0.05]call EFUNC(common,waitAndExecute);
deleteVehicle _logic;
};

View File

@ -17,6 +17,7 @@
#include "script_component.hpp"
params ["_unit","_state"];
TRACE_2("params",_unit,_state);
if (!local _unit) exitwith {
ERROR("running setHandcuffed on remote unit");
@ -43,24 +44,47 @@ if (_state) then {
// fix anim on mission start (should work on dedicated servers)
[{
params ["_unit"];
if (_unit getVariable [QGVAR(isHandcuffed), false] && {vehicle _unit == _unit}) then {
if (!(_unit getVariable [QGVAR(isHandcuffed), false])) exitWith {};
if ((vehicle _unit) == _unit) then {
[_unit] call EFUNC(common,fixLoweredRifleAnimation);
[_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation);
} else {
[_unit, "ACE_HandcuffedFFV", 2] call EFUNC(common,doAnimation);
[_unit, "ACE_HandcuffedFFV", 1] call EFUNC(common,doAnimation);
};
//Adds an animation changed eh
//If we get a change in animation then redo the animation (handles people vaulting to break the animation chain)
private "_animChangedEHID";
_animChangedEHID = _unit addEventHandler ["AnimChanged", {
PARAMS_2(_unit,_newAnimation);
//Adds an animation changed eh
//If we get a change in animation then redo the animation (handles people vaulting to break the animation chain)
private "_animChangedEHID";
_animChangedEHID = _unit addEventHandler ["AnimChanged", {
params ["_unit", "_newAnimation"];
TRACE_2("AnimChanged",_unit,_newAnimation);
if (_unit == (vehicle _unit)) then {
if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {!(_unit getVariable ["ACE_isUnconscious", false])}) then {
TRACE_1("Handcuff animation interrupted",_newAnimation);
[_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation);
};
}];
_unit setVariable [QGVAR(handcuffAnimEHID), _animChangedEHID];
} else {
};
}, [_unit], 0.01, 0] call EFUNC(common,waitAndExecute);
_turretPath = [];
{
_x params ["_xUnit", "", "", "_xTurretPath"];
if (_unit == _xUnit) exitWith {_turretPath = _xTurretPath};
} forEach (fullCrew (vehicle _unit));
TRACE_1("turret Path",_turretPath);
if (_turretPath isEqualTo []) exitWith {};
TRACE_1("Handcuff (FFV) animation interrupted",_newAnimation);
[_unit, "ACE_HandcuffedFFV", 2] call EFUNC(common,doAnimation);
[_unit, "ACE_HandcuffedFFV", 1] call EFUNC(common,doAnimation);
};
}];
TRACE_2("Adding animChangedEH",_unit,_animChangedEHID);
_unit setVariable [QGVAR(handcuffAnimEHID), _animChangedEHID];
}, [_unit], 0.01] call EFUNC(common,waitAndExecute);
} else {
_unit setVariable [QGVAR(isHandcuffed), false, true];
[_unit, QGVAR(Handcuffed), false] call EFUNC(common,setCaptivityStatus);
@ -68,6 +92,7 @@ if (_state) then {
//remove AnimChanged EH
private "_animChangedEHID";
_animChangedEHID = _unit getVariable [QGVAR(handcuffAnimEHID), -1];
TRACE_1("removing animChanged EH",_animChangedEHID);
_unit removeEventHandler ["AnimChanged", _animChangedEHID];
_unit setVariable [QGVAR(handcuffAnimEHID), -1];

View File

@ -17,6 +17,7 @@
#include "script_component.hpp"
params ["_unit","_state"];
TRACE_2("params",_unit,_state);
if (!local _unit) exitwith {
ERROR("running surrender on remote unit");
@ -43,13 +44,13 @@ if (_state) then {
// fix anim on mission start (should work on dedicated servers)
[{
PARAMS_1(_unit);
params ["_unit"];
if (_unit getVariable [QGVAR(isSurrendering), false] && {(vehicle _unit) == _unit}) then {
//Adds an animation changed eh
//If we get a change in animation then redo the animation (handles people vaulting to break the animation chain)
private "_animChangedEHID";
_animChangedEHID = _unit addEventHandler ["AnimChanged", {
PARAMS_2(_unit,_newAnimation);
params ["_unit", "_newAnimation"];
if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {!(_unit getVariable ["ACE_isUnconscious", false])}) then {
TRACE_1("Surrender animation interrupted",_newAnimation);
[_unit, "ACE_AmovPercMstpSsurWnonDnon", 1] call EFUNC(common,doAnimation);
@ -57,7 +58,7 @@ if (_state) then {
}];
_unit setVariable [QGVAR(surrenderAnimEHID), _animChangedEHID];
};
}, [_unit], 0.01, 0] call EFUNC(common,waitAndExecute);
}, [_unit], 0.01] call EFUNC(common,waitAndExecute);
} else {
_unit setVariable [QGVAR(isSurrendering), false, true];
[_unit, QGVAR(Surrendered), false] call EFUNC(common,setCaptivityStatus);
@ -85,8 +86,8 @@ if (_state) then {
//spin up a PFEH, to watching animationState for the next 20 seconds to make sure we don't enter "hands up"
//Handles long animation chains
[{
PARAMS_2(_args,_pfID);
EXPLODE_2_PVT(_args,_unit,_maxTime);
params ["_args", "_pfID"];
_args params ["_unit", "_maxTime"];
//If waited long enough or they re-surrendered or they are unconscious, exit loop
if ((ACE_time > _maxTime) || {_unit getVariable [QGVAR(isSurrendering), false]} || {_unit getVariable ["ACE_isUnconscious", false]}) exitWith {
[_pfID] call CBA_fnc_removePerFrameHandler;

View File

@ -16,11 +16,17 @@
*/
#include "script_component.hpp"
params ["_target","_vehicle"];
TRACE_2("params",_target,_vehicle);
private ["_cargoIndex"];
params ["_target","_vehicle"];
_getSeat = [_vehicle] call FUNC(findEmptyNonFFVCargoSeat);
TRACE_1("free cargo seat",_getSeat);
_cargoIndex = _getSeat select 0;
if (_cargoIndex == -1) exitWith {ERROR("cargo index -1");};
_target moveInCargo [_vehicle, _cargoIndex];
_target assignAsCargoIndex [_vehicle, _cargoIndex];
_target moveInCargo _vehicle;
_target assignAsCargo _vehicle;
_cargoIndex = _vehicle getCargoIndex _target;
_target setVariable [QGVAR(CargoIndex), _cargoIndex, true];

View File

@ -16,8 +16,11 @@
#include "script_component.hpp"
params ["_unit"];
TRACE_1("params",_unit);
_unit setVariable [QGVAR(CargoIndex), -1, true];
moveOut _unit;
[_unit, "ACE_AmovPercMstpScapWnonDnon", 2] call EFUNC(common,doAnimation);
[_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation);
unassignVehicle _unit;

View File

@ -1,6 +1,8 @@
#define COMPONENT captives
#include "\z\ace\addons\main\script_mod.hpp"
// #define DEBUG_MODE_FULL
#ifdef DEBUG_ENABLED_CAPTIVES
#define DEBUG_MODE_FULL
#endif