mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
paradrop crates from helicopter or plane cargo (#2468)
This commit is contained in:
parent
0bccaf698d
commit
9ef24d25ba
@ -222,6 +222,8 @@ class CfgVehicles {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class Heli_Transport_04_base_F: Helicopter_Base_H {
|
class Heli_Transport_04_base_F: Helicopter_Base_H {
|
||||||
|
// note the double brackets are because loadmasterTurrets is an array of arrays / turret paths
|
||||||
|
GVAR(loadmasterTurrets)[] = {{1}};
|
||||||
GVAR(space) = 0;
|
GVAR(space) = 0;
|
||||||
GVAR(hasCargo) = 0;
|
GVAR(hasCargo) = 0;
|
||||||
};
|
};
|
||||||
|
@ -14,6 +14,7 @@ PREP(makeLoadable);
|
|||||||
PREP(moduleMakeLoadable);
|
PREP(moduleMakeLoadable);
|
||||||
PREP(moduleSettings);
|
PREP(moduleSettings);
|
||||||
PREP(onMenuOpen);
|
PREP(onMenuOpen);
|
||||||
|
PREP(paradropItem);
|
||||||
PREP(startLoadIn);
|
PREP(startLoadIn);
|
||||||
PREP(startUnload);
|
PREP(startUnload);
|
||||||
PREP(unloadItem);
|
PREP(unloadItem);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
["ace_addCargo", {_this call FUNC(addCargoItem)}] call CBA_fnc_addEventHandler;
|
["ace_addCargo", {_this call FUNC(addCargoItem)}] call CBA_fnc_addEventHandler;
|
||||||
|
[QGVAR(paradropItem), {_this call FUNC(paradropItem)}] call CBA_fnc_addEventHandler;
|
||||||
|
|
||||||
["ace_loadCargo", {
|
["ace_loadCargo", {
|
||||||
params ["_item", "_vehicle"];
|
params ["_item", "_vehicle"];
|
||||||
|
@ -48,6 +48,7 @@ private _condition = {
|
|||||||
};
|
};
|
||||||
private _statement = {
|
private _statement = {
|
||||||
GVAR(interactionVehicle) = _target;
|
GVAR(interactionVehicle) = _target;
|
||||||
|
GVAR(interactionParadrop) = false;
|
||||||
createDialog QGVAR(menu);
|
createDialog QGVAR(menu);
|
||||||
};
|
};
|
||||||
private _text = localize LSTRING(openMenu);
|
private _text = localize LSTRING(openMenu);
|
||||||
@ -55,3 +56,24 @@ private _icon = "";
|
|||||||
|
|
||||||
private _action = [QGVAR(openMenu), _text, _icon, _statement, _condition] call EFUNC(interact_menu,createAction);
|
private _action = [QGVAR(openMenu), _text, _icon, _statement, _condition] call EFUNC(interact_menu,createAction);
|
||||||
[_type, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToClass);
|
[_type, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToClass);
|
||||||
|
|
||||||
|
// Add the paradrop self interaction for planes and helicopters
|
||||||
|
if (_vehicle isKindOf "Air") then {
|
||||||
|
private _condition = {
|
||||||
|
GVAR(enable) && {[_player, _target, []] call EFUNC(common,canInteractWith)} && {
|
||||||
|
private _turretPath = _player call CBA_fnc_turretPath;
|
||||||
|
(_player == (driver _target)) || // pilot
|
||||||
|
{(getNumber (([_target, _turretPath] call CBA_fnc_getTurret) >> "isCopilot")) == 1} || // coPilot
|
||||||
|
{_turretPath in (getArray (configFile >> "CfgVehicles" >> (typeOf _target) >> QGVAR(loadmasterTurrets)))}} // loadMaster turret from config
|
||||||
|
};
|
||||||
|
private _statement = {
|
||||||
|
GVAR(interactionVehicle) = _target;
|
||||||
|
GVAR(interactionParadrop) = true;
|
||||||
|
createDialog QGVAR(menu);
|
||||||
|
};
|
||||||
|
private _text = localize LSTRING(openMenu);
|
||||||
|
private _icon = "";
|
||||||
|
|
||||||
|
private _action = [QGVAR(openMenu), _text, _icon, _statement, _condition] call EFUNC(interact_menu,createAction);
|
||||||
|
[_type, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToClass); // self action on the vehicle
|
||||||
|
};
|
||||||
|
@ -21,6 +21,10 @@ params ["_display"];
|
|||||||
|
|
||||||
uiNamespace setVariable [QGVAR(menuDisplay), _display];
|
uiNamespace setVariable [QGVAR(menuDisplay), _display];
|
||||||
|
|
||||||
|
if (GVAR(interactionParadrop)) then {
|
||||||
|
(_display displayCtrl 12) ctrlSetText (localize LSTRING(paradropButton));
|
||||||
|
};
|
||||||
|
|
||||||
[{
|
[{
|
||||||
disableSerialization;
|
disableSerialization;
|
||||||
private _display = uiNamespace getVariable QGVAR(menuDisplay);
|
private _display = uiNamespace getVariable QGVAR(menuDisplay);
|
||||||
@ -28,7 +32,7 @@ uiNamespace setVariable [QGVAR(menuDisplay), _display];
|
|||||||
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isNull GVAR(interactionVehicle) || {ACE_player distance GVAR(interactionVehicle) >= 10}) exitWith {
|
if (isNull GVAR(interactionVehicle) || {(ACE_player distance GVAR(interactionVehicle) >= 10) && {(vehicle ACE_player) != GVAR(interactionVehicle)}}) exitWith {
|
||||||
closeDialog 0;
|
closeDialog 0;
|
||||||
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||||
};
|
};
|
||||||
|
93
addons/cargo/functions/fnc_paradropItem.sqf
Normal file
93
addons/cargo/functions/fnc_paradropItem.sqf
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Author: marc_book, commy2, CAA-Picard
|
||||||
|
* Unload and paradrop object from plane or helicopter.
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Object <OBJECT>
|
||||||
|
* 1: Vehicle <OBJECT>
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* Object unloaded <BOOL>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [object, vehicle] call ace_cargo_fnc_paradropItem
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
params ["_item", "_vehicle"];
|
||||||
|
TRACE_2("params",_item,_vehicle);
|
||||||
|
|
||||||
|
private _loaded = _vehicle getVariable [QGVAR(loaded), []];
|
||||||
|
|
||||||
|
if !(_item in _loaded) exitWith {false};
|
||||||
|
|
||||||
|
// unload item from cargo
|
||||||
|
_loaded deleteAt (_loaded find _item);
|
||||||
|
_vehicle setVariable [QGVAR(loaded), _loaded, true];
|
||||||
|
|
||||||
|
private _cargoSpace = [_vehicle] call FUNC(getCargoSpaceLeft);
|
||||||
|
private _itemSize = [_item] call FUNC(getSizeItem);
|
||||||
|
_vehicle setVariable [QGVAR(space), (_cargoSpace + _itemSize), true];
|
||||||
|
|
||||||
|
(boundingBoxReal q2) params ["_bb1", "_bb2"];
|
||||||
|
private _distBehind = ((_bb1 select 1) min (_bb2 select 1)) - 3; // 3 meters behind max bounding box
|
||||||
|
TRACE_1("",_distBehind);
|
||||||
|
private _posBehindVehicleAGL = _vehicle modelToWorld [0, _distBehind, -1];
|
||||||
|
|
||||||
|
|
||||||
|
private _itemObject = if (_item isEqualType objNull) then {
|
||||||
|
detach _item;
|
||||||
|
// hideObjectGlobal must be executed before setPos to ensure light objects are rendered correctly
|
||||||
|
// do both on server to ensure they are executed in the correct order
|
||||||
|
[QGVAR(serverUnload), [_item, _posBehindVehicleAGL]] call CBA_fnc_serverEvent;
|
||||||
|
_item
|
||||||
|
} else {
|
||||||
|
private _newItem = createVehicle [_item, _posBehindVehicleAGL, [], 0, ""];
|
||||||
|
_newItem setPosASL (AGLtoASL _posBehindVehicleAGL);
|
||||||
|
_newItem
|
||||||
|
};
|
||||||
|
|
||||||
|
_newItem setVelocity ((velocity _vehicle) vectorAdd ((vectorNormalized (vectorDir _vehicle)) vectorMultiply 10));
|
||||||
|
|
||||||
|
// open parachute and ir light effect
|
||||||
|
[{
|
||||||
|
params ["_item"];
|
||||||
|
|
||||||
|
if (isNull _item || {getPos _item select 2 < 1}) exitWith {};
|
||||||
|
|
||||||
|
private _itemPosASL = getPosASL _item;
|
||||||
|
private _itemVelocity = velocity _item;
|
||||||
|
private _parachute = createVehicle ["B_Parachute_02_F", [0,0,0], [], 0, "CAN_COLLIDE"];
|
||||||
|
|
||||||
|
_item attachTo [_parachute, [0,0,0.2]];
|
||||||
|
_parachute setPosASL _itemPosASL;
|
||||||
|
_parachute setVelocity _itemVelocity;
|
||||||
|
|
||||||
|
private _light = "Chemlight_yellow" createVehicle [0,0,0];
|
||||||
|
_light attachTo [_item, [0,0,0]];
|
||||||
|
|
||||||
|
}, [_itemObject], 0.7] call CBA_fnc_waitAndExecute;
|
||||||
|
|
||||||
|
// smoke effect when crate landed
|
||||||
|
[{
|
||||||
|
(_this select 0) params ["_item"];
|
||||||
|
|
||||||
|
if (isNull _item) exitWith {
|
||||||
|
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (getPos _item select 2 < 1) then {
|
||||||
|
private _smoke = "SmokeshellYellow" createVehicle [0,0,0];
|
||||||
|
_smoke attachTo [_item, [0,0,0]];
|
||||||
|
|
||||||
|
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||||
|
};
|
||||||
|
|
||||||
|
}, 1, [_itemObject]] call CBA_fnc_addPerFrameHandler;
|
||||||
|
|
||||||
|
// Invoke listenable event
|
||||||
|
["ace_cargoUnloaded", [_item, _vehicle, "paradrop"]] call CBA_fnc_globalEvent;
|
||||||
|
|
||||||
|
true
|
@ -30,7 +30,37 @@ private _selected = (lbCurSel _ctrl) max 0;
|
|||||||
if (count _loaded <= _selected) exitWith {};
|
if (count _loaded <= _selected) exitWith {};
|
||||||
private _item = _loaded select _selected; //This can be an object or a classname string
|
private _item = _loaded select _selected; //This can be an object or a classname string
|
||||||
|
|
||||||
// Start progress bar
|
if (GVAR(interactionParadrop)) exitWith {
|
||||||
|
// Start progress bar - paradrop
|
||||||
|
private _size = [_item] call FUNC(getSizeItem);
|
||||||
|
[
|
||||||
|
2.5 * _size,
|
||||||
|
[_item, GVAR(interactionVehicle), ACE_player],
|
||||||
|
{
|
||||||
|
(_this select 0) params ["_item", "_target", "_player"];
|
||||||
|
[QGVAR(paradropItem), [_item, _target]] call CBA_fnc_localEvent;
|
||||||
|
},
|
||||||
|
{
|
||||||
|
params ["_args", "", "", "_errorCode"]; // show warning if we failed because of flight conditions
|
||||||
|
if (_errorCode == 3) then {
|
||||||
|
_args params ["_item", "_target", "_player"];
|
||||||
|
[localize LSTRING(unlevelFlightWarning)] call EFUNC(common,displayTextStructured);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
localize LSTRING(UnloadingItem),
|
||||||
|
{
|
||||||
|
(_this select 0) params ["_item", "_target", "_player"];
|
||||||
|
if ((acos ((vectorUp _target) select 2)) > 30) exitWith {false}; // check flight level
|
||||||
|
if (((getPos _target) select 2) < 25) exitWith {false}; // check height
|
||||||
|
if ((speed _target) < -5) exitWith {false}; // check reverse
|
||||||
|
true
|
||||||
|
},
|
||||||
|
["isNotSwimming", "isNotInside"]
|
||||||
|
] call EFUNC(common,progressBar);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Start progress bar - normal ground unload
|
||||||
if ([_item, GVAR(interactionVehicle), ACE_player] call FUNC(canUnloadItem)) then {
|
if ([_item, GVAR(interactionVehicle), ACE_player] call FUNC(canUnloadItem)) then {
|
||||||
private _size = [_item] call FUNC(getSizeItem);
|
private _size = [_item] call FUNC(getSizeItem);
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ class GVAR(menu) {
|
|||||||
colorSelectBackground2[] = {0.3, 0.3, 0.3, 1.0};
|
colorSelectBackground2[] = {0.3, 0.3, 0.3, 1.0};
|
||||||
};
|
};
|
||||||
class btnCancel: ACE_gui_buttonBase {
|
class btnCancel: ACE_gui_buttonBase {
|
||||||
text = "Cancel";
|
text = "$STR_DISP_CANCEL";
|
||||||
idc = 11;
|
idc = 11;
|
||||||
x = "13.1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)";
|
x = "13.1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)";
|
||||||
y = "14.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
|
y = "14.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
|
||||||
|
@ -201,5 +201,13 @@
|
|||||||
<Portuguese>Tamanho do objeto</Portuguese>
|
<Portuguese>Tamanho do objeto</Portuguese>
|
||||||
<Russian>Размер объекта</Russian>
|
<Russian>Размер объекта</Russian>
|
||||||
</Key>
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Cargo_paradropButton">
|
||||||
|
<English>Airdrop</English>
|
||||||
|
<German>Türlast</German>
|
||||||
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Cargo_unlevelFlightWarning">
|
||||||
|
<English>Unlevel Flight</English>
|
||||||
|
<German>Schieflage</German>
|
||||||
|
</Key>
|
||||||
</Package>
|
</Package>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue
Block a user