mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Improve underwater cargo unloading
This commit is contained in:
parent
17a882fe4d
commit
7a7e0d689a
@ -4,6 +4,7 @@
|
||||
|
||||
["LoadCargo", {
|
||||
(_this select 0) params ["_item","_vehicle"];
|
||||
TRACE_2("LoadCargo EH",_item,_vehicle);
|
||||
|
||||
private _loaded = [_item, _vehicle] call FUNC(loadItem);
|
||||
|
||||
@ -22,8 +23,9 @@
|
||||
|
||||
["UnloadCargo", {
|
||||
(_this select 0) params ["_item","_vehicle", ["_unloader", objNull]];
|
||||
|
||||
private _unloaded = [_item, _vehicle, _player] call FUNC(unloadItem);
|
||||
TRACE_3("UnloadCargo EH",_item,_vehicle,_unloader);
|
||||
|
||||
private _unloaded = [_item, _vehicle, _unloader] call FUNC(unloadItem); //returns true if sucessful
|
||||
|
||||
private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item};
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_itemClass", "_vehicle", ["_amount", 1], ["_showHint", false, [false]] ];
|
||||
params ["_itemClass", "_vehicle", ["_amount", 1], ["_showHint", false, [false]]];
|
||||
TRACE_3("params",_itemClass,_vehicle,_amount);
|
||||
|
||||
for "_i" from 1 to _amount do {
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
params [["_item", "", [objNull,""]], "_vehicle"];
|
||||
|
||||
if (speed _vehicle > 1 || {((getPos _vehicle) select 2) > 3}) exitWith {false};
|
||||
if (speed _vehicle > 1 || {((getPos _vehicle) select 2) > 3}) exitWith {TRACE_1("vehicle not stable",_vehicle); false};
|
||||
|
||||
private _itemSize = [_item] call FUNC(getSizeItem);
|
||||
private _validItem = false;
|
||||
|
@ -6,7 +6,6 @@
|
||||
* Arguments:
|
||||
* 0: Item <OBJECT or STRING>
|
||||
* 1: Vehicle <OBJECT>
|
||||
* 2: Show Hint <BOOL> (default: true)
|
||||
*
|
||||
* Return value:
|
||||
* Object loaded <BOOL>
|
||||
@ -19,8 +18,9 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
params [["_item","",[objNull,""]], ["_vehicle",objNull,[objNull]]];
|
||||
TRACE_2("params",_item,_vehicle);
|
||||
|
||||
if !([_item, _vehicle] call FUNC(canLoadItemIn)) exitWith {false};
|
||||
if !([_item, _vehicle] call FUNC(canLoadItemIn)) exitWith {TRACE_2("cannot load",_item,_vehicle); false};
|
||||
|
||||
private _loaded = _vehicle getVariable [QGVAR(loaded), []];
|
||||
_loaded pushBack _item;
|
||||
|
@ -32,7 +32,7 @@ if (isNull _vehicle) exitWith {
|
||||
false
|
||||
};
|
||||
|
||||
_return = false;
|
||||
private _return = false;
|
||||
// Start progress bar
|
||||
if ([_object, _vehicle] call FUNC(canLoadItemIn)) then {
|
||||
private _size = [_object] call FUNC(getSizeItem);
|
||||
|
@ -34,7 +34,7 @@ private _item = _loaded select _selected; //This can be an object or a classname
|
||||
if ([_item, GVAR(interactionVehicle), ACE_player] call FUNC(canUnloadItem)) then {
|
||||
private _size = [_item] call FUNC(getSizeItem);
|
||||
|
||||
[5 * _size, [_item, GVAR(interactionVehicle), ACE_player], "UnloadCargo", {}, localize LSTRING(UnloadingItem)] call EFUNC(common,progressBar);
|
||||
[5 * _size, [_item, GVAR(interactionVehicle), ACE_player], "UnloadCargo", {}, localize LSTRING(UnloadingItem), {true}, ["isNotSwimming"]] call EFUNC(common,progressBar);
|
||||
} else {
|
||||
private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item};
|
||||
private _displayName = getText (configFile >> "CfgVehicles" >> _itemClass >> "displayName");
|
||||
|
@ -21,8 +21,8 @@
|
||||
#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
//Number of tests run
|
||||
#define MAX_TESTS 50
|
||||
//Number of tests run (effects performance in worst case scenarior where nothing is found VERSUES reliably finding a pos):
|
||||
#define MAX_TESTS 75
|
||||
|
||||
//Manual collision tests (count and radius):
|
||||
#define COL_TEST_COUNT 12
|
||||
@ -39,63 +39,78 @@ if (_checkVehicleIsStable) then {
|
||||
};
|
||||
};
|
||||
|
||||
private _radiusOfItem = 1.1;
|
||||
//`sizeOf` is unreliable, and does not work with object types that don't exist on map, so estimate size based on cargo size
|
||||
if (isNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size))) then {
|
||||
_radiusOfItem = (((getNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size))) ^ 0.35) max 1.1);
|
||||
private _radiusOfItem = 1;
|
||||
if (_typeOfCargo isKindOf "CAManBase") then {
|
||||
_radiusOfItem = 1.1;
|
||||
} else {
|
||||
//`sizeOf` is unreliable, and does not work with object types that don't exist on map, so estimate size based on cargo size
|
||||
if (isNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size))) then {
|
||||
_radiusOfItem = (((getNumber (configFile >> "CfgVehicles" >> _typeOfCargo >> QEGVAR(cargo,size))) ^ 0.35) max 0.75);
|
||||
};
|
||||
};
|
||||
|
||||
if (isNull _theUnloader) then {_theUnloader = _vehicle;};
|
||||
|
||||
//Ideal unload pos is halfway between unloader and vehicle
|
||||
//Ideal unload pos is halfway between unloader and vehicle (at the unloader's height)
|
||||
private _originASL = ((getPosASL _theUnloader) vectorAdd (getPosASL _vehicle)) vectorMultiply 0.5;
|
||||
_originASL set [2, (getPosASL _theUnloader) select 2];
|
||||
private _originAGL = ASLtoAGL _originASL;
|
||||
|
||||
//Do a manual search for empty pos (handles underwater, buildings or piers)
|
||||
TRACE_2("Checking for unload",_originAGL,_radiusOfItem);
|
||||
private _rangeToCheck = 0.5;
|
||||
while {_rangeToCheck < (sqrt _maxDistance)} do {
|
||||
private _roundAGL = _originAGL vectorAdd [(-1 * _rangeToCheck + (random 2 * _rangeToCheck)), (-1 * _rangeToCheck + (random 2 * _rangeToCheck)), 0];
|
||||
private _belowRoundArray = lineIntersectsSurfaces [(AGLtoASL _roundAGL) vectorAdd [0,0,0.5], (AGLtoASL _roundAGL) vectorAdd [0,0,-2]];
|
||||
TRACE_2("Testing Pos",_roundAGL,_belowRoundArray);
|
||||
if (!(_belowRoundArray isEqualTo [])) then {
|
||||
private _aboveBuilding = (_belowRoundArray select 0) select 2;
|
||||
private _rangeToCheck = 0;
|
||||
while {_rangeToCheck < _maxDistance} do {
|
||||
private _roundDistance = random _rangeToCheck;
|
||||
private _roundAngle = random 360;
|
||||
private _roundAGL = _originAGL vectorAdd [(cos _roundAngle) * _roundDistance, (sin _roundAngle) * _roundDistance, 0];
|
||||
|
||||
//Point is above something: Terrain(null) or Building
|
||||
if ((isNull _aboveBuilding) || {_aboveBuilding isKindOf "Building"}) then {
|
||||
//Get the real intersection point:
|
||||
_roundAGL = ASLtoAGL ((_belowRoundArray select 0) select 0);
|
||||
|
||||
//Do a fast check for people in the way
|
||||
private _roundPointIsValid = (_roundAGL nearEntities ["Man", _radiusOfItem]) isEqualTo [];
|
||||
if (_roundPointIsValid) then {
|
||||
for "_index" from 0 to (COL_TEST_COUNT -1) do {
|
||||
private _angle = _index * (360 / COL_TEST_COUNT);
|
||||
private _point1ASL = (AGLtoASL _roundAGL) vectorAdd [_radiusOfItem * cos _angle, _radiusOfItem * sin _angle, 0.1];
|
||||
private _point2ASL = (AGLtoASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, (_radiusOfItem + 0.5)];
|
||||
private _testIntersections = lineIntersectsSurfaces [_point1ASL, _point2ASL];
|
||||
if (!(_testIntersections isEqualTo [])) exitWith {
|
||||
TRACE_2("test point not valid",_roundAGL,_testIntersections);
|
||||
_roundPointIsValid = false;
|
||||
};
|
||||
_point1ASL = (AGLtoASL _roundAGL) vectorAdd [_radiusOfItem * cos _angle, _radiusOfItem * sin _angle, 0.5];
|
||||
_point2ASL = (AGLtoASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, 1];
|
||||
_testIntersections = lineIntersectsSurfaces [_point1ASL, _point2ASL];
|
||||
if (!(_testIntersections isEqualTo [])) exitWith {
|
||||
TRACE_2("test point not valid",_roundAGL,_testIntersections);
|
||||
_roundPointIsValid = false;
|
||||
};
|
||||
};
|
||||
if (_roundPointIsValid) then {
|
||||
TRACE_3("Valid point found", _rangeToCheck,_roundAGL, (_originAGL distance _roundAGL));
|
||||
//Add just a little so we don't sink through the floor:
|
||||
(_roundAGL vectorAdd [0,0,0.05]) breakOut "main";
|
||||
};
|
||||
private _roundPointIsValid = false;
|
||||
if (((AGLtoASL _roundAGL) select 2) > 0) then {
|
||||
//Shoot a ray down, and make sure we hit something solid like a building or the ground:
|
||||
private _belowRoundArray = lineIntersectsSurfaces [(AGLtoASL _roundAGL) vectorAdd [0,0,0.5], (AGLtoASL _roundAGL) vectorAdd [0,0,-1]];
|
||||
TRACE_4("Testing for solid",_roundDistance,_roundAngle,_roundAGL,_belowRoundArray);
|
||||
if (!(_belowRoundArray isEqualTo [])) then {
|
||||
private _aboveBuilding = (_belowRoundArray select 0) select 2;
|
||||
//Point is above something: Terrain(null) or Building
|
||||
if ((isNull _aboveBuilding) || {_aboveBuilding isKindOf "Building"}) then {
|
||||
//Get the real intersection point:
|
||||
_roundAGL = ASLtoAGL ((_belowRoundArray select 0) select 0);
|
||||
_roundPointIsValid = true;
|
||||
};
|
||||
};
|
||||
} else {
|
||||
//Underwater, just unload anywhere
|
||||
TRACE_3("Under the sea",_roundDistance,_roundAngle,_roundAGL);
|
||||
_roundPointIsValid = true;
|
||||
};
|
||||
_rangeToCheck = _rangeToCheck + ((sqrt _maxDistance) / MAX_TESTS);
|
||||
|
||||
//Make sure point is valid and do a fast check for people in the way (which sometimes aren't caught by line scaning)
|
||||
if (_roundPointIsValid && {(_roundAGL nearEntities ["Man", _radiusOfItem]) isEqualTo []}) then {
|
||||
for "_index" from 0 to (COL_TEST_COUNT -1) do {
|
||||
//Scan for colisions with objects with lineIntersectsSurfaces
|
||||
private _angle = _index * (360 / COL_TEST_COUNT);
|
||||
private _point1ASL = (AGLtoASL _roundAGL) vectorAdd [_radiusOfItem * cos _angle, _radiusOfItem * sin _angle, 0.1];
|
||||
private _point2ASL = (AGLtoASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, (_radiusOfItem + 0.5)];
|
||||
private _testIntersections = lineIntersectsSurfaces [_point1ASL, _point2ASL];
|
||||
if (!(_testIntersections isEqualTo [])) exitWith {
|
||||
TRACE_2("collision low/high",_roundAGL,_testIntersections);
|
||||
_roundPointIsValid = false;
|
||||
};
|
||||
_point1ASL = (AGLtoASL _roundAGL) vectorAdd [_radiusOfItem * cos _angle, _radiusOfItem * sin _angle, 0.5];
|
||||
_point2ASL = (AGLtoASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, 1];
|
||||
_testIntersections = lineIntersectsSurfaces [_point1ASL, _point2ASL];
|
||||
if (!(_testIntersections isEqualTo [])) exitWith {
|
||||
TRACE_2("collision mid",_roundAGL,_testIntersections);
|
||||
_roundPointIsValid = false;
|
||||
};
|
||||
};
|
||||
if (_roundPointIsValid) then {
|
||||
TRACE_3("Valid point found", _rangeToCheck,_roundAGL, (_originAGL distance _roundAGL));
|
||||
//Raise it slightly so we don't sink through the floor:
|
||||
(_roundAGL vectorAdd [0,0,0.05]) breakOut "main";
|
||||
};
|
||||
};
|
||||
_rangeToCheck = _rangeToCheck + (_maxDistance / MAX_TESTS);
|
||||
};
|
||||
|
||||
TRACE_1("no valid spots found",_rangeToCheck);
|
||||
|
Loading…
Reference in New Issue
Block a user