Add ViV cargo

- Paradrop handling is missing
- See what items should be able to be loaded via ViV or not
This commit is contained in:
johnb432 2024-07-19 18:34:14 +02:00
parent 61883dac06
commit ac7e398df7
24 changed files with 241 additions and 330 deletions

View File

@ -1,6 +0,0 @@
class CfgActions {
class None;
class UnloadAllVehicles: None {
show = 0;
};
};

View File

@ -1,8 +1,6 @@
PREP(addCargoItem); PREP(addCargoItem);
PREP(addCargoVehiclesActions); PREP(addCargoVehiclesActions);
PREP(canItemCargo);
PREP(canLoadItemIn); PREP(canLoadItemIn);
PREP(canShowUnloadAllVehicles);
PREP(canUnloadItem); PREP(canUnloadItem);
PREP(deployCancel); PREP(deployCancel);
PREP(deployConfirm); PREP(deployConfirm);
@ -10,8 +8,6 @@ PREP(getCargoSpaceLeft);
PREP(getNameItem); PREP(getNameItem);
PREP(getSelectedItem); PREP(getSelectedItem);
PREP(getSizeItem); PREP(getSizeItem);
PREP(getSurfaceItem);
PREP(getVehicleCargo);
PREP(handleDestroyed); PREP(handleDestroyed);
PREP(handleDeployInterrupt); PREP(handleDeployInterrupt);
PREP(handleScrollWheel); PREP(handleScrollWheel);
@ -29,6 +25,5 @@ PREP(startDeploy);
PREP(startLoadIn); PREP(startLoadIn);
PREP(startUnload); PREP(startUnload);
PREP(unload); PREP(unload);
PREP(unloadAllVehicles);
PREP(unloadCarryItem); PREP(unloadCarryItem);
PREP(unloadItem); PREP(unloadItem);

View File

@ -86,7 +86,13 @@ GVAR(vehicleAction) = [
GVAR(enable) && GVAR(enable) &&
{alive _target} && {alive _target} &&
{locked _target < 2} && {locked _target < 2} &&
{_target getVariable [QGVAR(hasCargo), getNumber (configOf _target >> QGVAR(hasCargo)) == 1]} && {
private _config = configOf _target;
// https://feedback.bistudio.com/T182949
(vehicleCargoEnabled _target && {isClass (_config >> "VehicleTransport" >> "Carrier")}) ||
{_target getVariable [QGVAR(hasCargo), getNumber (_config >> QGVAR(hasCargo)) == 1]}
} &&
{[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} &&
{[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} && {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} &&
{([_player, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} {([_player, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}
@ -121,6 +127,7 @@ GVAR(objectActions) = [
GVAR(enable) && GVAR(enable) &&
{alive _target} && {alive _target} &&
{locked _target < 2} && {locked _target < 2} &&
{isNull isVehicleCargo _target} &&
{_target getVariable [QGVAR(canLoad), getNumber (configOf _target >> QGVAR(canLoad)) == 1]} && {_target getVariable [QGVAR(canLoad), getNumber (configOf _target >> QGVAR(canLoad)) == 1]} &&
{[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} &&
{[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} && {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} &&
@ -132,29 +139,34 @@ GVAR(objectActions) = [
{([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} {([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}
}) != -1} }) != -1}
}, },
LINKFUNC(addCargoVehiclesActions) {_target call FUNC(addCargoVehiclesActions)}
] call EFUNC(interact_menu,createAction),
[QGVAR(loadViv), LLSTRING(loadObjectViv), "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa",
{
//IGNORE_PRIVATE_WARNING ["_target", "_player"];
[_player, _target, objNull, true] call FUNC(startLoadIn);
},
{
//IGNORE_PRIVATE_WARNING ["_target", "_player"];
GVAR(enable) &&
{alive _target} &&
{locked _target < 2} &&
{isNull isVehicleCargo _target} &&
{_target getVariable [QGVAR(canLoad), getNumber (configOf _target >> QGVAR(canLoad)) == 1]} &&
{[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} &&
{[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} &&
{((nearestObjects [_target, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]) findIf {
_x != _target &&
{alive _x} &&
{locked _x < 2} &&
{(_x canVehicleCargo _target) select 0} &&
{([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}
}) != -1}
},
{[_target, true] call FUNC(addCargoVehiclesActions)}
] call EFUNC(interact_menu,createAction) ] call EFUNC(interact_menu,createAction)
]; ];
{
[_x, "InitPost", {
params ["_vehicle"];
private _actionID = _vehicle addAction [
"",
FUNC(unloadAllVehicles),
nil,
3,
false,
true,
"",
'[_target, _this] call FUNC(canShowUnloadAllVehicles)'
];
_vehicle setUserActionText [_actionID, localize "STR_A3_ACTION_UNLOAD_ALL_VEHICLES", "<img image='\A3\Ui_f\data\IGUI\Cfg\Actions\unloadAllVehicles_ca.paa' size='1.8' shadow=2 />"];
_vehicle setVariable [QGVAR(unloadAllVehiclesAction), _actionID];
}, nil, nil, true] call CBA_fnc_addClassEventHandler;
} forEach ["LandVehicle", "Ship", "Air"];
// Find all remaining configured classes and init them, see XEH_preStart.sqf // Find all remaining configured classes and init them, see XEH_preStart.sqf
private _vehicleClassesAddAction = call (uiNamespace getVariable [QGVAR(initializedVehicleClasses), {[]}]); private _vehicleClassesAddAction = call (uiNamespace getVariable [QGVAR(initializedVehicleClasses), {[]}]);
@ -202,10 +214,7 @@ if (isServer) then {
GVAR(selectedItem) = objNull; GVAR(selectedItem) = objNull;
GVAR(itemPreviewObject) = objNull; GVAR(itemPreviewObject) = objNull;
GVAR(deployPFH) = -1; GVAR(deployPFH) = -1;
GVAR(deployDistance) = -1; GVAR(isViv) = false;
GVAR(deployDirection) = 0;
GVAR(deployHeight) = 0;
GVAR(canDeploy) = false;
if (!hasInterface) exitWith {}; if (!hasInterface) exitWith {};

View File

@ -20,4 +20,3 @@ class CfgPatches {
#include "CfgVehicles.hpp" #include "CfgVehicles.hpp"
#include "menu.hpp" #include "menu.hpp"
#include "renameMenu.hpp" #include "renameMenu.hpp"
#include "CfgActions.hpp"

View File

@ -5,6 +5,7 @@
* *
* Arguments: * Arguments:
* 0: Holder object (vehicle) <OBJECT> * 0: Holder object (vehicle) <OBJECT>
* 1: Is item to be loaded as ViV? <BOOL> (default: false)
* *
* Return Value: * Return Value:
* Child actions <ARRAY> * Child actions <ARRAY>
@ -15,20 +16,22 @@
* Public: No * Public: No
*/ */
params ["_vehicle"]; params ["_vehicle", ["_isViv", false]];
private _statement = { private _statement = compile format [QUOTE([ARR_4(_this select 1,_this select 0,_this select 2,%1)] call FUNC(startLoadIn)), _isViv];
params ["_item", "_loader", "_vehicle"];
[_loader, _item, _vehicle] call FUNC(startLoadIn);
};
private _vehicles = (nearestObjects [_vehicle, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]) select { private _vehicles = (nearestObjects [_vehicle, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]) select {
_x != _vehicle && _x != _vehicle &&
{alive _x} && {alive _x} &&
{locked _x < 2} && {locked _x < 2} &&
{_x getVariable [QGVAR(hasCargo), getNumber (configOf _x >> QGVAR(hasCargo)) == 1]} && {
if (_isViv) then {
(_x canVehicleCargo _vehicle) select 0
} else {
_x getVariable [QGVAR(hasCargo), getNumber (configOf _x >> QGVAR(hasCargo)) == 1]
}
} &&
{([_vehicle, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} {([_vehicle, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}
}; };
[_vehicles, _statement, _vehicle] call EFUNC(interact_menu,createVehiclesActions) [_vehicles, _statement, _vehicle] call EFUNC(interact_menu,createVehiclesActions) // return

View File

@ -1,32 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: Vdauphin
* Checks if an item would fit in the space currently used by loaded items.
*
* Arguments:
* 0: Item <OBJECT>
* 1: Vehicle <OBJECT>
* 2: Items from vehicle cargo <OBJECT>
*
* Return Value:
* Ig the item would fit or not <BOOL>
*
* Example:
* ["ACE_Wheel", cursorObject, []] call ace_cargo_fnc_canItemCargo
*
* Public: No
*/
params ["_item", "_vehicle", "_items"];
// If there are no items or if the item can't fit in the vehicle when empty, skip
if (_items isEqualTo [] || {!((_vehicle canVehicleCargo _item) select 1)}) exitWith {false};
private _itemSurface = _item call FUNC(getSurfaceItem);
private _itemsSurface = 0;
{
_itemsSurface = _itemsSurface + (_item call FUNC(getSurfaceItem));
} forEach _items;
_itemSurface <= _itemsSurface

View File

@ -7,6 +7,7 @@
* 0: Item to be loaded <STRING> or <OBJECT> * 0: Item to be loaded <STRING> or <OBJECT>
* 1: Holder object (vehicle) <OBJECT> * 1: Holder object (vehicle) <OBJECT>
* 2: Ignore interaction distance and stability checks <BOOL> (default: false) * 2: Ignore interaction distance and stability checks <BOOL> (default: false)
* 3: Is item to be loaded as ViV? <BOOL> (default: false)
* *
* Return Value: * Return Value:
* Can be loaded <BOOL> * Can be loaded <BOOL>
@ -17,7 +18,7 @@
* Public: No * Public: No
*/ */
params ["_item", "_vehicle", ["_ignoreInteraction", false]]; params ["_item", "_vehicle", ["_ignoreInteraction", false], ["_isViv", false]];
// Check if vehicle is stable // Check if vehicle is stable
if (!_ignoreInteraction && {speed _vehicle > 1 || {((getPos _vehicle) select 2) > 3}}) exitWith { if (!_ignoreInteraction && {speed _vehicle > 1 || {((getPos _vehicle) select 2) > 3}}) exitWith {
@ -52,6 +53,12 @@ private _validItem = if (_item isEqualType "") then {
_validItem && _validItem &&
{alive _vehicle} && {alive _vehicle} &&
{locked _vehicle < 2} && {locked _vehicle < 2} &&
{_vehicle getVariable [QGVAR(hasCargo), getNumber (configOf _vehicle >> QGVAR(hasCargo)) == 1]} && {
if (_isViv) then {
(_vehicle canVehicleCargo _item) select 0
} else {
_vehicle getVariable [QGVAR(hasCargo), getNumber (configOf _vehicle >> QGVAR(hasCargo)) == 1]
}
} &&
{_itemSize >= 0} && {_itemSize >= 0} &&
{_itemSize <= (_vehicle call FUNC(getCargoSpaceLeft)) max 0} {_isViv || {_itemSize <= (_vehicle call FUNC(getCargoSpaceLeft)) max 0}}

View File

@ -1,26 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: Vdauphin
* Checks if unload all vehicles interaction can be show.
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: Unit <OBJECT>
*
* Return Value:
* Can show menu <BOOL>
*
* Example:
* [vehicle player, player] call ace_cargo_fnc_canShowUnloadAllVehicles
*
* Public: No
*/
params [
"_vehicle",
["_unit", player, [objNull]]
];
driver _vehicle isEqualTo _unit &&
{isClass (configOf _vehicle >> "VehicleTransport" >> "Carrier")} &&
{!([_vehicle] call FUNC(getVehicleCargo) isEqualTo [])}

View File

@ -9,6 +9,7 @@
* 2: Unit doing the unloading <OBJECT> (default: objNull) * 2: Unit doing the unloading <OBJECT> (default: objNull)
* 3: Ignore interaction distance and stability checks <BOOL> (default: false) * 3: Ignore interaction distance and stability checks <BOOL> (default: false)
* 4: Ignore finding a suitable position <BOOL> (default: false) * 4: Ignore finding a suitable position <BOOL> (default: false)
* 5: Is item loaded as ViV? <BOOL> (default: false)
* *
* Return Value: * Return Value:
* Can be unloaded <BOOL> * Can be unloaded <BOOL>
@ -19,7 +20,7 @@
* Public: No * Public: No
*/ */
params ["_item", "_vehicle", ["_unloader", objNull], ["_ignoreInteraction", false], ["_ignoreFindPosition", false]]; params ["_item", "_vehicle", ["_unloader", objNull], ["_ignoreInteraction", false], ["_ignoreFindPosition", false], ["_isViv", false]];
TRACE_2("params",_item,_vehicle); TRACE_2("params",_item,_vehicle);
// Get config sensitive case name // Get config sensitive case name
@ -27,7 +28,8 @@ if (_item isEqualType "") then {
_item = _item call EFUNC(common,getConfigName); _item = _item call EFUNC(common,getConfigName);
}; };
if !(_item in (_vehicle getVariable [QGVAR(loaded), []])) exitWith {false}; if (_isViv && {_vehicle != isVehicleCargo _item}) exitWith {false};
if !(_isViv || {_item in (_vehicle getVariable [QGVAR(loaded), []])}) exitWith {false};
private _validItem = if (_item isEqualType objNull) then { private _validItem = if (_item isEqualType objNull) then {
alive _item alive _item
@ -38,7 +40,7 @@ private _validItem = if (_item isEqualType objNull) then {
_validItem && _validItem &&
{alive _vehicle} && {alive _vehicle} &&
{locked _vehicle < 2} && {locked _vehicle < 2} &&
{_vehicle getVariable [QGVAR(hasCargo), getNumber (configOf _vehicle >> QGVAR(hasCargo)) == 1]} && {_isViv || {_vehicle getVariable [QGVAR(hasCargo), getNumber (configOf _vehicle >> QGVAR(hasCargo)) == 1]}} &&
{_item call FUNC(getSizeItem) >= 0} && {_item call FUNC(getSizeItem) >= 0} &&
{_ignoreInteraction || {([_unloader, _vehicle] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}} && {_ignoreInteraction || {([_unloader, _vehicle] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}} &&
{_ignoreFindPosition || {([_vehicle, _item, _unloader, MAX_LOAD_DISTANCE, !_ignoreInteraction] call EFUNC(common,findUnloadPosition)) isNotEqualTo []}} {_ignoreFindPosition || {([_vehicle, _item, _unloader, MAX_LOAD_DISTANCE, !_ignoreInteraction] call EFUNC(common,findUnloadPosition)) isNotEqualTo []}}

View File

@ -20,7 +20,7 @@ if (GVAR(deployPFH) == -1) exitWith {};
params ["_unit"]; params ["_unit"];
// Delete placement dummy and unload real item from cargo at dummy position // Delete placement dummy and unload real item from cargo at dummy position
if (!isNull GVAR(itemPreviewObject) && {[GVAR(selectedItem), GVAR(interactionVehicle), _unit, false, true] call FUNC(canUnloadItem)}) then { if (!isNull GVAR(itemPreviewObject) && {[GVAR(selectedItem), GVAR(interactionVehicle), _unit, false, true, GVAR(isViv)] call FUNC(canUnloadItem)}) then {
// Position is AGL for unloading event // Position is AGL for unloading event
private _position = ASLToAGL getPosASL GVAR(itemPreviewObject); private _position = ASLToAGL getPosASL GVAR(itemPreviewObject);
private _direction = getDir GVAR(itemPreviewObject); private _direction = getDir GVAR(itemPreviewObject);
@ -28,25 +28,43 @@ if (!isNull GVAR(itemPreviewObject) && {[GVAR(selectedItem), GVAR(interactionVeh
// If unload time is 0, don't show a progress bar // If unload time is 0, don't show a progress bar
if (_duration <= 0) exitWith { if (_duration <= 0) exitWith {
if (GVAR(isViv)) then {
objNull setVehicleCargo GVAR(selectedItem);
GVAR(selectedItem) setDir _direction;
GVAR(selectedItem) setPosASL _position;
} else {
["ace_unloadCargo", [GVAR(selectedItem), GVAR(interactionVehicle), _unit, [_position, _direction]]] call CBA_fnc_localEvent; ["ace_unloadCargo", [GVAR(selectedItem), GVAR(interactionVehicle), _unit, [_position, _direction]]] call CBA_fnc_localEvent;
}; };
};
[ [
_duration, _duration,
[GVAR(selectedItem), GVAR(interactionVehicle), _unit, [_position, _direction]], [GVAR(selectedItem), GVAR(interactionVehicle), _unit, [_position, _direction], GVAR(isViv)],
{ {
TRACE_1("deploy finish",_this); TRACE_1("deploy finish",_this);
(_this select 0) params ["_item", "", "", "_posAndDir"];
// Is ViV
// Don't want to pass the isViv parameter to the ace_unloadCargo EH
if ((_this select 0) deleteAt 4) then {
objNull setVehicleCargo _item;
_item setDir (_posAndDir select 1);
_item setPosASL (AGLtoASL (_posAndDir select 0));
} else {
["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent; ["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent;
};
}, },
{ {
TRACE_1("deploy fail",_this); TRACE_1("deploy fail",_this);
}, },
format [LLSTRING(unloadingItem), [GVAR(selectedItem), true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")], format [LLSTRING(unloadingItem), [GVAR(selectedItem), true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")],
{ {
(_this select 0) params ["_item", "_vehicle", "_unit"]; (_this select 0) params ["_item", "_vehicle", "_unit", "", "_isViv"];
[_item, _vehicle, _unit, false, true] call FUNC(canUnloadItem) // don't check for a suitable unloading position when deploying [_item, _vehicle, _unit, false, true, _isViv] call FUNC(canUnloadItem) // Don't check for a suitable unloading position when deploying
}, },
["isNotSwimming"] ["isNotSwimming"]
] call EFUNC(common,progressBar); ] call EFUNC(common,progressBar);

View File

@ -15,13 +15,19 @@
* Public: No * Public: No
*/ */
params [["_isViv", false]];
disableSerialization; disableSerialization;
private _display = uiNamespace getVariable QGVAR(menuDisplay); private _display = uiNamespace getVariable QGVAR(menuDisplay);
if (isNil "_display") exitWith {}; if (isNil "_display") exitWith {};
private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; private _loaded = if (_isViv) then {
getVehicleCargo GVAR(interactionVehicle)
} else {
GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]
};
if (_loaded isEqualTo []) exitWith {}; if (_loaded isEqualTo []) exitWith {};

View File

@ -1,26 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: Vdauphin
* Gets surface of an item.
*
* Arguments:
* 0: Object <OBJECT>
*
* Return Value:
* Surface in m² <NUMBER>
*
* Example:
* cursorObject call ace_cargo_fnc_getSurfaceItem
*
* Public: No
*/
params ["_object"];
private _bbr = 0 boundingBoxReal _object;
private _p1 = _bbr select 0;
private _p2 = _bbr select 1;
private _width = abs ((_p2 select 0) - (_p1 select 0));
private _length = abs ((_p2 select 1) - (_p1 select 1));
_width * _length

View File

@ -1,22 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: Vdauphin
* Get vehicle in cargo.
*
* Arguments:
* 0: Vehicle <OBJECT>
*
* Return Value:
* Loaded vehicles not part of ACE Cargo <ARRAY>
*
* Example:
* [vehicle player] call ace_cargo_fnc_getVehicleCargo
*
* Public: No
*/
params ["_vehicle"];
(getVehicleCargo _vehicle - (_vehicle getVariable [QGVAR(loaded), []])) select {
!(_x getVariable [QGVAR(isCargoNet), false])
}

View File

@ -47,44 +47,6 @@ _vehicle setVariable [QGVAR(space), _cargoSpace - _itemSize, true];
if (_item isEqualType objNull) then { if (_item isEqualType objNull) then {
detach _item; detach _item;
// If the object couldn't be loaded as ViV, try to compact the existing ViV cargo
if !(_vehicle setVehicleCargo _item) then {
private _itemsViVCargo = _loaded arrayIntersect (getVehicleCargo _vehicle);
private _cargoNet = createVehicle [GVAR(cargoNetType), [0, 0, 0], [], 0, "CAN_COLLIDE"];
if ([_cargoNet, _vehicle, _itemsViVCargo] call FUNC(canItemCargo)) then {
// Move ViV cargo to ACE Cargo
while {!(_vehicle setVehicleCargo _cargoNet)} do {
if (_itemsViVCargo isEqualTo []) exitWith {
// Should not happen
deleteVehicle _cargoNet;
};
private _itemViV = _itemsViVCargo deleteAt 0;
// If the ViV object couldn't be unloaded, quit
if !(objNull setVehicleCargo _itemViV) exitWith {
deleteVehicle _cargoNet;
};
// If the ViV object was unloaded, store it as regular cargo
_itemViV setVariable [QGVAR(cargoNet), _cargoNet, true];
_itemViV attachTo [_vehicle, [0, 0, -100]];
[QEGVAR(common,hideObjectGlobal), [_itemViV, true]] call CBA_fnc_serverEvent;
// Some objects below water will take damage over time and eventualy become "water logged" and unfixable (because of negative z attach)
[_itemViV, "blockDamage", "ACE_cargo", true] call EFUNC(common,statusEffect_set);
};
} else {
deleteVehicle _cargoNet;
};
if (!isNull _cargoNet) then {
_cargoNet setVariable [QGVAR(isCargoNet), true, true];
_item setVariable [QGVAR(cargoNet), _cargoNet, true];
};
_item attachTo [_vehicle, [0, 0, -100]]; _item attachTo [_vehicle, [0, 0, -100]];
[QEGVAR(common,hideObjectGlobal), [_item, true]] call CBA_fnc_serverEvent; [QEGVAR(common,hideObjectGlobal), [_item, true]] call CBA_fnc_serverEvent;
@ -102,7 +64,6 @@ if (_item isEqualType objNull) then {
// Some objects below water will take damage over time, eventually becoming "water logged" and unfixable (because of negative z attach) // Some objects below water will take damage over time, eventually becoming "water logged" and unfixable (because of negative z attach)
[_item, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); [_item, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
}; };
};
// Invoke listenable event // Invoke listenable event
["ace_cargoLoaded", [_item, _vehicle]] call CBA_fnc_globalEvent; ["ace_cargoLoaded", [_item, _vehicle]] call CBA_fnc_globalEvent;

View File

@ -25,11 +25,25 @@ if (GVAR(interactionParadrop)) then {
(_display displayCtrl 12) ctrlSetText LLSTRING(paradropButton); (_display displayCtrl 12) ctrlSetText LLSTRING(paradropButton);
}; };
// https://feedback.bistudio.com/T182949
private _config = configOf GVAR(interactionVehicle);
private _isVivCapable = isClass (_config >> "VehicleTransport" >> "Carrier");
// Make sure that correct menu is displayed at start, if there are limitations
if !(GVAR(interactionVehicle) getVariable [QGVAR(hasCargo), getNumber (_config >> QGVAR(hasCargo)) == 1]) then {
GVAR(isViv) = true;
} else {
if !(_isVivCapable && {vehicleCargoEnabled GVAR(interactionVehicle)}) then {
GVAR(isViv) = false;
};
};
// Disable deploy option if paradropping or in Zeus // Disable deploy option if paradropping or in Zeus
(_display displayCtrl 13) ctrlEnable (GVAR(enableDeploy) && !GVAR(interactionParadrop) && {isNull curatorCamera}); (_display displayCtrl 13) ctrlEnable (GVAR(enableDeploy) && !GVAR(interactionParadrop) && {isNull curatorCamera});
[{ [{
params ["_vehicle", "_pfhID"]; params ["_args", "_pfhID"];
_args params ["_vehicle", "_isVivCapable"];
disableSerialization; disableSerialization;
@ -46,7 +60,15 @@ if (GVAR(interactionParadrop)) then {
!alive ACE_player || !alive ACE_player ||
{!alive _vehicle} || {!alive _vehicle} ||
{locked _vehicle >= 2} || {locked _vehicle >= 2} ||
{!(_vehicle getVariable [QGVAR(hasCargo), true])} || // if the cargo menu could be opened, the vehicle has QGVAR(hasCargo) in its config or the variable is set using FUNC(setSpace) {
// If the cargo menu could be opened, the vehicle has QGVAR(hasCargo) in its config or the variable is set using FUNC(setSpace)
// or ViV was enabled via config
if (GVAR(isViv)) then {
!vehicleCargoEnabled _vehicle
} else {
!(_vehicle getVariable [QGVAR(hasCargo), true])
};
} ||
{ {
isNull curatorCamera && // if in Zeus, ignore the checks that follow isNull curatorCamera && // if in Zeus, ignore the checks that follow
{([ACE_player, _vehicle] call EFUNC(interaction,getInteractionDistance)) >= MAX_LOAD_DISTANCE} && {([ACE_player, _vehicle] call EFUNC(interaction,getInteractionDistance)) >= MAX_LOAD_DISTANCE} &&
@ -60,27 +82,39 @@ if (GVAR(interactionParadrop)) then {
_pfhID call CBA_fnc_removePerFrameHandler; _pfhID call CBA_fnc_removePerFrameHandler;
}; };
// Set ViV on button
(_display displayCtrl 14) ctrlSetText localize ([LSTRING(vehicleInVehicle), LSTRING(openMenu)] select (GVAR(isViv)));
// Don't allow switching to other menu if vehicle doesn't have capability for other menu
if (GVAR(isViv)) then {
(_display displayCtrl 14) ctrlEnable (_vehicle getVariable [QGVAR(hasCargo), true]);
} else {
(_display displayCtrl 14) ctrlEnable (_isVivCapable && {vehicleCargoEnabled _vehicle});
};
private _ctrl = _display displayCtrl 100; private _ctrl = _display displayCtrl 100;
private _label = _display displayCtrl 2; private _label = _display displayCtrl 2;
// Remove previous entries // Remove previous entries
lbClear _ctrl; lbClear _ctrl;
// Display item names private _loaded = if (GVAR(isViv)) then {
private _displayName = ""; getVehicleCargo _vehicle
private _itemSize = 0; } else {
private _index = -1; _vehicle getVariable [QGVAR(loaded), []]
private _damageStr = "0%"; };
private _damage = 0;
private _maxMass = getNumber (configOf _vehicle >> "VehicleTransport" >> "Carrier" >> "maxLoadMass");
// Display item names
{ {
_displayName = [_x, true] call FUNC(getNameItem); private _displayName = [_x, true] call FUNC(getNameItem);
_itemSize = _x call FUNC(getSizeItem); private _itemSize = _x call FUNC(getSizeItem);
_damage = if (_x isEqualType "") then {0} else {damage _x}; private _damage = if (_x isEqualType "") then {0} else {damage _x};
_damageStr = ((_damage * 100) toFixed 0) + "%"; private _damageStr = ((_damage * 100) toFixed 0) + "%";
if (_itemSize >= 0) then { if (_itemSize >= 0) then {
_index = if (GVAR(interactionParadrop)) then { private _index = if (GVAR(interactionParadrop)) then {
_ctrl lbAdd format ["%1. %2 (%3s)", _forEachIndex + 1, _displayName, GVAR(paradropTimeCoefficent) * _itemSize] _ctrl lbAdd format ["%1. %2 (%3s)", _forEachIndex + 1, _displayName, GVAR(paradropTimeCoefficent) * _itemSize]
} else { } else {
_ctrl lbAdd format ["%1. %2", _forEachIndex + 1, _displayName] _ctrl lbAdd format ["%1. %2", _forEachIndex + 1, _displayName]
@ -90,13 +124,21 @@ if (GVAR(interactionParadrop)) then {
_ctrl lbSetTooltip [_index, _tooltip]; _ctrl lbSetTooltip [_index, _tooltip];
} else { } else {
// If item has a size < 0, it means it's not loadable // If item has a size < 0, it means it's not loadable
_index = _ctrl lbAdd _displayName; private _index = _ctrl lbAdd _displayName;
_ctrl lbSetTooltip [_index, LLSTRING(unloadingImpossible)]; _ctrl lbSetTooltip [_index, LLSTRING(unloadingImpossible)];
_ctrl lbSetColor [_index, [1, 0, 0, 1]]; // set text to red _ctrl lbSetColor [_index, [1, 0, 0, 1]]; // set text to red
_ctrl lbSetSelectColor [_index, [1, 0, 0, 1]]; _ctrl lbSetSelectColor [_index, [1, 0, 0, 1]];
}; };
} forEach (_vehicle getVariable [QGVAR(loaded), []]);
if (GVAR(isViv)) then {
_maxMass = _maxMass - getMass _x;
};
} forEach _loaded;
if (GVAR(isViv)) then {
_label ctrlSetText format [LLSTRING(labelSpace), _maxMass max 0];
} else {
_label ctrlSetText format [LLSTRING(labelSpace), (_vehicle call FUNC(getCargoSpaceLeft)) max 0]; _label ctrlSetText format [LLSTRING(labelSpace), (_vehicle call FUNC(getCargoSpaceLeft)) max 0];
}, 0, GVAR(interactionVehicle)] call CBA_fnc_addPerFrameHandler; };
}, 0, [GVAR(interactionVehicle), _isVivCapable]] call CBA_fnc_addPerFrameHandler;

View File

@ -68,7 +68,7 @@ private _object = [_item, _vehicle, _posBehindVehicleAGL, false] call FUNC(unloa
// Prevent collision damage // Prevent collision damage
[QEGVAR(common,fixCollision), _parachute] call CBA_fnc_localEvent; [QEGVAR(common,fixCollision), _parachute] call CBA_fnc_localEvent;
[QEGVAR(common,fixCollision), _object] call CBA_fnc_localEvent; [QEGVAR(common,fixCollision), _object, _object] call CBA_fnc_targetEvent;
// Cannot use setPos on parachutes without them closing down // Cannot use setPos on parachutes without them closing down
_parachute attachTo [_object, [0, 0, 0]]; _parachute attachTo [_object, [0, 0, 0]];

View File

@ -24,7 +24,7 @@ params ["_unit"];
if (_unit getVariable [QGVAR(isDeploying), false]) exitWith {}; if (_unit getVariable [QGVAR(isDeploying), false]) exitWith {};
// This can be an object or a classname string // This can be an object or a classname string
private _item = call FUNC(getSelectedItem); private _item = GVAR(isViv) call FUNC(getSelectedItem);
if (isNil "_item") exitWith {}; if (isNil "_item") exitWith {};
@ -64,15 +64,15 @@ _itemPreviewObject attachTo [_unit, [0, 1.5 * _itemPreviewObjectRadius, _offset]
// PFH that runs while the deployment is in progress // PFH that runs while the deployment is in progress
GVAR(deployPFH) = [{ GVAR(deployPFH) = [{
(_this select 0) params ["_unit", "_vehicle", "_item", "_itemPreviewObject"]; (_this select 0) params ["_unit", "_vehicle", "_item", "_itemPreviewObject", "_isViv"];
if !( if !(
!isNull _itemPreviewObject && !isNull _itemPreviewObject &&
{[_item, _vehicle, _unit, false, true] call FUNC(canUnloadItem)} // don't check for a suitable unloading position when deploying {[_item, _vehicle, _unit, false, true, _isViv] call FUNC(canUnloadItem)} // Don't check for a suitable unloading position when deploying
) exitWith { ) exitWith {
_unit call FUNC(deployCancel); _unit call FUNC(deployCancel);
}; };
}, 0.5, [_unit, GVAR(interactionVehicle), _item, _itemPreviewObject]] call CBA_fnc_addPerFrameHandler; }, 0.5, [_unit, GVAR(interactionVehicle), _item, _itemPreviewObject, GVAR(isViv)]] call CBA_fnc_addPerFrameHandler;
// Add mouse button action and hint // Add mouse button action and hint
[LLSTRING(unloadObject), localize "STR_DISP_CANCEL", LLSTRING(scrollAction)] call EFUNC(interaction,showMouseHint); [LLSTRING(unloadObject), localize "STR_DISP_CANCEL", LLSTRING(scrollAction)] call EFUNC(interaction,showMouseHint);

View File

@ -7,6 +7,7 @@
* 0: Unit doing the loading <OBJECT> * 0: Unit doing the loading <OBJECT>
* 1: Item to be loaded <OBJECT> * 1: Item to be loaded <OBJECT>
* 2: Holder object (vehicle) <OBJECT> (default: objNull) * 2: Holder object (vehicle) <OBJECT> (default: objNull)
* 3: Is item to be loaded as ViV? <BOOL> (default: false)
* *
* Return Value: * Return Value:
* Load ProgressBar Started <BOOL> * Load ProgressBar Started <BOOL>
@ -17,12 +18,12 @@
* Public: No * Public: No
*/ */
params ["_loader", "_item", ["_vehicle", objNull]]; params ["_loader", "_item", ["_vehicle", objNull], ["_isViv", false]];
TRACE_3("params",_loader,_item,_vehicle); TRACE_3("params",_loader,_item,_vehicle);
if (isNull _vehicle) then { if (isNull _vehicle) then {
{ {
if ([_item, _x] call FUNC(canLoadItemIn)) exitWith { if ([_item, _x, false, _isViv] call FUNC(canLoadItemIn)) exitWith {
_vehicle = _x; _vehicle = _x;
}; };
} forEach (nearestObjects [_loader, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]); } forEach (nearestObjects [_loader, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]);
@ -35,12 +36,16 @@ if (isNull _vehicle) exitWith {
}; };
// Start progress bar // Start progress bar
if ([_item, _vehicle] call FUNC(canLoadItemIn)) then { if ([_item, _vehicle, false, _isViv] call FUNC(canLoadItemIn)) then {
private _duration = GVAR(loadTimeCoefficient) * (_item call FUNC(getSizeItem)); private _duration = GVAR(loadTimeCoefficient) * (_item call FUNC(getSizeItem));
// If load time is 0, don't show a progress bar // If load time is 0, don't show a progress bar
if (_duration <= 0) exitWith { if (_duration <= 0) exitWith {
if (_isViv) then {
_vehicle setVehicleCargo _item;
} else {
["ace_loadCargo", [_item, _vehicle]] call CBA_fnc_localEvent; ["ace_loadCargo", [_item, _vehicle]] call CBA_fnc_localEvent;
};
true // return true // return
}; };
@ -50,13 +55,20 @@ if ([_item, _vehicle] call FUNC(canLoadItemIn)) then {
[ [
_duration, _duration,
[_item, _vehicle], [_item, _vehicle, _isViv],
{ {
TRACE_1("load finish",_this); TRACE_1("load finish",_this);
(_this select 0) params ["_item", "_vehicle"];
[objNull, _this select 0 select 0, true] call EFUNC(common,claim); [objNull, _item, true] call EFUNC(common,claim);
// Is ViV
// Don't want to pass the isViv parameter to the ace_unloadCargo EH
if ((_this select 0) deleteAt 2) then {
_vehicle setVehicleCargo _item;
} else {
["ace_loadCargo", _this select 0] call CBA_fnc_localEvent; ["ace_loadCargo", _this select 0] call CBA_fnc_localEvent;
};
}, },
{ {
TRACE_1("load fail",_this); TRACE_1("load fail",_this);
@ -80,7 +92,9 @@ if ([_item, _vehicle] call FUNC(canLoadItemIn)) then {
}, },
format [LLSTRING(loadingItem), [_item, true] call FUNC(getNameItem), getText (configOf _vehicle >> "displayName")], format [LLSTRING(loadingItem), [_item, true] call FUNC(getNameItem), getText (configOf _vehicle >> "displayName")],
{ {
(_this select 0) call FUNC(canLoadItemIn) (_this select 0) params ["_item", "_vehicle", "_isViv"];
[_item, _vehicle, false, _isViv] call FUNC(canLoadItemIn)
}, },
["isNotSwimming"] ["isNotSwimming"]
] call EFUNC(common,progressBar); ] call EFUNC(common,progressBar);

View File

@ -15,13 +15,13 @@
* Public: No * Public: No
*/ */
params ["_unit"];
// This can be an object or a classname string // This can be an object or a classname string
private _item = call FUNC(getSelectedItem); private _item = GVAR(isViv) call FUNC(getSelectedItem);
if (isNil "_item") exitWith {}; if (isNil "_item") exitWith {};
params ["_unit"];
if (GVAR(interactionParadrop)) exitWith { if (GVAR(interactionParadrop)) exitWith {
// Close the cargo menu // Close the cargo menu
closeDialog 0; closeDialog 0;
@ -66,18 +66,24 @@ if (GVAR(interactionParadrop)) exitWith {
// If in zeus // If in zeus
if (!isNull curatorCamera) exitWith { if (!isNull curatorCamera) exitWith {
// Do not check distance to unit, but do check for valid position // Do not check distance to unit, but do check for valid position
if !([_item, GVAR(interactionVehicle), objNull, true] call FUNC(canUnloadItem)) exitWith { // If ViV, ignore position, as engine will find one
if !([_item, GVAR(interactionVehicle), objNull, true, GVAR(isViv), GVAR(isViv)] call FUNC(canUnloadItem)) exitWith {
[[LSTRING(unloadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured); [[LSTRING(unloadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured);
}; };
// Close the cargo menu // Close the cargo menu
closeDialog 1; closeDialog 1;
if (GVAR(isViv)) then {
objNull setVehicleCargo _item;
} else {
["ace_unloadCargo", [_item, GVAR(interactionVehicle)]] call CBA_fnc_localEvent; ["ace_unloadCargo", [_item, GVAR(interactionVehicle)]] call CBA_fnc_localEvent;
}; };
};
// Start progress bar - normal ground unload // Start progress bar - normal ground unload
if ([_item, GVAR(interactionVehicle), _unit] call FUNC(canUnloadItem)) then { // If ViV, ignore position, as engine will find one
if ([_item, GVAR(interactionVehicle), _unit, false, GVAR(isViv), GVAR(isViv)] call FUNC(canUnloadItem)) then {
// Close the cargo menu // Close the cargo menu
closeDialog 0; closeDialog 0;
@ -85,25 +91,35 @@ if ([_item, GVAR(interactionVehicle), _unit] call FUNC(canUnloadItem)) then {
// If unload time is 0, don't show a progress bar // If unload time is 0, don't show a progress bar
if (_duration <= 0) exitWith { if (_duration <= 0) exitWith {
if (GVAR(isViv)) then {
objNull setVehicleCargo _item;
} else {
["ace_unloadCargo", [_item, GVAR(interactionVehicle), _unit]] call CBA_fnc_localEvent; ["ace_unloadCargo", [_item, GVAR(interactionVehicle), _unit]] call CBA_fnc_localEvent;
}; };
};
[ [
_duration, _duration,
[_item, GVAR(interactionVehicle), _unit], [_item, GVAR(interactionVehicle), _unit, GVAR(isViv)],
{ {
TRACE_1("unload finish",_this); TRACE_1("unload finish",_this);
// Is ViV
// Don't want to pass the isViv parameter to the ace_unloadCargo EH
if ((_this select 0) deleteAt 3) then {
objNull setVehicleCargo (_this select 0 select 0);
} else {
["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent; ["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent;
};
}, },
{ {
TRACE_1("unload fail",_this); TRACE_1("unload fail",_this);
}, },
format [LLSTRING(unloadingItem), [_item, true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")], format [LLSTRING(unloadingItem), [_item, true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")],
{ {
(_this select 0) params ["_item", "_vehicle", "_unit"]; (_this select 0) params ["_item", "_vehicle", "_unit", "_isViv"];
[_item, _vehicle, _unit, false, true] call FUNC(canUnloadItem) // don't check for a suitable unloading position every frame [_item, _vehicle, _unit, false, true, _isViv] call FUNC(canUnloadItem) // Don't check for a suitable unloading position every frame
}, },
["isNotSwimming"] ["isNotSwimming"]
] call EFUNC(common,progressBar); ] call EFUNC(common,progressBar);

View File

@ -33,7 +33,6 @@ _vehicle setVariable [QGVAR(space), _cargoSpace + (_item call FUNC(getSizeItem))
private _object = _item; private _object = _item;
if (_object isEqualType objNull) then { if (_object isEqualType objNull) then {
if (isNull isVehicleCargo _object) then {
detach _object; detach _object;
// If player unloads via deployment, set direction first, then unload // If player unloads via deployment, set direction first, then unload
@ -51,21 +50,6 @@ if (_object isEqualType objNull) then {
[QEGVAR(zeus,addObjects), [[_object], _objectCurators]] call CBA_fnc_serverEvent; [QEGVAR(zeus,addObjects), [[_object], _objectCurators]] call CBA_fnc_serverEvent;
}; };
private _cargoNet = _object getVariable [QGVAR(cargoNet), objNull];
// Delete cargo net if no items remain on it
if (
!isNull _cargoNet &&
{(_loaded findIf {_x isEqualType objNull && {_x getVariable [QGVAR(cargoNet), objNull] == _cargoNet}}) == -1}
) then {
objNull setVehicleCargo _cargoNet;
deleteVehicle _cargoNet;
};
} else {
objNull setVehicleCargo _object;
_object setPosASL (AGLtoASL _posAGL);
};
} else { } else {
_object = createVehicle [_item, _posAGL, [], 0, "NONE"]; _object = createVehicle [_item, _posAGL, [], 0, "NONE"];

View File

@ -1,26 +0,0 @@
#include "..\script_component.hpp"
/*
* Author: Vdauphin
* Unload all vehicles but not ACE Cargo.
*
* Arguments:
* 0: Vehicle <OBJECT>
*
* Return Value:
* Loaded vehicles not part of ACE Cargo <ARRAY>
*
* Example:
* [vehicle player] call ace_cargo_fnc_unloadAllVehicles
*
* Public: No
*/
params ["_vehicle"];
private _loadedVehicles = [_vehicle] call FUNC(getVehicleCargo);
private _unloadingInterval = getNumber (configOf _vehicle >> "VehicleTransport" >> "Carrier" >> "unloadingInterval");
{
[{objnull setVehicleCargo _this}, _x, _forEachIndex * _unloadingInterval] call CBA_fnc_waitAndExecute;
} forEach _loadedVehicles;
_loadedVehicles

View File

@ -59,12 +59,3 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
_category, _category,
true true
] call CBA_fnc_addSetting; ] call CBA_fnc_addSetting;
[
QGVAR(cargoNetType),
"LIST",
[LSTRING(cargoNetType), LSTRING(cargoNetType_description)],
_category,
[["CargoNet_01_box_F", "Land_WoodenBox_02_F"], [LSTRING(cargoNetType_modernStyle), LSTRING(cargoNetType_ww2)], 0],
1
] call CBA_fnc_addSetting;

View File

@ -5,6 +5,7 @@ class GVAR(menu) {
movingEnable = 1; movingEnable = 1;
onLoad = QUOTE([_this select 0] call FUNC(onMenuOpen)); onLoad = QUOTE([_this select 0] call FUNC(onMenuOpen));
onUnload = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(menuDisplay),nil)]); onUnload = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(menuDisplay),nil)]);
class controlsBackground { class controlsBackground {
class HeaderBackground: ACE_gui_backgroundBase { class HeaderBackground: ACE_gui_backgroundBase {
idc = -1; idc = -1;
@ -106,5 +107,12 @@ class GVAR(menu) {
action = QUOTE(ACE_player call FUNC(startDeploy)); action = QUOTE(ACE_player call FUNC(startDeploy));
colorDisabled[] = {0.25, 0.25, 0.25, 1}; colorDisabled[] = {0.25, 0.25, 0.25, 1};
}; };
class btnViv: btnCancel {
text = CSTRING(vehicleInVehicle);
idc = 14;
y = "15.2 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
action = QUOTE(GVAR(isViv) = !GVAR(isViv));
colorDisabled[] = {0.25, 0.25, 0.25, 1};
};
}; };
}; };

View File

@ -603,17 +603,11 @@
<German>Steuert, ob Frachtgegenstände über die Aufbaumethode entladen werden können.</German> <German>Steuert, ob Frachtgegenstände über die Aufbaumethode entladen werden können.</German>
<Spanish>Controla si los objetos de la carga pueden ser descargados mediante el método de despliegue.</Spanish> <Spanish>Controla si los objetos de la carga pueden ser descargados mediante el método de despliegue.</Spanish>
</Key> </Key>
<Key ID="STR_ACE_Cargo_cargoNetType"> <Key ID="STR_ACE_Cargo_vehicleInVehicle">
<English>Type of cargo</English> <English>ViV</English>
</Key> </Key>
<Key ID="STR_ACE_Cargo_cargoNetType_description"> <Key ID="STR_ACE_Cargo_loadObjectViv">
<English>Choose which cargo type will fit the period of history you are playing.</English> <English>Load to ViV</English>
</Key>
<Key ID="STR_ACE_Cargo_cargoNetType_modernStyle">
<English>Modern style</English>
</Key>
<Key ID="STR_ACE_Cargo_cargoNetType_ww2">
<English>World War 2</English>
</Key> </Key>
</Package> </Package>
</Project> </Project>