mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge branch 'master' into pr/9758
This commit is contained in:
commit
370f141776
@ -60,7 +60,7 @@ if (!hasInterface) exitWith {};
|
||||
}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
// - Duty factors -------------------------------------------------------------
|
||||
if (["ace_medical"] call EFUNC(common,isModLoaded)) then {
|
||||
if (GVAR(medicalLoaded)) then {
|
||||
[QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1
|
||||
linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true];
|
||||
}] call FUNC(addDutyFactor);
|
||||
|
@ -13,5 +13,6 @@ GVAR(dutyList) = createHashMap;
|
||||
GVAR(setAnimExclusions) = [];
|
||||
GVAR(inertia) = 0;
|
||||
GVAR(inertiaCache) = createHashMap;
|
||||
GVAR(medicalLoaded) = ["ace_medical"] call EFUNC(common,isModLoaded);
|
||||
|
||||
ADDON = true;
|
||||
|
@ -23,6 +23,12 @@ if (!alive ACE_player) exitWith {
|
||||
_staminaBarContainer ctrlCommit 1;
|
||||
};
|
||||
|
||||
|
||||
private _oxygen = 0.9; // Default AF oxygen saturation
|
||||
if (GVAR(medicalLoaded) && {EGVAR(medical_vitals,simulateSpo2)}) then {
|
||||
_oxygen = (ACE_player getVariable [QEGVAR(medical,spo2), 97]) / 100;
|
||||
};
|
||||
|
||||
private _currentWork = REE;
|
||||
private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6;
|
||||
|
||||
@ -42,8 +48,8 @@ GVAR(muscleDamage) = (GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.
|
||||
private _muscleIntegritySqrt = sqrt (1 - GVAR(muscleDamage));
|
||||
|
||||
// Calculate available power
|
||||
private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt;
|
||||
private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt;
|
||||
private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * _oxygen * _muscleIntegritySqrt;
|
||||
private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * _oxygen * _muscleIntegritySqrt;
|
||||
|
||||
// Calculate how much power is consumed from each reserve
|
||||
private _ae1Power = _currentWork min _ae1PathwayPowerFatigued;
|
||||
@ -58,8 +64,8 @@ GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP;
|
||||
GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1;
|
||||
|
||||
// Aerobic ATP reserve recovery
|
||||
GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + OXYGEN * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0;
|
||||
GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + OXYGEN * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0;
|
||||
GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + _oxygen * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0;
|
||||
GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + _oxygen * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0;
|
||||
|
||||
// Anaerobic ATP reserver and fatigue recovery
|
||||
GVAR(anReserve) = ((GVAR(anReserve)
|
||||
@ -70,9 +76,9 @@ GVAR(anFatigue) = ((GVAR(anFatigue)
|
||||
- (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor)
|
||||
) min 1) max 0;
|
||||
|
||||
private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2;
|
||||
private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE;
|
||||
private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage);
|
||||
GVAR(aeReservePercentage) = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2;
|
||||
GVAR(anReservePercentage) = GVAR(anReserve) / AN_MAXRESERVE;
|
||||
private _perceivedFatigue = 1 - (GVAR(anReservePercentage) min GVAR(aeReservePercentage));
|
||||
|
||||
[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects);
|
||||
|
||||
|
@ -15,3 +15,17 @@ class Extended_PostInit_EventHandlers {
|
||||
init = QUOTE(call COMPILE_SCRIPT(XEH_postInit));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_Killed_EventHandlers {
|
||||
class CAManBase {
|
||||
class ADDON {
|
||||
killed = QUOTE((_this select 0) call FUNC(handleDeployInterrupt));
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_DisplayLoad_EventHandlers {
|
||||
class RscDisplayMission {
|
||||
ADDON = QUOTE(_this call COMPILE_SCRIPT(XEH_missionDisplayLoad));
|
||||
};
|
||||
};
|
||||
|
@ -2,10 +2,15 @@ PREP(addCargoItem);
|
||||
PREP(addCargoVehiclesActions);
|
||||
PREP(canLoadItemIn);
|
||||
PREP(canUnloadItem);
|
||||
PREP(deployCancel);
|
||||
PREP(deployConfirm);
|
||||
PREP(getCargoSpaceLeft);
|
||||
PREP(getNameItem);
|
||||
PREP(getSelectedItem);
|
||||
PREP(getSizeItem);
|
||||
PREP(handleDestroyed);
|
||||
PREP(handleDeployInterrupt);
|
||||
PREP(handleScrollWheel);
|
||||
PREP(initObject);
|
||||
PREP(initVehicle);
|
||||
PREP(loadItem);
|
||||
@ -16,6 +21,7 @@ PREP(removeCargoItem);
|
||||
PREP(renameObject);
|
||||
PREP(setSize);
|
||||
PREP(setSpace);
|
||||
PREP(startDeploy);
|
||||
PREP(startLoadIn);
|
||||
PREP(startUnload);
|
||||
PREP(unloadCarryItem);
|
||||
|
11
addons/cargo/XEH_missionDisplayLoad.sqf
Normal file
11
addons/cargo/XEH_missionDisplayLoad.sqf
Normal file
@ -0,0 +1,11 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_display"];
|
||||
|
||||
_display displayAddEventHandler ["MouseZChanged", {(_this select 1) call FUNC(handleScrollWheel)}];
|
||||
_display displayAddEventHandler ["MouseButtonDown", {
|
||||
// Right clicking cancels deployment
|
||||
if (_this select 1 == 1) then {
|
||||
ACE_player call FUNC(handleDeployInterrupt);
|
||||
};
|
||||
}];
|
@ -17,10 +17,10 @@
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
["ace_unloadCargo", {
|
||||
params ["_item", "_vehicle", ["_unloader", objNull]];
|
||||
TRACE_3("UnloadCargo EH",_item,_vehicle,_unloader);
|
||||
params ["_item", "_vehicle", ["_unloader", objNull], ["_place", []]];
|
||||
TRACE_4("UnloadCargo EH",_item,_vehicle,_unloader,_place);
|
||||
|
||||
private _unloaded = [_item, _vehicle, _unloader] call FUNC(unloadItem); // returns true if successful
|
||||
private _unloaded = [_item, _vehicle, _unloader, _place] call FUNC(unloadItem); // returns true if successful
|
||||
|
||||
// Show hint as feedback
|
||||
private _hint = [LSTRING(unloadingFailed), LSTRING(unloadedItem)] select _unloaded;
|
||||
@ -36,13 +36,25 @@
|
||||
};
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
// Direction must be set before setting position according to wiki
|
||||
[QGVAR(setDirAndUnload), {
|
||||
params ["_item", "_emptyPosAGL", "_direction"];
|
||||
|
||||
_item setDir _direction;
|
||||
|
||||
[QGVAR(serverUnload), [_item, _emptyPosAGL]] call CBA_fnc_serverEvent;
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
// 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), {
|
||||
params ["_item", "_emptyPosAGL"];
|
||||
|
||||
_item hideObjectGlobal false;
|
||||
_item setPosASL (AGLtoASL _emptyPosAGL);
|
||||
|
||||
[_item, "blockDamage", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||
// Let objects remain invulernable for a short while after placement
|
||||
[EFUNC(common,statusEffect_set), [_item, "blockDamage", QUOTE(ADDON), false], 2] call CBA_fnc_waitAndExecute;
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
[QGVAR(paradropItem), {
|
||||
@ -166,3 +178,38 @@ if (isServer) then {
|
||||
_bodyBag setVariable [QGVAR(customName), [_target, false, true] call EFUNC(common,getName), true];
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
};
|
||||
|
||||
// Set variables, even on machines without interfaces, just to be safe
|
||||
GVAR(selectedItem) = objNull;
|
||||
GVAR(itemPreviewObject) = objNull;
|
||||
GVAR(deployPFH) = -1;
|
||||
GVAR(deployDistance) = -1;
|
||||
GVAR(deployDirection) = 0;
|
||||
GVAR(deployHeight) = 0;
|
||||
GVAR(canDeploy) = false;
|
||||
|
||||
if (!hasInterface) exitWith {};
|
||||
|
||||
// Cancel object deployment if interact menu opened
|
||||
["ace_interactMenuOpened", {ACE_player call FUNC(handleDeployInterrupt)}] call CBA_fnc_addEventHandler;
|
||||
|
||||
// Cancel deploy on player change. This does work when returning to lobby, but not when hard disconnecting
|
||||
["unit", LINKFUNC(handleDeployInterrupt)] call CBA_fnc_addPlayerEventHandler;
|
||||
["vehicle", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler;
|
||||
["weapon", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
// When changing feature cameras, stop deployment
|
||||
["featureCamera", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
// Handle falling unconscious while trying to deploy
|
||||
["ace_unconscious", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addEventHandler;
|
||||
|
||||
// Handle surrendering and handcuffing
|
||||
["ace_captiveStatusChanged", {
|
||||
params ["_unit", "_state"];
|
||||
|
||||
// If surrendered or handcuffed, stop deployment
|
||||
if (_state) then {
|
||||
_unit call FUNC(handleDeployInterrupt);
|
||||
};
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
39
addons/cargo/functions/fnc_deployCancel.sqf
Normal file
39
addons/cargo/functions/fnc_deployCancel.sqf
Normal file
@ -0,0 +1,39 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Garth 'L-H' de Wet, Ruthberg, commy2, Smith
|
||||
* Cancels unloading when deploying.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* player call ace_cargo_fnc_deployCancel
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
if (GVAR(deployPFH) == -1) exitWith {};
|
||||
|
||||
// Remove deployment pfh
|
||||
GVAR(deployPFH) call CBA_fnc_removePerFrameHandler;
|
||||
GVAR(deployPFH) = -1;
|
||||
|
||||
params ["_unit"];
|
||||
|
||||
// Enable running again
|
||||
[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||
[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||
|
||||
// Delete placement dummy
|
||||
deleteVehicle GVAR(itemPreviewObject);
|
||||
|
||||
// Remove mouse button actions
|
||||
call EFUNC(interaction,hideMouseHint);
|
||||
|
||||
[_unit, "DefaultAction", _unit getVariable [QGVAR(deploy), -1]] call EFUNC(common,removeActionEventHandler);
|
||||
_unit setVariable [QGVAR(deploy), -1];
|
||||
|
||||
_unit setVariable [QGVAR(isDeploying), false, true];
|
56
addons/cargo/functions/fnc_deployConfirm.sqf
Normal file
56
addons/cargo/functions/fnc_deployConfirm.sqf
Normal file
@ -0,0 +1,56 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Garth 'L-H' de Wet, Ruthberg, commy2, Smith
|
||||
* Confirms unloading when deploying.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* player call ace_cargo_fnc_deployConfirm
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
if (GVAR(deployPFH) == -1) exitWith {};
|
||||
|
||||
params ["_unit"];
|
||||
|
||||
// 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 {
|
||||
// Position is AGL for unloading event
|
||||
private _position = ASLToAGL getPosASL GVAR(itemPreviewObject);
|
||||
private _direction = getDir GVAR(itemPreviewObject);
|
||||
private _duration = GVAR(loadTimeCoefficient) * (GVAR(selectedItem) call FUNC(getSizeItem));
|
||||
|
||||
// If unload time is 0, don't show a progress bar
|
||||
if (_duration <= 0) exitWith {
|
||||
["ace_unloadCargo", [GVAR(selectedItem), GVAR(interactionVehicle), _unit, [_position, _direction]]] call CBA_fnc_localEvent;
|
||||
};
|
||||
|
||||
[
|
||||
_duration,
|
||||
[GVAR(selectedItem), GVAR(interactionVehicle), _unit, [_position, _direction]],
|
||||
{
|
||||
TRACE_1("deploy finish",_this);
|
||||
|
||||
["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent;
|
||||
},
|
||||
{
|
||||
TRACE_1("deploy fail",_this);
|
||||
},
|
||||
format [LLSTRING(unloadingItem), [GVAR(selectedItem), true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")],
|
||||
{
|
||||
(_this select 0) params ["_item", "_vehicle", "_unit"];
|
||||
|
||||
[_item, _vehicle, _unit, false, true] call FUNC(canUnloadItem) // don't check for a suitable unloading position when deploying
|
||||
},
|
||||
["isNotSwimming"]
|
||||
] call EFUNC(common,progressBar);
|
||||
};
|
||||
|
||||
// Cleanup EHs and preview object
|
||||
_unit call FUNC(deployCancel);
|
29
addons/cargo/functions/fnc_getSelectedItem.sqf
Normal file
29
addons/cargo/functions/fnc_getSelectedItem.sqf
Normal file
@ -0,0 +1,29 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Glowbal, Smith
|
||||
* Get selected item from cargo menu.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* Classname of selected item or selected object <STRING> or <OBJECT> (default: nil)
|
||||
*
|
||||
* Example:
|
||||
* call ace_cargo_fnc_getSelectedItem
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
disableSerialization;
|
||||
|
||||
private _display = uiNamespace getVariable QGVAR(menuDisplay);
|
||||
|
||||
if (isNil "_display") exitWith {};
|
||||
|
||||
private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []];
|
||||
|
||||
if (_loaded isEqualTo []) exitWith {};
|
||||
|
||||
// This can be an object or a classname string
|
||||
_loaded param [lbCurSel (_display displayCtrl 100), nil]
|
30
addons/cargo/functions/fnc_handleDeployInterrupt.sqf
Normal file
30
addons/cargo/functions/fnc_handleDeployInterrupt.sqf
Normal file
@ -0,0 +1,30 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: commy2, Smith
|
||||
* Handle various interruption types.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: (New) unit <OBJECT>
|
||||
* 1: Old unit (for player change) <OBJECT> (default: objNull)
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* player call ace_cargo_fnc_handleDeployInterrupt
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_newPlayer", ["_oldPlayer", objNull]];
|
||||
TRACE_2("params",_newPlayer,_oldPlayer);
|
||||
|
||||
if (!local _newPlayer) exitWith {};
|
||||
|
||||
if (_newPlayer getVariable [QGVAR(isDeploying), false]) then {
|
||||
_newPlayer call FUNC(deployCancel);
|
||||
};
|
||||
|
||||
if (_oldPlayer getVariable [QGVAR(isDeploying), false]) then {
|
||||
_oldPlayer call FUNC(deployCancel);
|
||||
};
|
58
addons/cargo/functions/fnc_handleScrollWheel.sqf
Normal file
58
addons/cargo/functions/fnc_handleScrollWheel.sqf
Normal file
@ -0,0 +1,58 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: L-H, commy2, Smith
|
||||
* Handles rotation of object to unload.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Scroll amount <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* If the scroll was handled <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* 1.2 call ace_cargo_fnc_handleScrollWheel
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
if (GVAR(deployPFH) == -1) exitWith {false};
|
||||
|
||||
params ["_scrollAmount"];
|
||||
|
||||
private _deployedItem = GVAR(itemPreviewObject);
|
||||
|
||||
if (!CBA_events_control) then {
|
||||
private _unit = ACE_player;
|
||||
|
||||
// Raise/lower
|
||||
// Move deployed item 15 cm per scroll interval
|
||||
_scrollAmount = _scrollAmount * 0.15;
|
||||
|
||||
private _position = getPosASL _deployedItem;
|
||||
private _maxHeight = (_unit modelToWorldVisualWorld [0, 0, 0]) select 2;
|
||||
|
||||
_position set [2, ((_position select 2) + _scrollAmount min (_maxHeight + 1.5)) max _maxHeight];
|
||||
|
||||
// Move up/down object and reattach at current position
|
||||
detach _deployedItem;
|
||||
|
||||
// Uses this method of selecting position because setPosATL did not have immediate effect
|
||||
private _positionChange = _position vectorDiff (getPosASL _deployedItem);
|
||||
private _selectionPosition = _unit worldToModel (ASLtoAGL getPosWorld _deployedItem);
|
||||
_selectionPosition = _selectionPosition vectorAdd _positionChange;
|
||||
_deployedItem attachTo [_unit, _selectionPosition];
|
||||
|
||||
// Reset the deploy direction
|
||||
private _direction = _deployedItem getVariable [QGVAR(deployDirection_temp), 0];
|
||||
_deployedItem setDir _direction;
|
||||
} else {
|
||||
// Rotate
|
||||
private _direction = _deployedItem getVariable [QGVAR(deployDirection_temp), 0];
|
||||
_scrollAmount = _scrollAmount * 10;
|
||||
_direction = _direction + _scrollAmount;
|
||||
|
||||
_deployedItem setDir _direction;
|
||||
_deployedItem setVariable [QGVAR(deployDirection_temp), _direction];
|
||||
};
|
||||
|
||||
true
|
@ -22,11 +22,17 @@ private _type = typeOf _vehicle;
|
||||
private _config = configOf _vehicle;
|
||||
|
||||
// If vehicle had space given to it via eden/public, then override config hasCargo setting
|
||||
private _hasCargoPublic = _vehicle getVariable [QGVAR(hasCargo), false];
|
||||
private _hasCargoPublic = _item getVariable QGVAR(hasCargo);
|
||||
private _hasCargoPublicDefined = !isNil "_canLoadPublic";
|
||||
|
||||
if (_hasCargoPublicDefined && {!(_hasCargoPublic isEqualType false)}) then {
|
||||
WARNING_4("%1[%2] - Variable %3 is %4 - Should be bool",_item,_type,QGVAR(hasCargo),_hasCargoPublic);
|
||||
};
|
||||
|
||||
private _hasCargoConfig = getNumber (_config >> QGVAR(hasCargo)) == 1;
|
||||
|
||||
// Nothing to do here if vehicle has no cargo space
|
||||
if !(_hasCargoConfig || _hasCargoPublic) exitWith {};
|
||||
if !((_hasCargoPublicDefined && {_hasCargoPublic in [true, 1]}) || {!_hasCargoPublicDefined && {_hasCargoConfig}}) exitWith {};
|
||||
|
||||
// Check if cargo is in cargo holder types (checked when trying to search for loadable objects)
|
||||
private _addCargoType = GVAR(cargoHolderTypes) findIf {_type isKindOf _x} == -1;
|
||||
|
@ -25,6 +25,9 @@ if (GVAR(interactionParadrop)) then {
|
||||
(_display displayCtrl 12) ctrlSetText LLSTRING(paradropButton);
|
||||
};
|
||||
|
||||
// Disable deploy option if paradropping or in Zeus
|
||||
(_display displayCtrl 13) ctrlEnable (GVAR(enableDeploy) && !GVAR(interactionParadrop) && {isNull curatorCamera});
|
||||
|
||||
[{
|
||||
params ["_vehicle", "_pfhID"];
|
||||
|
||||
@ -33,7 +36,6 @@ if (GVAR(interactionParadrop)) then {
|
||||
private _display = uiNamespace getVariable QGVAR(menuDisplay);
|
||||
|
||||
if (isNil "_display") exitWith {
|
||||
GVAR(interactionVehicle) = nil;
|
||||
GVAR(interactionParadrop) = nil;
|
||||
|
||||
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||
@ -41,18 +43,18 @@ if (GVAR(interactionParadrop)) then {
|
||||
|
||||
// Close menu if in invalid state
|
||||
if (
|
||||
!alive _vehicle ||
|
||||
!alive ACE_player ||
|
||||
{!alive _vehicle} ||
|
||||
{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)
|
||||
{
|
||||
isNull findDisplay 312 && // if in Zeus, ignore the following checks
|
||||
isNull curatorCamera && // if in Zeus, ignore the checks that follow
|
||||
{([ACE_player, _vehicle] call EFUNC(interaction,getInteractionDistance)) >= MAX_LOAD_DISTANCE} &&
|
||||
{(vehicle ACE_player) != _vehicle}
|
||||
}
|
||||
) exitWith {
|
||||
closeDialog 0;
|
||||
|
||||
GVAR(interactionVehicle) = nil;
|
||||
GVAR(interactionParadrop) = nil;
|
||||
|
||||
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||
|
86
addons/cargo/functions/fnc_startDeploy.sqf
Normal file
86
addons/cargo/functions/fnc_startDeploy.sqf
Normal file
@ -0,0 +1,86 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Garth 'L-H' de Wet, Ruthberg, commy2, Smith
|
||||
* Starts the deploy process for unloading an object.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit deploying <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* player call ace_cargo_fnc_startDeploy
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
// Deny creating preview item as it will destroy player vehicle instantly by collision
|
||||
if (GVAR(interactionParadrop)) exitWith {};
|
||||
|
||||
params ["_unit"];
|
||||
|
||||
// Don't allow deploying if already deploying
|
||||
if (_unit getVariable [QGVAR(isDeploying), false]) exitWith {};
|
||||
|
||||
// This can be an object or a classname string
|
||||
private _item = call FUNC(getSelectedItem);
|
||||
|
||||
if (isNil "_item") exitWith {};
|
||||
|
||||
// Close opened cargo menu
|
||||
closeDialog 0;
|
||||
|
||||
GVAR(selectedItem) = _item;
|
||||
|
||||
private _classname = _item;
|
||||
|
||||
if (_classname isEqualType objNull) then {
|
||||
_classname = typeOf _classname;
|
||||
};
|
||||
|
||||
// Prevent the placing unit from running
|
||||
[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
|
||||
// Create a local preview object
|
||||
private _itemPreviewObject = createVehicleLocal [_classname, [0, 0, 0], [], 0, "CAN_COLLIDE"];
|
||||
|
||||
GVAR(itemPreviewObject) = _itemPreviewObject;
|
||||
|
||||
// Prevent collisions with object
|
||||
_itemPreviewObject disableCollisionWith _unit;
|
||||
_itemPreviewObject enableSimulation false;
|
||||
_itemPreviewObject setMass 1e-12;
|
||||
|
||||
// Detect radius of zone where collision can damage the player
|
||||
private _itemPreviewObjectRadius = 1 max ((boundingBoxReal [_itemPreviewObject, "FireGeometry"]) select 2);
|
||||
|
||||
// Add height offset of model
|
||||
private _offset = ((_itemPreviewObject modelToWorldVisual [0, 0, 0]) select 2) - ((_unit modelToWorldVisual [0, 0, 0]) select 2) + 1;
|
||||
|
||||
// Attach object
|
||||
_itemPreviewObject attachTo [_unit, [0, 1.5 * _itemPreviewObjectRadius, _offset]];
|
||||
|
||||
// PFH that runs while the deployment is in progress
|
||||
GVAR(deployPFH) = [{
|
||||
(_this select 0) params ["_unit", "_vehicle", "_item", "_itemPreviewObject"];
|
||||
|
||||
if !(
|
||||
!isNull _itemPreviewObject &&
|
||||
{[_item, _vehicle, _unit, false, true] call FUNC(canUnloadItem)} // don't check for a suitable unloading position when deploying
|
||||
) exitWith {
|
||||
_unit call FUNC(deployCancel);
|
||||
};
|
||||
}, 0.5, [_unit, GVAR(interactionVehicle), _item, _itemPreviewObject]] call CBA_fnc_addPerFrameHandler;
|
||||
|
||||
// Add mouse button action and hint
|
||||
[LLSTRING(unloadObject), localize "STR_DISP_CANCEL", LLSTRING(scrollAction)] call EFUNC(interaction,showMouseHint);
|
||||
|
||||
_unit setVariable [QGVAR(deploy), [
|
||||
_unit, "DefaultAction",
|
||||
{GVAR(deployPFH) != -1},
|
||||
{[_this select 0] call FUNC(deployConfirm)}
|
||||
] call EFUNC(common,addActionEventHandler)];
|
||||
|
||||
_unit setVariable [QGVAR(isDeploying), true, true];
|
@ -15,18 +15,8 @@
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
disableSerialization;
|
||||
|
||||
private _display = uiNamespace getVariable QGVAR(menuDisplay);
|
||||
|
||||
if (isNil "_display") exitWith {};
|
||||
|
||||
private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []];
|
||||
|
||||
if (_loaded isEqualTo []) exitWith {};
|
||||
|
||||
// This can be an object or a classname string
|
||||
private _item = _loaded param [lbCurSel (_display displayCtrl 100), nil];
|
||||
private _item = call FUNC(getSelectedItem);
|
||||
|
||||
if (isNil "_item") exitWith {};
|
||||
|
||||
@ -60,11 +50,11 @@ if (GVAR(interactionParadrop)) exitWith {
|
||||
},
|
||||
format [LLSTRING(unloadingItem), [_item, true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")],
|
||||
{
|
||||
(_this select 0) params ["", "_target"];
|
||||
(_this select 0) params ["", "_vehicle"];
|
||||
|
||||
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
|
||||
if ((acos ((vectorUp _vehicle) select 2)) > 30) exitWith {false}; // check flight level
|
||||
if (((getPos _vehicle) select 2) < 25) exitWith {false}; // check height
|
||||
if ((speed _vehicle) < -5) exitWith {false}; // check reverse
|
||||
|
||||
true
|
||||
},
|
||||
@ -74,7 +64,7 @@ if (GVAR(interactionParadrop)) exitWith {
|
||||
};
|
||||
|
||||
// If in zeus
|
||||
if (!isNull findDisplay 312) exitWith {
|
||||
if (!isNull curatorCamera) exitWith {
|
||||
// Do not check distance to unit, but do check for valid position
|
||||
if !([_item, GVAR(interactionVehicle), objNull, true] call FUNC(canUnloadItem)) exitWith {
|
||||
[[LSTRING(unloadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured);
|
||||
|
@ -7,6 +7,9 @@
|
||||
* 0: Item to be unloaded <STRING> or <OBJECT> (default: "")
|
||||
* 1: Holder object (vehicle) <OBJECT> (default: objNull)
|
||||
* 2: Unloader <OBJECT> (default: objNull)
|
||||
* 3: Deploy parameters <ARRAY> (default: [])
|
||||
* - 0: Position AGL <ARRAY>
|
||||
* - 1: Direction <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* Object unloaded <BOOL>
|
||||
@ -17,8 +20,10 @@
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_unloader", objNull, [objNull]]];
|
||||
TRACE_3("params",_item,_vehicle,_unloader);
|
||||
params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_unloader", objNull, [objNull]], ["_deploy", []]];
|
||||
_deploy params ["_emptyPosAGL", "_direction"];
|
||||
|
||||
TRACE_4("params",_item,_vehicle,_unloader,_deploy);
|
||||
|
||||
// Get config sensitive case name
|
||||
if (_item isEqualType "") then {
|
||||
@ -41,9 +46,18 @@ if (_itemSize < 0) exitWith {
|
||||
false // return
|
||||
};
|
||||
|
||||
// This covers testing vehicle stability and finding a safe position
|
||||
private _emptyPosAGL = [_vehicle, _item, _unloader] call EFUNC(common,findUnloadPosition);
|
||||
TRACE_1("findUnloadPosition",_emptyPosAGL);
|
||||
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);
|
||||
|
||||
if (_emptyPosAGL isNotEqualTo []) exitWith {};
|
||||
};
|
||||
|
||||
TRACE_1("findUnloadPosition",_emptyPosAGL);
|
||||
};
|
||||
|
||||
if (_emptyPosAGL isEqualTo []) exitWith {
|
||||
// Display text saying there are no safe places to exit the vehicle
|
||||
@ -67,9 +81,12 @@ private _object = _item;
|
||||
if (_object isEqualType objNull) then {
|
||||
detach _object;
|
||||
|
||||
// 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), [_object, _emptyPosAGL]] call CBA_fnc_serverEvent;
|
||||
// If player unloads via deployment, set direction first, then unload
|
||||
if (_deployed) then {
|
||||
[QGVAR(setDirAndUnload), [_object, _emptyPosAGL, _direction], _object] call CBA_fnc_targetEvent;
|
||||
} else {
|
||||
[QGVAR(serverUnload), [_object, _emptyPosAGL]] call CBA_fnc_serverEvent;
|
||||
};
|
||||
|
||||
if (["ace_zeus"] call EFUNC(common,isModLoaded)) then {
|
||||
// Get which curators had this object as editable
|
||||
@ -81,6 +98,12 @@ if (_object isEqualType objNull) then {
|
||||
};
|
||||
} else {
|
||||
_object = createVehicle [_item, _emptyPosAGL, [], 0, "NONE"];
|
||||
|
||||
// If player unloads via deployment, set direction. Must happen before setPosASL command according to wiki
|
||||
if (_deployed) then {
|
||||
_object setDir _direction;
|
||||
};
|
||||
|
||||
_object setPosASL (AGLtoASL _emptyPosAGL);
|
||||
|
||||
[QEGVAR(common,fixCollision), _object] call CBA_fnc_localEvent;
|
||||
@ -88,7 +111,9 @@ if (_object isEqualType objNull) then {
|
||||
};
|
||||
|
||||
// Dragging integration
|
||||
[_unloader, _object] call FUNC(unloadCarryItem);
|
||||
if (!_deployed) then {
|
||||
[_unloader, _object] call FUNC(unloadCarryItem);
|
||||
};
|
||||
|
||||
// Invoke listenable event
|
||||
["ace_cargoUnloaded", [_object, _vehicle, "unload"]] call CBA_fnc_globalEvent;
|
||||
|
@ -6,7 +6,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
|
||||
[LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)],
|
||||
_category,
|
||||
true,
|
||||
true,
|
||||
1,
|
||||
{[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
@ -16,7 +16,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
|
||||
[LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)],
|
||||
_category,
|
||||
[0, 10, 5, 1],
|
||||
true,
|
||||
1,
|
||||
{[QGVAR(loadTimeCoefficient), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
@ -26,7 +26,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
|
||||
[LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)],
|
||||
_category,
|
||||
[0, 10, 2.5, 1],
|
||||
true,
|
||||
1,
|
||||
{[QGVAR(paradropTimeCoefficent), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
@ -36,26 +36,36 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
|
||||
[LSTRING(openAfterUnload), LSTRING(openAfterUnload_description)],
|
||||
_category,
|
||||
[[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0],
|
||||
false,
|
||||
0,
|
||||
{[QGVAR(openAfterUnload), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(enableRename),
|
||||
"CHECKBOX",
|
||||
[LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)],
|
||||
_category,
|
||||
true,
|
||||
false,
|
||||
{[QGVAR(enableRename), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(carryAfterUnload),
|
||||
"CHECKBOX",
|
||||
[LSTRING(carryAfterUnload), LSTRING(carryAfterUnload_description)],
|
||||
_category,
|
||||
true,
|
||||
false,
|
||||
0,
|
||||
{[QGVAR(carryAfterUnload), _this] call EFUNC(common,cbaSettings_settingChanged)}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(enableDeploy),
|
||||
"CHECKBOX",
|
||||
[LSTRING(enableDeploy), LSTRING(enableDeploy_description)],
|
||||
_category,
|
||||
true,
|
||||
1,
|
||||
{[QGVAR(enableDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
QGVAR(enableRename),
|
||||
"CHECKBOX",
|
||||
[LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)],
|
||||
_category,
|
||||
true,
|
||||
0,
|
||||
{[QGVAR(enableRename), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
@ -17,7 +17,7 @@ class GVAR(menu) {
|
||||
};
|
||||
class CenterBackground: HeaderBackground {
|
||||
y = "2.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
|
||||
h = "13.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
|
||||
h = "14.2 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
|
||||
text = "#(argb,8,8,3)color(0,0,0,0.8)";
|
||||
colorText[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"};
|
||||
colorBackground[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"};
|
||||
@ -72,7 +72,7 @@ class GVAR(menu) {
|
||||
idc = 11;
|
||||
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)";
|
||||
w = "5 * (((safezoneW / safezoneH) min 1.2) / 40)";
|
||||
w = "6 * (((safezoneW / safezoneH) min 1.2) / 40)";
|
||||
h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)";
|
||||
size = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)";
|
||||
SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.7)";
|
||||
@ -96,8 +96,15 @@ class GVAR(menu) {
|
||||
class btnUnload: btnCancel {
|
||||
text = CSTRING(unloadObject);
|
||||
idc = 12;
|
||||
x = "20.9 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)";
|
||||
x = "19.9 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)";
|
||||
action = QUOTE(ACE_player call FUNC(startUnload));
|
||||
};
|
||||
class btnPlace: btnUnload {
|
||||
text = CSTRING(deployObject);
|
||||
idc = 13;
|
||||
y = "15.2 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)";
|
||||
action = QUOTE(ACE_player call FUNC(startDeploy));
|
||||
colorDisabled[] = {0.25, 0.25, 0.25, 1};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -33,6 +33,40 @@
|
||||
<Chinesesimp>卸载</Chinesesimp>
|
||||
<Turkish>Boşalt</Turkish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Cargo_deployObject">
|
||||
<English>Deploy</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Cargo_ScrollAction">
|
||||
<English>Raise/Lower | (Ctrl + Scroll) Rotate</English>
|
||||
<German>Heben/Senken | (Strg + Scrollen) Drehen</German>
|
||||
<Italian>Alza/Abbassa | (Ctrl + Rotellina) Ruota</Italian>
|
||||
<French>Lever/Baisser | (Ctrl + Scroll) Rotation</French>
|
||||
<Japanese>上げる/下げる | (Ctrl + スクロール) 回転</Japanese>
|
||||
<Czech>Zvednout/Snížit | (Ctrl + Kolečko myši) Otáčet</Czech>
|
||||
<Russian>Поднять/опустить | (Ctrl + Скролл) Крутить</Russian>
|
||||
<Polish>Wyżej/niżej | (Ctrl + Kółko myszy) obracanie</Polish>
|
||||
<Turkish>Yükselt/Alçalt | (Ctrl + Tekerlek) Döndür</Turkish>
|
||||
<Spanish>Subir/Bajar | (Ctrl + Scroll) Rotar</Spanish>
|
||||
<Chinesesimp>抬起/放低 |(Ctrl + 鼠标滚轮)旋转</Chinesesimp>
|
||||
<Korean>높이기/내리기 | (컨트롤 + 스크롤) 회전</Korean>
|
||||
<Portuguese>Subir/Abaixar | (Ctrl + Scroll) Rotacionar</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Cargo_BlockedAction">
|
||||
<English>Blocked</English>
|
||||
<Spanish>Obstruido</Spanish>
|
||||
<Portuguese>Bloqueado</Portuguese>
|
||||
<Russian>Заблокировано</Russian>
|
||||
<Czech>Blokováno</Czech>
|
||||
<Polish>Zablokowany</Polish>
|
||||
<Italian>Bloccato</Italian>
|
||||
<German>Blockiert</German>
|
||||
<French>Bloqué</French>
|
||||
<Japanese>取り付け不可</Japanese>
|
||||
<Korean>막힘</Korean>
|
||||
<Chinesesimp>断开</Chinesesimp>
|
||||
<Chinese>斷開</Chinese>
|
||||
<Turkish>Bloke Edilmiş</Turkish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Cargo_renamedObject">
|
||||
<English>Renamed to:<br/>%1</English>
|
||||
<Japanese>名前を次に変更:<br/>%1</Japanese>
|
||||
@ -528,5 +562,11 @@
|
||||
<French>Active si les éléments de cargaison sont portés ou traînés après le déchargement.</French>
|
||||
<Portuguese>Controla se os itens de carga são carregados ou arrastados após a descarga.</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Cargo_enableDeploy">
|
||||
<English>Enable deploy</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Cargo_enableDeploy_description">
|
||||
<English>Controls whether cargo items can be unloaded via the deploy method.</English>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
|
@ -4,7 +4,7 @@ class CfgVehicles {
|
||||
class ACE_SelfActions {
|
||||
class GVAR(deploy) {
|
||||
displayName = CSTRING(PlaceTripod_displayName);
|
||||
condition = QUOTE(call FUNC(assemble_canDeployTripod));
|
||||
condition = QUOTE(call FUNC(canDeployTripod));
|
||||
statement = QUOTE(call FUNC(assemble_deployTripod));
|
||||
exceptions[] = {};
|
||||
};
|
||||
@ -36,7 +36,7 @@ class CfgVehicles {
|
||||
condition = "true";
|
||||
class GVAR(pickUp) {
|
||||
displayName = CSTRING(Pickup_displayName);
|
||||
condition = QUOTE(call FUNC(assemble_canPickupTripod));
|
||||
condition = QUOTE(call FUNC(canPickupTripod));
|
||||
statement = QUOTE(call FUNC(assemble_pickupTripod));
|
||||
};
|
||||
class GVAR(mountWeapon) {
|
||||
@ -125,10 +125,11 @@ class CfgVehicles {
|
||||
class StaticWeapon: LandVehicle {
|
||||
class ACE_Actions {
|
||||
class ACE_MainActions {
|
||||
// Workaround for static weapons' Get In memory point being at the front of the gun
|
||||
class GVAR(getIn) {
|
||||
displayName = CSTRING(GetIn_displayName);
|
||||
condition = QUOTE(call FUNC(canGetIn));
|
||||
statement = QUOTE(call FUNC(getIn));
|
||||
statement = QUOTE(_player moveInTurret [ARR_2(_target,[0])]);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -6,9 +6,9 @@ PREP(ai_handleFired);
|
||||
PREP(ai_handleGetIn);
|
||||
PREP(ai_reload);
|
||||
|
||||
PREP(assemble_canDeployTripod);
|
||||
PREP(canDeployTripod);
|
||||
PREP(assemble_canDeployWeapon);
|
||||
PREP(assemble_canPickupTripod);
|
||||
PREP(canPickupTripod);
|
||||
PREP(assemble_canPickupWeapon);
|
||||
PREP(assemble_deployTripod);
|
||||
PREP(assemble_deployWeapon);
|
||||
@ -17,13 +17,12 @@ PREP(assemble_pickupTripod);
|
||||
PREP(assemble_pickupWeapon);
|
||||
|
||||
PREP(canGetIn);
|
||||
PREP(getIn);
|
||||
|
||||
PREP(getCarryMagazine);
|
||||
PREP(proxyWeapon);
|
||||
|
||||
PREP(reload_actionsLoad);
|
||||
PREP(reload_actionsUnload);
|
||||
PREP(getLoadActions);
|
||||
PREP(getUnloadActions);
|
||||
PREP(reload_canLoadMagazine);
|
||||
PREP(reload_canUnloadMagazine);
|
||||
PREP(reload_getLoadableMagazines);
|
||||
@ -33,5 +32,5 @@ PREP(reload_handleRemoveTurretMag);
|
||||
PREP(reload_handleReturnAmmo);
|
||||
PREP(reload_loadMagazine);
|
||||
|
||||
PREP(staticWeaponInit);
|
||||
PREP(initVehicle);
|
||||
PREP(staticWeaponInit_unloadExtraMags);
|
||||
|
@ -6,18 +6,27 @@ GVAR(vehicleMagCache) = createHashMap;
|
||||
TRACE_3("settingsInit",GVAR(defaultAssemblyMode),GVAR(handleExtraMagazines),GVAR(ammoHandling));
|
||||
["StaticWeapon", "Init", {
|
||||
// needs a small delay for network syncing, or we end up with duplicate mags with ammo handling
|
||||
[LINKFUNC(staticWeaponInit), _this, 1] call CBA_fnc_waitAndExecute;
|
||||
[LINKFUNC(initVehicle), _this, 1] call CBA_fnc_waitAndExecute;
|
||||
}, true, [], true] call CBA_fnc_addClassEventHandler;
|
||||
|
||||
GVAR(quickmountEnabled) = (
|
||||
missionNamespace getVariable [QEGVAR(quickmount,enabled), false] &&
|
||||
{(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1,3]}
|
||||
);
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
["CBA_SettingChanged", {
|
||||
GVAR(quickmountEnabled) = (
|
||||
missionNamespace getVariable [QEGVAR(quickmount,enabled), false] &&
|
||||
{(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1,3]}
|
||||
);
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
// Event handlers:
|
||||
[QGVAR(addTurretMag), LINKFUNC(reload_handleAddTurretMag)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(removeTurretMag), LINKFUNC(reload_handleRemoveTurretMag)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(returnAmmo), LINKFUNC(reload_handleReturnAmmo)] call CBA_fnc_addEventHandler;
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
call compile preprocessFileLineNumbers QPATHTOF(dev\checkStaticWeapons.sqf);
|
||||
#endif
|
||||
|
@ -7,14 +7,14 @@ INFO("Checking static weapons");
|
||||
|
||||
private _staticWeaponConfigs = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(configName _x) isKindOf 'StaticWeapon'}", true];
|
||||
private _staticPublic = _staticWeaponConfigs select {(getNumber (_x >> "scope")) == 2};
|
||||
INFO_2("Static Weapons [%1] - CSW Enabled [%2]",count _staticPublic,{(getNumber (_x >> "ace_csw" >> "enabled")) == 1} count _staticPublic);
|
||||
INFO_2("Static Weapons [%1] - CSW Enabled [%2]",count _staticPublic,{(getNumber (_x >> QUOTE(ADDON) >> "enabled")) == 1} count _staticPublic);
|
||||
|
||||
INFO("------ Checking static weapons inheritance ------");
|
||||
private _explicitBases = [];
|
||||
private _inherited = [];
|
||||
{
|
||||
private _config = _x;
|
||||
private _configEnabled = (getNumber (_config >> "ace_csw" >> "enabled")) == 1;
|
||||
private _configEnabled = (getNumber (_config >> QUOTE(ADDON) >> "enabled")) == 1;
|
||||
if (_configEnabled) then {
|
||||
private _configExplicit = (count configProperties [_config, "configName _x == 'ace_csw'", false]) == 1;
|
||||
if (_configExplicit) then {
|
||||
@ -69,7 +69,7 @@ private _logAll = false;
|
||||
|
||||
{
|
||||
//IGNORE_PRIVATE_WARNING ["_x", "_y"];
|
||||
INFO_2("[%1] has no carry varient - Used in %2",_x,_y);
|
||||
INFO_2("[%1] has no carry variant - Used in %2",_x,_y);
|
||||
} forEach _hash;
|
||||
|
||||
INFO("------ End -------");
|
||||
|
@ -12,12 +12,12 @@
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_staticWeapon", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"];
|
||||
TRACE_8("firedEH:",_staticWeapon,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_gunner);
|
||||
params ["_vehicle", "_weapon", "", "", "", "_magazine", "", "_gunner"];
|
||||
TRACE_4("firedEH:",_vehicle,_weapon,_magazine,_gunner);
|
||||
|
||||
if (someAmmo _vehicle) exitWith {};
|
||||
if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {};
|
||||
if (someAmmo _staticWeapon) exitWith {};
|
||||
|
||||
TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon);
|
||||
TRACE_1("need ammo",magazinesAllTurrets _vehicle);
|
||||
|
||||
[_staticWeapon, _gunner, _weapon, _magazine] call FUNC(ai_reload);
|
||||
[_vehicle, _gunner, _weapon, _magazine] call FUNC(ai_reload);
|
||||
|
@ -11,12 +11,13 @@
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params ["_staticWeapon", "_role", "_gunner"];
|
||||
TRACE_3("getInEH:",_staticWeapon,_role,_gunner);
|
||||
|
||||
params ["_vehicle", "", "_gunner"];
|
||||
TRACE_2("getInEH:",_vehicle,_gunner);
|
||||
|
||||
if (someAmmo _vehicle) exitWith {};
|
||||
if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {};
|
||||
if (someAmmo _staticWeapon) exitWith {};
|
||||
|
||||
TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon);
|
||||
TRACE_1("need ammo",magazinesAllTurrets _vehicle);
|
||||
|
||||
[_staticWeapon, _gunner, currentWeapon _staticWeapon] call FUNC(ai_reload);
|
||||
[_vehicle, _gunner, currentWeapon _vehicle] call FUNC(ai_reload);
|
||||
|
@ -14,6 +14,7 @@
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_staticWeapon", "_gunner", "_weapon", ["_magazine", ""]];
|
||||
|
||||
private _turretPath = [_gunner] call EFUNC(common,getTurretIndex);
|
||||
|
@ -1,21 +0,0 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* Checks if the player can deploy the tripod.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can deploy <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [player] call ace_csw_fnc_assemble_canDeployTripod
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_player"];
|
||||
|
||||
(getText(configFile >> "CfgWeapons" >> (secondaryWeapon _player) >> QUOTE(ADDON) >> "type") == "mount")
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* Author: tcvm
|
||||
* Checks if you can deploy a weapon on the tripod
|
||||
*
|
||||
* Arguments:
|
||||
@ -22,4 +22,3 @@ if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapo
|
||||
// If the current launcher has a config-value that defines the tripod, it is a CSW
|
||||
(alive _target) &&
|
||||
{(getText(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> (typeOf _target))) != ""}
|
||||
|
||||
|
@ -1,22 +0,0 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* Checks if the player can pick-up the tripod.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Tripod <OBJECT>
|
||||
* 1: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can pickup <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [tripod, player] call ace_csw_fnc_assemble_canPickupTripod
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_tripod", "_player"];
|
||||
|
||||
((secondaryWeapon _player) isEqualTo "") && {alive _tripod}
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* Author: tcvm
|
||||
* If the CSW is mounted or in use this will not allow you to dismount the weapon
|
||||
*
|
||||
* Arguments:
|
||||
@ -23,4 +23,3 @@ private _notCrewed = (crew _staticWeapon) isEqualTo [];
|
||||
private _deadCrew = !(alive (gunner _staticWeapon)); // need to eject body???
|
||||
|
||||
_assemblyMode && {_notCrewed || _deadCrew}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* Author: tcvm
|
||||
* Deploys the tripod
|
||||
*
|
||||
* Arguments:
|
||||
@ -40,7 +40,7 @@
|
||||
_cswTripod setVariable [QGVAR(secondaryWeaponMagazine), _secondaryWeaponMagazine];
|
||||
};
|
||||
if (!GVAR(defaultAssemblyMode)) then {
|
||||
[_cswTripod, "disableWeaponAssembly", "ace_csw", true] call EFUNC(common,statusEffect_set);
|
||||
[_cswTripod, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
};
|
||||
|
||||
private _posATL = _player getRelPos [2, 0];
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* Author: tcvm
|
||||
* Deploys the current CSW
|
||||
*
|
||||
* Arguments:
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* Author: tcvm
|
||||
* Picks up the tripod and adds it to the player launcher slot
|
||||
*
|
||||
* Arguments:
|
||||
@ -44,4 +44,3 @@
|
||||
TRACE_3("",_pickupTime,typeOf _tripod,_tripodClassname);
|
||||
[TIME_PROGRESSBAR(_pickupTime), [_tripod, _player, _tripodClassname], _onFinish, {}, localize LSTRING(PickupTripod_progressBar), _condition] call EFUNC(common,progressBar);
|
||||
}, _this] call CBA_fnc_execNextFrame;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* Author: tcvm
|
||||
* Dismounts the weapon from the tripod and drops its backpack beside
|
||||
*
|
||||
* Arguments:
|
||||
|
22
addons/csw/functions/fnc_canDeployTripod.sqf
Normal file
22
addons/csw/functions/fnc_canDeployTripod.sqf
Normal file
@ -0,0 +1,22 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: tcvm
|
||||
* Checks if the unit can deploy a tripod
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can deploy <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* player call ace_csw_fnc_canDeployTripod
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_unit"];
|
||||
|
||||
private _secondaryWeapon = secondaryWeapon _unit;
|
||||
|
||||
_secondaryWeapon != "" && {getText (configFile >> "CfgWeapons" >> _secondaryWeapon >> QUOTE(ADDON) >> "type") == "mount"} // return
|
@ -1,28 +1,23 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* Checks if the player can get in the weapon
|
||||
* Author: tcvm
|
||||
* Checks if it's possible to get in the CSW
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Static Weapon <OBJECT>
|
||||
* 0: Vehicle <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject] call ace_csw_fnc_canGetIn
|
||||
* cursorObject call ace_csw_fnc_canGetIn
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
// hide this action if quick mount is enabled
|
||||
if ((missionNamespace getVariable [QEGVAR(quickmount,enabled), false]) && {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1, 3]}) exitWith {
|
||||
false
|
||||
};
|
||||
// Hide this action if quick mount is enabled
|
||||
if (GVAR(quickmountEnabled)) exitWith {false};
|
||||
|
||||
params ["_staticWeapon"];
|
||||
params ["_vehicle"];
|
||||
|
||||
alive _staticWeapon
|
||||
&& {!(alive (gunner _staticWeapon))}
|
||||
&& {(locked _staticWeapon) < 2}
|
||||
&& {0.3 < ((vectorUp _staticWeapon) select 2)}
|
||||
alive _vehicle && {!(alive (gunner _vehicle))} && {(locked _vehicle) < 2} && {!(_vehicle lockedTurret [0])} && {0.3 < ((vectorUp _vehicle) select 2)} // return
|
||||
|
21
addons/csw/functions/fnc_canPickupTripod.sqf
Normal file
21
addons/csw/functions/fnc_canPickupTripod.sqf
Normal file
@ -0,0 +1,21 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: tcvm
|
||||
* Checks if the unit can pickup the tripod
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Tripod <OBJECT>
|
||||
* 1: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Can pickup <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject, player] call ace_csw_fnc_canPickupTripod
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_tripod", "_unit"];
|
||||
|
||||
((secondaryWeapon _unit) == "") && {alive _tripod} // return
|
@ -1,24 +0,0 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* An action for the player to get in the CSW
|
||||
* Due to the fact that the default static weapons "Get In" memory point is at the front of
|
||||
* the gun and can't be acssesed from the back, I am implementing this to get around that issue.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Static Weapon <OBJECT>
|
||||
* 1: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject, player] call ace_csw_fnc_getIn
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_staticWeapon", "_player"];
|
||||
TRACE_2("getIn",_staticWeapon,_player);
|
||||
|
||||
_player moveInTurret [_staticWeapon, [0]];
|
@ -1,42 +1,42 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Gets sub actions for what the player can load into the static weapon
|
||||
* Gets sub actions for what the unit can load into the CSW
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Static Weapon <OBJECT>
|
||||
* 1: Player <OBJECT>
|
||||
* 0: Vehicle <OBJECT>
|
||||
* 1: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Actions <ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject, player] call ace_csw_fnc_reload_actionsLoad
|
||||
* [cursorObject, player] call ace_csw_fnc_getLoadActions
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_vehicle", "_player"];
|
||||
params ["_vehicle", "_unit"];
|
||||
|
||||
private _actions = [];
|
||||
private _loadableMagazines = [_vehicle, _player] call FUNC(reload_getLoadableMagazines);
|
||||
private _loadableMagazines = [_vehicle, _unit] call FUNC(reload_getLoadableMagazines);
|
||||
if (_loadableMagazines isEqualTo []) exitWith {[]};
|
||||
|
||||
private _statement = {
|
||||
params ["_target", "_player", "_params"];
|
||||
_params params ["_carryMag", "_turretPath", "", "_magSource"];
|
||||
params ["_target", "_player", "_args"];
|
||||
_args params ["_carryMag", "_turretPath", "", "_magSource"];
|
||||
|
||||
[_target, _turretPath, _carryMag, _magSource, _player] call FUNC(reload_loadMagazine);
|
||||
};
|
||||
|
||||
private _condition = {
|
||||
params ["_target", "_player", "_params"];
|
||||
_params params ["_carryMag", "_turretPath", "", "_magSource"];
|
||||
params ["_target", "_player", "_args"];
|
||||
_args params ["_carryMag", "_turretPath", "", "_magSource"];
|
||||
|
||||
([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0
|
||||
};
|
||||
|
||||
private _cfgMagazines = configFile >> "CfgMagazines"; // micro-optimization
|
||||
|
||||
private _actions = [];
|
||||
{
|
||||
_x params ["_carryMag", "", "_loadInfo"];
|
||||
_loadInfo params ["", "", "", "_isBeltLinking"];
|
74
addons/csw/functions/fnc_getUnloadActions.sqf
Normal file
74
addons/csw/functions/fnc_getUnloadActions.sqf
Normal file
@ -0,0 +1,74 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Gets sub actions for what can be unloaded from the CSW
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Vehicle <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Actions <ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* cursorObject call ace_csw_fnc_getUnloadActions
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_vehicle"];
|
||||
|
||||
private _statement = {
|
||||
params ["_target", "_player", "_args"];
|
||||
_args params ["_vehMag", "_turretPath", "_carryMag"];
|
||||
TRACE_5("starting unload",_target,_turretPath,_player,_carryMag,_vehMag);
|
||||
|
||||
private _timeToUnload = 1;
|
||||
if (!isNull (configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime")) then {
|
||||
_timeToUnload = getNumber (configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime");
|
||||
};
|
||||
|
||||
[
|
||||
TIME_PROGRESSBAR(_timeToUnload),
|
||||
[_target, _turretPath, _player, _carryMag, _vehMag],
|
||||
{
|
||||
(_this select 0) params ["_target", "_turretPath", "", "_carryMag", "_vehMag"];
|
||||
TRACE_5("unload progressBar finish",_target,_turretPath,_carryMag,_vehMag,_player);
|
||||
[QGVAR(removeTurretMag), [_target, _turretPath, _carryMag, _vehMag, _player]] call CBA_fnc_globalEvent;
|
||||
},
|
||||
{TRACE_1("unload progressBar fail",_this);},
|
||||
format [localize LSTRING(unloadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")],
|
||||
{(_this select 0) call FUNC(reload_canUnloadMagazine)},
|
||||
["isNotInside"]
|
||||
] call EFUNC(common,progressBar);
|
||||
};
|
||||
|
||||
private _condition = {
|
||||
params ["_target", "_player", "_args"];
|
||||
_args params ["_vehMag", "_turretPath", "_carryMag"];
|
||||
[_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine)
|
||||
};
|
||||
|
||||
private _actions = [];
|
||||
private _handledMagTypes = [];
|
||||
|
||||
private _cfgMagazines = configFile >> "CfgMagazines";
|
||||
|
||||
// Go through magazines on static weapon and check if any are unloadable
|
||||
{
|
||||
_x params ["_xMag", "_xTurret", "_xAmmo"];
|
||||
|
||||
if ((_xAmmo > 0) && {!(_xMag in _handledMagTypes)}) then {
|
||||
_handledMagTypes pushBack _xMag;
|
||||
private _carryMag = _xMag call FUNC(getCarryMagazine);
|
||||
if (_carryMag == "") exitWith {};
|
||||
|
||||
private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName");
|
||||
private _text = format [LLSTRING(unloadX), _displayName];
|
||||
private _picture = getText (_cfgMagazines >> _carryMag >> "picture");
|
||||
private _action = [format ["unload_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, [_xMag, _xTurret, _carryMag]] call EFUNC(interact_menu,createAction);
|
||||
_actions pushBack [_action, [], _vehicle];
|
||||
};
|
||||
} forEach (magazinesAllTurrets _vehicle);
|
||||
|
||||
TRACE_1("unloadActions",count _actions);
|
||||
_actions
|
@ -1,59 +1,63 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: tcvm
|
||||
* Initializes weapon to disable weapon disassembling
|
||||
* Initializes CSW systems on vehicle
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Weapon <OBJECT>
|
||||
* 0: Vehicle <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [weapon] call ace_csw_fnc_staticWeaponInit
|
||||
* cursorObject call ace_csw_fnc_initVehicle
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_staticWeapon"];
|
||||
if (isNull _staticWeapon) exitWith { WARNING_1("%1 became null",_staticWeapon) };
|
||||
private _typeOf = typeOf _staticWeapon;
|
||||
private _configOf = configOf _staticWeapon;
|
||||
private _configEnabled = (getNumber (_configOf >> "ace_csw" >> "enabled")) == 1;
|
||||
private _assemblyConfig = _configEnabled && {(getText (_configOf >> "ace_csw" >> "disassembleWeapon")) != ""};
|
||||
TRACE_4("staticWeaponInit",_staticWeapon,_typeOf,_configEnabled,_assemblyConfig);
|
||||
|
||||
if (_configEnabled && {GVAR(ammoHandling) == 2}) then {
|
||||
TRACE_1("adding AI fired handler",_staticWeapon);
|
||||
_staticWeapon addEventHandler ["Fired", LINKFUNC(ai_handleFired)];
|
||||
_staticWeapon addEventHandler ["GetIn", LINKFUNC(ai_handleGetIn)]; // handle AI getting inside weapon with no ammo
|
||||
params ["_vehicle"];
|
||||
if (!alive _vehicle) exitWith { WARNING_1("%1 not alive",_vehicle); };
|
||||
if (!simulationEnabled _vehicle) exitWith {
|
||||
[{simulationEnabled _this}, FUNC(initVehicle), _vehicle] call CBA_fnc_waitUntilAndExecute;
|
||||
};
|
||||
|
||||
TRACE_2("",local _staticWeapon,_staticWeapon turretLocal [0]);
|
||||
if (_configEnabled && {_staticWeapon turretLocal [0]}) then { // if turret is local to us, then handle mags/weapon
|
||||
private _typeOf = typeOf _vehicle;
|
||||
private _configOf = configOf _vehicle;
|
||||
private _configEnabled = (getNumber (_configOf >> QUOTE(ADDON) >> "enabled")) == 1;
|
||||
private _assemblyConfig = _configEnabled && {(getText (_configOf >> QUOTE(ADDON) >> "disassembleWeapon")) != ""};
|
||||
TRACE_4("initVehicle",_vehicle,_typeOf,_configEnabled,_assemblyConfig);
|
||||
|
||||
if (_configEnabled && {GVAR(ammoHandling) == 2}) then {
|
||||
TRACE_1("adding AI fired handler",_vehicle);
|
||||
_vehicle addEventHandler ["Fired", LINKFUNC(ai_handleFired)];
|
||||
_vehicle addEventHandler ["GetIn", LINKFUNC(ai_handleGetIn)]; // handle AI getting inside weapon with no ammo
|
||||
};
|
||||
|
||||
TRACE_2("",local _vehicle,_vehicle turretLocal [0]);
|
||||
if (_configEnabled && {_vehicle turretLocal [0]}) then { // if turret is local to us, then handle mags/weapon
|
||||
[{
|
||||
params ["_staticWeapon"];
|
||||
if (!alive _staticWeapon) exitWith { TRACE_1("dead/deleted",_staticWeapon); };
|
||||
params ["_vehicle"];
|
||||
if (!alive _vehicle) exitWith { TRACE_1("dead/deleted",_vehicle); };
|
||||
// Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default]
|
||||
private _assemblyModeIndex = _staticWeapon getVariable [QGVAR(assemblyMode), 3];
|
||||
private _assemblyModeIndex = _vehicle getVariable [QGVAR(assemblyMode), 3];
|
||||
private _emptyWeapon = _assemblyModeIndex isEqualTo 2;
|
||||
private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select _assemblyModeIndex;
|
||||
TRACE_2("turretLocal",_staticWeapon,_assemblyMode);
|
||||
[_staticWeapon, [0], _assemblyMode, _emptyWeapon] call FUNC(proxyWeapon);
|
||||
[_staticWeapon, _assemblyMode, _emptyWeapon] call FUNC(staticWeaponInit_unloadExtraMags);
|
||||
}, [_staticWeapon]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly
|
||||
TRACE_2("turretLocal",_vehicle,_assemblyMode);
|
||||
[_vehicle, [0], _assemblyMode, _emptyWeapon] call FUNC(proxyWeapon);
|
||||
[_vehicle, _assemblyMode, _emptyWeapon] call FUNC(staticWeaponInit_unloadExtraMags);
|
||||
}, [_vehicle]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly
|
||||
};
|
||||
|
||||
if (_assemblyConfig) then {
|
||||
[{
|
||||
params ["_staticWeapon"];
|
||||
if (!alive _staticWeapon) exitWith { TRACE_1("dead/deleted",_staticWeapon); };
|
||||
private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 3]);
|
||||
TRACE_2("assemblyConfig present",_staticWeapon,_assemblyMode);
|
||||
params ["_vehicle"];
|
||||
if (!alive _vehicle) exitWith { TRACE_1("dead/deleted",_vehicle); };
|
||||
private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_vehicle getVariable [QGVAR(assemblyMode), 3]);
|
||||
TRACE_2("assemblyConfig present",_vehicle,_assemblyMode);
|
||||
if (_assemblyMode) then { // Disable vanilla assembly if assemblyMode enabled
|
||||
[_staticWeapon, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
[_vehicle, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
};
|
||||
}, [_staticWeapon]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly
|
||||
}, [_vehicle]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly
|
||||
};
|
||||
|
||||
// Add interactions for players
|
||||
@ -76,7 +80,7 @@ if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then {
|
||||
};
|
||||
private _childenCode = {
|
||||
BEGIN_COUNTER(getActions); // can remove for final release
|
||||
private _ret = (call FUNC(reload_actionsLoad)) + (call FUNC(reload_actionsUnload));
|
||||
private _ret = (call FUNC(getLoadActions)) + (call FUNC(getUnloadActions));
|
||||
END_COUNTER(getActions);
|
||||
_ret
|
||||
};
|
@ -1,10 +1,10 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: tcvm, PabstMirror
|
||||
* Handles the use of proxy weapons to fix engine-reload times
|
||||
* Handles the use of proxy weapons to bypass engine reload times
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Weapon <OBJECT>
|
||||
* 0: Vehicle <OBJECT>
|
||||
* 1: Turret <ARRAY>
|
||||
* 2: Proxy weapon needed <BOOL>
|
||||
* 2: Weapon should be emptied <BOOL>
|
||||
@ -13,34 +13,34 @@
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [weapon, [0], true, false] call ace_csw_fnc_proxyWeapon
|
||||
* [cursorObject, [0], true, false] call ace_csw_fnc_proxyWeapon
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_staticWeapon", "_turret", "_needed", "_emptyWeapon"];
|
||||
TRACE_4("proxyWeapon",_staticWeapon,_turret,_needed,_emptyWeapon);
|
||||
params ["_vehicle", "_turret", "_needed", "_emptyWeapon"];
|
||||
TRACE_4("proxyWeapon",_vehicle,_turret,_needed,_emptyWeapon);
|
||||
|
||||
if (_staticWeapon getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _staticWeapon); };
|
||||
if (_vehicle getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _vehicle); };
|
||||
|
||||
private _proxyWeapon = getText (configOf _staticWeapon >> "ace_csw" >> "proxyWeapon");
|
||||
private _proxyWeapon = getText (configOf _vehicle >> QUOTE(ADDON) >> "proxyWeapon");
|
||||
|
||||
TRACE_2("",typeOf _staticWeapon,_proxyWeapon);
|
||||
TRACE_2("",typeOf _vehicle,_proxyWeapon);
|
||||
if (_proxyWeapon == "") exitWith {};
|
||||
|
||||
private _currentWeapon = (_staticWeapon weaponsTurret [0]) param [0, "#none"];
|
||||
private _currentWeapon = (_vehicle weaponsTurret [0]) param [0, "#none"];
|
||||
if ((missionNamespace getVariable [_proxyWeapon, objNull]) isEqualType {}) then { // check if string is a function
|
||||
TRACE_1("Calling proxyWeapon function",_proxyWeapon);
|
||||
// This function may replace magazines or do other things to the static weapon
|
||||
_proxyWeapon = [_staticWeapon, _turret, _currentWeapon, _needed, _emptyWeapon] call (missionNamespace getVariable _proxyWeapon);
|
||||
_proxyWeapon = [_vehicle, _turret, _currentWeapon, _needed, _emptyWeapon] call (missionNamespace getVariable _proxyWeapon);
|
||||
_needed = _proxyWeapon != "";
|
||||
};
|
||||
if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); };
|
||||
|
||||
// Rearm compatibility, prevent reloading entire static and breaking CSW
|
||||
_staticWeapon setVariable [QEGVAR(rearm,scriptedLoadout), true, true];
|
||||
_vehicle setVariable [QEGVAR(rearm,scriptedLoadout), true, true];
|
||||
|
||||
TRACE_2("swapping to proxy weapon",_currentWeapon,_proxyWeapon);
|
||||
_staticWeapon removeWeaponTurret [_currentWeapon, _turret];
|
||||
_staticWeapon addWeaponTurret [_proxyWeapon, _turret];
|
||||
_staticWeapon setVariable [format [QGVAR(proxyHandled_%1), _turret], true, true];
|
||||
_vehicle removeWeaponTurret [_currentWeapon, _turret];
|
||||
_vehicle addWeaponTurret [_proxyWeapon, _turret];
|
||||
_vehicle setVariable [format [QGVAR(proxyHandled_%1), _turret], true, true];
|
||||
|
@ -1,75 +0,0 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Gets sub actions for what the player can unload from the static weapon
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Target <OBJECT>
|
||||
* 1: Player <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Actions <ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject, player] call ace_csw_fnc_reload_actionsUnload
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_vehicle", "_player"];
|
||||
|
||||
private _statement = {
|
||||
params ["_target", "_player", "_params"];
|
||||
_params params ["_vehMag", "_turretPath", "_carryMag"];
|
||||
TRACE_5("starting unload",_target,_turretPath,_player,_carryMag,_vehMag);
|
||||
|
||||
private _timeToUnload = 1;
|
||||
if (!isNull(configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime")) then {
|
||||
_timeToUnload = getNumber(configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime");
|
||||
};
|
||||
|
||||
[
|
||||
TIME_PROGRESSBAR(_timeToUnload),
|
||||
[_target, _turretPath, _player, _carryMag, _vehMag],
|
||||
{
|
||||
(_this select 0) params ["_target", "_turretPath", "", "_carryMag", "_vehMag"];
|
||||
TRACE_5("unload progressBar finish",_target,_turretPath,_carryMag,_vehMag,_player);
|
||||
[QGVAR(removeTurretMag), [_target, _turretPath, _carryMag, _vehMag, _player]] call CBA_fnc_globalEvent;
|
||||
},
|
||||
{TRACE_1("unload progressBar fail",_this);},
|
||||
format [localize LSTRING(unloadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")],
|
||||
{(_this select 0) call FUNC(reload_canUnloadMagazine)},
|
||||
["isNotInside"]
|
||||
] call EFUNC(common,progressBar);
|
||||
};
|
||||
|
||||
private _condition = {
|
||||
params ["_target", "_player", "_params"];
|
||||
_params params ["_vehMag", "_turretPath", "_carryMag"];
|
||||
[_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine)
|
||||
};
|
||||
|
||||
private _actions = [];
|
||||
private _handeledMagTypes = [];
|
||||
|
||||
private _cfgMagazines = configFile >> "CfgMagazines";
|
||||
|
||||
// Go through magazines on static weapon and check if any are unloadable
|
||||
{
|
||||
_x params ["_xMag", "_xTurret", "_xAmmo"];
|
||||
|
||||
if ((_xAmmo > 0) && {!(_xMag in _handeledMagTypes)}) then {
|
||||
_handeledMagTypes pushBack _xMag;
|
||||
private _carryMag = _xMag call FUNC(getCarryMagazine);
|
||||
if (_carryMag == "") exitWith {};
|
||||
|
||||
private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName");
|
||||
private _text = format [LLSTRING(unloadX), _displayName];
|
||||
private _picture = getText (_cfgMagazines >> _carryMag >> "picture");
|
||||
private _action = [format ["unload_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, [_xMag, _xTurret, _carryMag]] call EFUNC(interact_menu,createAction);
|
||||
_actions pushBack [_action, [], _vehicle];
|
||||
};
|
||||
} forEach (magazinesAllTurrets _vehicle);
|
||||
|
||||
TRACE_1("unloadActions",count _actions);
|
||||
_actions
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm, PabstMirror
|
||||
* Author: tcvm, PabstMirror
|
||||
* Handles adding ammo to a turret
|
||||
* Called from a global event but only runs where turret is local
|
||||
*
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author:tcvm
|
||||
* Author: tcvm
|
||||
* Handles removing ammo from a turret
|
||||
* Called from a global event but only runs where turret is local
|
||||
*
|
||||
|
@ -21,5 +21,4 @@ params ["_target", "_unit"];
|
||||
&& {!alive (gunner _target)}
|
||||
&& {!(_target getVariable [QGVAR(fired), false])}
|
||||
&& {!(_target getVariable [QGVAR(sightAttached), ((typeOf _target) == QGVAR(staticAssembled))])}
|
||||
&& EFUNC(csw,assemble_canPickupTripod)
|
||||
|
||||
&& EFUNC(csw,canPickupTripod)
|
||||
|
@ -10,6 +10,7 @@ PREP(cancelPlacement);
|
||||
PREP(canDefuse);
|
||||
PREP(canDetonate);
|
||||
PREP(connectExplosive);
|
||||
PREP(cycleActiveTrigger);
|
||||
PREP(defuseExplosive);
|
||||
PREP(detonateExplosive);
|
||||
PREP(detonateExplosiveAll);
|
||||
|
@ -8,8 +8,11 @@ PREP_RECOMPILE_START;
|
||||
#include "XEH_PREP.hpp"
|
||||
PREP_RECOMPILE_END;
|
||||
|
||||
#include "initKeybinds.inc.sqf"
|
||||
#include "initSettings.inc.sqf"
|
||||
|
||||
GVAR(activeTrigger) = "";
|
||||
|
||||
GVAR(detonationHandlers) = [];
|
||||
GVAR(excludedMines) = [];
|
||||
|
||||
|
@ -49,18 +49,43 @@ private _explosivesList = [];
|
||||
};
|
||||
};
|
||||
} forEach _result;
|
||||
if (_detonator != "ACE_DeadManSwitch") then {
|
||||
// Add action to detonate all explosives tied to the detonator
|
||||
if (count _explosivesList > 0) then {
|
||||
_children pushBack [
|
||||
|
||||
// If the detonator is not active, is a clacker and has assigned explosives, generate an interaction to make it the active detonator for use with the "trigger all" keybind
|
||||
if (
|
||||
_detonator != GVAR(activeTrigger) &&
|
||||
{_detonator != "Cellphone"} &&
|
||||
{
|
||||
_explosivesList isNotEqualTo [] ||
|
||||
{_detonator == "ACE_DeadManSwitch" && {_unit getVariable [QGVAR(deadmanInvExplosive), ""] != ""}}
|
||||
}
|
||||
) then {
|
||||
_children pushBack [
|
||||
[
|
||||
"Explosive_All",
|
||||
localize LSTRING(DetonateAll),
|
||||
getText(ConfigFile >> "CfgWeapons" >> _detonator >> "picture"),
|
||||
{(_this select 2) call FUNC(detonateExplosiveAll);},
|
||||
QGVAR(setActiveTrigger),
|
||||
LLSTRING(SetActiveTrigger),
|
||||
"",
|
||||
{GVAR(activeTrigger) = (_this select 2) select 0;},
|
||||
{true},
|
||||
{},
|
||||
[_unit,_range,_explosivesList, _detonator]
|
||||
[_detonator]
|
||||
] call EFUNC(interact_menu,createAction),
|
||||
[],
|
||||
_unit
|
||||
];
|
||||
};
|
||||
|
||||
if (_detonator != "ACE_DeadManSwitch") then {
|
||||
// Add action to detonate all explosives tied to the detonator
|
||||
if (count _explosivesList > 1) then {
|
||||
_children pushBack [
|
||||
[
|
||||
"Explosive_All",
|
||||
LLSTRING(DetonateAll),
|
||||
getText (configFile >> "CfgWeapons" >> _detonator >> "picture"),
|
||||
{(_this select 2) call FUNC(detonateExplosiveAll);},
|
||||
{true},
|
||||
{},
|
||||
[_unit, _range, _explosivesList, _detonator]
|
||||
] call EFUNC(interact_menu,createAction),
|
||||
[],
|
||||
_unit
|
||||
@ -69,15 +94,15 @@ if (_detonator != "ACE_DeadManSwitch") then {
|
||||
} else {
|
||||
//Add action to detonate all explosives (including the inventory explosive):
|
||||
_children pushBack [
|
||||
[
|
||||
"Explosive_All_Deadman",
|
||||
localize LSTRING(DetonateAll),
|
||||
getText(ConfigFile >> "CfgWeapons" >> _detonator >> "picture"),
|
||||
{[_player] call FUNC(onIncapacitated)},
|
||||
{true}
|
||||
] call EFUNC(interact_menu,createAction),
|
||||
[],
|
||||
_unit
|
||||
[
|
||||
"Explosive_All_Deadman",
|
||||
LLSTRING(DetonateAll),
|
||||
getText (configFile >> "CfgWeapons" >> _detonator >> "picture"),
|
||||
{[_player] call FUNC(onIncapacitated)},
|
||||
{true}
|
||||
] call EFUNC(interact_menu,createAction),
|
||||
[],
|
||||
_unit
|
||||
];
|
||||
|
||||
//Adds actions for the explosives you can connect to the deadman switch.
|
||||
@ -89,7 +114,7 @@ if (_detonator != "ACE_DeadManSwitch") then {
|
||||
|
||||
_connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""];
|
||||
if (_connectedInventoryExplosive != "") then {
|
||||
//Add the disconect action
|
||||
//Add the disconnect action
|
||||
private _magConfig = configFile >> "CfgMagazines" >> _connectedInventoryExplosive;
|
||||
private _name = if ((getText (_magConfig >> "displayNameShort")) != "") then {
|
||||
getText (_magConfig >> "displayNameShort")
|
||||
@ -99,17 +124,20 @@ if (_detonator != "ACE_DeadManSwitch") then {
|
||||
private _picture = getText (_magConfig >> "picture");
|
||||
|
||||
_children pushBack [
|
||||
([
|
||||
"Deadman_disconnect",
|
||||
format ["%1 %2", localize "str_disp_disconnect", _name],
|
||||
_picture,
|
||||
{
|
||||
params ["_player"];
|
||||
TRACE_1("clear",_player);
|
||||
_player setVariable [QGVAR(deadmanInvExplosive), "", true];
|
||||
},
|
||||
{true}
|
||||
] call EFUNC(interact_menu,createAction)), [], _unit];
|
||||
([
|
||||
"Deadman_disconnect",
|
||||
format ["%1 %2", localize "str_disp_disconnect", _name],
|
||||
_picture,
|
||||
{
|
||||
params ["_player"];
|
||||
TRACE_1("clear",_player);
|
||||
_player setVariable [QGVAR(deadmanInvExplosive), "", true];
|
||||
},
|
||||
{true}
|
||||
] call EFUNC(interact_menu,createAction)),
|
||||
[],
|
||||
_unit
|
||||
];
|
||||
|
||||
} else {
|
||||
//Add all magazines that would work with the deadman switch
|
||||
|
53
addons/explosives/functions/fnc_cycleActiveTrigger.sqf
Normal file
53
addons/explosives/functions/fnc_cycleActiveTrigger.sqf
Normal file
@ -0,0 +1,53 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: mrschick
|
||||
* Cycles the "Active Trigger" of a unit and shows a CBA Hint that displays the new Active Trigger.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [ACE_player] call ace_explosives_fnc_cycleActiveTrigger;
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_unit"];
|
||||
TRACE_1("params",_unit);
|
||||
|
||||
private _detonators = _unit call FUNC(getDetonators);
|
||||
|
||||
// Remove ACE_Cellphone from list, as it should never be the active trigger due to having its own keybind
|
||||
_detonators deleteAt (_detonators findIf {_x == "ACE_Cellphone"});
|
||||
|
||||
// Reset Active Trigger if none available
|
||||
if (_detonators isEqualTo []) exitWith {
|
||||
GVAR(activeTrigger) = "";
|
||||
};
|
||||
|
||||
private _activeTrigger = GVAR(activeTrigger);
|
||||
private _index = _detonators findIf {_x == _activeTrigger};
|
||||
private _count = count _detonators;
|
||||
|
||||
if (_activeTrigger != "" && {_index != -1} && {_count > 1}) then {
|
||||
// If active trigger is set and among current detonators, switch to the next one
|
||||
if (_index < _count - 1) then {
|
||||
_index = _index + 1;
|
||||
} else {
|
||||
_index = 0;
|
||||
};
|
||||
_activeTrigger = _detonators select _index;
|
||||
} else {
|
||||
// Assign first detonator in list as the active one
|
||||
_activeTrigger = _detonators select 0;
|
||||
};
|
||||
|
||||
GVAR(activeTrigger) = _activeTrigger;
|
||||
private _triggerConfig = configFile >> "CfgWeapons" >> _activeTrigger;
|
||||
private _triggerName = getText (_triggerConfig >> "displayName");
|
||||
private _triggerIcon = getText (_triggerConfig >> "picture");
|
||||
|
||||
[format ["%1: %2", LLSTRING(ActiveTrigger), _triggerName], _triggerIcon] call EFUNC(common,displayTextPicture);
|
@ -22,6 +22,15 @@ TRACE_3("params",_explosive,_magazine,_trigger);
|
||||
|
||||
private _config = ConfigFile >> "ACE_Triggers" >> _trigger;
|
||||
|
||||
// Make selected trigger the active one (for keybind) if it's the first to be connected
|
||||
private _activeTrigger = GVAR(activeTrigger);
|
||||
if (
|
||||
_activeTrigger == "" &&
|
||||
{(["Command", "MK16_Transmitter", "DeadManSwitch"] findIf {_x == _trigger}) != -1}
|
||||
) then {
|
||||
GVAR(activeTrigger) = getArray (_config >> "requires") select 0;
|
||||
};
|
||||
|
||||
// If the onSetup function returns true, it is handled elsewhere
|
||||
if (isText(_config >> "onSetup") && {[_explosive,_magazine] call compile getText (_config >> "onSetup")}) exitWith {
|
||||
TRACE_2("onSetup returned true",_explosive,_trigger);
|
||||
|
50
addons/explosives/initKeybinds.inc.sqf
Normal file
50
addons/explosives/initKeybinds.inc.sqf
Normal file
@ -0,0 +1,50 @@
|
||||
#include "\a3\ui_f\hpp\defineDIKCodes.inc"
|
||||
|
||||
["ACE3 Equipment", QGVAR(openCellphone), LLSTRING(cellphone_displayName), {
|
||||
if (
|
||||
!([ACE_player, "ACE_Cellphone"] call EFUNC(common,hasItem)) ||
|
||||
!([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith))
|
||||
) exitWith {};
|
||||
|
||||
closeDialog 0;
|
||||
createDialog "Rsc_ACE_PhoneInterface";
|
||||
|
||||
true
|
||||
}] call CBA_fnc_addKeybind; // Unbound
|
||||
|
||||
["ACE3 Equipment", QGVAR(detonateActiveClacker), LLSTRING(DetonateAllOnActive), {
|
||||
// Prevent use of keybind while surrendering or captive
|
||||
if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {};
|
||||
|
||||
private _detonator = GVAR(activeTrigger);
|
||||
if (_detonator == "" || !(_detonator in ([ACE_player] call FUNC(getDetonators)))) exitWith {};
|
||||
|
||||
// When using a Dead Man's Switch, skip all other logic and just call fnc_onIncapacitated, since it already handles everything that is required to detonate all connected explosives
|
||||
if (_detonator == "ACE_DeadManSwitch") exitWith {
|
||||
[ACE_player] call FUNC(onIncapacitated);
|
||||
};
|
||||
|
||||
private _range = getNumber (configFile >> "CfgWeapons" >> _detonator >> QGVAR(Range));
|
||||
|
||||
private _explosivesList = [];
|
||||
{
|
||||
if (!isNull (_x select 0)) then {
|
||||
private _required = getArray (configFile >> "ACE_Triggers" >> _x select 4 >> "requires");
|
||||
if (_detonator in _required) then {
|
||||
_explosivesList pushBack _x;
|
||||
};
|
||||
};
|
||||
} forEach ([ACE_player] call FUNC(getPlacedExplosives));
|
||||
|
||||
[ACE_player, _range, _explosivesList, _detonator] call FUNC(detonateExplosiveAll);
|
||||
|
||||
true
|
||||
}] call CBA_fnc_addKeybind; // Unbound
|
||||
|
||||
["ACE3 Equipment", QGVAR(cycleActiveClacker), LLSTRING(CycleActiveTrigger), {
|
||||
if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {};
|
||||
|
||||
[ACE_player] call FUNC(cycleActiveTrigger);
|
||||
|
||||
true
|
||||
}] call CBA_fnc_addKeybind; // Unbound
|
@ -68,6 +68,26 @@
|
||||
<Chinese>引爆全部</Chinese>
|
||||
<Turkish>Hepsini Patlat</Turkish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Explosives_DetonateAllOnActive">
|
||||
<English>Detonate All on Active Clacker</English>
|
||||
<German>Alle auf Standardzünder zünden</German>
|
||||
<Italian>Detona Tutti sul Detonatore Attivo</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Explosives_SetActiveTrigger">
|
||||
<English>Set Active Clacker</English>
|
||||
<German>Als Standardzünder wählen</German>
|
||||
<Italian>Imposta Detonatore Attivo</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Explosives_CycleActiveTrigger">
|
||||
<English>Cycle Active Clacker</English>
|
||||
<German>Standardzünder wechseln</German>
|
||||
<Italian>Cambia Detonatore Attivo</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Explosives_ActiveTrigger">
|
||||
<English>Active Clacker</English>
|
||||
<German>Standardzünder</German>
|
||||
<Italian>Detonatore Attivo</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Explosives_DetonateCode">
|
||||
<English>Explosive code: %1</English>
|
||||
<German>Sprengstoffcode: %1</German>
|
||||
|
@ -3,6 +3,7 @@ PREP(addLaserTarget);
|
||||
PREP(addMapHandler);
|
||||
PREP(dev_drawVisibleLaserTargets);
|
||||
PREP(findLaserSource);
|
||||
PREP(getLaserCode);
|
||||
PREP(handleLaserTargetCreation);
|
||||
PREP(keyLaserCodeChange);
|
||||
PREP(laserOff);
|
||||
@ -13,6 +14,7 @@ PREP(onLaserDesignatorDraw);
|
||||
PREP(rotateVectLine);
|
||||
PREP(rotateVectLineGetMap);
|
||||
PREP(seekerFindLaserSpot);
|
||||
PREP(setLaserCode);
|
||||
PREP(shootCone);
|
||||
PREP(shootRay);
|
||||
PREP(showVehicleHud);
|
||||
|
24
addons/laser/functions/fnc_getLaserCode.sqf
Normal file
24
addons/laser/functions/fnc_getLaserCode.sqf
Normal file
@ -0,0 +1,24 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: johnb43
|
||||
* Gets the laser code of a laser source.
|
||||
*
|
||||
* Argument:
|
||||
* 0: Laser source <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* Laser code <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* player call ace_laser_fnc_getLaserCode;
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [["_laserSource", objNull, [objNull]]];
|
||||
|
||||
if (isNull _laserSource) exitWith {
|
||||
-1
|
||||
};
|
||||
|
||||
_laserSource getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]
|
21
addons/laser/functions/fnc_setLaserCode.sqf
Normal file
21
addons/laser/functions/fnc_setLaserCode.sqf
Normal file
@ -0,0 +1,21 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: johnb43
|
||||
* Sets the laser code on a laser source.
|
||||
*
|
||||
* Argument:
|
||||
* 0: Laser source <OBJECT>
|
||||
* 1: Laser code <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, 1111] call ace_laser_fnc_setLaserCode;
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [["_laserSource", objNull, [objNull]], ["_laserCode", ACE_DEFAULT_LASER_CODE, [0]]];
|
||||
|
||||
_laserSource setVariable [QGVAR(code), _laserCode, true];
|
@ -42,6 +42,7 @@
|
||||
#define GET_ARRAY(config,default) (if (isArray (config)) then {getArray (config)} else {default})
|
||||
|
||||
#define DEFAULT_HEART_RATE 80
|
||||
#define DEFAULT_SPO2 97
|
||||
#define DEFAULT_PERIPH_RES 100
|
||||
|
||||
// --- blood
|
||||
@ -153,6 +154,8 @@
|
||||
#define VAR_WOUND_BLEEDING QEGVAR(medical,woundBleeding)
|
||||
#define VAR_CRDC_ARRST QEGVAR(medical,inCardiacArrest)
|
||||
#define VAR_HEART_RATE QEGVAR(medical,heartRate)
|
||||
#define VAR_SPO2 QEGVAR(medical,spo2)
|
||||
#define VAR_OXYGEN_DEMAND QEGVAR(medical,oxygenDemand)
|
||||
#define VAR_PAIN QEGVAR(medical,pain)
|
||||
#define VAR_PAIN_SUPP QEGVAR(medical,painSuppress)
|
||||
#define VAR_PERIPH_RES QEGVAR(medical,peripheralResistance)
|
||||
@ -175,6 +178,7 @@
|
||||
#define GET_BLOOD_VOLUME(unit) (unit getVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME])
|
||||
#define GET_WOUND_BLEEDING(unit) (unit getVariable [VAR_WOUND_BLEEDING, 0])
|
||||
#define GET_HEART_RATE(unit) (unit getVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE])
|
||||
#define GET_SPO2(unit) (unit getVariable [VAR_SPO2, DEFAULT_SPO2])
|
||||
#define GET_HEMORRHAGE(unit) (unit getVariable [VAR_HEMORRHAGE, 0])
|
||||
#define GET_PAIN(unit) (unit getVariable [VAR_PAIN, 0])
|
||||
#define GET_PAIN_SUPPRESS(unit) (unit getVariable [VAR_PAIN_SUPP, 0])
|
||||
|
@ -32,13 +32,15 @@ if (damage _unit > 0) then {
|
||||
if (_isRespawn) then {
|
||||
TRACE_1("reseting all vars on respawn",_isRespawn); // note: state is handled by ace_medical_statemachine_fnc_resetStateDefault
|
||||
|
||||
// - Blood and heart ----------------------------------------------------------
|
||||
// - Vitals ------------------------------------------------------------------
|
||||
_unit setVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME, true];
|
||||
_unit setVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE, true];
|
||||
_unit setVariable [VAR_BLOOD_PRESS, [80, 120], true];
|
||||
_unit setVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES, true];
|
||||
_unit setVariable [VAR_CRDC_ARRST, false, true];
|
||||
_unit setVariable [VAR_HEMORRHAGE, 0, true];
|
||||
_unit setVariable [VAR_SPO2, DEFAULT_SPO2, true];
|
||||
_unit setVariable [VAR_OXYGEN_DEMAND, 0, true];
|
||||
|
||||
// - Pain ---------------------------------------------------------------------
|
||||
_unit setVariable [VAR_PAIN, 0, true];
|
||||
|
@ -57,9 +57,19 @@ if (_active) then {
|
||||
// Do "Unlock controls" user action, co-pilot will then have to do the "Take Controls" actions
|
||||
_unit action ["UnlockVehicleControl", vehicle _unit];
|
||||
};
|
||||
|
||||
// Disable AI talking (yes, this needs to be explicit)
|
||||
if (!isPlayer _unit && {_unit checkAIFeature "RADIOPROTOCOL"}) then {
|
||||
_unit disableAI "RADIOPROTOCOL";
|
||||
_unit setVariable [QGVAR(reenableRadioProtocol), true, true];
|
||||
};
|
||||
} else {
|
||||
// Unit has woken up, no longer need to track this
|
||||
_unit setVariable [QEGVAR(medical,lastWakeUpCheck), nil];
|
||||
|
||||
if (_unit getVariable [QGVAR(reenableRadioProtocol), false]) then {
|
||||
_unit enableAI "RADIOPROTOCOL";
|
||||
};
|
||||
};
|
||||
|
||||
// This event doesn't correspond to unconscious in statemachine
|
||||
|
@ -63,6 +63,8 @@ _patient setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true];
|
||||
_patient setVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE, true];
|
||||
_patient setVariable [VAR_BLOOD_PRESS, [80, 120], true];
|
||||
_patient setVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES, true];
|
||||
_patient setVariable [VAR_SPO2, DEFAULT_SPO2, true];
|
||||
_patient setVariable [VAR_OXYGEN_DEMAND, 0, true];
|
||||
|
||||
// IVs
|
||||
_patient setVariable [QEGVAR(medical,ivBags), nil, true];
|
||||
|
10
addons/medical_vitals/CfgWeapons.hpp
Normal file
10
addons/medical_vitals/CfgWeapons.hpp
Normal file
@ -0,0 +1,10 @@
|
||||
class CfgWeapons {
|
||||
class H_HelmetB;
|
||||
class H_PilotHelmetFighter_B: H_HelmetB {
|
||||
GVAR(oxygenSupply) = QUOTE(vehicle _this isKindOf 'Plane' || vehicle _this isKindOf 'Helicopter');
|
||||
};
|
||||
class Vest_Camo_Base;
|
||||
class V_RebreatherB: Vest_Camo_Base {
|
||||
GVAR(oxygenSupply) = QUOTE(eyePos _this select 2 < 0); // will only work for sea-level water
|
||||
};
|
||||
};
|
@ -1,4 +1,6 @@
|
||||
PREP(handleUnitVitals);
|
||||
PREP(scanConfig);
|
||||
PREP(updateHeartRate);
|
||||
PREP(updateOxygen);
|
||||
PREP(updatePainSuppress);
|
||||
PREP(updatePeripheralResistance);
|
||||
|
@ -6,4 +6,8 @@ PREP_RECOMPILE_START;
|
||||
#include "XEH_PREP.hpp"
|
||||
PREP_RECOMPILE_END;
|
||||
|
||||
#include "initSettings.inc.sqf"
|
||||
|
||||
GVAR(oxygenSupplyConditionCache) = uiNamespace getVariable QGVAR(oxygenSupplyConditionCache);
|
||||
|
||||
ADDON = true;
|
||||
|
@ -1,3 +1,9 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
#include "XEH_PREP.hpp"
|
||||
|
||||
GVAR(oxygenSupplyConditionCache) = createHashMap;
|
||||
|
||||
call FUNC(scanConfig);
|
||||
|
||||
GVAR(oxygenSupplyConditionCache) = compileFinal GVAR(oxygenSupplyConditionCache);
|
||||
|
@ -23,5 +23,6 @@ class CfgPatches {
|
||||
};
|
||||
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "CfgWeapons.hpp"
|
||||
|
||||
#endif
|
||||
|
@ -31,6 +31,9 @@ if (_syncValues) then {
|
||||
_unit setVariable [QGVAR(lastMomentValuesSynced), CBA_missionTime];
|
||||
};
|
||||
|
||||
// Update SPO2 intake and usage since last update
|
||||
[_unit, _deltaT, _syncValues] call FUNC(updateOxygen);
|
||||
|
||||
private _bloodVolume = GET_BLOOD_VOLUME(_unit) + ([_unit, _deltaT, _syncValues] call EFUNC(medical_status,getBloodVolumeChange));
|
||||
_bloodVolume = 0 max _bloodVolume min DEFAULT_BLOOD_VOLUME;
|
||||
|
||||
|
23
addons/medical_vitals/functions/fnc_scanConfig.sqf
Normal file
23
addons/medical_vitals/functions/fnc_scanConfig.sqf
Normal file
@ -0,0 +1,23 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: LinkIsGrim
|
||||
* Cache a hashmap of all oxygen-providing items for SpO2 simulation
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
private _filter = toString {getText (_x >> QGVAR(oxygenSupply)) != ""};
|
||||
|
||||
{
|
||||
private _cfgRoot = configFile >> _x;
|
||||
{
|
||||
private _condition = compile getText (_x >> QGVAR(oxygenSupply));
|
||||
GVAR(oxygenSupplyConditionCache) set [configName _x, _condition];
|
||||
} forEach (_filter configClasses _cfgRoot);
|
||||
} forEach ["CfgWeapons", "CfgGoggles"];
|
@ -37,6 +37,7 @@ if IN_CRDC_ARRST(_unit) then {
|
||||
if (_bloodVolume > BLOOD_VOLUME_CLASS_4_HEMORRHAGE) then {
|
||||
GET_BLOOD_PRESSURE(_unit) params ["_bloodPressureL", "_bloodPressureH"];
|
||||
private _meanBP = (2/3) * _bloodPressureH + (1/3) * _bloodPressureL;
|
||||
private _spo2 = GET_SPO2(_unit);
|
||||
private _painLevel = GET_PAIN_PERCEIVED(_unit);
|
||||
|
||||
private _targetBP = 107;
|
||||
@ -51,8 +52,11 @@ if IN_CRDC_ARRST(_unit) then {
|
||||
if (_painLevel > 0.2) then {
|
||||
_targetHR = _targetHR max (80 + 50 * _painLevel);
|
||||
};
|
||||
// Increase HR to compensate for low blood oxygen
|
||||
// Increase HR to compensate for higher oxygen demand (e.g. running, recovering from sprint)
|
||||
private _oxygenDemand = _unit getVariable [VAR_OXYGEN_DEMAND, 0];
|
||||
_targetHR = _targetHR + ((97 - _spo2) * 2) + (_oxygenDemand * -1000);
|
||||
_targetHR = (_targetHR + _hrTargetAdjustment) max 0;
|
||||
|
||||
_hrChange = round(_targetHR - _heartRate) / 2;
|
||||
} else {
|
||||
_hrChange = -round(_heartRate / 10);
|
||||
|
75
addons/medical_vitals/functions/fnc_updateOxygen.sqf
Normal file
75
addons/medical_vitals/functions/fnc_updateOxygen.sqf
Normal file
@ -0,0 +1,75 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Brett Mayson
|
||||
* Update the oxygen levels
|
||||
*
|
||||
* Arguments:
|
||||
* 0: The Unit <OBJECT>
|
||||
* 1: Time since last update <NUMBER>
|
||||
* 2: Sync value? <BOOL>
|
||||
*
|
||||
* ReturnValue:
|
||||
* Current SPO2 <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* [player, 1, false] call ace_medical_vitals_fnc_updateOxygen
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_unit", "_deltaT", "_syncValue"];
|
||||
|
||||
if (!GVAR(simulateSpO2)) exitWith {}; // changing back to default is handled in initSettings.inc.sqf
|
||||
|
||||
#define IDEAL_PPO2 0.255
|
||||
|
||||
private _current = GET_SPO2(_unit);
|
||||
private _heartRate = GET_HEART_RATE(_unit);
|
||||
|
||||
private _altitude = EGVAR(common,mapAltitude) + ((getPosASL _unit) select 2);
|
||||
private _po2 = if (missionNamespace getVariable [QEGVAR(weather,enabled), false]) then {
|
||||
private _temperature = _altitude call EFUNC(weather,calculateTemperatureAtHeight);
|
||||
private _pressure = _altitude call EFUNC(weather,calculateBarometricPressure);
|
||||
[_temperature, _pressure, EGVAR(weather,currentHumidity)] call EFUNC(weather,calculateOxygenDensity)
|
||||
} else {
|
||||
// Rough approximation of the partial pressure of oxygen in the air
|
||||
0.25725 * (_altitude / 1000 + 1)
|
||||
};
|
||||
|
||||
private _oxygenSaturation = (IDEAL_PPO2 min _po2) / IDEAL_PPO2;
|
||||
|
||||
// Check gear for oxygen supply
|
||||
[goggles _unit, headgear _unit, vest _unit] findIf {
|
||||
_x in GVAR(oxygenSupplyConditionCache) &&
|
||||
{ACE_player call (GVAR(oxygenSupplyConditionCache) get _x)} &&
|
||||
{ // Will only run this if other conditions are met due to lazy eval
|
||||
_oxygenSaturation = 1;
|
||||
_po2 = IDEAL_PPO2;
|
||||
true
|
||||
}
|
||||
};
|
||||
|
||||
// Base oxygen consumption rate
|
||||
private _negativeChange = BASE_OXYGEN_USE;
|
||||
|
||||
// Fatigue & exercise will demand more oxygen
|
||||
// Assuming a trained male in midst of peak exercise will have a peak heart rate of ~180 BPM
|
||||
// Ref: https://academic.oup.com/bjaed/article-pdf/4/6/185/894114/mkh050.pdf table 2, though we don't take stroke volume change into account
|
||||
if (_unit == ACE_player && {missionNamespace getVariable [QEGVAR(advanced_fatigue,enabled), false]}) then {
|
||||
_negativeChange = _negativeChange - ((1 - EGVAR(advanced_fatigue,aeReservePercentage)) * 0.1) - ((1 - EGVAR(advanced_fatigue,anReservePercentage)) * 0.05);
|
||||
};
|
||||
|
||||
// Effectiveness of capturing oxygen
|
||||
// increases slightly as po2 starts lowering
|
||||
// but falls off quickly as po2 drops further
|
||||
private _capture = 1 max ((_po2 / IDEAL_PPO2) ^ (-_po2 * 3));
|
||||
private _positiveChange = _heartRate * 0.00368 * _oxygenSaturation * _capture;
|
||||
|
||||
private _breathingEffectiveness = 1;
|
||||
|
||||
private _rateOfChange = _negativeChange + (_positiveChange * _breathingEffectiveness);
|
||||
|
||||
private _spo2 = (_current + (_rateOfChange * _deltaT)) max 0 min 100;
|
||||
|
||||
_unit setVariable [VAR_OXYGEN_DEMAND, _negativeChange - BASE_OXYGEN_USE];
|
||||
_unit setVariable [VAR_SPO2, _spo2, _syncValue];
|
15
addons/medical_vitals/initSettings.inc.sqf
Normal file
15
addons/medical_vitals/initSettings.inc.sqf
Normal file
@ -0,0 +1,15 @@
|
||||
[
|
||||
QGVAR(simulateSpO2),
|
||||
"CHECKBOX",
|
||||
[LSTRING(simulateSpO2_DisplayName), LSTRING(simulateSpO2_Description)],
|
||||
[ELSTRING(medical,Category), LSTRING(SubCategory)],
|
||||
true,
|
||||
1,
|
||||
{
|
||||
if (_this) exitWith {}; // skip if true
|
||||
{
|
||||
_x setVariable [VAR_OXYGEN_DEMAND, 0, true];
|
||||
_x setVariable [VAR_SPO2, DEFAULT_SPO2, true];
|
||||
} forEach (allUnits select {local _x})
|
||||
} // reset oxygen demand on setting change
|
||||
] call CBA_fnc_addSetting;
|
@ -16,3 +16,5 @@
|
||||
|
||||
#include "\z\ace\addons\medical_engine\script_macros_medical.hpp"
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
#define BASE_OXYGEN_USE -0.25
|
||||
|
15
addons/medical_vitals/stringtable.xml
Normal file
15
addons/medical_vitals/stringtable.xml
Normal file
@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project name="ACE">
|
||||
<Package name="Medical_Vitals">
|
||||
<Key ID="STR_ACE_Medical_Vitals_SubCategory">
|
||||
<English>Vitals</English>
|
||||
<Portuguese>Vitais</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Medical_Vitals_simulateSpO2_DisplayName">
|
||||
<English>Enable SpO2 Simulation</English>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Medical_Vitals_simulateSpO2_Description">
|
||||
<English>Enables oxygen saturation simulation, providing variable heart rate and oxygen demand based on physical activity and altitude. Required for Airway Management.</English>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
@ -1,9 +1,9 @@
|
||||
|
||||
PREP(calculateAirDensity);
|
||||
PREP(calculateBarometricPressure);
|
||||
PREP(calculateDensityAltitude);
|
||||
PREP(calculateDewPoint);
|
||||
PREP(calculateHeatIndex);
|
||||
PREP(calculateOxygenDensity);
|
||||
PREP(calculateRoughnessLength);
|
||||
PREP(calculateSpeedOfSound);
|
||||
PREP(calculateTemperatureAtHeight);
|
||||
|
20
addons/weather/functions/fnc_calculateOxygenDensity.sqf
Normal file
20
addons/weather/functions/fnc_calculateOxygenDensity.sqf
Normal file
@ -0,0 +1,20 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Brett Mayson
|
||||
* Calculates the oxygen density
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Temperature - °C <NUMBER>
|
||||
* 1: Pressure - hPa <NUMBER>
|
||||
* 2: Relative humidity - value between 0.0 and 1.0 <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* Density of oxygen - kg * m^(-3) <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* [0, 1020] call ace_weather_fnc_calculateOxygenDensity
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
(_this call FUNC(calculateAirDensity)) * 0.21
|
@ -35,6 +35,7 @@ Enables attaching explosives to vehicles.
|
||||
- Interact with the explosive <kbd>⊞ Win</kbd> (ACE3 default key bind `Interact Key`).
|
||||
- Choose the arming method.
|
||||
- For clackers use Self Interaction `Explosives` → `Detonate` and choose the corresponding Firing Device.
|
||||
- Alternatively, use <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>C</kbd> (ACE3 default key bind `Detonate All on Active Clacker`) to detonate all explosives tied to the `Active Detonator`, which can be changed via the `Set Active Detonator` interaction on the desired Clacker / Dead Man Switch.
|
||||
|
||||
### 2.3 Defusing explosives
|
||||
- A `Defusal Kit` is required.
|
||||
|
34
docs/wiki/framework/laser-framework.md
Normal file
34
docs/wiki/framework/laser-framework.md
Normal file
@ -0,0 +1,34 @@
|
||||
---
|
||||
layout: wiki
|
||||
title: Laser
|
||||
description: Explains the functions available for laser designators.
|
||||
group: framework
|
||||
order: 5
|
||||
parent: wiki
|
||||
mod: ace
|
||||
version:
|
||||
major: 3
|
||||
minor: 16
|
||||
patch: 4
|
||||
---
|
||||
|
||||
## 1. Scripting
|
||||
|
||||
### 1.1. Get object's laser code
|
||||
|
||||
`ace_laser_fnc_getLaserCode`
|
||||
|
||||
| | Arguments | Type | Optional (default value)
|
||||
---| --------- | ---- | ------------------------
|
||||
0 | Unit/Vehicle | Object | Required
|
||||
**R** | Laser code | Number | Return value
|
||||
|
||||
### 1.2. Set object's laser code
|
||||
|
||||
`ace_laser_fnc_setLaserCode`
|
||||
|
||||
| | Arguments | Type | Optional (default value)
|
||||
---| --------- | ---- | ------------------------
|
||||
0 | Unit/Vehicle | Object | Required
|
||||
1 | Laser code | Number | Required
|
||||
**R** | None | None | Return value
|
Loading…
Reference in New Issue
Block a user