mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge pull request #3228 from acemod/theTechnology
findUnloadPosition (Redo)
This commit is contained in:
commit
9f62334713
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
["LoadCargo", {
|
["LoadCargo", {
|
||||||
(_this select 0) params ["_item","_vehicle"];
|
(_this select 0) params ["_item","_vehicle"];
|
||||||
|
TRACE_2("LoadCargo EH",_item,_vehicle);
|
||||||
|
|
||||||
private _loaded = [_item, _vehicle] call FUNC(loadItem);
|
private _loaded = [_item, _vehicle] call FUNC(loadItem);
|
||||||
|
|
||||||
@ -21,9 +22,10 @@
|
|||||||
}] call EFUNC(common,addEventHandler);
|
}] call EFUNC(common,addEventHandler);
|
||||||
|
|
||||||
["UnloadCargo", {
|
["UnloadCargo", {
|
||||||
(_this select 0) params ["_item","_vehicle"];
|
(_this select 0) params ["_item","_vehicle", ["_unloader", objNull]];
|
||||||
|
TRACE_3("UnloadCargo EH",_item,_vehicle,_unloader);
|
||||||
private _unloaded = [_item, _vehicle] call FUNC(unloadItem);
|
|
||||||
|
private _unloaded = [_item, _vehicle, _unloader] call FUNC(unloadItem); //returns true if sucessful
|
||||||
|
|
||||||
private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item};
|
private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item};
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
#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);
|
TRACE_3("params",_itemClass,_vehicle,_amount);
|
||||||
|
|
||||||
for "_i" from 1 to _amount do {
|
for "_i" from 1 to _amount do {
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
params [["_item", "", [objNull,""]], "_vehicle"];
|
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 _itemSize = [_item] call FUNC(getSizeItem);
|
||||||
private _validItem = false;
|
private _validItem = false;
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: loaded Object <OBJECT>
|
* 0: loaded Object <OBJECT>
|
||||||
* 1: Object <OBJECT>
|
* 1: Object <OBJECT>
|
||||||
|
* 2: Unloader (player) <OPTIONAL><OBJECT>
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value:
|
||||||
* Can be unloaded <BOOL>
|
* Can be unloaded <BOOL>
|
||||||
@ -16,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
params ["_item", "_vehicle"];
|
params ["_item", "_vehicle", ["_unloader", objNull]];
|
||||||
TRACE_2("params",_item,_vehicle);
|
TRACE_2("params",_item,_vehicle);
|
||||||
|
|
||||||
private _loaded = _vehicle getVariable [QGVAR(loaded), []];
|
private _loaded = _vehicle getVariable [QGVAR(loaded), []];
|
||||||
@ -24,22 +25,6 @@ if !(_item in _loaded) exitWith {false};
|
|||||||
|
|
||||||
private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item};
|
private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item};
|
||||||
|
|
||||||
private _validVehiclestate = true;
|
private _emptyPos = [_vehicle, _itemClass, _unloader] call EFUNC(common,findUnloadPosition);
|
||||||
private _emptyPos = [];
|
|
||||||
if (_vehicle isKindOf "Ship" ) then {
|
|
||||||
if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false};
|
|
||||||
_emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, _itemClass]); // TODO: if spot is underwater pick another spot.
|
|
||||||
} else {
|
|
||||||
if (_vehicle isKindOf "Air" ) then {
|
|
||||||
if !(speed _vehicle <1 && {isTouchingGround _vehicle}) then {_validVehiclestate = false};
|
|
||||||
_emptyPos = (getPosASL _vehicle) call EFUNC(common,ASLtoPosition);
|
|
||||||
_emptyPos = [(_emptyPos select 0) + random(5), (_emptyPos select 1) + random(5), _emptyPos select 2 ];
|
|
||||||
} else {
|
|
||||||
if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false};
|
|
||||||
_emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, _itemClass]);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!_validVehiclestate) exitWith {false};
|
(count _emptyPos) == 3
|
||||||
|
|
||||||
(count _emptyPos != 0)
|
|
||||||
|
@ -43,7 +43,7 @@ if (getNumber (configFile >> "CfgVehicles" >> _type >> QGVAR(hasCargo)) != 1) ex
|
|||||||
TRACE_1("Adding unload cargo action to class", _type);
|
TRACE_1("Adding unload cargo action to class", _type);
|
||||||
|
|
||||||
private _condition = {
|
private _condition = {
|
||||||
GVAR(enable) && {locked _target < 2} && {alive _target} && {[_player, _target, []] call EFUNC(common,canInteractWith)}
|
GVAR(enable) && {locked _target < 2} && {alive _target} && {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)}
|
||||||
};
|
};
|
||||||
private _statement = {
|
private _statement = {
|
||||||
GVAR(interactionVehicle) = _target;
|
GVAR(interactionVehicle) = _target;
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: Item <OBJECT or STRING>
|
* 0: Item <OBJECT or STRING>
|
||||||
* 1: Vehicle <OBJECT>
|
* 1: Vehicle <OBJECT>
|
||||||
* 2: Show Hint <BOOL> (default: true)
|
|
||||||
*
|
*
|
||||||
* Return value:
|
* Return value:
|
||||||
* Object loaded <BOOL>
|
* Object loaded <BOOL>
|
||||||
@ -19,8 +18,9 @@
|
|||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
params [["_item","",[objNull,""]], ["_vehicle",objNull,[objNull]]];
|
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), []];
|
private _loaded = _vehicle getVariable [QGVAR(loaded), []];
|
||||||
_loaded pushBack _item;
|
_loaded pushBack _item;
|
||||||
|
@ -32,7 +32,7 @@ if (isNull _vehicle) exitWith {
|
|||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
_return = false;
|
private _return = false;
|
||||||
// Start progress bar
|
// Start progress bar
|
||||||
if ([_object, _vehicle] call FUNC(canLoadItemIn)) then {
|
if ([_object, _vehicle] call FUNC(canLoadItemIn)) then {
|
||||||
private _size = [_object] call FUNC(getSizeItem);
|
private _size = [_object] call FUNC(getSizeItem);
|
||||||
|
@ -31,10 +31,10 @@ 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
|
// Start progress bar
|
||||||
if ([_item, GVAR(interactionVehicle)] 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);
|
||||||
|
|
||||||
[5 * _size, [_item, GVAR(interactionVehicle)], "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 {
|
} else {
|
||||||
private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item};
|
private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item};
|
||||||
private _displayName = getText (configFile >> "CfgVehicles" >> _itemClass >> "displayName");
|
private _displayName = getText (configFile >> "CfgVehicles" >> _itemClass >> "displayName");
|
||||||
|
@ -16,38 +16,31 @@
|
|||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
|
|
||||||
params ["_item", "_vehicle"];
|
params ["_item", "_vehicle", ["_unloader", objNull]];
|
||||||
TRACE_2("params",_item,_vehicle);
|
TRACE_3("params",_item,_vehicle,_unloader);
|
||||||
|
|
||||||
if !([_item, _vehicle] call FUNC(canUnloadItem)) exitWith {
|
private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item};
|
||||||
|
|
||||||
|
//This covers testing vehicle stability and finding a safe position
|
||||||
|
private _emptyPosAGL = [_vehicle, _itemClass, _unloader] call EFUNC(common,findUnloadPosition);
|
||||||
|
TRACE_1("findUnloadPosition",_emptyPosAGL);
|
||||||
|
|
||||||
|
if ((count _emptyPosAGL) != 3) exitWith {
|
||||||
|
TRACE_4("Could not find unload pos",_vehicle,getPosASL _vehicle,isTouchingGround _vehicle,speed _vehicle);
|
||||||
|
if ((!isNull _unloader) && {_unloader == ACE_player}) then {
|
||||||
|
//display text saying there are no safe places to exit the vehicle
|
||||||
|
["displayTextStructured", [localize ELSTRING(common,NoRoomToUnload)]] call EFUNC(common,localEvent);
|
||||||
|
};
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
_itemClass = if (_item isEqualType "") then {_item} else {typeOf _item};
|
private _loaded = _vehicle getVariable [QGVAR(loaded), []];
|
||||||
|
|
||||||
private _validVehiclestate = true;
|
if !(_item in _loaded) exitWith {
|
||||||
private _emptyPos = [];
|
ACE_LOGERROR_3("Tried to unload item [%1] not in vehicle[%2] cargo[%3]", _item, _vehicle, _loaded);
|
||||||
if (_vehicle isKindOf "Ship" ) then {
|
false
|
||||||
if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false};
|
|
||||||
TRACE_1("SHIP Ground Check", getPosATL _vehicle );
|
|
||||||
_emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 15, _itemClass]); // TODO: if spot is underwater pick another spot.
|
|
||||||
} else {
|
|
||||||
if (_vehicle isKindOf "Air" ) then {
|
|
||||||
if !(speed _vehicle <1 && {isTouchingGround _vehicle}) then {_validVehiclestate = false};
|
|
||||||
TRACE_1("Vehicle Ground Check", isTouchingGround _vehicle);
|
|
||||||
_emptyPos = (getPosASL _vehicle) call EFUNC(common,ASLtoPosition);
|
|
||||||
_emptyPos = [(_emptyPos select 0) + random(5), (_emptyPos select 1) + random(5), _emptyPos select 2 ];
|
|
||||||
} else {
|
|
||||||
if !(speed _vehicle <1 && {(((getPosATL _vehicle) select 2) < 2)}) then {_validVehiclestate = false};
|
|
||||||
TRACE_1("Vehicle Ground Check", isTouchingGround _vehicle);
|
|
||||||
_emptyPos = ((getPosASL _vehicle) call EFUNC(common,ASLtoPosition) findEmptyPosition [0, 13, _itemClass]);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
TRACE_1("getPosASL Vehicle Check", getPosASL _vehicle);
|
|
||||||
if ((!_validVehiclestate) || {_emptyPos isEqualTo []}) exitWith {false};
|
|
||||||
|
|
||||||
private _loaded = _vehicle getVariable [QGVAR(loaded), []];
|
|
||||||
_loaded deleteAt (_loaded find _item);
|
_loaded deleteAt (_loaded find _item);
|
||||||
_vehicle setVariable [QGVAR(loaded), _loaded, true];
|
_vehicle setVariable [QGVAR(loaded), _loaded, true];
|
||||||
|
|
||||||
@ -57,10 +50,11 @@ _vehicle setVariable [QGVAR(space), (_space + _itemSize), true];
|
|||||||
|
|
||||||
if (_item isEqualType objNull) then {
|
if (_item isEqualType objNull) then {
|
||||||
detach _item;
|
detach _item;
|
||||||
_item setPosASL (_emptyPos call EFUNC(common,PositiontoASL));
|
_item setPosASL (AGLtoASL _emptyPosAGL);
|
||||||
["hideObjectGlobal", [_item, false]] call EFUNC(common,serverEvent);
|
["hideObjectGlobal", [_item, false]] call EFUNC(common,serverEvent);
|
||||||
} else {
|
} else {
|
||||||
createVehicle [_item, _emptyPos, [], 0, ""];
|
private _newItem = createVehicle [_item, _emptyPosAGL, [], 0, ""];
|
||||||
|
_newItem setPosASL (AGLtoASL _emptyPosAGL);
|
||||||
};
|
};
|
||||||
|
|
||||||
true
|
true
|
||||||
|
@ -47,6 +47,7 @@ PREP(execPersistentFnc);
|
|||||||
PREP(execRemoteFnc);
|
PREP(execRemoteFnc);
|
||||||
PREP(executePersistent);
|
PREP(executePersistent);
|
||||||
PREP(filter);
|
PREP(filter);
|
||||||
|
PREP(findUnloadPosition);
|
||||||
PREP(fixCollision);
|
PREP(fixCollision);
|
||||||
PREP(fixFloating);
|
PREP(fixFloating);
|
||||||
PREP(fixLoweredRifleAnimation);
|
PREP(fixLoweredRifleAnimation);
|
||||||
|
117
addons/common/functions/fnc_findUnloadPosition.sqf
Normal file
117
addons/common/functions/fnc_findUnloadPosition.sqf
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* Author: PabstMirror, ViperMaul
|
||||||
|
* Find a safe place near a vehicle to unload something
|
||||||
|
* Handles Normal Terrain, In Water or On Buildings (Pier, StaticShip)
|
||||||
|
*
|
||||||
|
* Arguments:
|
||||||
|
* 0: Source Vehicle <OBJECT>
|
||||||
|
* 1: Cargo Classname <STRING>
|
||||||
|
* 2: Unloader (player) <OBJECT><OPTIONAL>
|
||||||
|
* 3: Max Distance (meters) <NUMBER><OPTIONAL>
|
||||||
|
* 4: Check Vehicle is Stable <BOOL><OPTIONAL>
|
||||||
|
*
|
||||||
|
* Return Value:
|
||||||
|
* Unload PositionAGL (Can Be [] if no valid pos found) <ARRAY>
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* [theCar, "CAManBase", player, 10, true] call ace_common_fnc_findUnloadPosition;
|
||||||
|
*
|
||||||
|
* Public: No
|
||||||
|
*/
|
||||||
|
#define DEBUG_MODE_FULL
|
||||||
|
#include "script_component.hpp"
|
||||||
|
|
||||||
|
//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
|
||||||
|
|
||||||
|
params ["_vehicle", "_typeOfCargo", ["_theUnloader", objNull], ["_maxDistance", 10], ["_checkVehicleIsStable", true]];
|
||||||
|
TRACE_5("params",_vehicle,_typeOfCargo,_theUnloader,_maxDistance,_checkVehicleIsStable);
|
||||||
|
|
||||||
|
scopeName "main";
|
||||||
|
|
||||||
|
if (_checkVehicleIsStable) then {
|
||||||
|
if (((vectorMagnitude (velocity _vehicle)) > 1.5) || {(!(_vehicle isKindOf "Ship")) && {(!isTouchingGround _vehicle) && {((getPos _vehicle) select 2) > 1.5}}}) then {
|
||||||
|
TRACE_4("bad vehicle state",_vehicle,velocity _vehicle,isTouchingGround _vehicle,getPos _vehicle);
|
||||||
|
[] breakOut "main";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
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 (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;
|
||||||
|
while {_rangeToCheck < _maxDistance} do {
|
||||||
|
private _roundDistance = random _rangeToCheck;
|
||||||
|
private _roundAngle = random 360;
|
||||||
|
private _roundAGL = _originAGL vectorAdd [(cos _roundAngle) * _roundDistance, (sin _roundAngle) * _roundDistance, 0];
|
||||||
|
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
//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);
|
||||||
|
[] //return empty array
|
@ -8,6 +8,9 @@
|
|||||||
* Return Value:
|
* Return Value:
|
||||||
* Returns true if succesfully unloaded person <BOOL>
|
* Returns true if succesfully unloaded person <BOOL>
|
||||||
*
|
*
|
||||||
|
* Example:
|
||||||
|
* [hurtGuy] call ace_common_fnc_unloadPerson
|
||||||
|
*
|
||||||
* Public: No
|
* Public: No
|
||||||
*/
|
*/
|
||||||
#include "script_component.hpp"
|
#include "script_component.hpp"
|
||||||
@ -20,14 +23,10 @@ private _vehicle = vehicle _unit;
|
|||||||
|
|
||||||
if (_vehicle == _unit) exitWith {false};
|
if (_vehicle == _unit) exitWith {false};
|
||||||
|
|
||||||
if (speed _vehicle > 1 || getPos _vehicle select 2 > 2) exitWith {false};
|
if (speed _vehicle > 1 || {((getPos _vehicle) select 2) > 2}) exitWith {false};
|
||||||
|
|
||||||
private _emptyPos = (getPos _vehicle) findEmptyPosition [0, 10, typeOf _unit]; // @todo to small?
|
|
||||||
|
|
||||||
if (count _emptyPos == 0) exitWith {false};
|
|
||||||
|
|
||||||
if (!isNull _vehicle) then {
|
if (!isNull _vehicle) then {
|
||||||
[[_unit], QUOTE(FUNC(unloadPersonLocal)), _unit, false] call FUNC(execRemoteFnc);
|
["unloadPersonEvent", [_unit], [_unit, _vehicle]] call EFUNC(common,targetEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
true
|
true
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
* Unload a person from a vehicle, local
|
* Unload a person from a vehicle, local
|
||||||
*
|
*
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* 0: unit <OBJECT>
|
* 0: unit to unload <OBJECT>
|
||||||
|
* 1: Vehicle <OBJECT>
|
||||||
|
* 2: Unloader (player) <OBJECT><OPTIONAL>
|
||||||
*
|
*
|
||||||
* Return Value:
|
* Return Value:
|
||||||
* Returns true if succesfully unloaded person <BOOL>
|
* Returns true if succesfully unloaded person <BOOL>
|
||||||
@ -14,53 +16,22 @@
|
|||||||
|
|
||||||
#define GROUP_SWITCH_ID QUOTE(FUNC(loadPerson))
|
#define GROUP_SWITCH_ID QUOTE(FUNC(loadPerson))
|
||||||
|
|
||||||
params ["_unit", "_vehicle"];
|
params ["_unit", "_vehicle", ["_unloader", objNull]];
|
||||||
TRACE_2("params",_unit,_vehicle);
|
TRACE_3("params",_unit,_vehicle,_unloader);
|
||||||
|
|
||||||
private _validVehiclestate = true;
|
//This covers testing vehicle stability and finding a safe position
|
||||||
private _emptyPos = [];
|
private _emptyPos = [_vehicle, (typeOf _unit), _unloader] call EFUNC(common,findUnloadPosition);
|
||||||
|
TRACE_1("findUnloadPosition",_emptyPos);
|
||||||
|
|
||||||
if (_vehicle isKindOf "Ship") then {
|
if (count _emptyPos != 3) exitwith {
|
||||||
if (speed _vehicle > 1 || {getPos _vehicle select 2 > 2}) then {
|
ACE_LOGWARNING_4("Could not find unload pos %1-ASL: %2 isTouchingGround: %3 Speed: %4",_vehicle, getPosASL _vehicle, isTouchingGround _vehicle, speed _vehicle);
|
||||||
_validVehiclestate = false;
|
if ((!isNull _unloader) && {[_unloader] call FUNC(isPlayer)}) then {
|
||||||
|
//display text saying there are no safe places to exit the vehicle
|
||||||
|
["displayTextStructured", [_unloader], [localize LSTRING(NoRoomToUnload)]] call FUNC(targetEvent);
|
||||||
};
|
};
|
||||||
|
|
||||||
TRACE_1("SHIP Ground Check",getPos _vehicle);
|
|
||||||
|
|
||||||
_emptyPos = (ASLToAGL getPosASL _vehicle) findEmptyPosition [0, 13, typeOf _unit]; // TODO: if spot is underwater pick another spot.
|
|
||||||
} else {
|
|
||||||
if (_vehicle isKindOf "Air") then {
|
|
||||||
if (speed _vehicle > 1 || {!isTouchingGround _vehicle}) then {
|
|
||||||
_validVehiclestate = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
TRACE_1("Vehicle Ground Check",isTouchingGround _vehicle);
|
|
||||||
|
|
||||||
_emptyPos = ASLToAGL getPosASL _vehicle;
|
|
||||||
_emptyPos = _emptyPos vectorAdd [random 10 - 5, random 10 - 5, 0];
|
|
||||||
} else {
|
|
||||||
if (speed _vehicle > 1 || {getPos _vehicle select 2 > 2}) then {
|
|
||||||
_validVehiclestate = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
TRACE_1("Vehicle Ground Check", isTouchingGround _vehicle);
|
|
||||||
|
|
||||||
_emptyPos = (ASLToAGL getPosASL _vehicle) findEmptyPosition [0, 13, typeOf _unit];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
TRACE_1("getPosASL Vehicle Check", getPosASL _vehicle);
|
|
||||||
|
|
||||||
if !(_validVehiclestate) exitWith {
|
|
||||||
ACE_LOGWARNING_4("Unable to unload patient because invalid (%1) vehicle state. Either moving or Not close enough on the ground. position: %2 isTouchingGround: %3 Speed: %4",_vehicle,getPos _vehicle,isTouchingGround _vehicle,speed _vehicle);
|
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
|
|
||||||
if (count _emptyPos == 0) exitWith {
|
|
||||||
ACE_LOGWARNING_1("No safe empty spots to unload patient. %1",_emptyPos);
|
|
||||||
false
|
|
||||||
}; //consider displaying text saying there are no safe places to exit the vehicle
|
|
||||||
|
|
||||||
unassignVehicle _unit;
|
unassignVehicle _unit;
|
||||||
[_unit] orderGetIn false;
|
[_unit] orderGetIn false;
|
||||||
|
|
||||||
@ -87,16 +58,16 @@ _unit action ["Eject", vehicle _unit];
|
|||||||
if ((_unit getVariable "ACE_isUnconscious") and (animationState _unit != _anim)) then {
|
if ((_unit getVariable "ACE_isUnconscious") and (animationState _unit != _anim)) then {
|
||||||
[_unit, _anim, 2, true] call FUNC(doAnimation);
|
[_unit, _anim, 2, true] call FUNC(doAnimation);
|
||||||
};
|
};
|
||||||
}, [_unit, _anim], 0.5, 0] call FUNC(waitAndExecute);
|
}, [_unit, _anim], 0.5] call FUNC(waitAndExecute);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}, [_unit, _emptyPos], 0.5, 0] call FUNC(waitAndExecute);
|
}, [_unit, _emptyPos], 0.5] call FUNC(waitAndExecute);
|
||||||
|
|
||||||
[_unit, false, GROUP_SWITCH_ID, side group _unit] call FUNC(switchToGroupSide);
|
[_unit, false, GROUP_SWITCH_ID, side group _unit] call FUNC(switchToGroupSide);
|
||||||
|
|
||||||
private _loaded = _vehicle getVariable [QGVAR(loaded_persons),[]];
|
private _loaded = _vehicle getvariable [QGVAR(loaded_persons),[]];
|
||||||
_loaded deleteAt (_loaded find _unit);
|
_loaded deleteAt (_loaded find _unit);
|
||||||
|
|
||||||
_vehicle setVariable [QGVAR(loaded_persons), _loaded, true];
|
_vehicle setvariable [QGVAR(loaded_persons), _loaded, true];
|
||||||
|
|
||||||
true
|
true
|
||||||
|
@ -762,5 +762,8 @@
|
|||||||
<Czech>ACE3 Vozidla</Czech>
|
<Czech>ACE3 Vozidla</Czech>
|
||||||
<Spanish>ACE3 Vehículos</Spanish>
|
<Spanish>ACE3 Vehículos</Spanish>
|
||||||
</Key>
|
</Key>
|
||||||
|
<Key ID="STR_ACE_Common_NoRoomToUnload">
|
||||||
|
<English>No Room to unload</English>
|
||||||
|
</Key>
|
||||||
</Package>
|
</Package>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -21,4 +21,4 @@ params ["_caller", "_target", ["_drag", false]];
|
|||||||
if (vehicle _target == _target) exitWith {};
|
if (vehicle _target == _target) exitWith {};
|
||||||
if (([_target] call EFUNC(common,isAwake))) exitWith {};
|
if (([_target] call EFUNC(common,isAwake))) exitWith {};
|
||||||
|
|
||||||
["unloadPersonEvent", _target, [_target, vehicle _target]] call EFUNC(common,targetEvent)
|
["unloadPersonEvent", _target, [_target, vehicle _target, _caller]] call EFUNC(common,targetEvent);
|
||||||
|
Loading…
Reference in New Issue
Block a user