diff --git a/addons/cargo/XEH_postInit.sqf b/addons/cargo/XEH_postInit.sqf index f01c92ef0e6..867330488a1 100644 --- a/addons/cargo/XEH_postInit.sqf +++ b/addons/cargo/XEH_postInit.sqf @@ -36,6 +36,25 @@ }; }] call CBA_fnc_addEventHandler; +[QGVAR(unloadedCargoOnKilled), { + params ["_item", "_vehicle", ["_flying", false]]; + + // Get direction from vehicle to item, so that item is thrown away from vehicle + private _vectorDir = (getPosWorld _vehicle) vectorFromTo (getPosWorld _item); + + // Give some z + _vectorDir set [2, random [0.5, 0.75, 1]]; + + // Add some randomness to resulting velocity, but only if on the ground, tends to shoot the cargo too far away when airbourne + if (!_flying) then { + _vectorDir = (_vectorDir vectorMultiply random CARGO_TUMBLE_RANDOM_MUL); + }; + _vectorDir = _vectorDir vectorAdd (velocity _vehicle); + + _item setVelocity _vectorDir; + _item addTorque [random CARGO_TUMBLE_TORQUE, random CARGO_TUMBLE_TORQUE, random CARGO_TUMBLE_TORQUE]; +}] call CBA_fnc_addEventHandler; + // Direction must be set before setting position according to wiki [QGVAR(setDirAndUnload), { params ["_item", "_emptyPosAGL", "_direction"]; diff --git a/addons/cargo/functions/fnc_handleDestroyed.sqf b/addons/cargo/functions/fnc_handleDestroyed.sqf index cc5777723dc..679907b5fc3 100644 --- a/addons/cargo/functions/fnc_handleDestroyed.sqf +++ b/addons/cargo/functions/fnc_handleDestroyed.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: mharis001, Glowbal + * Author: mharis001, Glowbal, drofseh * Handles an object being destroyed/deleted. * If object contained loaded cargo, the cargo is deleted. * If object was loaded cargo, it's removed from loaded cargo list. @@ -19,16 +19,38 @@ params ["_object"]; +private _killed = count _this > 1; // The Killed event has 4 params. The Deleted event only has 1 param. + private _loaded = _object getVariable [QGVAR(loaded), []]; if (_loaded isNotEqualTo []) then { // Delete all cargo { if (_x isEqualType objNull) then { - detach _x; - deleteVehicle _x; + private _delete = true; + private _flying = false; + + if (_killed && {random 1 < GVAR(unloadOnKilled)}) then { + private _pos = getPos _object; + if (_object isKindOf "Air" && {_pos select 2 > 1}) then { // flying aircraft don't work with FUNC(unloadItem) so work around it. + [QGVAR(serverUnload), [_x, getPosATL _object vectorAdd [random [-3, 0, 3], random [-3, 0, 3], random -3]]] call CBA_fnc_serverEvent; + detach _x; + _x addForce [[0,0,1], [0,0,0]]; + _delete = false; + _flying = true; + } else { + _delete = !([_x, _object, objNull, [], false] call FUNC(unloadItem)); // If a safe position to unload cannot be found FUNC(unloadItem) returns false, delete cargo instead + }; + }; + + if (_delete) then { + detach _x; + deleteVehicle _x; + } else { + [QGVAR(unloadedCargoOnKilled), [_x, _object, _flying], _x] call CBA_fnc_targetEvent; + }; }; - } forEach _loaded; + } forEachReversed _loaded; // In case vehicle is killed, but not deleted, reset loaded list _object setVariable [QGVAR(loaded), [], true]; diff --git a/addons/cargo/functions/fnc_unloadItem.sqf b/addons/cargo/functions/fnc_unloadItem.sqf index e22d87a098b..3ecd2891253 100644 --- a/addons/cargo/functions/fnc_unloadItem.sqf +++ b/addons/cargo/functions/fnc_unloadItem.sqf @@ -10,6 +10,7 @@ * 3: Deploy parameters (default: []) * - 0: Position AGL * - 1: Direction + * 4: Unload only if stable (default: true) (Applies only if argument 3 is []) * * Return Value: * Object unloaded @@ -20,10 +21,16 @@ * Public: Yes */ -params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_unloader", objNull, [objNull]], ["_deploy", []]]; +params [ + ["_item", "", [objNull, ""]], + ["_vehicle", objNull, [objNull]], + ["_unloader", objNull, [objNull]], + ["_deploy", []], + ["_checkVehicleIsStable", true, [true]] +]; _deploy params ["_emptyPosAGL", "_direction"]; -TRACE_4("params",_item,_vehicle,_unloader,_deploy); +TRACE_5("params",_item,_vehicle,_unloader,_deploy,_checkVehicleIsStable); // Get config sensitive case name if (_item isEqualType "") then { @@ -51,7 +58,7 @@ private _deployed = _deploy isNotEqualTo []; if (!_deployed) then { // This covers testing vehicle stability and finding a safe position for "_i" from 1 to 3 do { - _emptyPosAGL = [_vehicle, _item, _unloader] call EFUNC(common,findUnloadPosition); + _emptyPosAGL = [_vehicle, _item, _unloader, nil, _checkVehicleIsStable] call EFUNC(common,findUnloadPosition); if (_emptyPosAGL isNotEqualTo []) exitWith {}; }; diff --git a/addons/cargo/initSettings.inc.sqf b/addons/cargo/initSettings.inc.sqf index 7e482670272..5544b7c29c3 100644 --- a/addons/cargo/initSettings.inc.sqf +++ b/addons/cargo/initSettings.inc.sqf @@ -27,6 +27,15 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; 1 ] call CBA_fnc_addSetting; +[ + QGVAR(unloadOnKilled), + "SLIDER", + [LSTRING(unloadOnKilled), LSTRING(unloadOnKilled_description)], + _category, + [0, 1, 0.5, 1, true], // [_min, _max, _default, _trailingDecimals, _isPercentage] + 1 +] call CBA_fnc_addSetting; + [ QGVAR(openAfterUnload), "LIST", diff --git a/addons/cargo/script_component.hpp b/addons/cargo/script_component.hpp index 00629c73d27..49cba6f5569 100644 --- a/addons/cargo/script_component.hpp +++ b/addons/cargo/script_component.hpp @@ -19,3 +19,6 @@ #define MAX_LOAD_DISTANCE 5 #define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) + +#define CARGO_TUMBLE_RANDOM_MUL 8 +#define CARGO_TUMBLE_TORQUE 500 diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index 8fc4d0d531e..932074832c9 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -631,5 +631,11 @@ 卸载 Boşalt + + Unload Cargo On Killed + + + The chance for each cargo loaded into a vehicle to be unloaded if the vehicle is killed.\nApplies to objects only. + - + \ No newline at end of file