mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge branch 'master' into add-fire-sources-to-wrecks
This commit is contained in:
commit
32f3dca815
@ -24,22 +24,6 @@ if (!hasInterface) exitWith {};
|
||||
|
||||
// Register Perframe Handler
|
||||
[LINKFUNC(handleFirePFH), GVAR(simulationInterval)] call CBA_fnc_addPerFrameHandler;
|
||||
|
||||
//Add warnings for missing compat PBOs (only if AB is on)
|
||||
{
|
||||
_x params ["_modPBO", "_compatPBO"];
|
||||
if ([_modPBO] call EFUNC(common,isModLoaded) && {!([_compatPBO] call EFUNC(common,isModLoaded))}) then {
|
||||
WARNING_2("Weapon Mod [%1] missing ace compat pbo [%2] (from @ace\optionals)",_modPBO,_compatPBO);
|
||||
};
|
||||
} forEach [
|
||||
["RH_acc","ace_compat_rh_acc"],
|
||||
["RH_de_cfg","ace_compat_rh_de"],
|
||||
["RH_m4_cfg","ace_compat_rh_m4"],
|
||||
["RH_PDW","ace_compat_rh_pdw"],
|
||||
["RKSL_PMII","ace_compat_rksl_pm_ii"],
|
||||
["iansky_opt","ace_compat_sma3_iansky"],
|
||||
["R3F_Armes","ace_compat_r3f"]
|
||||
];
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
|
@ -19,7 +19,7 @@
|
||||
//IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"];
|
||||
TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret);
|
||||
|
||||
if (!(_ammo isKindOf "BulletBase")) exitWith {};
|
||||
if !(_ammo isKindOf "BulletBase") exitWith {};
|
||||
if (!alive _projectile) exitWith {};
|
||||
if (underwater _unit) exitWith {};
|
||||
|
||||
|
@ -40,7 +40,7 @@ if (_transonicStabilityCoef == 0) then {
|
||||
_transonicStabilityCoef = 0.5;
|
||||
};
|
||||
private _dragModel = getNumber(_ammoConfig >> "ACE_dragModel");
|
||||
if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then {
|
||||
if !(_dragModel in [1, 2, 5, 6, 7, 8]) then {
|
||||
_dragModel = 1;
|
||||
};
|
||||
private _ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients");
|
||||
|
@ -5,7 +5,9 @@ private _category = format ["ACE %1", localize LSTRING(DisplayName)];
|
||||
[LSTRING(enabled_DisplayName), LSTRING(enabled_Description)],
|
||||
_category,
|
||||
false,
|
||||
1
|
||||
1,
|
||||
{[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||
true // Needs mission restart
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
@ -45,5 +47,7 @@ private _category = format ["ACE %1", localize LSTRING(DisplayName)];
|
||||
[LSTRING(simulationInterval_DisplayName), LSTRING(simulationInterval_Description)],
|
||||
_category,
|
||||
[0, 0.2, 0.05, 2],
|
||||
1
|
||||
1,
|
||||
{[QGVAR(simulationInterval), _this] call EFUNC(common,cbaSettings_settingChanged)},
|
||||
true // Needs mission restart
|
||||
] call CBA_fnc_addSetting;
|
||||
|
@ -9,3 +9,4 @@ PREP(handleStaminaBar);
|
||||
PREP(mainLoop);
|
||||
PREP(moduleSettings);
|
||||
PREP(removeDutyFactor);
|
||||
PREP(renderDebugLines);
|
||||
|
@ -2,6 +2,10 @@
|
||||
|
||||
if (!hasInterface) exitWith {};
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
call FUNC(renderDebugLines);
|
||||
#endif
|
||||
|
||||
// recheck weapon inertia after weapon swap, change of attachments or switching unit
|
||||
["weapon", {[ACE_player] call FUNC(getWeaponInertia)}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
["loadout", {[ACE_player] call FUNC(getWeaponInertia)}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
@ -33,25 +37,23 @@ if (!hasInterface) exitWith {};
|
||||
GVAR(ppeBlackout) ppEffectCommit 0.4;
|
||||
|
||||
// - GVAR updating and initialization -----------------------------------------
|
||||
["unit", LINKFUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler;
|
||||
["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
["visibleMap", {
|
||||
params ["", "_visibleMap"]; // command visibleMap is updated one frame later
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlShow ((!_visibleMap) && {(vehicle ACE_player) == ACE_player});
|
||||
(uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]) ctrlShow (!_visibleMap && isNull objectParent ACE_player);
|
||||
}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
["vehicle", {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlShow ((!visibleMap) && {(vehicle ACE_player) == ACE_player});
|
||||
(uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]) ctrlShow (!visibleMap && isNull objectParent ACE_player);
|
||||
}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
// - Duty factors -------------------------------------------------------------
|
||||
if (GVAR(medicalLoaded)) then {
|
||||
if (GETEGVAR(medical,enabled,false)) 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];
|
||||
linearConversion [0, 1, _this getVariable [QEGVAR(medical,pain), 0], 1, 1.1, true];
|
||||
}] call FUNC(addDutyFactor);
|
||||
[QEGVAR(medical,bloodVolume), { // 6->1.0, 5->1.167, 4->1.33
|
||||
linearConversion [6, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 6]), 1, 2, true];
|
||||
linearConversion [6, 0, _this getVariable [QEGVAR(medical,bloodVolume), 6], 1, 2, true];
|
||||
}] call FUNC(addDutyFactor);
|
||||
};
|
||||
if (["ace_dragging"] call EFUNC(common,isModLoaded)) then {
|
||||
@ -62,7 +64,7 @@ if (!hasInterface) exitWith {};
|
||||
// Weather has an off switch, Dragging & Medical don't.
|
||||
if (missionNamespace getVariable [QEGVAR(weather,enabled), false]) then {
|
||||
[QEGVAR(weather,temperature), { // 35->1, 45->2
|
||||
linearConversion [35, 45, (missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25]), 1, 2, true];
|
||||
linearConversion [35, 45, missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25], 1, 2, true];
|
||||
}] call FUNC(addDutyFactor);
|
||||
};
|
||||
|
||||
|
@ -13,6 +13,5 @@ GVAR(dutyList) = createHashMap;
|
||||
GVAR(setAnimExclusions) = [];
|
||||
GVAR(inertia) = 0;
|
||||
GVAR(inertiaCache) = createHashMap;
|
||||
GVAR(medicalLoaded) = ["ace_medical"] call EFUNC(common,isModLoaded);
|
||||
|
||||
ADDON = true;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Calculates the duty of the current animation.
|
||||
* Calculates the duty ('postureWeight') of the current animation.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
|
@ -1,54 +1,74 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Calculates the current metabolic costs for a unit.
|
||||
* Author: BaerMitUmlaut, ulteq
|
||||
* Calculates the current metabolic costs.
|
||||
* Calculation is done according to the Pandolf/Wojtowicz formulas.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Speed <NUMBER>
|
||||
* 0: Duty of animation
|
||||
* 1: Mass of unit <NUMBER>
|
||||
* 2: Terrain gradient <NUMBER>
|
||||
* 3: Terrain factor <NUMBER>
|
||||
* 4: Speed <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* Metabolic cost <NUMBER>
|
||||
*
|
||||
* Example:
|
||||
* [player, 3.3] call ace_advanced_fatigue_fnc_getMetabolicCosts
|
||||
* [1, 840, 20, 1, 4] call ace_advanced_fatigue_fnc_getMetabolicCosts
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params ["_unit", "_velocity"];
|
||||
|
||||
private _gearMass = ((_unit getVariable [QEGVAR(movement,totalLoad), loadAbs _unit]) / 22.046) * GVAR(loadFactor);
|
||||
|
||||
private _terrainAngle = asin (1 - ((surfaceNormal getPosASL _unit) select 2));
|
||||
private _terrainGradient = (_terrainAngle / 45 min 1) * 5 * GVAR(terrainGradientFactor);
|
||||
private _duty = GVAR(animDuty);
|
||||
|
||||
{
|
||||
if (_x isEqualType 0) then {
|
||||
_duty = _duty * _x;
|
||||
} else {
|
||||
_duty = _duty * (_unit call _x);
|
||||
};
|
||||
} forEach (values GVAR(dutyList));
|
||||
|
||||
if (GVAR(isSwimming)) then {
|
||||
_terrainGradient = 0;
|
||||
};
|
||||
params ["_duty", "_gearMass", "_terrainGradient", "_terrainFactor", "_speed"];
|
||||
|
||||
// Metabolic cost for walking and running is different
|
||||
if (_velocity > 2) then {
|
||||
if (_speed > 2) then {
|
||||
// Running
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
private _baseline = 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 0.9 * (_speed ^ 2);
|
||||
private _graded = 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.9 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient);
|
||||
private _terrainImpact = abs ((_graded / _baseline) - 1);
|
||||
hintSilent format ["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n TerrainImpact: %5 \n Speed: %6 | CarriedLoad: %7 \n Duty: %8 | Work: %9",
|
||||
_fwdAngle toFixed 1,
|
||||
_sideAngle toFixed 1,
|
||||
_terrainFactor toFixed 2,
|
||||
_terrainGradient toFixed 1,
|
||||
_terrainImpact toFixed 2,
|
||||
_speed toFixed 2,
|
||||
_gearMass toFixed 1,
|
||||
_duty toFixed 2,
|
||||
round (_graded * BIOMECH_EFFICIENCY * _duty)
|
||||
];
|
||||
#endif
|
||||
|
||||
(
|
||||
2.10 * SIM_BODYMASS
|
||||
2.1 * SIM_BODYMASS
|
||||
+ 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
||||
+ (SIM_BODYMASS + _gearMass) * (0.9 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient)
|
||||
) * 0.23 * _duty
|
||||
+ _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.9 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient)
|
||||
) * BIOMECH_EFFICIENCY * _duty
|
||||
} else {
|
||||
// Walking
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
private _baseline = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 1.15 * (_speed ^ 2);
|
||||
private _graded = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient);
|
||||
private _terrainImpact = abs ((_graded / _baseline) - 1);
|
||||
hintSilent format ["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n TerrainImpact: %5 \n Speed: %6 | CarriedLoad: %7 \n Duty: %8 | Work: %9",
|
||||
_fwdAngle toFixed 1,
|
||||
_sideAngle toFixed 1,
|
||||
_terrainFactor toFixed 2,
|
||||
_terrainGradient toFixed 1,
|
||||
_terrainImpact toFixed 2,
|
||||
_speed toFixed 2,
|
||||
_gearMass toFixed 1,
|
||||
_duty toFixed 2,
|
||||
round (_graded * BIOMECH_EFFICIENCY * _duty)
|
||||
];
|
||||
#endif
|
||||
|
||||
(
|
||||
1.05 * SIM_BODYMASS
|
||||
+ 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2)
|
||||
+ (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient)
|
||||
) * 0.23 * _duty
|
||||
+ _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient)
|
||||
) * BIOMECH_EFFICIENCY * _duty
|
||||
};
|
||||
|
@ -1,33 +1,32 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Author: BaerMitUmlaut, ulteq
|
||||
* Handles any audible, visual and physical effects of fatigue.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Fatigue <NUMBER>
|
||||
* 2: Speed <NUMBER>
|
||||
* 3: Overexhausted <BOOL>
|
||||
* 2: Overexhausted <BOOL>
|
||||
* 3: Forward Angle <NUMBER>
|
||||
* 4: Side Angle <NUMBER>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [_player, 0.5, 3.3, true] call ace_advanced_fatigue_fnc_handleEffects
|
||||
* [_player, 0.5, 3.3, true, 0, 0] call ace_advanced_fatigue_fnc_handleEffects
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params ["_unit", "_fatigue", "_speed", "_overexhausted"];
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
systemChat str _fatigue;
|
||||
systemChat str vectorMagnitude velocity _unit;
|
||||
#endif
|
||||
params ["_unit", "_fatigue", "_overexhausted", "_fwdAngle", "_sideAngle"];
|
||||
|
||||
// - Audible effects ----------------------------------------------------------
|
||||
GVAR(lastBreath) = GVAR(lastBreath) + 1;
|
||||
|
||||
if (_fatigue > 0.4 && {GVAR(lastBreath) > (_fatigue * -10 + 9)} && {!underwater _unit}) then {
|
||||
if (!isGameFocused) exitWith {};
|
||||
|
||||
switch (true) do {
|
||||
case (_fatigue < 0.6): {
|
||||
playSound (QGVAR(breathLow) + str (floor random 6));
|
||||
@ -39,6 +38,7 @@ if (_fatigue > 0.4 && {GVAR(lastBreath) > (_fatigue * -10 + 9)} && {!underwater
|
||||
playSound (QGVAR(breathMax) + str (floor random 6));
|
||||
};
|
||||
};
|
||||
|
||||
GVAR(lastBreath) = 0;
|
||||
};
|
||||
|
||||
@ -62,31 +62,35 @@ if (GVAR(isSwimming)) exitWith {
|
||||
if (GVAR(setAnimExclusions) isEqualTo []) then {
|
||||
_unit setAnimSpeedCoef linearConversion [0.7, 0.9, _fatigue, 1, 0.5, true];
|
||||
};
|
||||
if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then {
|
||||
|
||||
if (isSprintAllowed _unit && _fatigue > 0.7) then { // small checks like these are faster without lazy eval
|
||||
[_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
if ((!isSprintAllowed _unit) && {_fatigue < 0.7}) then {
|
||||
if (!isSprintAllowed _unit && _fatigue < 0.7) then {
|
||||
[_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||
};
|
||||
};
|
||||
};
|
||||
if ((getAnimSpeedCoef _unit) != 1) then {
|
||||
if (GVAR(setAnimExclusions) isEqualTo []) then {
|
||||
|
||||
// If other components are setting setAnimSpeedCoef, do not change animSpeedCoef
|
||||
if (getAnimSpeedCoef _unit != 1 && {GVAR(setAnimExclusions) isEqualTo []}) then {
|
||||
TRACE_1("reset",getAnimSpeedCoef _unit);
|
||||
_unit setAnimSpeedCoef 1;
|
||||
};
|
||||
};
|
||||
|
||||
if (_overexhausted) then {
|
||||
if (!isForcedWalk _unit && _fatigue >= 1) then { // small checks like these are faster without lazy eval
|
||||
[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
if (isForcedWalk _unit && {_fatigue < 0.7}) then {
|
||||
[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then {
|
||||
[_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
if ((!isSprintAllowed _unit) && {_fatigue < 0.6}) then {
|
||||
if (isForcedWalk _unit && _fatigue < 0.7) then {
|
||||
[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||
[_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
// Forward angle is the slope of the terrain, side angle simulates the unevenness/roughness of the terrain
|
||||
if (isSprintAllowed _unit && {_fatigue > 0.7 || abs _fwdAngle > 20 || abs _sideAngle > 20}) then {
|
||||
[_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
} else {
|
||||
if (!isSprintAllowed _unit && _fatigue < 0.6 && abs _fwdAngle < 20 && abs _sideAngle < 20) then {
|
||||
[_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
|
||||
};
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Handles switching units (once on init and afterwards via Zeus).
|
||||
* Author: BaerMitUmlaut, ulteq
|
||||
* Handles switching units (once on init and afterwards via Zeus). Also handles CBA setting change for performance factor.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: New Unit <OBJECT>
|
||||
@ -15,20 +15,24 @@
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_newUnit", "_oldUnit"];
|
||||
|
||||
TRACE_2("unit changed",_newUnit,_oldUnit);
|
||||
|
||||
if !(isNull _oldUnit) then {
|
||||
if (!isNull _oldUnit) then {
|
||||
TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler));
|
||||
|
||||
_oldUnit enableStamina true;
|
||||
_oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]];
|
||||
_oldUnit setVariable [QGVAR(animHandler), nil];
|
||||
TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler));
|
||||
|
||||
_oldUnit setVariable [QGVAR(ae1Reserve), GVAR(ae1Reserve)];
|
||||
_oldUnit setVariable [QGVAR(ae2Reserve), GVAR(ae2Reserve)];
|
||||
_oldUnit setVariable [QGVAR(anReserve), GVAR(anReserve)];
|
||||
_oldUnit setVariable [QGVAR(anFatigue), GVAR(anFatigue)];
|
||||
_oldUnit setVariable [QGVAR(muscleDamage), GVAR(muscleDamage)];
|
||||
_oldUnit setVariable [QGVAR(respiratoryRate), GVAR(respiratoryRate)];
|
||||
};
|
||||
|
||||
_newUnit enableStamina false;
|
||||
@ -38,6 +42,7 @@ if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then {
|
||||
private _animHandler = _newUnit addEventHandler ["AnimChanged", {
|
||||
GVAR(animDuty) = _this call FUNC(getAnimDuty);
|
||||
}];
|
||||
|
||||
TRACE_1("add new",_animHandler);
|
||||
_newUnit setVariable [QGVAR(animHandler), _animHandler];
|
||||
};
|
||||
@ -47,18 +52,27 @@ GVAR(ae2Reserve) = _newUnit getVariable [QGVAR(ae2Reserve), AE2_MAXRESERVE]
|
||||
GVAR(anReserve) = _newUnit getVariable [QGVAR(anReserve), AN_MAXRESERVE];
|
||||
GVAR(anFatigue) = _newUnit getVariable [QGVAR(anFatigue), 0];
|
||||
GVAR(muscleDamage) = _newUnit getVariable [QGVAR(muscleDamage), 0];
|
||||
GVAR(respiratoryRate) = _newUnit getVariable [QGVAR(respiratoryRate), 0];
|
||||
|
||||
// Clean variables for respawning units
|
||||
{
|
||||
_newUnit setVariable [_x, nil];
|
||||
} forEach [QGVAR(ae1Reserve), QGVAR(ae2Reserve), QGVAR(anReserve), QGVAR(anFatigue), QGVAR(muscleDamage)];
|
||||
} forEach [QGVAR(ae1Reserve), QGVAR(ae2Reserve), QGVAR(anReserve), QGVAR(anFatigue), QGVAR(muscleDamage), QGVAR(respiratoryRate)];
|
||||
|
||||
GVAR(VO2Max) = 35 + 20 * (_newUnit getVariable [QGVAR(performanceFactor), GVAR(performanceFactor)]);
|
||||
GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * 0.23 * JOULES_PER_ML_O2 / 60;
|
||||
GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * BIOMECH_EFFICIENCY * JOULES_PER_ML_O2 / 60;
|
||||
GVAR(peakPower) = VO2MAX_STRENGTH * GVAR(VO2MaxPower);
|
||||
|
||||
GVAR(ae1PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 13.3 * ANTPERCENT ^ 1.28 * 1.362;
|
||||
GVAR(ae2PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 16.7 * ANTPERCENT ^ 1.28 * 1.362;
|
||||
GVAR(ae1PathwayPower) = GVAR(peakPower) / (AE1_ATP_RELEASE_RATE + AE2_ATP_RELEASE_RATE + AN_ATP_RELEASE_RATE) * AE1_ATP_RELEASE_RATE * ANTPERCENT ^ 1.28 * 1.362;
|
||||
GVAR(ae2PathwayPower) = GVAR(peakPower) / (AE1_ATP_RELEASE_RATE + AE2_ATP_RELEASE_RATE + AN_ATP_RELEASE_RATE) * AE2_ATP_RELEASE_RATE * ANTPERCENT ^ 1.28 * 1.362;
|
||||
GVAR(aePathwayPower) = GVAR(ae1PathwayPower) + GVAR(ae2PathwayPower);
|
||||
GVAR(anPathwayPower) = GVAR(peakPower) - GVAR(aePathwayPower);
|
||||
|
||||
GVAR(aeWattsPerATP) = GVAR(ae1PathwayPower) / AE1_ATP_RELEASE_RATE;
|
||||
GVAR(anWattsPerATP) = GVAR(anPathwayPower) / AN_ATP_RELEASE_RATE;
|
||||
|
||||
GVAR(respiratoryBufferDivisor) = (RESPIRATORY_BUFFER - 1) / RESPIRATORY_BUFFER;
|
||||
GVAR(maxPowerFatigueRatio) = 0.057 / GVAR(peakPower);
|
||||
|
||||
GVAR(ppeBlackoutLast) = 100;
|
||||
GVAR(lastBreath) = 0;
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: BaerMitUmlaut
|
||||
* Author: BaerMitUmlaut, ulteq
|
||||
* Main looping function that updates fatigue values.
|
||||
*
|
||||
* Arguments:
|
||||
@ -17,73 +17,131 @@
|
||||
|
||||
// Dead people don't breathe, will also handle null (map intros)
|
||||
if (!alive ACE_player) exitWith {
|
||||
[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
||||
[LINKFUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
||||
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 1;
|
||||
_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 _velocity = velocity ACE_player;
|
||||
private _normal = surfaceNormal (getPosWorld ACE_player);
|
||||
private _movementVector = vectorNormalized _velocity;
|
||||
private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal);
|
||||
private _fwdAngle = asin (_movementVector select 2);
|
||||
private _sideAngle = asin (_sideVector select 2);
|
||||
|
||||
private _currentWork = REE;
|
||||
private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6;
|
||||
private _currentSpeed = (vectorMagnitude _velocity) min 6;
|
||||
|
||||
// fix #4481. Diving to the ground is recorded as PRONE stance with running speed velocity. Cap maximum speed to fix.
|
||||
if (GVAR(isProne)) then {
|
||||
_currentSpeed = _currentSpeed min 1.5;
|
||||
};
|
||||
|
||||
if ((vehicle ACE_player == ACE_player) && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then {
|
||||
_currentWork = [ACE_player, _currentSpeed] call FUNC(getMetabolicCosts);
|
||||
// Get the current duty
|
||||
private _duty = GVAR(animDuty);
|
||||
|
||||
{
|
||||
if (_x isEqualType 0) then {
|
||||
_duty = _duty * _x;
|
||||
} else {
|
||||
_duty = _duty * (ACE_player call _x);
|
||||
};
|
||||
} forEach (values GVAR(dutyList));
|
||||
|
||||
private _terrainGradient = abs _fwdAngle;
|
||||
private _terrainFactor = 1;
|
||||
private _gearMass = 0 max (((ACE_player getVariable [QEGVAR(movement,totalLoad), loadAbs ACE_player]) / 22.046 - UNDERWEAR_WEIGHT) * GVAR(loadFactor));
|
||||
|
||||
if (isNull objectParent ACE_player && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then {
|
||||
if (!GVAR(isSwimming)) then {
|
||||
// If the unit is going downhill, it's much less demanding
|
||||
if (_fwdAngle < 0) then {
|
||||
_terrainGradient = 0.15 * _terrainGradient;
|
||||
};
|
||||
|
||||
// Used to simulate the unevenness/roughness of the terrain
|
||||
if ((getPosATL ACE_player) select 2 < 0.01) then {
|
||||
private _sideGradient = abs (_sideAngle / 45) min 1;
|
||||
|
||||
_terrainFactor = 1 + _sideGradient ^ 4;
|
||||
};
|
||||
};
|
||||
|
||||
_currentWork = [_duty, _gearMass, _terrainGradient * GVAR(terrainGradientFactor), _terrainFactor, _currentSpeed] call FUNC(getMetabolicCosts);
|
||||
_currentWork = _currentWork max REE;
|
||||
};
|
||||
|
||||
// Oxygen calculation
|
||||
private _oxygen = if (GETEGVAR(medical,enabled,false) && {EGVAR(medical_vitals,simulateSpo2)}) then { // Defer to medical
|
||||
(ACE_player getVariable [QEGVAR(medical,spo2), 97]) / 100
|
||||
} else {
|
||||
1 - 0.131 * GVAR(respiratoryRate) ^ 2 // Default AF oxygen saturation
|
||||
};
|
||||
// Calculate muscle damage increase
|
||||
// Note: Muscle damage recovery is ignored as it takes multiple days
|
||||
GVAR(muscleDamage) = (GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * 0.00004) min 1;
|
||||
private _muscleIntegritySqrt = sqrt (1 - GVAR(muscleDamage));
|
||||
GVAR(muscleDamage) = GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * MUSCLE_TEAR_RATE;
|
||||
|
||||
// Calculate muscle damage recovery
|
||||
GVAR(muscleDamage) = 0 max (GVAR(muscleDamage) - MUSCLE_RECOVERY * GVAR(recoveryFactor)) min 1;
|
||||
private _muscleIntegrity = 1 - GVAR(muscleDamage);
|
||||
private _muscleFactor = sqrt _muscleIntegrity;
|
||||
|
||||
// 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 * _muscleFactor;
|
||||
private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * _oxygen * _muscleFactor;
|
||||
private _aePathwayPowerFatigued = _ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued;
|
||||
private _anPathwayPowerFatigued = GVAR(anPathwayPower) * sqrt (GVAR(anReserve) / AN_MAXRESERVE) * _oxygen * _muscleIntegrity;
|
||||
|
||||
// Calculate how much power is consumed from each reserve
|
||||
private _ae1Power = _currentWork min _ae1PathwayPowerFatigued;
|
||||
private _ae2Power = ((_currentWork - _ae1Power) max 0) min _ae2PathwayPowerFatigued;
|
||||
private _anPower = (_currentWork - _ae1Power - _ae2Power) max 0;
|
||||
private _ae2Power = (_currentWork - _ae1Power) min _ae2PathwayPowerFatigued;
|
||||
private _anPower = 0 max (_currentWork - _ae1Power - _ae2Power);
|
||||
|
||||
// Remove ATP from reserves for current work
|
||||
GVAR(ae1Reserve) = GVAR(ae1Reserve) - _ae1Power / WATTSPERATP;
|
||||
GVAR(ae2Reserve) = GVAR(ae2Reserve) - _ae2Power / WATTSPERATP;
|
||||
GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP;
|
||||
// Increase anearobic fatigue
|
||||
GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1;
|
||||
GVAR(ae1Reserve) = 0 max (GVAR(ae1Reserve) - _ae1Power / GVAR(aeWattsPerATP));
|
||||
GVAR(ae2Reserve) = 0 max (GVAR(ae2Reserve) - _ae2Power / GVAR(aeWattsPerATP));
|
||||
GVAR(anReserve) = 0 max (GVAR(anReserve) - _anPower / GVAR(anWattsPerATP));
|
||||
|
||||
// Acidosis accumulation
|
||||
GVAR(anFatigue) = GVAR(anFatigue) + _anPower * GVAR(maxPowerFatigueRatio) * 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 * GVAR(recoveryFactor) * AE1_ATP_RECOVERY * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower)) min AE1_MAXRESERVE;
|
||||
GVAR(ae2Reserve) = (GVAR(ae2Reserve) + _oxygen * GVAR(recoveryFactor) * AE2_ATP_RECOVERY * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower)) min AE2_MAXRESERVE;
|
||||
|
||||
// Anaerobic ATP reserver and fatigue recovery
|
||||
GVAR(anReserve) = ((GVAR(anReserve)
|
||||
+ (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) / GVAR(VO2MaxPower) * 56.7 * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor)
|
||||
) min AN_MAXRESERVE) max 0;
|
||||
private _aeSurplus = _ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power;
|
||||
|
||||
GVAR(anFatigue) = ((GVAR(anFatigue)
|
||||
- (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor)
|
||||
) min 1) max 0;
|
||||
// Anaerobic ATP reserve recovery
|
||||
GVAR(anReserve) = 0 max (GVAR(anReserve) + _aeSurplus / GVAR(VO2MaxPower) * AN_ATP_RECOVERY * GVAR(recoveryFactor) * (GVAR(anFatigue) max linearConversion [AN_MAXRESERVE, 0, GVAR(anReserve), 0, 0.75, true]) ^ 2) min AN_MAXRESERVE; // max linearConversion ensures that if GVAR(anFatigue) is very low, it will still regenerate reserves
|
||||
// Acidosis recovery
|
||||
GVAR(anFatigue) = 0 max (GVAR(anFatigue) - _aeSurplus * GVAR(maxPowerFatigueRatio) * GVAR(recoveryFactor) * GVAR(anFatigue) ^ 2) min 1;
|
||||
|
||||
// Respiratory rate decrease
|
||||
GVAR(respiratoryRate) = GVAR(respiratoryRate) * GVAR(respiratoryBufferDivisor);
|
||||
|
||||
// Respiratory rate increase
|
||||
private _aePowerRatio = (GVAR(aePathwayPower) / _aePathwayPowerFatigued) min 2;
|
||||
private _respiratorySampleDivisor = 1 / (RESPIRATORY_BUFFER * 4.72 * GVAR(VO2Max));
|
||||
GVAR(respiratoryRate) = (GVAR(respiratoryRate) + _currentWork * _respiratorySampleDivisor * _aePowerRatio) min 1;
|
||||
|
||||
// Calculate a pseudo-perceived fatigue, which is used for effects
|
||||
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);
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
systemChat format ["---- muscleDamage: %1 ----", GVAR(muscleDamage) toFixed 8];
|
||||
systemChat format ["---- ae2: %1 - an: %2 ----", (GVAR(ae2Reserve) / AE2_MAXRESERVE) toFixed 2, (GVAR(anReserve) / AN_MAXRESERVE) toFixed 2];
|
||||
systemChat format ["---- anFatigue: %1 - perceivedFatigue: %2 ----", GVAR(anFatigue) toFixed 2, _perceivedFatigue toFixed 2];
|
||||
systemChat format ["---- velocity %1 - respiratoryRate: %2 ----", (vectorMagnitude _velocity) toFixed 2, GVAR(respiratoryRate) toFixed 2];
|
||||
// systemChat format ["---- aePower: %1 ----", _aePathwayPowerFatigued toFixed 1];
|
||||
#endif
|
||||
|
||||
[ACE_player, _perceivedFatigue, GVAR(anReserve) == 0, _fwdAngle, _sideAngle] call FUNC(handleEffects);
|
||||
|
||||
if (GVAR(enableStaminaBar)) then {
|
||||
[GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar);
|
||||
};
|
||||
|
||||
[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
||||
[LINKFUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute;
|
||||
|
40
addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf
Normal file
40
addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf
Normal file
@ -0,0 +1,40 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: ulteq
|
||||
* Draw lines for debugging.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* call ace_advanced_fatigue_fnc_renderDebugLines
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
addMissionEventHandler ["Draw3D", {
|
||||
private _normal = surfaceNormal (getPosWorld ACE_player);
|
||||
private _beg = (getPosWorld ACE_player) vectorAdd (_normal vectorMultiply 0.5);
|
||||
private _end = _beg vectorAdd (_normal vectorMultiply 2);
|
||||
drawLine3D [ASLToATL _beg, ASLToATL _end, [0, 1, 0, 1]];
|
||||
|
||||
private _side = vectorNormalized (_normal vectorCrossProduct [0, 0, 1]);
|
||||
private _end = _beg vectorAdd (_side vectorMultiply 2);
|
||||
drawLine3D [ASLToATL _beg, ASLToATL _end, [0, 0, 1, 1]];
|
||||
|
||||
private _up = vectorNormalized (_normal vectorCrossProduct _side);
|
||||
private _end = _beg vectorAdd (_up vectorMultiply 2);
|
||||
drawLine3D [ASLToATL _beg, ASLToATL _end, [1, 0, 0, 1]];
|
||||
|
||||
private _movementVector = vectorNormalized (velocity ACE_player);
|
||||
private _end = _beg vectorAdd (_movementVector vectorMultiply 2);
|
||||
drawLine3D [ASLToATL _beg, ASLToATL _end, [1, 1, 0, 1]];
|
||||
|
||||
private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal);
|
||||
_sideVector set [2, 0];
|
||||
private _end = _beg vectorAdd (_sideVector vectorMultiply 2);
|
||||
drawLine3D [ASLToATL _beg, ASLToATL _end, [0, 1, 1, 1]];
|
||||
}];
|
@ -4,12 +4,14 @@
|
||||
[LSTRING(Enabled), LSTRING(Enabled_Description)],
|
||||
LSTRING(DisplayName),
|
||||
true,
|
||||
true, {
|
||||
1,
|
||||
{
|
||||
if (!_this) then {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 1;
|
||||
_staminaBarContainer ctrlCommit 0;
|
||||
};
|
||||
|
||||
[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)
|
||||
},
|
||||
true // Needs mission restart
|
||||
@ -21,7 +23,8 @@
|
||||
[LSTRING(EnableStaminaBar), LSTRING(EnableStaminaBar_Description)],
|
||||
LSTRING(DisplayName),
|
||||
true,
|
||||
true, {
|
||||
1,
|
||||
{
|
||||
if (!_this) then {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 1;
|
||||
@ -36,7 +39,8 @@
|
||||
[LSTRING(FadeStaminaBar), LSTRING(FadeStaminaBar_Description)],
|
||||
LSTRING(DisplayName),
|
||||
true,
|
||||
false, {
|
||||
0,
|
||||
{
|
||||
if (!_this && GVAR(enabled) && GVAR(enableStaminaBar)) then {
|
||||
private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull];
|
||||
_staminaBarContainer ctrlSetFade 0;
|
||||
@ -50,8 +54,14 @@
|
||||
"SLIDER",
|
||||
[LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 5, 1, 1],
|
||||
true
|
||||
[0, 10, 1, 2],
|
||||
1,
|
||||
{
|
||||
// Recalculate values if the setting is changed mid-mission
|
||||
if (GVAR(enabled) && hasInterface && !isNull ACE_player) then {
|
||||
[ACE_player, ACE_player] call FUNC(handlePlayerChanged);
|
||||
};
|
||||
}
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
@ -59,8 +69,8 @@
|
||||
"SLIDER",
|
||||
[LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 5, 1, 1],
|
||||
true
|
||||
[0, 10, 1, 2],
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
@ -68,8 +78,8 @@
|
||||
"SLIDER",
|
||||
[LSTRING(LoadFactor), LSTRING(LoadFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 5, 1, 1],
|
||||
true
|
||||
[0, 5, 1, 2],
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
||||
[
|
||||
@ -77,6 +87,6 @@
|
||||
"SLIDER",
|
||||
[LSTRING(TerrainGradientFactor), LSTRING(TerrainGradientFactor_Description)],
|
||||
LSTRING(DisplayName),
|
||||
[0, 5, 1, 1],
|
||||
true
|
||||
[0, 5, 1, 2],
|
||||
1
|
||||
] call CBA_fnc_addSetting;
|
||||
|
@ -16,14 +16,28 @@
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
#define UNDERWEAR_WEIGHT 3.5
|
||||
|
||||
#define ANTPERCENT 0.8
|
||||
#define SIM_BODYMASS 70
|
||||
#define JOULES_PER_ML_O2 20.9
|
||||
#define VO2MAX_STRENGTH 4.1
|
||||
#define REE 18.83 //((0.5617 * SIM_BODYMASS + 42.57) * 0.23)
|
||||
#define OXYGEN 0.9
|
||||
#define WATTSPERATP 7
|
||||
#define BIOMECH_EFFICIENCY 0.23
|
||||
#define REE 18.83 // ((0.5617 * SIM_BODYMASS + 42.57) * BIOMECH_EFFICIENCY)
|
||||
|
||||
#define AE1_MAXRESERVE 4000000
|
||||
#define AE2_MAXRESERVE 84000
|
||||
#define AN_MAXRESERVE 2300
|
||||
#define RESPIRATORY_BUFFER 60
|
||||
|
||||
#define MUSCLE_TEAR_RATE 0.00004
|
||||
#define MUSCLE_RECOVERY 0.00000386
|
||||
|
||||
#define AE1_ATP_RELEASE_RATE 13.3 // mmol
|
||||
#define AE2_ATP_RELEASE_RATE 16.7 // mmol
|
||||
#define AN_ATP_RELEASE_RATE 113.3 // mmol
|
||||
|
||||
#define AE1_ATP_RECOVERY 6.60 // mmol
|
||||
#define AE2_ATP_RECOVERY 5.83 // mmol
|
||||
#define AN_ATP_RECOVERY 56.70 // mmol
|
||||
|
||||
#define AE1_MAXRESERVE 4000000 // mmol
|
||||
#define AE2_MAXRESERVE 84000 // mmol
|
||||
#define AN_MAXRESERVE 2300 // mmol
|
||||
|
@ -10,20 +10,10 @@ if (!hasInterface) exitWith {};
|
||||
// Temporary Wind Info indication
|
||||
GVAR(tempWindInfo) = false;
|
||||
|
||||
// Ammo/Magazines look-up hash for correctness of initSpeed
|
||||
GVAR(ammoMagLookup) = call CBA_fnc_createNamespace;
|
||||
{
|
||||
{
|
||||
private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo");
|
||||
if (_ammo != "") then { GVAR(ammoMagLookup) setVariable [_ammo, _x]; };
|
||||
} forEach (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"));
|
||||
} forEach getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles");
|
||||
|
||||
|
||||
// Add keybinds
|
||||
["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), {
|
||||
// Condition
|
||||
if (!([ACE_player] call FUNC(canPrepare))) exitWith {false};
|
||||
if !([ACE_player] call FUNC(canPrepare)) exitWith {false};
|
||||
if (EGVAR(common,isReloading)) exitWith {true};
|
||||
|
||||
// Statement
|
||||
|
@ -1,3 +1,21 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
#include "XEH_PREP.hpp"
|
||||
|
||||
// Ammo/Magazines look-up hash for correctness of initSpeed
|
||||
private _cfgMagazines = configFile >> "CfgMagazines";
|
||||
private _cfgAmmo = configFile >> "CfgAmmo";
|
||||
private _cfgThrow = configFile >> "CfgWeapons" >> "Throw";
|
||||
|
||||
private _ammoMagLookup = createHashMap;
|
||||
|
||||
{
|
||||
{
|
||||
private _ammo = getText (_cfgMagazines >> _x >> "ammo");
|
||||
if (_ammo != "") then {
|
||||
_ammoMagLookup set [configName (_cfgAmmo >> _ammo), _x];
|
||||
};
|
||||
} forEach (getArray (_cfgThrow >> _x >> "magazines"));
|
||||
} forEach (getArray (_cfgThrow >> "muzzles"));
|
||||
|
||||
uiNamespace setVariable [QGVAR(ammoMagLookup), compileFinal _ammoMagLookup];
|
||||
|
@ -43,13 +43,10 @@ if ((!_primed) && {!((_throwableMag in (uniformItems ACE_player)) || {_throwable
|
||||
|
||||
// Get correct throw power for primed grenade
|
||||
if (_primed) then {
|
||||
private _ammoType = typeOf _activeThrowable;
|
||||
_throwableMag = GVAR(ammoMagLookup) getVariable _ammoType;
|
||||
if (isNil "_throwableMag") then {
|
||||
// If ammo type is not found:
|
||||
// What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke)
|
||||
// Just use HandGrenade as it has an average initSpeed value
|
||||
_throwableMag = "HandGrenade";
|
||||
};
|
||||
_throwableMag = (uiNamespace getVariable QGVAR(ammoMagLookup)) getOrDefault [typeOf _activeThrowable, "HandGrenade"];
|
||||
};
|
||||
|
||||
// Some throwables have different classname for magazine and ammo
|
||||
|
@ -21,7 +21,7 @@ TRACE_1("params",_unit);
|
||||
// Select next throwable if one already in hand
|
||||
if (_unit getVariable [QGVAR(inHand), false]) exitWith {
|
||||
TRACE_1("inHand",_unit);
|
||||
if (!(_unit getVariable [QGVAR(primed), false])) then {
|
||||
if !(_unit getVariable [QGVAR(primed), false]) then {
|
||||
TRACE_1("not primed",_unit);
|
||||
// Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory)
|
||||
// selectNextGrenade relies on muzzles array (setAmmo 0 removes the muzzle from the array and current can't be found, cycles between 0 and 1 muzzles)
|
||||
|
@ -20,7 +20,7 @@ TRACE_1("params",_unit);
|
||||
|
||||
// Prime the throwable if it hasn't been cooking already
|
||||
// Next to proper simulation this also has to happen before delay for orientation of the throwable to be set
|
||||
if (!(_unit getVariable [QGVAR(primed), false])) then {
|
||||
if !(_unit getVariable [QGVAR(primed), false]) then {
|
||||
[_unit] call FUNC(prime);
|
||||
};
|
||||
|
||||
|
@ -144,7 +144,7 @@
|
||||
<English>Enables ability to pick up throwables from the ground.</English>
|
||||
<Spanish>Activa la habilidad de coger objetos lanzados del suelo</Spanish>
|
||||
<Russian>Включает возможность подбирать гранаты с земли.</Russian>
|
||||
<Japanese>地面に落ちている投擲物を拾い上げる機能を有効化します。</Japanese>
|
||||
<Japanese>地面に落ちている投擲物を拾う機能を有効化します。</Japanese>
|
||||
<Polish>Umożliwia podnoszenie obiektów miotanych z ziemi.</Polish>
|
||||
<German>Aktiviert die Möglichkeit, geworfene Objekte wieder vom Boden aufzuheben.</German>
|
||||
<Korean>땅에 떨어진 투척물을 주울 수 있게 해줍니다.</Korean>
|
||||
@ -174,7 +174,7 @@
|
||||
<English>Enables ability to pick up throwables from attached objects.</English>
|
||||
<Spanish>Activa la habilidad de lanzar objetos enganchados</Spanish>
|
||||
<Russian>Включает возможность подбирать гранаты, прикрепленные к объектам.</Russian>
|
||||
<Japanese>オブジェクトに装着された投擲可能物を拾い上げる機能を有効化します。</Japanese>
|
||||
<Japanese>オブジェクトに装着された投擲物を拾う機能を有効化します。</Japanese>
|
||||
<Polish>Umożliwia podnoszenie obiektów miotanych przyczepionych do innych obiektów.</Polish>
|
||||
<German>Aktiviert die Möglichkeit, befestigte Wurfobjekte erneut aufzunehmen.</German>
|
||||
<Korean>부착된 투척물을 주울 수 있게 해줍니다.</Korean>
|
||||
@ -254,7 +254,7 @@
|
||||
<English>Primed</English>
|
||||
<Spanish>Preparado</Spanish>
|
||||
<Russian>Подготовлена</Russian>
|
||||
<Japanese>点火</Japanese>
|
||||
<Japanese>を点火した</Japanese>
|
||||
<Polish>Odbezpieczony</Polish>
|
||||
<German>Scharf gemacht</German>
|
||||
<Korean>뇌관 작동</Korean>
|
||||
|
@ -22,7 +22,7 @@ if (!alive _vehicle) exitWith {};
|
||||
if (_vehicle getVariable [QGVAR(droneActionsAdded), false]) exitWith {};
|
||||
_vehicle setVariable [QGVAR(droneActionsAdded), true];
|
||||
|
||||
// move to location
|
||||
// Move to location
|
||||
private _condition = {
|
||||
params ["_vehicle"];
|
||||
(missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]}
|
||||
@ -37,9 +37,58 @@ private _action = [QGVAR(droneSetWaypointMove), localize "$STR_AC_MOVE",
|
||||
"\a3\3DEN\Data\CfgWaypoints\Move_ca.paa", _statement, _condition] call EFUNC(interact_menu,createAction);
|
||||
[_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject);
|
||||
|
||||
// Follow unit/vehicle at turret location
|
||||
_condition = {
|
||||
params ["_vehicle"];
|
||||
private _target = cursorTarget;
|
||||
(missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} && {!isNull _target} && {["CAManBase", "LandVehicle", "Ship"] findIf {_target isKindOf _x} != -1}
|
||||
};
|
||||
_statement = {
|
||||
params ["_vehicle"];
|
||||
private _group = group driver _vehicle;
|
||||
private _pos = ([_vehicle, [0]] call FUNC(droneGetTurretTargetPos)) select 0;
|
||||
[QGVAR(droneSetWaypoint), [_vehicle, _group, _pos, "FOLLOW", cursorTarget], _group] call CBA_fnc_targetEvent;
|
||||
private _followDistance = _vehicle getVariable [QGVAR(wpFollowDistance), 0];
|
||||
[[LLSTRING(DroneFollowHint), _followDistance], 3] call EFUNC(common,displayTextStructured);
|
||||
};
|
||||
_action = [QGVAR(droneSetWaypointFollow), localize "$STR_AC_FOLLOW", "\a3\3DEN\Data\CfgWaypoints\Follow_ca.paa", _statement, _condition] call EFUNC(interact_menu,createAction);
|
||||
[_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject);
|
||||
|
||||
// Set drone follow distance
|
||||
_condition = {
|
||||
params ["_vehicle"];
|
||||
private _group = group driver _vehicle;
|
||||
private _index = (currentWaypoint _group) min count waypoints _group;
|
||||
private _waypoint = [_group, _index];
|
||||
(missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} && {(waypointType _waypoint) == "HOLD"}
|
||||
};
|
||||
_statement = {
|
||||
params ["_vehicle", "", "_value"];
|
||||
_vehicle setVariable [QGVAR(wpFollowDistance), _value];
|
||||
[[LLSTRING(DroneFollowHint), _value], 3] call EFUNC(common,displayTextStructured);
|
||||
};
|
||||
_action = [QGVAR(droneSetFollowDistance), LLSTRING(DroneFollowDistance), "", {}, _condition] call EFUNC(interact_menu,createAction);
|
||||
private _base = [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject);
|
||||
private _followDistances = if (_vehicle isKindOf "Car_F") then {
|
||||
[0, 25, 50, 100, 200]
|
||||
} else {
|
||||
[0, 100, 200, 300, 400, 500]
|
||||
};
|
||||
{
|
||||
_action = [
|
||||
QGVAR(droneSetFollowDistance_) + str _x,
|
||||
str _x,
|
||||
"",
|
||||
_statement,
|
||||
{true},
|
||||
{},
|
||||
_x
|
||||
] call EFUNC(interact_menu,createAction);
|
||||
[_vehicle, 1, _base, _action] call EFUNC(interact_menu,addActionToObject);
|
||||
} forEach _followDistances;
|
||||
|
||||
if (_vehicle isKindOf "Air") then {
|
||||
// loiter at location
|
||||
// Loiter at location
|
||||
_condition = {
|
||||
params ["_vehicle"];
|
||||
(missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]}
|
||||
@ -55,7 +104,7 @@ if (_vehicle isKindOf "Air") then {
|
||||
[_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject);
|
||||
|
||||
|
||||
// set height
|
||||
// Set height
|
||||
_condition = {
|
||||
params ["_vehicle"];
|
||||
(missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]}
|
||||
@ -74,7 +123,7 @@ if (_vehicle isKindOf "Air") then {
|
||||
} forEach [20, 50, 200, 500, 2000];
|
||||
|
||||
|
||||
// set loiter radius
|
||||
// Set loiter radius
|
||||
_condition = {
|
||||
params ["_vehicle"];
|
||||
private _group = group driver _vehicle;
|
||||
@ -97,7 +146,7 @@ if (_vehicle isKindOf "Air") then {
|
||||
} forEach [500, 750, 1000, 1250, 1500];
|
||||
|
||||
|
||||
// set loiter direction
|
||||
// Set loiter direction
|
||||
_condition = {
|
||||
params ["_vehicle", "", "_args"];
|
||||
private _group = group driver _vehicle;
|
||||
|
@ -8,6 +8,7 @@
|
||||
* 1: Group <GROUP>
|
||||
* 2: Pos 2D <ARRAY>
|
||||
* 3: Type <STRING>
|
||||
* 4: Target to follow <OBJECT> (default: objNull)
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -18,7 +19,7 @@
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_vehicle", "_group", "_pos", "_type"];
|
||||
params ["_vehicle", "_group", "_pos", "_type", ["_target", objNull]];
|
||||
TRACE_4("droneSetWaypoint",_vehicle,_group,_pos,_type);
|
||||
|
||||
private _index = (currentWaypoint _group) min count waypoints _group;
|
||||
@ -34,9 +35,34 @@ _pos set [
|
||||
[0, _currentHeight] select (_currentHeight >= 50)
|
||||
];
|
||||
|
||||
// [_group] call CBA_fnc_clearWaypoints;
|
||||
_waypoint = _group addWaypoint [_pos, 0];
|
||||
_waypoint setWaypointType _type;
|
||||
// The Vanilla "FOLLOW"-type waypoint is not used directly, due to 2 main issues (as of v2.16):
|
||||
// - It does not work at all for UGVs, which is a known issue https://feedback.bistudio.com/T126283;
|
||||
// - No clear scripting way was found to mimic the UAV Terminal's "Follow Distance" functionality;
|
||||
// Instead, the solution for both UAV and UGV following consists of a CBA PFH that moves a "HOLD"-type Waypoint every 3 seconds.
|
||||
// Either on the target itself, or on the Drone's current position if the target is within the desired follow distance.
|
||||
if (_type == "FOLLOW" && {["CAManBase", "LandVehicle", "Ship"] findIf {_target isKindOf _x} != -1}) then {
|
||||
_waypoint setWaypointType "HOLD";
|
||||
[{
|
||||
params ["_args", "_handle"];
|
||||
_args params ["_vehicle", "_group", "_waypoint", "_target"];
|
||||
|
||||
if ( // Abort PFH if a new waypoint is created via UAV Terminal or ACE Interaction
|
||||
_waypoint select 1 != currentWaypoint _group ||
|
||||
{!alive _vehicle} || {isNull _target}
|
||||
) exitWith {
|
||||
deleteWaypoint _waypoint;
|
||||
[_handle] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
private _followDistance = _vehicle getVariable [QGVAR(wpFollowDistance), 0];
|
||||
if ((_vehicle distance2D _target) < _followDistance) then {
|
||||
_waypoint setWaypointPosition [getPosASL _vehicle, -1];
|
||||
} else {
|
||||
_waypoint setWaypointPosition [getPosASL _target, -1];
|
||||
};
|
||||
}, 3, [_vehicle, _group, _waypoint, _target]] call CBA_fnc_addPerFrameHandler;
|
||||
};
|
||||
|
||||
TRACE_3("",_currentHeight,_currentLoiterRadius,_currentLoiterType);
|
||||
if (_currentHeight > 1) then { _vehicle flyInHeight _currentHeight; };
|
||||
|
@ -129,7 +129,7 @@
|
||||
<Japanese>30mm コンバット ミックス 4:1 劣化ウラン徹甲弾:焼夷榴弾</Japanese>
|
||||
<Czech>30mm Bojový Mix 4:1 DU:HEI</Czech>
|
||||
<Russian>30мм Смешанное боепитание 4:1 ОУ:ОФЗ</Russian>
|
||||
<Korean>30mm 4:1 열화:고폭소이</Korean>
|
||||
<Korean>30mm 열화우라늄:고폭소이 4:1 혼합</Korean>
|
||||
<Portuguese>30mm Mix de Combate 4:1 DU:AEI</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Aircraft_GatlingDescriptionShortCM41">
|
||||
@ -145,7 +145,7 @@
|
||||
<Japanese>30mm CM 4:1</Japanese>
|
||||
<Czech>30mm BM 4:1</Czech>
|
||||
<Russian>30мм СБ 4:1</Russian>
|
||||
<Korean>30mm CM 4:1</Korean>
|
||||
<Korean>30mm 4:1 혼합</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Aircraft_GatlingDescriptionCM51">
|
||||
<English>30mm Combat Mix 5:1 DU:HEI</English>
|
||||
@ -160,7 +160,7 @@
|
||||
<Japanese>30mm コンバット ミックス 5:1 劣化ウラン徹甲弾:焼夷榴弾</Japanese>
|
||||
<Czech>30mm Bojový Mix 5:1 DU:HEI</Czech>
|
||||
<Russian>30мм Смешанное боепитание 5:1 ОУ:ОФЗ</Russian>
|
||||
<Korean>30mm 5:1 열화:고폭소이</Korean>
|
||||
<Korean>30mm 열화우라늄:고폭소이 5:1 혼합</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Aircraft_GatlingDescriptionShortCM51">
|
||||
<English>30mm CM 5:1</English>
|
||||
@ -175,7 +175,21 @@
|
||||
<Japanese>30mm CM 5:1</Japanese>
|
||||
<Czech>30mm BM 5:1</Czech>
|
||||
<Russian>30мм СБ 5:1</Russian>
|
||||
<Korean>30mm CM 5:1</Korean>
|
||||
<Korean>30mm 5:1 혼합</Korean>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Aircraft_DroneFollowDistance">
|
||||
<English>Follow Distance</English>
|
||||
<Italian>Distanza di seguimento</Italian>
|
||||
<German>Folge-Entfernung</German>
|
||||
<Korean>따라가는 거리</Korean>
|
||||
<Japanese>追跡距離</Japanese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Aircraft_DroneFollowHint">
|
||||
<English>Following unit within %1m</English>
|
||||
<Italian>Seguendo unità entro %1m</Italian>
|
||||
<German>Folgt Einheit bis zu %1m</German>
|
||||
<Korean>%1m 이내로 유닛을 따라갑니다</Korean>
|
||||
<Japanese>%1m 間隔で 目標を追跡します</Japanese>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
|
@ -78,6 +78,7 @@ PREP(removeStat);
|
||||
PREP(removeVirtualItems);
|
||||
PREP(renameDefaultLoadout);
|
||||
PREP(replaceUniqueItemsLoadout);
|
||||
PREP(saveLoadout);
|
||||
PREP(scanConfig);
|
||||
PREP(showItem);
|
||||
PREP(sortPanel);
|
||||
|
@ -85,10 +85,10 @@ private _insigniaCondition = toString {
|
||||
|
||||
// Ref fnc_addListBoxItem, 0/nil = configFile, 1 = campaignConfigFile, 2 = missionConfigFile
|
||||
{
|
||||
GVAR(insigniaCache) set [_x, 1];
|
||||
GVAR(insigniaCache) set [configName _x, 1];
|
||||
} forEach (_insigniaCondition configClasses (campaignConfigFile >> "CfgUnitInsignia"));
|
||||
{
|
||||
GVAR(insigniaCache) set [_x, 2];
|
||||
GVAR(insigniaCache) set [configName _x, 2];
|
||||
} forEach (_insigniaCondition configClasses (missionConfigFile >> "CfgUnitInsignia"));
|
||||
|
||||
ADDON = true;
|
||||
|
@ -18,7 +18,7 @@
|
||||
(_this select 1) params ["", "_exitCode"];
|
||||
|
||||
[QGVAR(displayClosed), []] call CBA_fnc_localEvent;
|
||||
removeMissionEventHandler ["draw3D", GVAR(camPosUpdateHandle)];
|
||||
removeMissionEventHandler ["Draw3D", GVAR(camPosUpdateHandle)];
|
||||
|
||||
if (is3DEN) then {
|
||||
private _centerOriginParent = objectParent GVAR(centerOrigin);
|
||||
|
@ -278,4 +278,4 @@ showCinemaBorder false;
|
||||
|
||||
//--------------- Reset camera pos
|
||||
[nil, [controlNull, 0, 0]] call FUNC(handleMouse);
|
||||
GVAR(camPosUpdateHandle) = addMissionEventHandler ["draw3D", {call FUNC(updateCamPos)}];
|
||||
GVAR(camPosUpdateHandle) = addMissionEventHandler ["Draw3D", {call FUNC(updateCamPos)}];
|
||||
|
37
addons/arsenal/functions/fnc_saveLoadout.sqf
Normal file
37
addons/arsenal/functions/fnc_saveLoadout.sqf
Normal file
@ -0,0 +1,37 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: DartRuffian
|
||||
* Saves a given loadout to the client's profile.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Name of loadout <STRING>
|
||||
* 1: CBA extended loadout or getUnitLoadout array <ARRAY>
|
||||
* 2: Replace existing loadout <BOOL> (default: false)
|
||||
*
|
||||
* Return Value:
|
||||
* True if loadout was saved, otherwise false <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* ["Current Loadout", getUnitLoadout ACE_player] call ace_arsenal_fnc_saveLoadout
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [["_name", "", [""]], ["_loadout", [], [[]]], ["_replaceExisting", false, [false]]];
|
||||
|
||||
if (_name == "" || {_loadout isEqualTo []}) exitWith { false };
|
||||
|
||||
private _loadouts = profileNamespace getVariable [QGVAR(saved_loadouts), []];
|
||||
private _loadoutIndex = _loadouts findIf {(_x#0) == _name};
|
||||
|
||||
// If a loadout with same name already exists and no overwriting enabled, quit
|
||||
if (!_replaceExisting && {_loadoutIndex != -1}) exitWith { false };
|
||||
|
||||
if (_loadoutIndex == -1) then {
|
||||
_loadouts pushBack [_name, _loadout];
|
||||
} else {
|
||||
_loadouts set [_loadoutIndex, [_name, _loadout]];
|
||||
};
|
||||
|
||||
profileNamespace setVariable [QGVAR(saved_loadouts), _loadouts];
|
||||
true
|
@ -72,6 +72,6 @@ if (_nextAction != GVAR(currentAction)) then {
|
||||
GVAR(currentAction) = _nextAction;
|
||||
};
|
||||
|
||||
if (!(GVAR(currentAction) in ["Civil", "Salute"])) then {
|
||||
if !(GVAR(currentAction) in ["Civil", "Salute"]) then {
|
||||
GVAR(center) selectWeapon ([primaryWeapon GVAR(center), secondaryWeapon GVAR(center), handgunWeapon GVAR(center), binocular GVAR(center)] select GVAR(selectedWeaponType)); // select correct weapon, prevents floating weapons
|
||||
};
|
||||
|
@ -63,7 +63,7 @@ _target switchMove "amovpercmstpslowwrfldnon";
|
||||
_target setVariable ["origin", _position];
|
||||
|
||||
// When killed, respawn AI
|
||||
_target addEventHandler ["killed", {
|
||||
_target addEventHandler ["Killed", {
|
||||
params ["_target"];
|
||||
|
||||
// Killed may fire twice, 2nd will be null - https://github.com/acemod/ACE3/pull/7561
|
||||
|
@ -23,7 +23,7 @@
|
||||
<French>Masque l'interface</French>
|
||||
<German>Oberfläche verstecken</German>
|
||||
<Polish>Ukryj interfejs</Polish>
|
||||
<Japanese>インターフェースを隠す</Japanese>
|
||||
<Japanese>インタフェースを隠す</Japanese>
|
||||
<Italian>Nascondi interfaccia</Italian>
|
||||
<Korean>인터페이스 숨기기</Korean>
|
||||
<Chinese>隱藏介面</Chinese>
|
||||
@ -1245,6 +1245,7 @@
|
||||
<Russian>Интегрирован тепловизор.</Russian>
|
||||
<Korean>열화상 내장</Korean>
|
||||
<French>Thermique intégrée</French>
|
||||
<German>Thermal integriert</German>
|
||||
<Spanish>Térmica integrada</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Arsenal_statVisionMode_intPrimTi">
|
||||
@ -1254,6 +1255,7 @@
|
||||
<Russian>Интегрирован тепловизор и осн.прицел.</Russian>
|
||||
<Korean>열화상과 주무기 내장</Korean>
|
||||
<French>Thermique et primaire intégrés</French>
|
||||
<German>Thermal und in Primärwaffe integriert</German>
|
||||
<Spanish>Térmica y Primaria integrada</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Arsenal_statVisionMode_NoSup">
|
||||
|
@ -25,7 +25,7 @@
|
||||
params ["_vehicle", "", "", "", "", "_magazine", "_projectile", "_gunner"];
|
||||
TRACE_4("firedEH",_vehicle,_magazine,_projectile,_gunner);
|
||||
|
||||
if (!([_gunner] call EFUNC(common,isPlayer))) exitWith {}; // AI don't know how to use (this does give them more range than a player)
|
||||
if !([_gunner] call EFUNC(common,isPlayer)) exitWith {}; // AI don't know how to use (this does give them more range than a player)
|
||||
if ((gunner _vehicle) != _gunner) exitWith {}; // check if primaryGunner
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ if (isNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(airFriction)))
|
||||
_airFriction = getNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(airFriction));
|
||||
};
|
||||
TRACE_1("",_airFriction);
|
||||
if (_airFriction >= 0) exitWith {}; // 0 disables everything, >0 makes no sense
|
||||
if (_airFriction == 0) exitWith {}; // 0 disables everything
|
||||
|
||||
BEGIN_COUNTER(adjustmentsCalc);
|
||||
|
||||
@ -60,6 +60,7 @@ if (_newMuzzleVelocityCoefficent != 1) then {
|
||||
_projectile setVelocity _bulletVelocity;
|
||||
};
|
||||
|
||||
if (_airFriction > 0) exitWith {}; // positive value indicates it has vanilla airFriction, so we can just exit
|
||||
|
||||
[{
|
||||
params ["_projectile", "_kFactor", "_time"];
|
||||
|
@ -19,7 +19,7 @@ params ["_menuType"];
|
||||
TRACE_1("interactMenuOpened",_menuType);
|
||||
|
||||
if (_menuType != 1) exitWith {};
|
||||
if (!("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems)))) exitWith {};
|
||||
if !("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems))) exitWith {};
|
||||
|
||||
private _vehicleAdded = ace_player getVariable [QGVAR(vehiclesAdded), []];
|
||||
private _rangeTablesShown = ace_player getVariable [QGVAR(rangeTablesShown), []];
|
||||
|
@ -41,8 +41,15 @@ _mags = _mags apply {
|
||||
private _initSpeed = getNumber (_magCfg >> _x >> "initSpeed");
|
||||
_magParamsArray pushBackUnique _initSpeed;
|
||||
private _airFriction = 0;
|
||||
private _magAirFriction = getNumber (_magCfg >> _x >> QGVAR(airFriction));
|
||||
if (_magAirFriction <= 0) then {
|
||||
if (_advCorrection) then {
|
||||
_airFriction = if (isNumber (_magCfg >> _x >> QGVAR(airFriction))) then { getNumber (_magCfg >> _x >> QGVAR(airFriction)) } else { DEFAULT_AIR_FRICTION };
|
||||
_airFriction = [DEFAULT_AIR_FRICTION, _magAirFriction] select (isNumber (_magCfg >> _x >> QGVAR(airFriction)));
|
||||
};
|
||||
} else {
|
||||
// positive value, use ammo's airFriction (regardless of setting)
|
||||
private _ammo = getText (_magCfg >> _x >> "ammo");
|
||||
_airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction");
|
||||
};
|
||||
_magParamsArray pushBackUnique _airFriction;
|
||||
[getText (_magCfg >> _x >> "displayNameShort"), getText (_magCfg >> _x >> "displayName"), _initSpeed, _airFriction]
|
||||
|
@ -23,7 +23,7 @@ if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) ==
|
||||
_resetGunList = false;
|
||||
{
|
||||
// Verify each gun has correct param type
|
||||
if (!(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false])) exitWith {
|
||||
if !(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false]) exitWith {
|
||||
_resetGunList = true;
|
||||
};
|
||||
} forEach GVAR(gunList);
|
||||
|
@ -74,7 +74,7 @@ private _validate_preset = {
|
||||
ERROR(_errorMsg);
|
||||
_valid = false;
|
||||
};
|
||||
if (!((_this select 17) in ["ASM", "ICAO"])) then {
|
||||
if !((_this select 17) in ["ASM", "ICAO"]) then {
|
||||
private _errorMsg = format ["Invalid atmosphere model: %1", _this select 17];
|
||||
ERROR(_errorMsg);
|
||||
_valid = false;
|
||||
|
@ -26,7 +26,7 @@ if !(ctrlVisible 9000) then {
|
||||
params ["_args"];
|
||||
_args params ["_startTime"];
|
||||
|
||||
if (!(GVAR(speedAssistTimer))) exitWith {
|
||||
if !(GVAR(speedAssistTimer)) exitWith {
|
||||
GVAR(speedAssistTimer) = true;
|
||||
|
||||
ctrlSetText [8006, Str(Round((CBA_missionTime - _startTime) * 10) / 10)];
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {};
|
||||
if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {};
|
||||
|
||||
if (ctrlVisible 17000) then {
|
||||
false call FUNC(show_c1_ballistic_coefficient_data);
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {};
|
||||
if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {};
|
||||
|
||||
if (ctrlVisible 16000) then {
|
||||
false call FUNC(show_muzzle_velocity_data);
|
||||
|
@ -15,7 +15,7 @@
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {};
|
||||
if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {};
|
||||
|
||||
if (ctrlVisible 18000) then {
|
||||
false call FUNC(show_truing_drop);
|
||||
|
@ -35,7 +35,7 @@ if (!GVAR(atmosphereModeTBH)) then {
|
||||
_relativeHumidity = 0.5;
|
||||
};
|
||||
|
||||
private _scopeBaseAngle = if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then {
|
||||
private _scopeBaseAngle = if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
|
||||
private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight];
|
||||
(parseNumber _zeroAngle)
|
||||
} else {
|
||||
|
@ -28,7 +28,7 @@ if (_attachedList isEqualTo []) exitWith {};
|
||||
TRACE_2("detaching",_xObject,_deadUnit);
|
||||
detach _xObject;
|
||||
//If it's a vehicle, also delete the attached
|
||||
if (!(_deadUnit isKindOf "CAManBase")) then {
|
||||
if !(_deadUnit isKindOf "CAManBase") then {
|
||||
_xObject setPos ((getPos _deadUnit) vectorAdd [0, 0, -1000]);
|
||||
[{deleteVehicle (_this select 0)}, [_xObject], 2] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
|
@ -1710,7 +1710,7 @@
|
||||
<Portuguese>Carregador de 16 cartuchos 9x19 mm</Portuguese>
|
||||
<Hungarian>9x19 mm 16-lövedékes tár</Hungarian>
|
||||
<Japanese>9x19 mm 16Rnd マガジン</Japanese>
|
||||
<Korean>17발들이 9x19mm 탄창</Korean>
|
||||
<Korean>16발 들이 9x19mm 탄창</Korean>
|
||||
<Chinese>9x19毫米 16發 彈匣</Chinese>
|
||||
<Chinesesimp>9x19 mm 16发 弹匣</Chinesesimp>
|
||||
<Turkish>9x19 mm 16Rnd Mag</Turkish>
|
||||
|
@ -24,7 +24,7 @@ if (isServer) then {
|
||||
}];
|
||||
};
|
||||
|
||||
["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler;
|
||||
["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler;
|
||||
[QGVAR(moveInCaptive), LINKFUNC(vehicleCaptiveMoveIn)] call CBA_fnc_addEventHandler;
|
||||
[QGVAR(moveOutCaptive), LINKFUNC(vehicleCaptiveMoveOut)] call CBA_fnc_addEventHandler;
|
||||
|
||||
|
@ -21,7 +21,6 @@ params ["_unit", "_target"];
|
||||
|
||||
(_target getVariable [QGVAR(isHandcuffed), false]) &&
|
||||
{isNull (attachedTo _target)} &&
|
||||
{alive _target} &&
|
||||
{!(_target getVariable ["ACE_isUnconscious", false])} &&
|
||||
{_target call EFUNC(common,isAwake)} &&
|
||||
{(vehicle _unit) == _unit} &&
|
||||
{(vehicle _target) == _target}
|
||||
|
@ -20,7 +20,7 @@
|
||||
params ["_unit", "_target", "_vehicle"];
|
||||
|
||||
// Don't show "Load Captive" if unit is unconscious (already has "Load Patient")
|
||||
if (_target getVariable ["ACE_isUnconscious", false]) exitWith {false};
|
||||
if !(_target call EFUNC(common,isAwake)) exitWith {false};
|
||||
|
||||
if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then {
|
||||
//Looking at a vehicle while escorting, get target from attached objects:
|
||||
|
@ -39,12 +39,12 @@ if (_state) then {
|
||||
_args params ["_unit", "_target", "_actionID"];
|
||||
|
||||
if (_unit getVariable [QGVAR(isEscorting), false]) then {
|
||||
if (!alive _target || {!alive _unit} || {!canStand _target} || {!canStand _unit} || {_target getVariable ["ACE_isUnconscious", false]} || {_unit getVariable ["ACE_isUnconscious", false]} || {!isNull (attachedTo _unit)}) then {
|
||||
if (!canStand _target || {!canStand _unit} || {!(_target call EFUNC(common,isAwake))} || {!(_unit call EFUNC(common,isAwake))} || {!isNull (attachedTo _unit)}) then {
|
||||
_unit setVariable [QGVAR(isEscorting), false, true];
|
||||
};
|
||||
};
|
||||
|
||||
if (!(_unit getVariable [QGVAR(isEscorting), false])) then {
|
||||
if !(_unit getVariable [QGVAR(isEscorting), false]) then {
|
||||
[(_this select 1)] call CBA_fnc_removePerFrameHandler;
|
||||
[objNull, _target, false] call EFUNC(common,claim);
|
||||
detach _target;
|
||||
|
@ -19,7 +19,7 @@
|
||||
params ["_unit", "_newAnimation"];
|
||||
TRACE_2("AnimChanged",_unit,_newAnimation);
|
||||
if (_unit == (vehicle _unit)) then {
|
||||
if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {!(_unit getVariable ["ACE_isUnconscious", false])}) then {
|
||||
if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {_unit call EFUNC(common,isAwake)}) then {
|
||||
TRACE_1("Handcuff animation interrupted",_newAnimation);
|
||||
[_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation);
|
||||
};
|
||||
|
@ -19,7 +19,7 @@
|
||||
params ["_unit", "_newAnimation"];
|
||||
|
||||
TRACE_2("AnimChanged",_unit,_newAnimation);
|
||||
if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {!(_unit getVariable ["ACE_isUnconscious", false])}) then {
|
||||
if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {_unit call EFUNC(common,isAwake)}) then {
|
||||
TRACE_1("Surrender animation interrupted",_newAnimation);
|
||||
[_unit, "ACE_AmovPercMstpSsurWnonDnon", 1] call EFUNC(common,doAnimation);
|
||||
};
|
||||
|
@ -58,7 +58,7 @@ if (_state) then {
|
||||
// fix anim on mission start (should work on dedicated servers)
|
||||
[{
|
||||
params ["_unit"];
|
||||
if (!(_unit getVariable [QGVAR(isHandcuffed), false])) exitWith {};
|
||||
if !(_unit getVariable [QGVAR(isHandcuffed), false]) exitWith {};
|
||||
|
||||
if ((vehicle _unit) == _unit) then {
|
||||
[_unit] call EFUNC(common,fixLoweredRifleAnimation);
|
||||
@ -91,7 +91,7 @@ if (_state) then {
|
||||
_unit removeEventHandler ["AnimChanged", _animChangedEHID];
|
||||
_unit setVariable [QGVAR(handcuffAnimEHID), -1];
|
||||
|
||||
if (((vehicle _unit) == _unit) && {!(_unit getVariable ["ACE_isUnconscious", false])}) then {
|
||||
if (((vehicle _unit) == _unit) && {_unit call EFUNC(common,isAwake)}) then {
|
||||
//Break out of hands up animation loop
|
||||
[_unit, "ACE_AmovPercMstpScapWnonDnon_AmovPercMstpSnonWnonDnon", 2] call EFUNC(common,doAnimation);
|
||||
};
|
||||
|
@ -81,13 +81,12 @@ if (_state) then {
|
||||
|
||||
if (_unit == ACE_player) then {
|
||||
//only re-enable HUD if not handcuffed
|
||||
if (!(_unit getVariable [QGVAR(isHandcuffed), false])) then {
|
||||
if !(_unit getVariable [QGVAR(isHandcuffed), false]) then {
|
||||
["captive", []] call EFUNC(common,showHud); //same as showHud true;
|
||||
};
|
||||
};
|
||||
|
||||
if (!alive _unit) exitWith {};
|
||||
if (_unit getVariable ["ACE_isUnconscious", false]) exitWith {}; //don't touch animations if unconscious
|
||||
if !(_unit call EFUNC(common,isAwake)) exitWith {}; //don't touch animations if unconscious
|
||||
|
||||
//if we are in "hands up" animationState, crack it now
|
||||
if (((vehicle _unit) == _unit) && {(animationState _unit) == "ACE_AmovPercMstpSsurWnonDnon"}) then {
|
||||
@ -99,7 +98,7 @@ if (_state) then {
|
||||
params ["_args", "_pfID"];
|
||||
_args params ["_unit", "_maxTime"];
|
||||
//If waited long enough or they re-surrendered or they are unconscious, exit loop
|
||||
if ((CBA_missionTime > _maxTime) || {_unit getVariable [QGVAR(isSurrendering), false]} || {_unit getVariable ["ACE_isUnconscious", false]}) exitWith {
|
||||
if ((CBA_missionTime > _maxTime) || {_unit getVariable [QGVAR(isSurrendering), false]} || {!(_unit call EFUNC(common,isAwake))}) exitWith {
|
||||
[_pfID] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
//Only break animation if they are actualy the "hands up" animation (because we are using switchmove there won't be an transition)
|
||||
|
@ -158,6 +158,7 @@
|
||||
<Japanese>目隠しを外す</Japanese>
|
||||
<Russian>Снять повязку с глаз</Russian>
|
||||
<Spanish>Quitar vendas de los ojos</Spanish>
|
||||
<Portuguese>Remover a venda</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Captives_CableTie">
|
||||
<English>Cable Tie</English>
|
||||
|
@ -41,6 +41,8 @@ if (_item isEqualType "") then {
|
||||
TRACE_1("loaded",_loaded);
|
||||
|
||||
// Invoke listenable event
|
||||
if (_loaded > 0) then {
|
||||
["ace_cargoAdded", [_item, _vehicle, _loaded]] call CBA_fnc_globalEvent;
|
||||
};
|
||||
|
||||
_loaded // return
|
||||
|
@ -62,6 +62,17 @@ if (_item isEqualType objNull) then {
|
||||
|
||||
// Some objects below water will take damage over time, eventually becoming "water logged" and unfixable (because of negative z attach)
|
||||
[_item, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
|
||||
|
||||
// Prevent UAVs from firing
|
||||
private _UAVCrew = _item call EFUNC(common,getVehicleUAVCrew);
|
||||
|
||||
if (_UAVCrew isNotEqualTo []) then {
|
||||
{
|
||||
[_x, true] call EFUNC(common,disableAiUAV);
|
||||
} forEach _UAVCrew;
|
||||
|
||||
_item setVariable [QGVAR(isUAV), _UAVCrew, true];
|
||||
};
|
||||
};
|
||||
|
||||
// Invoke listenable event
|
||||
|
@ -100,14 +100,26 @@ if (_item isEqualType objNull) then {
|
||||
|
||||
// Create smoke effect when crate landed
|
||||
[{
|
||||
(_this select 0) params ["_object"];
|
||||
params ["_object", "_pfhID"];
|
||||
|
||||
if (isNull _object) exitWith {
|
||||
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
if (getPos _object select 2 < 1) exitWith {
|
||||
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||
_pfhID call CBA_fnc_removePerFrameHandler;
|
||||
|
||||
// Reenable UAV crew
|
||||
private _UAVCrew = _object getVariable [QGVAR(isUAV), []];
|
||||
|
||||
if (_UAVCrew isNotEqualTo []) then {
|
||||
// Reenable AI
|
||||
{
|
||||
[_x, false] call EFUNC(common,disableAiUAV);
|
||||
} forEach _UAVCrew;
|
||||
|
||||
_object setVariable [QGVAR(isUAV), nil, true];
|
||||
};
|
||||
|
||||
if ((GVAR(disableParadropEffectsClasstypes) findIf {_object isKindOf _x}) == -1) then {
|
||||
private _smoke = "SmokeshellYellow" createVehicle [0, 0, 0];
|
||||
|
@ -96,6 +96,18 @@ if (_object isEqualType objNull) then {
|
||||
|
||||
[QEGVAR(zeus,addObjects), [[_object], _objectCurators]] call CBA_fnc_serverEvent;
|
||||
};
|
||||
|
||||
// Reenable UAV crew
|
||||
private _UAVCrew = _object getVariable [QGVAR(isUAV), []];
|
||||
|
||||
if (_UAVCrew isNotEqualTo []) then {
|
||||
// Reenable AI
|
||||
{
|
||||
[_x, false] call EFUNC(common,disableAiUAV);
|
||||
} forEach _UAVCrew;
|
||||
|
||||
_object setVariable [QGVAR(isUAV), nil, true];
|
||||
};
|
||||
} else {
|
||||
_object = createVehicle [_item, _emptyPosAGL, [], 0, "NONE"];
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
||||
<Japanese>配置する</Japanese>
|
||||
<Korean>배치하기</Korean>
|
||||
<French>Déployer</French>
|
||||
<German>Aufstellen</German>
|
||||
<Spanish>Desplegar</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Cargo_ScrollAction">
|
||||
@ -288,6 +289,7 @@
|
||||
<Russian>Загружаем %1 в %2...</Russian>
|
||||
<Korean>%1을(를) %2에 싣는 중...</Korean>
|
||||
<French>Chargement %1 dans %2...</French>
|
||||
<German>%1 wird in %2 geladen...</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Cargo_UnloadingItem">
|
||||
<English>Unloading %1 from %2...</English>
|
||||
@ -297,6 +299,7 @@
|
||||
<Russian>Выгружаем %1 из %2...</Russian>
|
||||
<Korean>%1을(를) %2(으)로부터 내리는 중...</Korean>
|
||||
<French>Déchargement %1 de %2...</French>
|
||||
<German>%1 wird von %2 entladen...</German>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Cargo_LoadingFailed">
|
||||
<English>%1<br/>could not be loaded</English>
|
||||
@ -503,7 +506,7 @@
|
||||
<German>Ladezeitmultiplikator</German>
|
||||
<Japanese>積載の所要時間係数</Japanese>
|
||||
<Polish>Współczynnik czasu załadowania</Polish>
|
||||
<Italian>Coefficente Tempo Caricamento</Italian>
|
||||
<Italian>Coefficiente Tempo Caricamento</Italian>
|
||||
<Russian>Коэф. времени погрузки</Russian>
|
||||
<Portuguese>Fator de tempo para carregar</Portuguese>
|
||||
<French>Coefficient du temps de chargement</French>
|
||||
@ -587,6 +590,7 @@
|
||||
<Japanese>配置機能を有効化</Japanese>
|
||||
<Korean>배치 활성화</Korean>
|
||||
<French>Permettre le placement</French>
|
||||
<German>Aktiviere Aufbauen</German>
|
||||
<Spanish>Habilitar despliegue</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Cargo_enableDeploy_description">
|
||||
@ -596,6 +600,7 @@
|
||||
<Japanese>配置機能を介して貨物アイテムを降ろすことが出来るかどうかを制御します。</Japanese>
|
||||
<Korean>배치 방법을 통해 화물 아이템을 내릴 수 있는지 여부를 제어합니다.</Korean>
|
||||
<French>Contrôler si les éléments de cargaison peuvent être déchargés via la méthode de déploiement.</French>
|
||||
<German>Steuert, ob Frachtgegenstände über die Aufbaumethode entladen werden können.</German>
|
||||
<Spanish>Controla si los objetos de la carga pueden ser descargados mediante el método de despliegue.</Spanish>
|
||||
</Key>
|
||||
</Package>
|
||||
|
@ -1,7 +1,12 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (!hasInterface || !GVAR(enabled)) exitWith {};
|
||||
if (!hasInterface) exitWith {};
|
||||
|
||||
["CBA_settingsInitialized", {
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
GVAR(cachedCasings) = createHashMap;
|
||||
GVAR(casings) = [];
|
||||
|
||||
["CAManBase", "FiredMan", LINKFUNC(createCasing)] call CBA_fnc_addClassEventHandler;
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
name = COMPONENT_NAME;
|
||||
units[] = {"ACE_Box_Chemlights","ACE_Item_Chemlight_Shield","ACE_Item_Chemlight_Shield_Green","ACE_Item_Chemlight_Shield_Red","ACE_Item_Chemlight_Shield_Blue","ACE_Item_Chemlight_Shield_Yellow","ACE_Item_Chemlight_Shield_Orange","ACE_Item_Chemlight_Shield_White","ModuleChemlightOrange","ModuleChemlightWhite","ModuleChemlightHiRed","ModuleChemlightHiYellow","ModuleChemlightHiWhite","ModuleChemlightHiBlue","ModuleChemlightHiGreen","ModuleChemlightUltraHiOrange"};
|
||||
weapons[] = {"ACE_Chemlight_Shield", "ACE_Chemlight_Shield_Green","ACE_Chemlight_Shield_Red","ACE_Chemlight_Shield_Blue","ACE_Chemlight_Shield_Yellow","ACE_Chemlight_Shield_Orange","ACE_Chemlight_Shield_White"};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#define COMPONENT chemlights
|
||||
#define COMPONENT_BEAUTIFIED Chemlights
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
// #define DEBUG_MODE_FULL
|
||||
|
@ -30,6 +30,7 @@ PREP(changeProjectileDirection);
|
||||
PREP(checkFiles);
|
||||
PREP(checkFiles_diagnoseACE);
|
||||
PREP(checkPBOs);
|
||||
PREP(checkVersionNumber);
|
||||
PREP(claim);
|
||||
PREP(claimSafeServer);
|
||||
PREP(codeToString);
|
||||
@ -42,6 +43,7 @@ PREP(deviceKeyFindValidIndex);
|
||||
PREP(deviceKeyRegisterNew);
|
||||
PREP(deprecateComponent);
|
||||
PREP(disableAI);
|
||||
PREP(disableAiUAV);
|
||||
PREP(disableUserInput);
|
||||
PREP(displayIcon);
|
||||
PREP(displayText);
|
||||
@ -103,6 +105,7 @@ PREP(getWeaponAzimuthAndInclination);
|
||||
PREP(getWeaponIndex);
|
||||
PREP(getWeaponState);
|
||||
PREP(getWeight);
|
||||
PREP(getWheelHitPointsWithSelections);
|
||||
PREP(getWindDirection);
|
||||
PREP(getZoom);
|
||||
PREP(goKneeling);
|
||||
@ -175,6 +178,7 @@ PREP(setupLocalUnitsHandler);
|
||||
PREP(setVariableJIP);
|
||||
PREP(setVariablePublic);
|
||||
PREP(setVolume);
|
||||
PREP(setWeaponLightLaserState);
|
||||
PREP(showHud);
|
||||
PREP(statusEffect_addType);
|
||||
PREP(statusEffect_get);
|
||||
@ -187,6 +191,7 @@ PREP(stopGesture);
|
||||
PREP(stringCompare);
|
||||
PREP(stringToColoredText);
|
||||
PREP(swayLoop);
|
||||
PREP(switchAttachmentMode);
|
||||
PREP(switchPersistentLaser);
|
||||
PREP(switchToGroupSide);
|
||||
PREP(throttledPublicVariable);
|
||||
@ -265,6 +270,7 @@ PREP(_handleRequestAllSyncedEvents);
|
||||
PREP(addActionEventHandler);
|
||||
PREP(addActionMenuEventHandler);
|
||||
PREP(addMapMarkerCreatedEventHandler);
|
||||
PREP(addPlayerEH);
|
||||
|
||||
PREP(removeActionEventHandler);
|
||||
PREP(removeActionMenuEventHandler);
|
||||
|
@ -133,6 +133,30 @@
|
||||
_object lockInventory (_set > 0);
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
[QGVAR(disableAiUAV), {
|
||||
params ["_unit", "_disable"];
|
||||
|
||||
if (_disable) then {
|
||||
private _features = ["AUTOTARGET", "TARGET", "WEAPONAIM"/*, "FIREWEAPON"*/, "RADIOPROTOCOL"]; // TODO: Uncomment in 2.18
|
||||
|
||||
// Save current status
|
||||
_unit setVariable [QGVAR(featuresAiUAV), _features apply {[_x, _unit checkAIFeature _x]}];
|
||||
|
||||
{
|
||||
_unit enableAIFeature [_x, false];
|
||||
} forEach _features;
|
||||
} else {
|
||||
// Restore previous status
|
||||
private _features = _unit getVariable [QGVAR(featuresAiUAV), []];
|
||||
|
||||
{
|
||||
_unit enableAIFeature [_x select 0, _x select 1];
|
||||
} forEach _features;
|
||||
|
||||
_unit setVariable [QGVAR(featuresAiUAV), nil];
|
||||
};
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
//Add a fix for BIS's zeus remoteControl module not reseting variables on DC when RC a unit
|
||||
//This variable is used for isPlayer checks
|
||||
if (isServer) then {
|
||||
|
@ -10,6 +10,7 @@ PREP_RECOMPILE_END;
|
||||
GVAR(syncedEvents) = createHashMap;
|
||||
GVAR(showHudHash) = createHashMap;
|
||||
GVAR(vehicleIconCache) = createHashMap; // for getVehicleIcon
|
||||
GVAR(wheelSelections) = createHashMap;
|
||||
|
||||
GVAR(blockItemReplacement) = false;
|
||||
|
||||
|
@ -15,3 +15,25 @@ uiNamespace setVariable [QGVAR(addonCache), createHashMap];
|
||||
|
||||
// Cache for FUNC(getConfigName)
|
||||
uiNamespace setVariable [QGVAR(configNames), createHashMap];
|
||||
|
||||
//Add warnings for missing compat PBOs
|
||||
GVAR(isModLoadedCache) = createHashMap;
|
||||
{
|
||||
_x params ["_modPBO", "_compatPBO"];
|
||||
if ([_modPBO] call FUNC(isModLoaded) && {!([_compatPBO] call FUNC(isModLoaded))}) then {
|
||||
WARNING_2("Weapon Mod [%1] missing ace compat pbo [%2]",_modPBO,_compatPBO);
|
||||
};
|
||||
} forEach [
|
||||
["CUP_Creatures_People_LoadOrder","ace_compat_cup_units"],
|
||||
["CUP_Vehicles_LoadOrder","ace_compat_cup_vehicles"],
|
||||
["CUP_Weapons_LoadOrder","ace_compat_cup_weapons"],
|
||||
["r3f_armes_c","ace_compat_r3f"],
|
||||
["RF_Data_Loadorder","ace_compat_rf"],
|
||||
["RH_acc","ace_compat_rh_acc"],
|
||||
["RH_de_cfg","ace_compat_rh_de"],
|
||||
["RH_m4_cfg","ace_compat_rh_m4"],
|
||||
["RH_PDW","ace_compat_rh_pdw"],
|
||||
["RKSL_PMII","ace_compat_rksl_pm_ii"],
|
||||
["iansky_opt","ace_compat_sma3_iansky"],
|
||||
["R3F_Armes","ace_compat_r3f"]
|
||||
];
|
||||
|
@ -50,7 +50,7 @@ private _allWeapons = [];
|
||||
private _vics = "(configName _x) select [0,3] == 'ace'" configClasses (configFile >> "CfgVehicles");
|
||||
{
|
||||
if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then {
|
||||
if (!((toLowerANSI configName _x) in _allUnits)) then {
|
||||
if !((toLowerANSI configName _x) in _allUnits) then {
|
||||
WARNING_2("Not in any units[] - %1 from %2",configName _x,configSourceMod _x);
|
||||
_testPass = false;
|
||||
};
|
||||
@ -62,7 +62,7 @@ private _weapons = "(configName _x) select [0,3] == 'ace'" configClasses (config
|
||||
{
|
||||
private _type = toLowerANSI configName _x;
|
||||
if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then {
|
||||
if (!((toLowerANSI configName _x) in _allWeapons)) then {
|
||||
if !((toLowerANSI configName _x) in _allWeapons) then {
|
||||
WARNING_2("Not in any weapons[] - %1 from %2",configName _x,configSourceMod _x);
|
||||
_testPass = false;
|
||||
};
|
||||
|
@ -43,10 +43,10 @@ if (isNil "_keyTable") then {
|
||||
};
|
||||
};
|
||||
|
||||
private _keyCache = uiNamespace getVariable [QGVAR(keyNameCache), locationNull];
|
||||
private _keyCache = uiNamespace getVariable QGVAR(keyNameCache); // @TODO: Move cache creation to preStart/somewhere else
|
||||
|
||||
if (isNull _keyCache) then {
|
||||
_keyCache = call CBA_fnc_createNamespace;
|
||||
if (isNil "_keyCache") then {
|
||||
_keyCache = createHashMap;
|
||||
uiNamespace setVariable [QGVAR(keyNameCache), _keyCache];
|
||||
};
|
||||
|
||||
@ -54,7 +54,7 @@ params [["_action", "", [""]]];
|
||||
|
||||
private _keybinds = actionKeysNamesArray _action apply {
|
||||
private _keyName = _x;
|
||||
private _keybind = _keyCache getVariable _keyName;
|
||||
private _keybind = _keyCache get _keyName;
|
||||
|
||||
if (isNil "_keybind") then {
|
||||
private _key = -1;
|
||||
@ -101,7 +101,7 @@ private _keybinds = actionKeysNamesArray _action apply {
|
||||
|
||||
// cache
|
||||
_keybind = [_key, _shift, _ctrl, _alt];
|
||||
_keyCache setVariable [_keyName, _keybind];
|
||||
_keyCache set [_keyName, _keybind];
|
||||
};
|
||||
|
||||
_keybind
|
||||
|
63
addons/common/functions/fnc_addPlayerEH.sqf
Normal file
63
addons/common/functions/fnc_addPlayerEH.sqf
Normal file
@ -0,0 +1,63 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Adds event handler just to ACE_player
|
||||
* Can be removed after cba 3.18 is released for CBA_fnc_addBISPlayerEventHandler
|
||||
* This never was public in a release
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Key <STRING>
|
||||
* 1: Event Type <STRING>
|
||||
* 2: Event Code <CODE>
|
||||
* 3: Ignore Virtual Units (spectators, virtual zeus, uav RC) <BOOL> (default: true)
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* ["example", "FiredNear", {systemChat str _this}] call ace_common_fnc_addPlayerEH
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
params [["_key", "", [""]], ["_type", "", [""]], ["_code", {}, [{}]], ["_ignoreVirtual", true, [true]]];
|
||||
TRACE_3("addPlayerEH",_key,_type,_ignoreVirtual);
|
||||
|
||||
if (isNil QGVAR(playerEventsHash)) then { // first-run init
|
||||
GVAR(playerEventsHash) = createHashMap;
|
||||
["unit", {
|
||||
params ["_newPlayer", "_oldPlayer"];
|
||||
// uav check only applies to direct controlling UAVs from zeus, no effect on normal UAV operation
|
||||
private _isVirutal = (unitIsUAV _newPlayer) || {getNumber (configOf _newPlayer >> "isPlayableLogic") == 1};
|
||||
|
||||
TRACE_4("",_newPlayer,_oldPlayer,_isVirutal,count GVAR(playerEventsHash));
|
||||
{
|
||||
_y params ["_type", "_code", "_ignoreVirtual"];
|
||||
|
||||
private _oldEH = _oldPlayer getVariable [_x, -1];
|
||||
if (_oldEH != -1) then {
|
||||
_oldPlayer removeEventHandler [_type, _oldEH];
|
||||
_oldPlayer setVariable [_x, nil];
|
||||
};
|
||||
|
||||
_oldEH = _newPlayer getVariable [_x, -1];
|
||||
if (_oldEH != -1) then { continue }; // if respawned then var and EH already exists
|
||||
if (_ignoreVirtual && _isVirutal) then { continue };
|
||||
|
||||
private _newEH = _newPlayer addEventHandler [_type, _code];
|
||||
_newPlayer setVariable [_x, _newEH];
|
||||
} forEach GVAR(playerEventsHash);
|
||||
}, false] call CBA_fnc_addPlayerEventHandler;
|
||||
};
|
||||
|
||||
|
||||
_key = format [QGVAR(playerEvents_%1), toLower _key];
|
||||
if (_key in GVAR(playerEventsHash)) exitWith { ERROR_1("bad key %1",_this); };
|
||||
|
||||
GVAR(playerEventsHash) set [_key, [_type, _code, _ignoreVirtual]];
|
||||
|
||||
if (isNull ACE_player) exitWith {};
|
||||
if (_ignoreVirtual && {(unitIsUAV ACE_player) || {getNumber (configOf ACE_player >> "isPlayableLogic") == 1}}) exitWith {};
|
||||
|
||||
// Add event now
|
||||
private _newEH = ACE_player addEventHandler [_type, _code];
|
||||
ACE_player setVariable [_key, _newEH];
|
@ -15,15 +15,20 @@
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
// Don't execute in scheduled environment
|
||||
if (canSuspend) exitWith {
|
||||
[FUNC(checkFiles), nil] call CBA_fnc_directCall;
|
||||
};
|
||||
|
||||
///////////////
|
||||
// check addons
|
||||
// Check addons
|
||||
///////////////
|
||||
private _mainCfg = configFile >> "CfgPatches" >> "ace_main";
|
||||
private _mainVersion = getText (_mainCfg >> "versionStr");
|
||||
private _mainSource = configSourceMod _mainCfg;
|
||||
private _cfgPatches = configFile >> "CfgPatches";
|
||||
private _mainVersion = getText (_cfgPatches >> "ace_main" >> "versionStr");
|
||||
private _mainSource = configSourceMod (_cfgPatches >> "ace_main");
|
||||
|
||||
// CBA Versioning check - close main display if using incompatible version
|
||||
private _cbaVersionAr = getArray (configFile >> "CfgPatches" >> "cba_main" >> "versionAr");
|
||||
private _cbaVersionAr = getArray (_cfgPatches >> "cba_main" >> "versionAr");
|
||||
private _cbaRequiredAr = getArray (configFile >> "CfgSettings" >> "CBA" >> "Versioning" >> "ACE" >> "dependencies" >> "CBA") select 1;
|
||||
|
||||
private _cbaVersionStr = _cbaVersionAr joinString ".";
|
||||
@ -31,53 +36,62 @@ private _cbaRequiredStr = _cbaRequiredAr joinString ".";
|
||||
|
||||
INFO_3("ACE is version %1 - CBA is version %2 (min required %3)",_mainVersion,_cbaVersionStr,_cbaRequiredStr);
|
||||
|
||||
if ([_cbaRequiredAr, _cbaVersionAr] call cba_versioning_fnc_version_compare) then {
|
||||
if ([_cbaRequiredAr, _cbaVersionAr] call CBA_versioning_fnc_version_compare) then {
|
||||
private _errorMsg = format ["CBA version %1 is outdated (required %2)", _cbaVersionStr, _cbaRequiredStr];
|
||||
ERROR(_errorMsg);
|
||||
|
||||
if (hasInterface) then {
|
||||
["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
|
||||
["[ACE] ERROR", _errorMsg] call FUNC(errorMessage);
|
||||
};
|
||||
};
|
||||
|
||||
//private _addons = activatedAddons; // broken with High-Command module, see #2134
|
||||
private _addons = (cba_common_addons select {(_x select [0,4]) == "ace_"}) apply {toLowerANSI _x};
|
||||
//private _addons = activatedAddons; // Broken with High-Command module, see #2134
|
||||
private _addons = (CBA_common_addons select {(_x select [0, 4]) == "ace_"}) apply {toLowerANSI _x};
|
||||
|
||||
private _oldAddons = [];
|
||||
private _oldSources = [];
|
||||
private _oldCompats = [];
|
||||
|
||||
{
|
||||
private _addonCfg = configFile >> "CfgPatches" >> _x;
|
||||
private _addonVersion = getText (_addonCfg >> "versionStr");
|
||||
|
||||
if (_addonVersion != _mainVersion) then {
|
||||
private _addonSource = configSourceMod _addonCfg;
|
||||
|
||||
_oldSources pushBackUnique _addonSource;
|
||||
|
||||
// Check ACE install
|
||||
call FUNC(checkFiles_diagnoseACE);
|
||||
|
||||
// Don't block game if it's just an old compat pbo
|
||||
if ((_x select [0, 10]) != "ace_compat") then {
|
||||
if (hasInterface) then {
|
||||
_oldAddons pushBack _x;
|
||||
};
|
||||
} else {
|
||||
_oldCompats pushBack [_x, _addonVersion]; // Don't block game if it's just an old compat pbo
|
||||
_oldCompats pushBack [_x, _addonVersion];
|
||||
};
|
||||
};
|
||||
} forEach _addons;
|
||||
|
||||
if (_oldAddons isNotEqualTo []) then {
|
||||
_oldAddons = _oldAddons apply {format ["%1.pbo", _x]};
|
||||
private _errorMsg = "";
|
||||
if (count _oldAddons > 3) then {
|
||||
_errorMsg = format ["The following files are outdated: %1, and %2 more.<br/>ACE Main version is %3 from %4.<br/>Loaded mods with outdated ACE files: %5", (_oldAddons select [0, 3]) joinString ", ", (count _oldAddons) -3, _mainVersion, _mainSource, (_oldSources joinString ", ")];
|
||||
|
||||
private _errorMsg = if (count _oldAddons > 3) then {
|
||||
format ["The following files are outdated: %1, and %2 more.<br/>ACE Main version is %3 from %4.<br/>Loaded mods with outdated ACE files: %5", (_oldAddons select [0, 3]) joinString ", ", (count _oldAddons) - 3, _mainVersion, _mainSource, _oldSources joinString ", "];
|
||||
} else {
|
||||
_errorMsg = format ["The following files are outdated: %1.<br/>ACE Main version is %2 from %3.<br/>Loaded mods with outdated ACE files: %4", (_oldAddons) joinString ", ", _mainVersion, _mainSource, (_oldSources) joinString ", "];
|
||||
format ["The following files are outdated: %1.<br/>ACE Main version is %2 from %3.<br/>Loaded mods with outdated ACE files: %4", _oldAddons joinString ", ", _mainVersion, _mainSource, _oldSources joinString ", "];
|
||||
};
|
||||
|
||||
if (hasInterface) then {
|
||||
["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
|
||||
["[ACE] ERROR", _errorMsg] call FUNC(errorMessage);
|
||||
};
|
||||
|
||||
ERROR(_errorMsg);
|
||||
};
|
||||
|
||||
if (_oldCompats isNotEqualTo []) then {
|
||||
_oldCompats = _oldCompats apply {format ["%1 (%2)", _x select 0, _x select 1]};
|
||||
|
||||
[{
|
||||
// Lasts for ~10 seconds
|
||||
ERROR_WITH_TITLE_3("The following ACE compatiblity PBOs are outdated","%1. ACE Main version is %2 from %3.",_this select 0,_this select 1,_this select 2);
|
||||
@ -85,9 +99,10 @@ if (_oldCompats isNotEqualTo []) then {
|
||||
};
|
||||
|
||||
///////////////
|
||||
// check extensions
|
||||
// Check extensions
|
||||
///////////////
|
||||
private _platform = toLowerANSI (productVersion select 6);
|
||||
|
||||
if (!isServer && {_platform in ["linux", "osx"]}) then {
|
||||
// Linux and OSX client ports do not support extensions at all
|
||||
INFO("Operating system does not support extensions");
|
||||
@ -101,8 +116,10 @@ if (!isServer && {_platform in ["linux", "osx"]}) then {
|
||||
|
||||
if ((_isWindows || _isLinux) && {_isClient || _isServer}) then {
|
||||
private _versionEx = _extension callExtension "version";
|
||||
|
||||
if (_versionEx == "") then {
|
||||
private _extensionFile = _extension;
|
||||
|
||||
if (productVersion select 7 == "x64") then {
|
||||
_extensionFile = format ["%1_x64", _extensionFile];
|
||||
};
|
||||
@ -114,7 +131,7 @@ if (!isServer && {_platform in ["linux", "osx"]}) then {
|
||||
ERROR(_errorMsg);
|
||||
|
||||
if (hasInterface) then {
|
||||
["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
|
||||
["[ACE] ERROR", _errorMsg] call FUNC(errorMessage);
|
||||
};
|
||||
} else {
|
||||
// Print the current extension version
|
||||
@ -123,54 +140,66 @@ if (!isServer && {_platform in ["linux", "osx"]}) then {
|
||||
};
|
||||
} forEach ("true" configClasses (configFile >> "ACE_Extensions"));
|
||||
};
|
||||
|
||||
if (isArray (configFile >> "ACE_Extensions" >> "extensions")) then {
|
||||
WARNING("extensions[] array no longer supported");
|
||||
};
|
||||
|
||||
///////////////
|
||||
// check server version/addons
|
||||
// Check server version/addons
|
||||
///////////////
|
||||
if (isMultiplayer) then {
|
||||
// don't check optional addons
|
||||
_addons = _addons select {getNumber (configFile >> "CfgPatches" >> _x >> "ACE_isOptional") != 1};
|
||||
// Don't check optional addons
|
||||
_addons = _addons select {getNumber (_cfgPatches >> _x >> "ACE_isOptional") != 1};
|
||||
|
||||
if (isServer) then {
|
||||
// send servers version of ACE to all clients
|
||||
GVAR(ServerVersion) = _mainVersion;
|
||||
GVAR(ServerAddons) = _addons;
|
||||
publicVariable QGVAR(ServerVersion);
|
||||
publicVariable QGVAR(ServerAddons);
|
||||
// Send server's version of ACE to all clients
|
||||
GVAR(serverVersion) = _mainVersion;
|
||||
GVAR(serverAddons) = _addons;
|
||||
GVAR(serverSource) = _mainSource;
|
||||
|
||||
publicVariable QGVAR(serverVersion);
|
||||
publicVariable QGVAR(serverAddons);
|
||||
publicVariable QGVAR(serverSource);
|
||||
} else {
|
||||
// clients have to wait for the variables
|
||||
[{
|
||||
if (isNil QGVAR(ServerVersion) || isNil QGVAR(ServerAddons)) exitWith {};
|
||||
GVAR(clientVersion) = _version;
|
||||
GVAR(clientAddons) = _addons;
|
||||
|
||||
(_this select 0) params ["_mainVersion", "_addons"];
|
||||
|
||||
if (_mainVersion != GVAR(ServerVersion)) then {
|
||||
private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2.", GVAR(ServerVersion), _mainVersion];
|
||||
private _fnc_check = {
|
||||
if (GVAR(clientVersion) != GVAR(serverVersion)) then {
|
||||
private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2. Server modDir: %3", GVAR(serverVersion), GVAR(clientVersion), GVAR(serverSource)];
|
||||
|
||||
// Check ACE install
|
||||
call FUNC(checkFiles_diagnoseACE);
|
||||
|
||||
ERROR(_errorMsg);
|
||||
|
||||
if (hasInterface) then {
|
||||
["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
|
||||
["[ACE] ERROR", _errorMsg] call FUNC(errorMessage);
|
||||
};
|
||||
};
|
||||
|
||||
_addons = _addons - GVAR(ServerAddons);
|
||||
private _addons = GVAR(clientAddons) - GVAR(serverAddons);
|
||||
|
||||
if (_addons isNotEqualTo []) then {
|
||||
private _errorMsg = format ["Client/Server Addon Mismatch. Client has extra addons: %1.",_addons];
|
||||
private _errorMsg = format ["Client/Server Addon Mismatch. Client has additional addons: %1. Server modDir: %2", _addons, GVAR(serverSource)];
|
||||
|
||||
// Check ACE install
|
||||
call FUNC(checkFiles_diagnoseACE);
|
||||
|
||||
ERROR(_errorMsg);
|
||||
|
||||
if (hasInterface) then {
|
||||
["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
|
||||
["[ACE] ERROR", _errorMsg] call FUNC(errorMessage);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||
}, 1, [_mainVersion,_addons]] call CBA_fnc_addPerFrameHandler;
|
||||
// Clients have to wait for the variables
|
||||
if (isNil QGVAR(serverVersion) || isNil QGVAR(serverAddons)) then {
|
||||
GVAR(serverVersion) addPublicVariableEventHandler _fnc_check;
|
||||
} else {
|
||||
call _fnc_check;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,13 +1,13 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Diagnose ACE install problems, this will only be called if there is a known problem
|
||||
* Diagnoses ACE install problems, this will only be called if there is a known problem.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
* ACE addons' WS IDs <HASHMAP>
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_common_fnc_checkFiles_diagnoseACE
|
||||
@ -16,23 +16,35 @@
|
||||
*/
|
||||
|
||||
// Only run once
|
||||
if (missionNameSpace getVariable [QGVAR(checkFiles_diagnoseACE), false]) exitWith {};
|
||||
if (missionNameSpace getVariable [QGVAR(checkFiles_diagnoseACE), false]) exitWith {
|
||||
createHashMap // return
|
||||
};
|
||||
|
||||
GVAR(checkFiles_diagnoseACE) = true;
|
||||
|
||||
private _addons = cba_common_addons select {(_x select [0,4]) == "ace_"};
|
||||
private _addons = CBA_common_addons select {(_x select [0, 4]) == "ace_"};
|
||||
private _cfgPatches = configFile >> "CfgPatches";
|
||||
private _allMods = createHashMap;
|
||||
private _getLoadedModsInfo = getLoadedModsInfo;
|
||||
|
||||
// Check ACE_ADDONs are in expected mod DIR
|
||||
// Check if ACE_ADDONs are in expected mod DIR
|
||||
{
|
||||
private _cfg = (_cfgPatches >> _x);
|
||||
private _cfg = _cfgPatches >> _x;
|
||||
private _actualModDir = configSourceMod _cfg;
|
||||
private _expectedModDir = getText (_cfg >> "ACE_expectedModDir");
|
||||
if (_expectedModDir == "") then { _expectedModDir = "@ace" };
|
||||
|
||||
if (_expectedModDir == "") then {
|
||||
_expectedModDir = "@ace";
|
||||
};
|
||||
|
||||
private _expectedSteamID = getText (_cfg >> "ACE_expectedSteamID");
|
||||
if (_expectedSteamID == "") then { _expectedSteamID = "463939057" };
|
||||
|
||||
if (_expectedSteamID == "") then {
|
||||
_expectedSteamID = "463939057"
|
||||
};
|
||||
|
||||
(_allMods getOrDefault [_actualModDir, [], true]) pushBackUnique _expectedSteamID;
|
||||
|
||||
if (_actualModDir != _expectedModDir) then {
|
||||
private _errorMsg = format ["%1 loading from unexpected modDir [%2]", _x, _actualModDir];
|
||||
systemChat _errorMsg;
|
||||
@ -40,13 +52,17 @@ private _allMods = createHashMap;
|
||||
};
|
||||
} forEach _addons;
|
||||
|
||||
// Check all ACE ModDirs have expected steam WS ID
|
||||
// Check if all ACE ModDirs have expected steam WS ID
|
||||
{
|
||||
private _modDir = _x;
|
||||
if ((count _y) != 1) then { ERROR_2("Unexpected multiple steamIDs %1 - %2",_modDir,_y) };
|
||||
private _expectedSteamID = _y # 0;
|
||||
private _index = getLoadedModsInfo findIf {_x#1 == _modDir};
|
||||
(getLoadedModsInfo param [_index, []]) params [["_modName", "$Error$"], "", "", "", "", "", "", ["_actualID", ""]];
|
||||
|
||||
if (count _y != 1) then {
|
||||
ERROR_2("Unexpected multiple steamIDs %1 - %2",_modDir,_y);
|
||||
};
|
||||
|
||||
private _expectedSteamID = _y select 0;
|
||||
private _index = _getLoadedModsInfo findIf {_x select 1 == _modDir};
|
||||
(_getLoadedModsInfo param [_index, []]) params [["_modName", "$Error$"], "", "", "", "", "", "", ["_actualID", ""]];
|
||||
|
||||
if (_actualID != _expectedSteamID) then {
|
||||
private _errorMsg = format ["%1 [%2] unexpected workshopID [%3]", _modDir, _modName, _actualID];
|
||||
@ -55,4 +71,4 @@ private _allMods = createHashMap;
|
||||
};
|
||||
} forEach _allMods;
|
||||
|
||||
_allMods
|
||||
_allMods // return
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: commy2
|
||||
* Author: commy2, johnb43
|
||||
* Used to execute the checkPBOs module without placing the module. Don't use this together with the module.
|
||||
* Checks PBO versions and compares to the one running on server.
|
||||
*
|
||||
@ -9,8 +9,8 @@
|
||||
* 0 = Warn once
|
||||
* 1 = Warn permanently
|
||||
* 2 = Kick
|
||||
* 1: Check all PBOs? (default: false) <BOOL>
|
||||
* 2: Whitelist (default: "") <STRING>
|
||||
* 1: Check all PBOs? <BOOL> (default: false)
|
||||
* 2: Whitelist <STRING> (default: "")
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
@ -24,7 +24,7 @@
|
||||
params ["_mode", ["_checkAll", false], ["_whitelist", "", [""]]];
|
||||
TRACE_3("params",_mode,_checkAll,_whitelist);
|
||||
|
||||
//lowercase and convert whiteList String into array of strings:
|
||||
// Lowercase and convert whiteList string into array of strings
|
||||
_whitelist = toLowerANSI _whitelist;
|
||||
_whitelist = _whitelist splitString "[,""']";
|
||||
TRACE_1("Array",_whitelist);
|
||||
@ -32,75 +32,67 @@ TRACE_1("Array",_whitelist);
|
||||
ACE_Version_CheckAll = _checkAll;
|
||||
ACE_Version_Whitelist = _whitelist;
|
||||
|
||||
if (!_checkAll) exitWith {}; //ACE is checked by FUNC(checkFiles)
|
||||
// ACE is checked by FUNC(checkFiles)
|
||||
if (!_checkAll) exitWith {};
|
||||
|
||||
if (!isServer) then {
|
||||
[{
|
||||
if (isNil "ACE_Version_ClientErrors") exitWith {};
|
||||
["ace_versioning_clientCheckDone", {
|
||||
// Don't let this event get triggered again
|
||||
[_thisType, _thisId] call CBA_fnc_removeEventHandler;
|
||||
|
||||
ACE_Version_ClientErrors params ["_missingAddon", "_missingAddonServer", "_oldVersionClient", "_oldVersionServer"];
|
||||
params ["_clientErrors"];
|
||||
_clientErrors params ["_missingAddonClient", "_additionalAddonClient", "_olderVersionClient", "_newerVersionClient"];
|
||||
_thisArgs params ["_mode"];
|
||||
|
||||
(_this select 0) params ["_mode", "_checkAll", "_whitelist"];
|
||||
// Display error message(s)
|
||||
if (_missingAddonClient || {_additionalAddonClient} || {_olderVersionClient} || {_newerVersionClient}) then {
|
||||
private _errorMsg = "[ACE] Version mismatch:<br/><br/>";
|
||||
private _error = [];
|
||||
|
||||
// Display error message.
|
||||
if (_missingAddon || {_missingAddonServer} || {_oldVersionClient} || {_oldVersionServer}) then {
|
||||
private _text = "[ACE] Version mismatch:<br/><br/>";
|
||||
private _error = format ["ACE version mismatch: %1: ", profileName];
|
||||
|
||||
if (_missingAddon) then {
|
||||
_text = _text + "Detected missing addon on client<br/>";
|
||||
_error = _error + "Missing file(s); ";
|
||||
};
|
||||
if (_missingAddonServer) then {
|
||||
_text = _text + "Detected missing addon on server<br/>";
|
||||
_error = _error + "Additional file(s); ";
|
||||
};
|
||||
if (_oldVersionClient) then {
|
||||
_text = _text + "Detected old client version<br/>";
|
||||
_error = _error + "Older version; ";
|
||||
};
|
||||
if (_oldVersionServer) then {
|
||||
_text = _text + "Detected old server version<br/>";
|
||||
_error = _error + "Newer version; ";
|
||||
if (_missingAddonClient) then {
|
||||
_errorMsg = _errorMsg + "Detected missing addon on client<br/>";
|
||||
_error pushBack "Missing file(s)";
|
||||
};
|
||||
|
||||
//[QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent;
|
||||
if (_additionalAddonClient) then {
|
||||
_errorMsg = _errorMsg + "Detected additional addon on client<br/>";
|
||||
_error pushBack "Additional file(s)";
|
||||
};
|
||||
|
||||
ERROR(_error);
|
||||
if (_olderVersionClient) then {
|
||||
_errorMsg = _errorMsg + "Detected older client version<br/>";
|
||||
_error pushBack "Older version";
|
||||
};
|
||||
|
||||
if (_newerVersionClient) then {
|
||||
_errorMsg = _errorMsg + "Detected newer client version<br/>";
|
||||
_error pushBack "Newer version";
|
||||
};
|
||||
|
||||
ERROR_2("[ACE] Version mismatch: %1: %2",profileName,_error joinString ", ");
|
||||
|
||||
_errorMsg = parseText format ["<t align='center'>%1</t>", _errorMsg];
|
||||
|
||||
// Warn
|
||||
if (_mode < 2) then {
|
||||
_text = composeText [lineBreak, parseText format ["<t align='center'>%1</t>", _text]];
|
||||
|
||||
private _rscLayer = "ACE_RscErrorHint" call BIS_fnc_rscLayer;
|
||||
_rscLayer cutRsc ["ACE_RscErrorHint", "PLAIN", 0, true];
|
||||
|
||||
disableSerialization;
|
||||
private _ctrlHint = uiNamespace getVariable "ACE_ctrlErrorHint";
|
||||
_ctrlHint ctrlSetStructuredText _text;
|
||||
(uiNamespace getVariable "ACE_ctrlErrorHint") ctrlSetStructuredText composeText [lineBreak, _errorMsg];
|
||||
|
||||
if (_mode == 0) then {
|
||||
[{
|
||||
params ["_rscLayer"];
|
||||
TRACE_2("Hiding Error message after 10 seconds",time,_rscLayer);
|
||||
_rscLayer cutFadeOut 0.2;
|
||||
}, [_rscLayer], 10] call CBA_fnc_waitAndExecute;
|
||||
TRACE_2("Hiding Error message after 10 seconds",time,_this);
|
||||
_this cutFadeOut 0.2;
|
||||
}, _rscLayer, 10] call CBA_fnc_waitAndExecute;
|
||||
};
|
||||
} else {
|
||||
// Kick
|
||||
["[ACE] ERROR", composeText [_errorMsg]] call FUNC(errorMessage);
|
||||
};
|
||||
};
|
||||
}, [_mode]] call CBA_fnc_addEventHandlerArgs;
|
||||
};
|
||||
|
||||
if (_mode == 2) then {
|
||||
[{alive player}, { // To be able to show list if using checkAll
|
||||
params ["_text"];
|
||||
TRACE_2("Player is alive, showing msg and exiting",time,_text);
|
||||
_text = composeText [parseText format ["<t align='center'>%1</t>", _text]];
|
||||
["[ACE] ERROR", _text, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage);
|
||||
}, [_text]] call CBA_fnc_waitUntilAndExecute;
|
||||
};
|
||||
};
|
||||
|
||||
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||
}, 1, [_mode, _checkAll, _whitelist]] call CBA_fnc_addPerFrameHandler;
|
||||
};
|
||||
|
||||
if (_checkAll) then {
|
||||
0 spawn COMPILE_FILE(scripts\checkVersionNumber); // @todo
|
||||
};
|
||||
// Check file version numbers
|
||||
[_whitelist] call FUNC(checkVersionNumber);
|
||||
|
161
addons/common/functions/fnc_checkVersionNumber.sqf
Normal file
161
addons/common/functions/fnc_checkVersionNumber.sqf
Normal file
@ -0,0 +1,161 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: commy2, johnb43
|
||||
* Compares version numbers from loaded addons.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Lowercase addon whitelist <ARRAY> (default: missionNamespace getVariable ["ACE_Version_Whitelist", []])
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* call ace_common_fnc_checkVersionNumber
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
// Don't execute in scheduled environment
|
||||
if (canSuspend) exitWith {
|
||||
[FUNC(checkVersionNumber), _this] call CBA_fnc_directCall;
|
||||
};
|
||||
|
||||
params [["_whitelist", missionNamespace getVariable ["ACE_Version_Whitelist", []]]];
|
||||
|
||||
private _files = CBA_common_addons select {
|
||||
(_x select [0, 3] != "a3_") &&
|
||||
{_x select [0, 4] != "ace_"} &&
|
||||
{!((toLowerANSI _x) in _whitelist)}
|
||||
};
|
||||
|
||||
private _cfgPatches = configFile >> "CfgPatches";
|
||||
private _versions = [];
|
||||
|
||||
{
|
||||
(getText (_cfgPatches >> _x >> "version") splitString ".") params [["_major", "0"], ["_minor", "0"]];
|
||||
private _version = parseNumber _major + parseNumber _minor / 100;
|
||||
_versions pushBack _version;
|
||||
} forEach _files;
|
||||
|
||||
if (isServer) exitWith {
|
||||
ACE_Version_ServerVersions = [_files, _versions];
|
||||
publicVariable "ACE_Version_ServerVersions";
|
||||
|
||||
// Raise event when done
|
||||
["ace_versioning_serverCheckDone", [+ACE_Version_ServerVersions]] call CBA_fnc_localEvent;
|
||||
};
|
||||
|
||||
// Begin client version check
|
||||
ACE_Version_ClientVersions = [_files, _versions];
|
||||
|
||||
private _fnc_check = {
|
||||
ACE_Version_ClientVersions params [["_files", []], ["_versions", []]];
|
||||
ACE_Version_ServerVersions params [["_serverFiles", []], ["_serverVersions", []]];
|
||||
|
||||
// Compare client and server files and versions
|
||||
private _client = profileName;
|
||||
private _missingAddonsClient = [];
|
||||
private _olderVersionsClient = [];
|
||||
private _newerVersionsClient = [];
|
||||
|
||||
{
|
||||
private _serverVersion = _serverVersions select _forEachIndex;
|
||||
|
||||
private _index = _files find _x;
|
||||
|
||||
if (_index == -1) then {
|
||||
if (_x != "ace_server") then {
|
||||
_missingAddonsClient pushBack _x;
|
||||
};
|
||||
} else {
|
||||
private _clientVersion = _versions select _index;
|
||||
|
||||
if (_clientVersion < _serverVersion) then {
|
||||
_olderVersionsClient pushBack [_x, _clientVersion, _serverVersion];
|
||||
};
|
||||
|
||||
if (_clientVersion > _serverVersion) then {
|
||||
_newerVersionsClient pushBack [_x, _clientVersion, _serverVersion];
|
||||
};
|
||||
};
|
||||
} forEach _serverFiles;
|
||||
|
||||
// Find client files which the server doesn't have
|
||||
private _additionalAddonsClient = _files select {!(_x in _serverFiles)};
|
||||
|
||||
// Check for client missing addons, server missing addons, client outdated addons and server outdated addons
|
||||
private _clientErrors = [];
|
||||
|
||||
#define DISPLAY_NUMBER_ADDONS (10 + 1) // +1 to account for header
|
||||
|
||||
{
|
||||
_x params ["_items", "_string"];
|
||||
|
||||
// Check if something is either missing or outdated
|
||||
private _isMissingItems = _items isNotEqualTo [];
|
||||
|
||||
if (_isMissingItems) then {
|
||||
// Generate error message
|
||||
private _errorLog = +_items;
|
||||
private _header = format ["[ACE] %1: ERROR %2 addon(s): ", _client, _string];
|
||||
|
||||
// Don't display all missing items, as they are logged
|
||||
private _errorMsg = _header + ((_errorLog select [0, DISPLAY_NUMBER_ADDONS]) joinString ", ");
|
||||
_errorLog = _header + (_errorLog joinString ", ");
|
||||
|
||||
private _count = count _items;
|
||||
|
||||
if (_count > DISPLAY_NUMBER_ADDONS) then {
|
||||
_errorMsg = _errorMsg + format [", and %1 more.", _count - DISPLAY_NUMBER_ADDONS];
|
||||
};
|
||||
|
||||
// Wait until in briefing screen
|
||||
[{
|
||||
getClientStateNumber >= 9 // "BRIEFING SHOWN"
|
||||
}, {
|
||||
params ["_errorLog", "_errorMsg"];
|
||||
|
||||
// Log and display error messages
|
||||
diag_log text _errorLog;
|
||||
[QGVAR(serverLog), _errorLog] call CBA_fnc_serverEvent;
|
||||
[QGVAR(systemChatGlobal), _errorMsg] call CBA_fnc_globalEvent;
|
||||
|
||||
// Wait until after map screen
|
||||
[{
|
||||
!isNull (call BIS_fnc_displayMission)
|
||||
}, {
|
||||
params ["_errorMsg", "_timeOut"];
|
||||
|
||||
// If the briefing screen was shown for less than 5 seconds, display the error message again, but locally
|
||||
if (_timeOut < CBA_missionTime) exitWith {};
|
||||
|
||||
// Make sure systemChat is ready by waiting a bit
|
||||
[{
|
||||
systemChat _this;
|
||||
}, _errorMsg, 1] call CBA_fnc_waitAndExecute;
|
||||
}, [_errorMsg, CBA_missionTime + 5]] call CBA_fnc_waitUntilAndExecute;
|
||||
}, [_errorLog, _errorMsg]] call CBA_fnc_waitUntilAndExecute;
|
||||
};
|
||||
|
||||
_clientErrors pushBack _isMissingItems;
|
||||
} forEach [
|
||||
[_missingAddonsClient, "client missing"],
|
||||
[_additionalAddonsClient, "client additional"],
|
||||
[_olderVersionsClient, "older client"],
|
||||
[_newerVersionsClient, "newer client"]
|
||||
];
|
||||
|
||||
TRACE_4("",_missingAddonsClient,_additionalAddonsClient,_olderVersionsClient,_newerVersionsClient);
|
||||
|
||||
ACE_Version_ClientErrors = _clientErrors;
|
||||
|
||||
// Raise event when done
|
||||
["ace_versioning_clientCheckDone", [+ACE_Version_ClientErrors]] call CBA_fnc_localEvent;
|
||||
};
|
||||
|
||||
// Wait for server to send the servers files and version numbers
|
||||
if (isNil "ACE_Version_ServerVersions") then {
|
||||
ACE_Version_ServerVersions addPublicVariableEventHandler _fnc_check;
|
||||
} else {
|
||||
call _fnc_check;
|
||||
};
|
@ -24,7 +24,7 @@ params ["_name", "_value", "_defaultGlobal", "_category", ["_code", 0], ["_persi
|
||||
|
||||
if (isNil "_defaultGlobal") exitWith {};
|
||||
|
||||
if (!(_name isEqualType "")) exitwith {
|
||||
if !(_name isEqualType "") exitwith {
|
||||
[format ["Tried to the deinfe a variable with an invalid name: %1 Arguments: %2", _name, _this]] call FUNC(debug);
|
||||
};
|
||||
|
||||
|
@ -29,7 +29,7 @@ if !([_unit] call EFUNC(common,isPlayer)) then {
|
||||
_unit disableConversation true;
|
||||
} else {
|
||||
//Sanity check to make sure we don't enable unconsious AI
|
||||
if (_unit getVariable ["ace_isunconscious", false] && alive _unit) exitWith {
|
||||
if (_unit getVariable ["ACE_isUnconscious", false] && alive _unit) exitWith {
|
||||
ERROR("Enabling AI for unconsious unit");
|
||||
};
|
||||
|
||||
|
45
addons/common/functions/fnc_disableAiUAV.sqf
Normal file
45
addons/common/functions/fnc_disableAiUAV.sqf
Normal file
@ -0,0 +1,45 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: johnb43
|
||||
* Disables/Enables UAV AI crew members, can be run on any machine and is applied globally.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Disable AI <BOOL>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [cursorObject, true] call ace_common_fnc_disableAiUAV
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params [["_unit", objNull, [objNull]], ["_disable", true, [false]]];
|
||||
|
||||
// Allow disabling of Zeus remote controlled units
|
||||
if (!alive _unit || {isPlayer _unit} || {!unitIsUAV _unit}) exitWith {};
|
||||
|
||||
if (_disable) then {
|
||||
// Ignore if already disabled
|
||||
if (!isNil "_jipID") exitWith {};
|
||||
|
||||
// Disable shooting and targeting on every machine
|
||||
// Give predefined JIP ID, in case of simultaneous executions on different machines
|
||||
private _jipID = [QGVAR(disableAiUAV), [_unit, _disable], QGVAR(disableAiUAV_) + hashValue _unit] call CBA_fnc_globalEventJIP;
|
||||
[_jipID, _unit] call CBA_fnc_removeGlobalEventJIP;
|
||||
|
||||
_unit setVariable [QGVAR(disableAiUavJipID), _jipID, true];
|
||||
} else {
|
||||
// Restore shooting and targeting to each client's individual state prior to disabling
|
||||
private _jipID = _unit getVariable QGVAR(disableAiUavJipID);
|
||||
|
||||
if (isNil "_jipID") exitWith {};
|
||||
|
||||
_jipID call CBA_fnc_removeGlobalEventJIP;
|
||||
|
||||
_unit setVariable [QGVAR(disableAiUavJipID), nil, true];
|
||||
|
||||
[QGVAR(disableAiUAV), [_unit, _disable]] call CBA_fnc_globalEvent;
|
||||
};
|
@ -1,46 +1,53 @@
|
||||
#include "..\script_component.hpp"
|
||||
#include "\a3\ui_f\hpp\defineResincl.inc"
|
||||
#include "\a3\ui_f\hpp\defineDIKCodes.inc"
|
||||
/*
|
||||
* Author: commy2, based on BIS_fnc_errorMsg and BIS_fnc_guiMessage by Karel Moricky (BI)
|
||||
* Stops simulation and opens a textbox with error message.
|
||||
* Author: commy2, johnb43, based on BIS_fnc_errorMsg and BIS_fnc_guiMessage by Karel Moricky (BI)
|
||||
* Opens a textbox with an error message, used for PBO checking.
|
||||
*
|
||||
* Arguments:
|
||||
* ?
|
||||
* 0: Header <STRING>
|
||||
* 1: Text <STRING|TEXT>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* call ace_common_fnc_errorMessage
|
||||
* ["[ACE] ERROR", "Test"] call ace_common_fnc_errorMessage
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
disableSerialization;
|
||||
// Force stop any loading screens
|
||||
endLoadingScreen;
|
||||
|
||||
// no message without player possible
|
||||
// No message without interface possible
|
||||
if (!hasInterface) exitWith {};
|
||||
|
||||
// wait for display
|
||||
if (isNull (call BIS_fnc_displayMission)) exitWith {
|
||||
[{
|
||||
if (isNull (call BIS_fnc_displayMission)) exitWith {};
|
||||
!isNull (call BIS_fnc_displayMission)
|
||||
}, {
|
||||
params ["_textHeader", "_textMessage"];
|
||||
|
||||
(_this select 0) call FUNC(errorMessage);
|
||||
[_this select 1] call CBA_fnc_removePerFrameHandler;
|
||||
disableSerialization;
|
||||
|
||||
}, 1, _this] call CBA_fnc_addPerFrameHandler;
|
||||
// Use curator display if present
|
||||
private _curatorDisplay = findDisplay 312;
|
||||
|
||||
private _mainDisplay = if (!isNull _curatorDisplay) then {
|
||||
_curatorDisplay
|
||||
} else {
|
||||
call BIS_fnc_displayMission
|
||||
};
|
||||
|
||||
params ["_textHeader", "_textMessage", ["_onOK", {}], ["_onCancel", {}]];
|
||||
|
||||
if (_textMessage isEqualType "") then {
|
||||
_textMessage = parseText _textMessage;
|
||||
};
|
||||
|
||||
ARR_SELECT(_this,4,call BIS_fnc_displayMission) createDisplay "RscDisplayCommonMessagePause";
|
||||
private _display = _mainDisplay createDisplay "RscDisplayCommonMessagePause";
|
||||
|
||||
if (isNull _display) exitWith {};
|
||||
|
||||
private _display = uiNamespace getVariable "RscDisplayCommonMessage_display";
|
||||
private _ctrlRscMessageBox = _display displayCtrl 2351;
|
||||
private _ctrlBcgCommonTop = _display displayCtrl 235100;
|
||||
private _ctrlBcgCommon = _display displayCtrl 235101;
|
||||
@ -109,39 +116,26 @@ _ctrlRscMessageBox ctrlSetPosition [
|
||||
_ctrlRscMessageBox ctrlEnable true;
|
||||
_ctrlRscMessageBox ctrlCommit 0;
|
||||
|
||||
if (_onOK isEqualTo {}) then {
|
||||
_ctrlButtonOK ctrlEnable false;
|
||||
_ctrlButtonOK ctrlSetFade 0;
|
||||
_ctrlButtonOK ctrlSetText "";
|
||||
_ctrlButtonOK ctrlCommit 0;
|
||||
} else {
|
||||
// Enable ok button
|
||||
_ctrlButtonOK ctrlEnable true;
|
||||
_ctrlButtonOK ctrlSetFade 0;
|
||||
_ctrlButtonOK ctrlSetText localize "STR_DISP_OK";
|
||||
_ctrlButtonOK ctrlCommit 0;
|
||||
|
||||
ctrlSetFocus _ctrlButtonOK;
|
||||
};
|
||||
|
||||
if (_onCancel isEqualTo {}) then {
|
||||
// Disable cancel button
|
||||
_ctrlButtonCancel ctrlEnable false;
|
||||
_ctrlButtonCancel ctrlSetFade 0;
|
||||
_ctrlButtonCancel ctrlSetText "";
|
||||
_ctrlButtonCancel ctrlCommit 0;
|
||||
} else {
|
||||
_ctrlButtonCancel ctrlEnable true;
|
||||
_ctrlButtonCancel ctrlSetFade 0;
|
||||
_ctrlButtonCancel ctrlSetText localize "STR_DISP_CANCEL";
|
||||
_ctrlButtonCancel ctrlCommit 0;
|
||||
|
||||
ctrlSetFocus _ctrlButtonCancel;
|
||||
};
|
||||
_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", {(ctrlParent (_this select 0)) closeDisplay IDC_OK; true}];
|
||||
|
||||
_ctrlButtonOK ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 1; true}];
|
||||
_ctrlButtonCancel ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 2; true}];
|
||||
// Intercept all keystrokes except the enter keys
|
||||
_display displayAddEventHandler ["KeyDown", {!((_this select 1) in [DIK_RETURN, DIK_NUMPADENTER])}];
|
||||
|
||||
GVAR(errorOnOK) = _onOK;
|
||||
GVAR(errorOnCancel) = _onCancel;
|
||||
|
||||
_display displayAddEventHandler ["unload", {call ([{}, GVAR(errorOnOK), GVAR(errorOnCancel)] select (_this select 1))}];
|
||||
_display displayAddEventHandler ["keyDown", {_this select 1 == 1}];
|
||||
// Close curator and mission displays (because of the message display, it doesn't quit the mission yet)
|
||||
findDisplay 312 closeDisplay 0;
|
||||
findDisplay 46 closeDisplay 0;
|
||||
}, _this] call CBA_fnc_waitUntilAndExecute;
|
||||
|
@ -32,7 +32,6 @@ scopeName "main";
|
||||
if (_x select 0 == _name) then {
|
||||
_x breakOut "main";
|
||||
};
|
||||
false
|
||||
} count GVAR(settings);
|
||||
} forEach GVAR(settings);
|
||||
|
||||
[]
|
||||
|
@ -1,34 +1,45 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: commy2
|
||||
* Author: commy2, johnb43
|
||||
* Get the available firing modes of a weapon. Will ignore the AI helper modes.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Weapon <STRING>
|
||||
* 1: Muzzle <STRING> (default: weapon)
|
||||
*
|
||||
* Return Value:
|
||||
* Firing Modes <ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* ["gun"] call ace_common_fnc_getWeaponModes
|
||||
* "arifle_AK12_F" call ace_common_fnc_getWeaponModes
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [["_weapon", "", [""]]];
|
||||
params [["_weapon", "", [""]], ["_muzzle", nil, [""]]];
|
||||
|
||||
private _config = configFile >> "CfgWeapons" >> _weapon;
|
||||
|
||||
if (!isNil "_muzzle") then {
|
||||
_config = _config >> _muzzle
|
||||
};
|
||||
|
||||
if (!isClass _config) exitWith {
|
||||
[] // return
|
||||
};
|
||||
|
||||
private _modes = [];
|
||||
|
||||
{
|
||||
if (getNumber (_config >> _x >> "showToPlayer") == 1) then {
|
||||
_modes pushBack _x;
|
||||
};
|
||||
|
||||
if (_x == "this") then {
|
||||
_modes pushBack _weapon;
|
||||
_modes pushBack (configName _config);
|
||||
} else {
|
||||
if (isClass (_config >> _x)) then {
|
||||
_modes pushBack (configName (_config >> _x));
|
||||
};
|
||||
};
|
||||
};
|
||||
} forEach getArray (_config >> "modes");
|
||||
|
||||
_modes
|
||||
_modes // return
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: commy2
|
||||
* Author: commy2, johnb43
|
||||
* Get the muzzles of a weapon.
|
||||
*
|
||||
* Arguments:
|
||||
@ -10,19 +10,30 @@
|
||||
* All weapon muzzles <ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* ["gun"] call ace_common_fnc_getWeaponMuzzles
|
||||
* "arifle_AK12_F" call ace_common_fnc_getWeaponMuzzles
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [["_weapon", "", [""]]];
|
||||
|
||||
private _muzzles = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles");
|
||||
private _config = configFile >> "CfgWeapons" >> _weapon;
|
||||
|
||||
if (!isClass _config) exitWith {
|
||||
[] // return
|
||||
};
|
||||
|
||||
private _muzzles = [];
|
||||
|
||||
// Get config case muzzle names
|
||||
{
|
||||
if (_x == "this") then {
|
||||
_muzzles set [_forEachIndex, configName (configFile >> "CfgWeapons" >> _weapon)];
|
||||
_muzzles pushBack (configName _config);
|
||||
} else {
|
||||
if (isClass (_config >> _x)) then {
|
||||
_muzzles pushBack (configName (_config >> _x));
|
||||
};
|
||||
} forEach _muzzles;
|
||||
};
|
||||
} forEach getArray (_config >> "muzzles");
|
||||
|
||||
_muzzles
|
||||
_muzzles // return
|
||||
|
104
addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf
Normal file
104
addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf
Normal file
@ -0,0 +1,104 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: commy2, johnb43
|
||||
* Returns the wheel hitpoints and their selections.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Vehicle <OBJECT>
|
||||
*
|
||||
* Return Value:
|
||||
* 0: Wheel hitpoints <ARRAY>
|
||||
* 1: Wheel hitpoint selections <ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* cursorObject call ace_common_fnc_getWheelHitPointsWithSelections
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_vehicle"];
|
||||
TRACE_1("params",_vehicle);
|
||||
|
||||
// TODO: Fix for GM vehicles
|
||||
GVAR(wheelSelections) getOrDefaultCall [typeOf _vehicle, {
|
||||
// Get the vehicles wheel config
|
||||
private _wheels = configOf _vehicle >> "Wheels";
|
||||
|
||||
if (isClass _wheels) then {
|
||||
// Get all hitpoints and selections
|
||||
(getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"];
|
||||
|
||||
// Get all wheels and read selections from config
|
||||
_wheels = "true" configClasses _wheels;
|
||||
|
||||
private _wheelHitPoints = [];
|
||||
private _wheelHitPointSelections = [];
|
||||
|
||||
{
|
||||
private _wheelName = configName _x;
|
||||
private _wheelCenter = getText (_x >> "center");
|
||||
private _wheelBone = getText (_x >> "boneName");
|
||||
private _wheelBoneNameResized = _wheelBone select [0, 9]; // Count "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles.
|
||||
|
||||
TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized);
|
||||
|
||||
private _wheelHitPoint = "";
|
||||
private _wheelHitPointSelection = "";
|
||||
|
||||
// Commy's orginal method
|
||||
{
|
||||
if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx.
|
||||
_wheelHitPoint = _hitPoints select _forEachIndex;
|
||||
_wheelHitPointSelection = _hitPointSelections select _forEachIndex;
|
||||
TRACE_2("wheel found [Orginal]",_wheelName,_wheelHitPoint);
|
||||
};
|
||||
} forEach _hitPointSelections;
|
||||
|
||||
|
||||
if (_vehicle isKindOf "Car") then {
|
||||
// Backup method, search for the closest hitpoint to the wheel's center selection pos.
|
||||
// Ref #2742 - RHS's HMMWV
|
||||
if (_wheelHitPoint == "") then {
|
||||
private _wheelCenterPos = _vehicle selectionPosition _wheelCenter;
|
||||
if (_wheelCenterPos isEqualTo [0, 0, 0]) exitWith {TRACE_1("no center?",_wheelCenter);};
|
||||
|
||||
|
||||
private _bestDist = 99;
|
||||
private _bestIndex = -1;
|
||||
{
|
||||
if (_x != "") then {
|
||||
// Filter out things that definitly aren't wheeels (#3759)
|
||||
if ((toLowerANSI (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)};
|
||||
private _xPos = _vehicle selectionPosition _x;
|
||||
if (_xPos isEqualTo [0, 0, 0]) exitWith {};
|
||||
private _xDist = _wheelCenterPos distance _xPos;
|
||||
if (_xDist < _bestDist) then {
|
||||
_bestIndex = _forEachIndex;
|
||||
_bestDist = _xDist;
|
||||
};
|
||||
};
|
||||
} forEach _hitPointSelections;
|
||||
|
||||
TRACE_2("closestPoint",_bestDist,_bestIndex);
|
||||
if (_bestIndex != -1) then {
|
||||
_wheelHitPoint = _hitPoints select _bestIndex;
|
||||
_wheelHitPointSelection = _hitPointSelections select _bestIndex;
|
||||
TRACE_2("wheel found [Backup]",_wheelName,_wheelHitPoint);
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then {
|
||||
_wheelHitPoints pushBack _wheelHitPoint;
|
||||
_wheelHitPointSelections pushBack _wheelHitPointSelection;
|
||||
};
|
||||
} forEach _wheels;
|
||||
|
||||
[_wheelHitPoints, _wheelHitPointSelections]
|
||||
} else {
|
||||
// Exit with nothing if the vehicle has no wheels class
|
||||
TRACE_1("No Wheels",_wheels);
|
||||
|
||||
[[], []]
|
||||
}
|
||||
}, true] // return
|
@ -1,21 +1,21 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Glowbal
|
||||
* Check if unit has item. Note: case-sensitive.
|
||||
* Check if given unit has an item of given classname. Note: Case sensitive.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Item Classname <STRING>
|
||||
* 1: Item classname <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* Unit has Item <BOOL>
|
||||
* Unit has item <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [bob, "item"] call ace_common_fnc_hasItem
|
||||
* [player, "ACE_Banana"] call ace_common_fnc_hasItem
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [["_unit", objNull, [objNull]], ["_item", "", [""]]];
|
||||
|
||||
_item in (_unit call EFUNC(common,uniqueItems))
|
||||
_item in (_unit call FUNC(uniqueItems)) // return
|
||||
|
@ -1,23 +1,21 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Glowbal
|
||||
* Check if given unit has a magazine of given classname
|
||||
* Check if given unit has a magazine of given classname. Note: Case sensitive.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Magazine Classname <STRING>
|
||||
* 1: Magazine classname <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* has Magazine <BOOL>
|
||||
* Unit has magazine <BOOL>
|
||||
*
|
||||
* Example:
|
||||
* [bob, "magazine"] call ace_common_fnc_hasMagazine
|
||||
* [player, "30Rnd_65x39_caseless_mag"] call ace_common_fnc_hasMagazine
|
||||
*
|
||||
* Public: yes
|
||||
*
|
||||
* Note: Case sensitive
|
||||
*/
|
||||
|
||||
params [["_unit", objNull, [objNull]], ["_magazine", "", [""]]];
|
||||
|
||||
_magazine in magazines _unit // return
|
||||
_magazine in ([_unit, 2] call FUNC(uniqueItems)) // return
|
||||
|
@ -22,7 +22,7 @@ params ["_unit", ["_distance", 10], ["_cargoOnly", false]];
|
||||
private _nearVehicles = nearestObjects [_unit, ["Car", "Air", "Tank", "Ship_F", "Pod_Heli_Transport_04_crewed_base_F"], _distance];
|
||||
_nearVehicles select {
|
||||
// Filter cargo seats that will eject unconscious units (e.g. quad bike)
|
||||
private _canSitInCargo = (!(_unit getVariable ['ACE_isUnconscious', false])) || {(getNumber (configOf _x >> "ejectDeadCargo")) == 0};
|
||||
private _canSitInCargo = (_unit call EFUNC(common,isAwake)) || {(getNumber (configOf _x >> "ejectDeadCargo")) == 0};
|
||||
((fullCrew [_x, "", true]) findIf {
|
||||
_x params ["_body", "_role", "_cargoIndex"];
|
||||
(isNull _body) // seat empty
|
||||
|
@ -20,15 +20,23 @@
|
||||
params [["_oldItem", "", [0,""]], ["_newItems", "", ["", []]], ["_replaceInherited", false, [false]]];
|
||||
TRACE_3("registerItemReplacement",_oldItem,_newItems,_replaceInherited);
|
||||
|
||||
|
||||
// Setup on first run
|
||||
if (isNil QGVAR(itemReplacements)) then {
|
||||
GVAR(itemReplacements) = [] call CBA_fnc_createNamespace;
|
||||
GVAR(itemReplacements) = createHashMap;
|
||||
GVAR(inheritedReplacements) = [];
|
||||
GVAR(oldItems) = [];
|
||||
["loadout", LINKFUNC(replaceRegisteredItems)] call CBA_fnc_addPlayerEventHandler;
|
||||
};
|
||||
|
||||
// Get config case - if item doesn't exist, "" is returned
|
||||
if (_oldItem isEqualType "") then {
|
||||
_oldItem = _oldItem call FUNC(getConfigName);
|
||||
};
|
||||
|
||||
if (_oldItem isEqualTo "") exitWith {
|
||||
ERROR("Item doesn't exist");
|
||||
};
|
||||
|
||||
// Save item replacement
|
||||
// $ prefix is used for types (numbers) and replacements with inheritance
|
||||
if (_replaceInherited) then {
|
||||
@ -42,9 +50,8 @@ if (_newItems isEqualType "") then {
|
||||
_newItems = [_newItems];
|
||||
};
|
||||
|
||||
private _oldReplacements = GVAR(itemReplacements) getVariable [_oldItem, []];
|
||||
private _oldReplacements = GVAR(itemReplacements) getOrDefault [_oldItem, [], true];
|
||||
_oldReplacements append _newItems;
|
||||
GVAR(itemReplacements) setVariable [_oldItem, _oldReplacements];
|
||||
|
||||
// Force item scan when new replacement was registered in PostInit
|
||||
if !(isNull ACE_player) then {
|
||||
|
@ -42,7 +42,7 @@ for "_i" from 0 to count _newItems - 1 do {
|
||||
private _replacements = [];
|
||||
|
||||
// Determine replacement items: direct replacements, ...
|
||||
private _directReplacements = GVAR(itemReplacements) getVariable _item;
|
||||
private _directReplacements = GVAR(itemReplacements) get _item;
|
||||
if (!isNil "_directReplacements") then {
|
||||
_doReplace = true;
|
||||
_replacements append _directReplacements;
|
||||
@ -50,7 +50,7 @@ for "_i" from 0 to count _newItems - 1 do {
|
||||
|
||||
// ... item type replacements ...
|
||||
private _type = getNumber (_cfgWeapons >> _item >> "ItemInfo" >> "type");
|
||||
private _typeReplacements = GVAR(itemReplacements) getVariable ("$" + str _type);
|
||||
private _typeReplacements = GVAR(itemReplacements) get ("$" + str _type);
|
||||
if (!isNil "_typeReplacements") then {
|
||||
_doReplace = true;
|
||||
_replacements append _typeReplacements;
|
||||
@ -59,7 +59,7 @@ for "_i" from 0 to count _newItems - 1 do {
|
||||
// ... and inherited replacements
|
||||
{
|
||||
if (_item isKindOf [_x, _cfgWeapons]) then {
|
||||
private _inheritedReplacements = GVAR(itemReplacements) getVariable _x;
|
||||
private _inheritedReplacements = GVAR(itemReplacements) get _x;
|
||||
if (!isNil "_inheritedReplacements") then {
|
||||
_doReplace = true;
|
||||
_replacements append _inheritedReplacements;
|
||||
|
@ -24,7 +24,7 @@ if (!local _unit) exitWith {
|
||||
WARNING_1("setDead executed on non-local unit - %1",_this);
|
||||
};
|
||||
|
||||
if (["ace_medical"] call EFUNC(common,isModLoaded)) then {
|
||||
if (GETEGVAR(medical,enabled,false)) then {
|
||||
[_unit, _reason, _source, _instigator] call EFUNC(medical_status,setDead);
|
||||
} else {
|
||||
// From 'ace_medical_status_fnc_setDead': Kill the unit without changing visual appearance
|
||||
|
59
addons/common/functions/fnc_setWeaponLightLaserState.sqf
Normal file
59
addons/common/functions/fnc_setWeaponLightLaserState.sqf
Normal file
@ -0,0 +1,59 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: johnb43
|
||||
* Toggles the unit's current weapon's light & laser.
|
||||
* API for persistent lasers. Doesn't work on AI, as they have their own logic.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Weapon light/laser state <BOOL> (default: false)
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, true] call ace_common_fnc_setWeaponLightLaserState
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
|
||||
params [["_unit", objNull, [objNull]], ["_state", false, [false]]];
|
||||
|
||||
if (!local _unit || {!alive _unit} || {!(_unit call FUNC(isPlayer))}) exitWith {};
|
||||
|
||||
if !(_unit call CBA_fnc_canUseWeapon) exitWith {};
|
||||
|
||||
private _currentWeapon = currentWeapon _unit;
|
||||
|
||||
// Exit if unit has no weapon selected
|
||||
if (_currentWeapon == "") exitWith {};
|
||||
|
||||
private _weaponIndex = [_unit, _currentWeapon] call FUNC(getWeaponIndex);
|
||||
|
||||
// Ignore binoculars
|
||||
if (_weaponIndex == -1) exitWith {};
|
||||
|
||||
_unit setVariable [QGVAR(laserEnabled_) + str _weaponIndex, _state];
|
||||
|
||||
// Turn off light/laser (switching between weapons can leave previous weapon laser on)
|
||||
action ["GunLightOff", _unit];
|
||||
action ["IRLaserOff", _unit];
|
||||
|
||||
// Light/laser is off, don't need to do anything more
|
||||
if (!_state) exitWith {};
|
||||
|
||||
// Turn laser on next frame (if weapon hasn't changed)
|
||||
[{
|
||||
params ["_unit", "_currentWeapon"];
|
||||
|
||||
private _weaponState = (weaponState _unit) select [0, 3];
|
||||
|
||||
if (_weaponState select 0 != _currentWeapon) exitWith {};
|
||||
|
||||
action ["GunLightOn", _unit];
|
||||
action ["IRLaserOn", _unit];
|
||||
|
||||
_unit selectWeapon _weaponState;
|
||||
}, [_unit, _currentWeapon]] call CBA_fnc_execNextFrame;
|
||||
|
||||
nil
|
@ -56,7 +56,7 @@ private _resultMask = [];
|
||||
for "_index" from 0 to 9 do {
|
||||
private _set = true; //Default to true
|
||||
{
|
||||
if (!(_x select _index)) exitWith {
|
||||
if !(_x select _index) exitWith {
|
||||
_set = false; //Any false will make it false
|
||||
};
|
||||
} forEach _masks;
|
||||
|
73
addons/common/functions/fnc_switchAttachmentMode.sqf
Normal file
73
addons/common/functions/fnc_switchAttachmentMode.sqf
Normal file
@ -0,0 +1,73 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Switch attachment from one mode to another - based on CBA_accessory_fnc_switchAttachment
|
||||
* ToDo: Port this to CBA?
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit <OBJECT>
|
||||
* 1: Weapon (String or CBA-Weapon-Index (not ace's getWeaponIndex)) <STRING|NUMBER>
|
||||
* 2: From <STRING>
|
||||
* 3: To <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [player, 0, "ACE_DBAL_A3_Green_VP", "ACE_DBAL_A3_Green"] call ace_common_fnc_switchAttachmentMode
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
params ["_unit", "_weapon", "_currItem", "_switchItem"];
|
||||
TRACE_4("switchAttachmentMode",_unit,_weapon,_currItem,_switchItem);
|
||||
|
||||
if (_weapon isEqualTo "") exitWith {};
|
||||
|
||||
private _exit = _unit != ACE_player;
|
||||
switch (_weapon) do {
|
||||
case 0;
|
||||
case (primaryWeapon _unit): {
|
||||
private _currWeaponType = 0;
|
||||
_unit removePrimaryWeaponItem _currItem;
|
||||
[{
|
||||
params ["_unit", "", "_switchItem"];
|
||||
_unit addPrimaryWeaponItem _switchItem;
|
||||
["CBA_attachmentSwitched", _this] call CBA_fnc_localEvent;
|
||||
}, [_unit, _currItem, _switchItem, _currWeaponType]] call CBA_fnc_execNextFrame;
|
||||
};
|
||||
case 1;
|
||||
case (handgunWeapon _unit): {
|
||||
private _currWeaponType = 1;
|
||||
_unit removeHandgunItem _currItem;
|
||||
[{
|
||||
params ["_unit", "", "_switchItem"];
|
||||
_unit addHandgunItem _switchItem;
|
||||
["CBA_attachmentSwitched", _this] call CBA_fnc_localEvent;
|
||||
}, [_unit, _currItem, _switchItem, _currWeaponType]] call CBA_fnc_execNextFrame;
|
||||
};
|
||||
case 2;
|
||||
case (secondaryWeapon _unit): {
|
||||
private _currWeaponType = 2;
|
||||
_unit removeSecondaryWeaponItem _currItem;
|
||||
[{
|
||||
params ["_unit", "", "_switchItem"];
|
||||
_unit addSecondaryWeaponItem _switchItem;
|
||||
["CBA_attachmentSwitched", _this] call CBA_fnc_localEvent;
|
||||
}, [_unit, _currItem, _switchItem, _currWeaponType]] call CBA_fnc_execNextFrame;
|
||||
};
|
||||
default {
|
||||
ERROR_1("bad weapon - %1",_this);
|
||||
_exit = true;
|
||||
};
|
||||
};
|
||||
if (_exit) exitWith {}; // Don't notify if the unit isn't the local player or if an invalid weapon was passed
|
||||
|
||||
private _configSwitchItem = configfile >> "CfgWeapons" >> _switchItem;
|
||||
private _switchItemHintText = getText (_configSwitchItem >> "MRT_SwitchItemHintText");
|
||||
private _switchItemHintImage = getText (_configSwitchItem >> "picture");
|
||||
|
||||
playSound "click";
|
||||
if (_switchItemHintText != "") then {
|
||||
[[_switchItemHintImage, 2.0], [_switchItemHintText], true] call CBA_fnc_notify;
|
||||
};
|
@ -1,6 +1,6 @@
|
||||
#include "..\script_component.hpp"
|
||||
/*
|
||||
* Author: Dystopian
|
||||
* Author: Dystopian, johnb43
|
||||
* Controls persistent laser state.
|
||||
*
|
||||
* Arguments:
|
||||
@ -17,51 +17,85 @@
|
||||
|
||||
params ["_enabled"];
|
||||
|
||||
if (!hasInterface) exitwith {};
|
||||
|
||||
// Reset state
|
||||
{
|
||||
ACE_player setVariable [QGVAR(laserEnabled_) + str _x, nil];
|
||||
} forEach [0, 1, 2];
|
||||
|
||||
if (!_enabled) exitWith {
|
||||
if (isNil QGVAR(laserKeyDownEH)) exitWith {};
|
||||
["KeyDown", GVAR(laserKeyDownEH)] call CBA_fnc_removeDisplayHandler;
|
||||
|
||||
removeUserActionEventHandler ["headlights", "Activate", GVAR(laserKeyDownEH)];
|
||||
|
||||
["loadout", GVAR(laserLoadoutEH)] call CBA_fnc_removePlayerEventHandler;
|
||||
["turret", GVAR(laserTurretEH)] call CBA_fnc_removePlayerEventHandler;
|
||||
["vehicle", GVAR(laserVehicleEH)] call CBA_fnc_removePlayerEventHandler;
|
||||
["weapon", GVAR(laserWeaponEH)] call CBA_fnc_removePlayerEventHandler;
|
||||
|
||||
GVAR(laserKeyDownEH) = nil;
|
||||
GVAR(laserLoadoutEH) = nil;
|
||||
GVAR(laserTurretEH) = nil;
|
||||
GVAR(laserVehicleEH) = nil;
|
||||
GVAR(laserWeaponEH) = nil;
|
||||
};
|
||||
|
||||
GVAR(laserKeyDownEH) = ["KeyDown", {
|
||||
if !((_this select 1) in actionKeys "headlights") exitWith {false};
|
||||
private _weapon = currentWeapon ACE_player;
|
||||
[
|
||||
{
|
||||
params ["_weapon", "_laserWasEnabled"];
|
||||
private _laserEnabled = ACE_player isIRLaserOn _weapon || {ACE_player isFlashlightOn _weapon};
|
||||
if (_laserEnabled && {_laserWasEnabled} || {!_laserEnabled && {!_laserWasEnabled}}) exitWith {};
|
||||
private _weaponIndex = [ACE_player, _weapon] call FUNC(getWeaponIndex);
|
||||
ACE_player setVariable [QGVAR(laserEnabled_) + str _weaponIndex, [nil, true] select _laserEnabled];
|
||||
},
|
||||
[_weapon, ACE_player isIRLaserOn _weapon || {ACE_player isFlashlightOn _weapon}]
|
||||
] call CBA_fnc_execNextFrame;
|
||||
false
|
||||
}] call CBA_fnc_addDisplayHandler;
|
||||
private _fnc_getLightLaserState = {
|
||||
private _currentWeapon = currentWeapon ACE_player;
|
||||
|
||||
private _laserEH = {
|
||||
if (sunOrMoon == 1) exitWith {};
|
||||
params ["_player"];
|
||||
private _weaponIndex = [_player, currentWeapon _player] call FUNC(getWeaponIndex);
|
||||
if (
|
||||
!(_player getVariable [QGVAR(laserEnabled_) + str _weaponIndex, false])
|
||||
|| {_weaponIndex > 0 && {"" != primaryWeapon _player}} // Arma switches to primary weapon if exists
|
||||
|| {!(_player call CBA_fnc_canUseWeapon)} // ignore in vehicle except FFV
|
||||
) exitWith {};
|
||||
[
|
||||
// wait for weapon in "ready to fire" direction
|
||||
{0.01 > getCameraViewDirection _this vectorDistance (_this weaponDirection currentWeapon _this)},
|
||||
{{_this action [_x, _this]} forEach ["GunLightOn", "IRLaserOn"]},
|
||||
_player,
|
||||
3,
|
||||
{{_this action [_x, _this]} forEach ["GunLightOn", "IRLaserOn"]}
|
||||
] call CBA_fnc_waitUntilAndExecute;
|
||||
if (_currentWeapon == "") exitWith {};
|
||||
|
||||
// Ignore in vehicle except FFV
|
||||
if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {};
|
||||
|
||||
private _weaponIndex = [ACE_player, _currentWeapon] call FUNC(getWeaponIndex);
|
||||
|
||||
if (_weaponIndex == -1) exitWith {};
|
||||
|
||||
// Light/laser state only changes in the next frame
|
||||
[{
|
||||
ACE_player setVariable [
|
||||
QGVAR(laserEnabled_) + str (_this select 1),
|
||||
ACE_player isIRLaserOn (_this select 0) || {ACE_player isFlashlightOn (_this select 0)}
|
||||
];
|
||||
}, [_currentWeapon, _weaponIndex]] call CBA_fnc_execNextFrame;
|
||||
};
|
||||
|
||||
GVAR(laserLoadoutEH) = ["loadout", _laserEH] call CBA_fnc_addPlayerEventHandler;
|
||||
GVAR(laserTurretEH) = ["turret", _laserEH] call CBA_fnc_addPlayerEventHandler;
|
||||
GVAR(laserVehicleEH) = ["vehicle", _laserEH] call CBA_fnc_addPlayerEventHandler;
|
||||
GVAR(laserWeaponEH) = ["weapon", _laserEH] call CBA_fnc_addPlayerEventHandler;
|
||||
// Get current weapon light/laser state
|
||||
call _fnc_getLightLaserState;
|
||||
|
||||
// Update state every time it's changed
|
||||
GVAR(laserKeyDownEH) = addUserActionEventHandler ["headlights", "Activate", _fnc_getLightLaserState];
|
||||
|
||||
// Dropping weapons turns off lights/lasers
|
||||
GVAR(lastWeapons) = [primaryWeapon ACE_player, handgunWeapon ACE_player, secondaryWeapon ACE_player];
|
||||
|
||||
// Monitor weapon addition/removal here
|
||||
GVAR(laserLoadoutEH) = ["loadout", {
|
||||
params ["_unit"];
|
||||
|
||||
private _weapons = [primaryWeapon _unit, handgunWeapon _unit, secondaryWeapon _unit];
|
||||
|
||||
if (_weapons isEqualTo GVAR(lastWeapons)) exitWith {};
|
||||
|
||||
GVAR(lastWeapons) = _weapons;
|
||||
|
||||
[
|
||||
_unit,
|
||||
_unit getVariable [QGVAR(laserEnabled_) + str ([_unit, currentWeapon _unit] call FUNC(getWeaponIndex)), false]
|
||||
] call FUNC(setWeaponLightLaserState);
|
||||
}] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
private _fnc_switchPersistentLaserEH = {
|
||||
params ["_unit"];
|
||||
|
||||
[
|
||||
_unit,
|
||||
_unit getVariable [QGVAR(laserEnabled_) + str ([_unit, currentWeapon _unit] call FUNC(getWeaponIndex)), false]
|
||||
] call FUNC(setWeaponLightLaserState);
|
||||
};
|
||||
|
||||
GVAR(laserTurretEH) = ["turret", _fnc_switchPersistentLaserEH] call CBA_fnc_addPlayerEventHandler;
|
||||
GVAR(laserVehicleEH) = ["vehicle", _fnc_switchPersistentLaserEH] call CBA_fnc_addPlayerEventHandler;
|
||||
GVAR(laserWeaponEH) = ["weapon", _fnc_switchPersistentLaserEH] call CBA_fnc_addPlayerEventHandler;
|
||||
|
@ -28,10 +28,12 @@ private _fnc_getItems = {
|
||||
_inventoryItems append ((getItemCargo vestContainer _target) select 0);
|
||||
_inventoryItems append ((getItemCargo backpackContainer _target) select 0);
|
||||
|
||||
_items set [0, _inventoryItems];
|
||||
_items set [1, magazines _target];
|
||||
private _magazines = magazines _target;
|
||||
|
||||
_items arrayIntersect _items
|
||||
_items set [0, _inventoryItems arrayIntersect _inventoryItems];
|
||||
_items set [1, _magazines arrayIntersect _magazines];
|
||||
|
||||
_items
|
||||
};
|
||||
|
||||
// Cache items list if unit is ACE_player
|
||||
|
@ -1,160 +0,0 @@
|
||||
// by commy2
|
||||
#include "..\script_component.hpp"
|
||||
|
||||
private _aceWhitelist = missionNamespace getVariable ["ACE_Version_Whitelist", []];
|
||||
private _files = CBA_common_addons select {
|
||||
(_x select [0,3] != "a3_") &&
|
||||
{_x select [0,4] != "ace_"} &&
|
||||
{!((toLowerANSI _x) in _aceWhitelist)}
|
||||
};
|
||||
|
||||
private _versions = [];
|
||||
{
|
||||
getText (configFile >> "CfgPatches" >> _x >> "version") splitString "." params [["_major", "0"], ["_minor", "0"]];
|
||||
private _version = parseNumber _major + parseNumber _minor/100;
|
||||
_versions set [_forEachIndex, _version];
|
||||
} forEach _files;
|
||||
|
||||
if (isServer) then {
|
||||
ACE_Version_ServerVersions = [_files, _versions];
|
||||
publicVariable "ACE_Version_ServerVersions";
|
||||
} else {
|
||||
ACE_Version_ClientVersions = [_files, _versions];
|
||||
};
|
||||
|
||||
// Begin client version check
|
||||
if (!isServer) then {
|
||||
// Wait for server to send the servers files and version numbers
|
||||
waitUntil {
|
||||
sleep 1;
|
||||
!isNil "ACE_Version_ClientVersions" && {!isNil "ACE_Version_ServerVersions"}
|
||||
};
|
||||
|
||||
private _client = profileName;
|
||||
|
||||
_files = ACE_Version_ClientVersions select 0;
|
||||
_versions = ACE_Version_ClientVersions select 1;
|
||||
|
||||
private _serverFiles = ACE_Version_ServerVersions select 0;
|
||||
private _serverVersions = ACE_Version_ServerVersions select 1;
|
||||
|
||||
// Compare client and server files and versions
|
||||
private _missingAddons = [];
|
||||
private _oldVersionsClient = [];
|
||||
private _oldVersionsServer = [];
|
||||
{
|
||||
private _serverVersion = _serverVersions select _forEachIndex;
|
||||
|
||||
private _index = _files find _x;
|
||||
if (_index == -1) then {
|
||||
if (_x != "ace_server") then {_missingAddons pushBack _x;};
|
||||
} else {
|
||||
|
||||
private _clientVersion = _versions select _index;
|
||||
|
||||
if (_clientVersion < _serverVersion) then {
|
||||
_oldVersionsClient pushBack [_x, _clientVersion, _serverVersion];
|
||||
};
|
||||
|
||||
if (_clientVersion > _serverVersion) then {
|
||||
_oldVersionsServer pushBack [_x, _clientVersion, _serverVersion];
|
||||
};
|
||||
};
|
||||
} forEach _serverFiles;
|
||||
|
||||
// find client files which the server doesn't have
|
||||
private _missingAddonsServer = [];
|
||||
{
|
||||
private _index = _serverFiles find _x;
|
||||
if (_index == -1) then {
|
||||
_missingAddonsServer pushBack _x;
|
||||
}
|
||||
} forEach _files;
|
||||
|
||||
// display and log error messages
|
||||
private _fnc_cutComma = {
|
||||
private _string = _this;
|
||||
_string = toArray _string;
|
||||
|
||||
private _count = count _string;
|
||||
_string set [_count - 2, toArray "." select 0];
|
||||
_string set [_count - 1, -1];
|
||||
_string = _string - [-1];
|
||||
|
||||
toString _string;
|
||||
};
|
||||
|
||||
private _missingAddon = false;
|
||||
if (count _missingAddons > 0) then {
|
||||
_missingAddon = true;
|
||||
|
||||
private _error = format ["[ACE] %1: ERROR client missing addon(s): ", _client];
|
||||
{
|
||||
_error = _error + format ["%1, ", _x];
|
||||
|
||||
if (_forEachIndex > 9) exitWith {};
|
||||
} forEach _missingAddons;
|
||||
|
||||
_error = _error call _fnc_cutComma;
|
||||
|
||||
diag_log text _error;
|
||||
[QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent;
|
||||
[QGVAR(serverLog), _error] call CBA_fnc_serverEvent;
|
||||
};
|
||||
|
||||
private _missingAddonServer = false;
|
||||
if (count _missingAddonsServer > 0) then {
|
||||
_missingAddonServer = true;
|
||||
|
||||
private _error = format ["[ACE] %1: ERROR server missing addon(s): ", _client];
|
||||
{
|
||||
_error = _error + format ["%1, ", _x];
|
||||
|
||||
if (_forEachIndex > 9) exitWith {};
|
||||
} forEach _missingAddonsServer;
|
||||
|
||||
_error = _error call _fnc_cutComma;
|
||||
|
||||
diag_log text _error;
|
||||
[QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent;
|
||||
[QGVAR(serverLog), _error] call CBA_fnc_serverEvent;
|
||||
};
|
||||
|
||||
private _oldVersionClient = false;
|
||||
if (count _oldVersionsClient > 0) then {
|
||||
_oldVersionClient = true;
|
||||
|
||||
private _error = format ["[ACE] %1: ERROR outdated client addon(s): ", _client];
|
||||
{
|
||||
_error = _error + format ["%1 (client: %2, server: %3), ", _x select 0, _x select 1, _x select 2];
|
||||
|
||||
if (_forEachIndex > 9) exitWith {};
|
||||
} forEach _oldVersionsClient;
|
||||
|
||||
_error = _error call _fnc_cutComma;
|
||||
|
||||
diag_log text _error;
|
||||
[QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent;
|
||||
[QGVAR(serverLog), _error] call CBA_fnc_serverEvent;
|
||||
};
|
||||
|
||||
private _oldVersionServer = false;
|
||||
if (count _oldVersionsServer > 0) then {
|
||||
_oldVersionServer = true;
|
||||
|
||||
private _error = format ["[ACE] %1: ERROR outdated server addon(s): ", _client];
|
||||
{
|
||||
_error = _error + format ["%1 (client: %2, server: %3), ", _x select 0, _x select 1, _x select 2];
|
||||
|
||||
if (_forEachIndex > 9) exitWith {};
|
||||
} forEach _oldVersionsServer;
|
||||
|
||||
_error = _error call _fnc_cutComma;
|
||||
|
||||
diag_log text _error;
|
||||
[QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent;
|
||||
[QGVAR(serverLog), _error] call CBA_fnc_serverEvent;
|
||||
};
|
||||
|
||||
ACE_Version_ClientErrors = [_missingAddon, _missingAddonServer, _oldVersionClient, _oldVersionServer];
|
||||
};
|
@ -402,7 +402,7 @@
|
||||
<Portuguese>[ACE] Itens diversos</Portuguese>
|
||||
<Hungarian>[ACE] Egyéb tárgyak</Hungarian>
|
||||
<Italian>[ACE] Oggetti vari</Italian>
|
||||
<Japanese>[ACE] その他アイテム</Japanese>
|
||||
<Japanese>[ACE] その他のアイテム</Japanese>
|
||||
<Korean>[ACE] 기타 물품.</Korean>
|
||||
<Chinese>[ACE] 雜項</Chinese>
|
||||
<Chinesesimp>[ACE] 杂项</Chinesesimp>
|
||||
@ -726,7 +726,7 @@
|
||||
<Key ID="STR_ACE_Common_SettingPersistentLaserDesc">
|
||||
<English>Enable gunlight after weapon switch or vehicle enter/exit if it was previously enabled.</English>
|
||||
<Russian>Включать ЛЦУ/тактический фонарь после смены оружия или входа/выхода из машины, если он был до этого включен.</Russian>
|
||||
<Japanese>銃のライト等を点けていると武器を切り替えた後や車両を乗り降りしても、ライト等を点けたままにします。</Japanese>
|
||||
<Japanese>銃のライトをつけていた場合、武器の切り替え後または車両の出入り後にライトを再度点灯します。</Japanese>
|
||||
<Italian>Abilita la torcia/laser dopo il cambio dell'arma o l'entrata/uscita del veicolo se precedentemente attiva.</Italian>
|
||||
<Korean>이전에 무기의 손전등/레이저를 켠 경우 무기 전환이나 차량 승하차시 켠 상태를 유지합니다.</Korean>
|
||||
<German>Aktiviert Laserpointer/Taktisches Licht nach einem Waffenwechsel oder dem Auf-/Absitzen, falls es zuvor aktiv war.</German>
|
||||
@ -1360,7 +1360,7 @@
|
||||
<Italian>Non hai più spazio</Italian>
|
||||
<Hungarian>Nincs több hely</Hungarian>
|
||||
<Russian>В инвентаре нет места</Russian>
|
||||
<Japanese>インベントリに空きがない</Japanese>
|
||||
<Japanese>インベントリに空きがありません</Japanese>
|
||||
<Korean>넣을 공간이 없습니다</Korean>
|
||||
<Chinese>無可用空間</Chinese>
|
||||
<Chinesesimp>无可用空间</Chinesesimp>
|
||||
@ -1406,7 +1406,7 @@
|
||||
<Korean>음악 끄기 허용</Korean>
|
||||
<Chinese>允許調低音樂音量</Chinese>
|
||||
<Chinesesimp>允许调低音乐音量</Chinesesimp>
|
||||
<Japanese>音楽の音量低下を許可</Japanese>
|
||||
<Japanese>音楽音量の低減を許可</Japanese>
|
||||
<Italian>Permesso di abbassare la musica</Italian>
|
||||
<Polish>Zezwól na przyciszanie muzyki</Polish>
|
||||
<Russian>Разрешить приглушение музыки</Russian>
|
||||
@ -1422,7 +1422,7 @@
|
||||
<Korean>ACE 스크립트가 음악을 끌 수 있습니다.</Korean>
|
||||
<Chinese>允許ACE腳本去控制音樂的音量</Chinese>
|
||||
<Chinesesimp>允许 ACE 脚本去控制音乐的音量。</Chinesesimp>
|
||||
<Japanese>ACEのスクリプトに音量低下を許可します。</Japanese>
|
||||
<Japanese>ACEのスクリプトに音楽音量の低減を許可します。</Japanese>
|
||||
<Italian>Permetti agli script di ACEdi abbassare la musica.</Italian>
|
||||
<Polish>Zezwól skrypty ACE na przyciszanie muzyki.</Polish>
|
||||
<Russian>Позволить скриптам ACE приглушать музыку</Russian>
|
||||
@ -1435,7 +1435,7 @@
|
||||
<Key ID="STR_ACE_Common_EpilepsyFriendlyMode">
|
||||
<English>Epilepsy friendly mode</English>
|
||||
<German>Epilepsiefreundlicher Modus</German>
|
||||
<Japanese>けいれん回避モード</Japanese>
|
||||
<Japanese>てんかん対応モード</Japanese>
|
||||
<Polish>Tryb dla epileptyków</Polish>
|
||||
<French>Mode adapté à l'épilepsie</French>
|
||||
<Italian>Modalità per Epilettici</Italian>
|
||||
@ -1448,7 +1448,7 @@
|
||||
<Key ID="STR_ACE_Common_EpilepsyFriendlyModeTooltip">
|
||||
<English>Disables some flashing light effects to reduce seizure risk.</English>
|
||||
<German>Deaktiviert einige Lichtflackereffekte um das Risiko von Epilepsieanfällen zu reduzieren.</German>
|
||||
<Japanese>いくつかの光点滅エフェクトを無効化し、けいれんの恐れを低下させます。</Japanese>
|
||||
<Japanese>てんかん発作のリスクを軽減するために、一部の点滅する光の効果を無効にします。</Japanese>
|
||||
<Polish>Wyłącz część migających efektów w celu zredukowania ryzyka napadu epilepsji</Polish>
|
||||
<French>Désactive certains effets de lumière clignotante afin de réduire les risques de crise d'épilepsie.</French>
|
||||
<Italian>Disattiva alcuni effetti di luci intermittenti per ridurre il rischio di crisi epilettiche.</Italian>
|
||||
@ -1464,7 +1464,7 @@
|
||||
<Chinesesimp>旗帜(ACE-黑色):</Chinesesimp>
|
||||
<Chinese>旗幟(ACE-黑色)</Chinese>
|
||||
<Italian>Bandiera (ACE - Nera)</Italian>
|
||||
<Japanese>旗 (ACE - 黒)</Japanese>
|
||||
<Japanese>旗 (ACE - 黒色)</Japanese>
|
||||
<Polish>Flaga (ACE - Czarna)</Polish>
|
||||
<Russian>Флаг (ACE - Черный)</Russian>
|
||||
<Portuguese>Bandeira (ACE - Preto)</Portuguese>
|
||||
@ -1480,7 +1480,7 @@
|
||||
<Chinesesimp>旗帜(ACE-白色):</Chinesesimp>
|
||||
<Chinese>旗幟(ACE-白色)</Chinese>
|
||||
<Italian>Bandiera (ACE - Bianca)</Italian>
|
||||
<Japanese>旗 (ACE - 白)</Japanese>
|
||||
<Japanese>旗 (ACE - 白色)</Japanese>
|
||||
<Polish>Flaga (ACE - Biała)</Polish>
|
||||
<Russian>Флаг (ACE - Белый)</Russian>
|
||||
<Portuguese>Bandeira (ACE - Branco)</Portuguese>
|
||||
@ -1544,7 +1544,7 @@
|
||||
<Chinesesimp>在自我互动菜单内显示动作</Chinesesimp>
|
||||
<Polish>Pokaż akcje w menu interakcji własnej</Polish>
|
||||
<Portuguese>Mostra a ação no menu de auto-interação</Portuguese>
|
||||
<Japanese>セルフ インタラクションにアクションを表示</Japanese>
|
||||
<Japanese>セルフ・インタラクションにアクションを表示します</Japanese>
|
||||
<Italian>Mostra le azioni nel menu di interazione con se stessi</Italian>
|
||||
<Spanish>Mostrar la acción en el menú de interacción propio</Spanish>
|
||||
<Czech>Zobrazit akci v menu vlastních interakcí</Czech>
|
||||
@ -1834,6 +1834,7 @@
|
||||
<Korean>무기 흔들림</Korean>
|
||||
<French>Oscillation de l'arme</French>
|
||||
<Russian>Колебание оружия</Russian>
|
||||
<German>Waffen schwanken</German>
|
||||
<Spanish>Oscilación del arma</Spanish>
|
||||
<Italian>Oscillazione arma</Italian>
|
||||
</Key>
|
||||
@ -1843,6 +1844,7 @@
|
||||
<Korean>무기 흔들림 추가</Korean>
|
||||
<French>Activer l'oscillation de l'arme</French>
|
||||
<Russian>Включить колебание оружия</Russian>
|
||||
<German>Aktiviere Waffen schwanken</German>
|
||||
<Spanish>Habilitar oscilación del arma</Spanish>
|
||||
<Italian>Abilita oscillazione arma</Italian>
|
||||
</Key>
|
||||
@ -1852,6 +1854,7 @@
|
||||
<Korean>흔들림 계수, 자세, 피로도, 건강 상태 등의 요인에 영향을 받는 무기 흔들림을 활성화합니다.\n이 설정을 비활성화하면 바닐라 또는 다른 모드의 흔들림으로 대체됩니다.</Korean>
|
||||
<French>Active l'oscillation de l'arme influencé par les facteurs d'oscillation, tels que la position, la fatigue et l'état de santé.\nLa désactivation de ce paramètre reportera l'oscillation à vanilla ou à d'autres mods.</French>
|
||||
<Russian>Активируйте колебание оружия в зависимости от таких факторов, как стойка, усталость и состояние здоровья.\nОтключение этого параметра приведет к переносу раскачивания на vanilla или другие моды.</Russian>
|
||||
<German>Ermöglicht die Beeinflussung des Waffen-Schwankens durch Beeinflussungsfaktoren wie Haltung, Müdigkeit und Gesundheitszustand.\nDie Deaktivierung dieser Einstellung erlaubt die Beeinflussung durch Vanilla oder andere Mods.</German>
|
||||
<Spanish>Habilita la oscilación del arma afectado por factores como la postura, la fatiga y la condición médica.\nDeshabilitar esta opción hará que el comportamiento de la oscilación venga definido por Vanilla o por otros mods.</Spanish>
|
||||
<Italian>Abilita l'oscillazione ACE, influenzata da fattori come postura, fatica e condizione medica.\nDisabilitare questa impostazione farà controllare l'oscillazione al gioco vanilla o altre mod.</Italian>
|
||||
</Key>
|
||||
@ -1893,7 +1896,7 @@
|
||||
<German>Verwacklungsfaktor, wenn aufgelegt</German>
|
||||
<Italian>Fattore di Oscillazione Appoggiato</Italian>
|
||||
<Japanese>静止依託時の手ぶれ係数</Japanese>
|
||||
<Russian>Коэффициент колебания прицела в состоянии покоя</Russian>
|
||||
<Russian>Коэф. колебания прицела в состоянии покоя</Russian>
|
||||
<Spanish>Factor de oscilación apoyado</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_RestedSwayFactor_Description">
|
||||
@ -1915,7 +1918,7 @@
|
||||
<German>Verwacklungsfaktor, wenn Zweibein aufgestellt ist.</German>
|
||||
<Italian>Fattore di Oscillazione su Bipode</Italian>
|
||||
<Japanese>接地展開時の手ぶれ係数</Japanese>
|
||||
<Russian>Коэффициент колебания прицела при развертывании</Russian>
|
||||
<Russian>Коэф. колебания прицела при развертывании</Russian>
|
||||
<Spanish>Factor de oscilación desplegado</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Common_DeployedSwayFactor_Description">
|
||||
|
492
addons/compat_cup_units/CfgGlasses.hpp
Normal file
492
addons/compat_cup_units/CfgGlasses.hpp
Normal file
@ -0,0 +1,492 @@
|
||||
class CfgGlasses {
|
||||
|
||||
#define ESS_OVERLAY \
|
||||
ace_overlay = QPATHTOEF(goggles,textures\hud\combatgoggles.paa); \
|
||||
ace_overlayCracked = QPATHTOEF(goggles,textures\hud\combatgogglescracked.paa)
|
||||
|
||||
class None;
|
||||
class CUP_G_PMC_RadioHeadset_Glasses;
|
||||
|
||||
// ESS Goggles - Dark
|
||||
class CUP_G_ESS_BLK_Dark: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Blk: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Blk_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Blk_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Face_Blk: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_CBR_Dark: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Dark: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_RGR_Dark: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
|
||||
// ESS Goggles - Ember
|
||||
class CUP_G_ESS_BLK_Ember: None {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_CBR_Ember: None {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_RGR_Ember: None {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Ember: None {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Facewrap_White: None {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
|
||||
// ESS Goggles - Clear
|
||||
class CUP_G_ESS_BLK: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_CBR: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_RGR: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Facewrap_Black: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Facewrap_Black_GPS: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Face_Grn: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Face_Grn_GPS: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Face_Red: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Face_White: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Face_White_GPS: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Grn: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Grn_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Grn_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Grn_GPS: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Red: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Red_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_Red_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_White: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_White_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_White_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_White_GPS: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_White_GPS_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_BLK_Scarf_White_GPS_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_CBR_Facewrap_Red: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Facewrap_Tan: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Scarf_Face_Tan: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Scarf_Face_Tan_GPS: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Scarf_Tan: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Scarf_Tan_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Scarf_Tan_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Scarf_Tan_GPS: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_RGR_Facewrap_Ranger: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_RGR_Facewrap_Skull: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
class CUP_G_ESS_RGR_Facewrap_Tropical: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
ESS_OVERLAY;
|
||||
};
|
||||
|
||||
// Oakleys - Dark
|
||||
class CUP_G_Oakleys_Drk: None {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Black_Glasses_Dark: None {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Black_Glasses_Dark_Headset: None {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Tan_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Tan_Glasses_Dark_Headset: None {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Tropical_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Tropical_Glasses_Dark_Headset: None {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Winter_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Winter_Glasses_Dark_Headset: None {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_RadioHeadset_Glasses_Dark: CUP_G_PMC_RadioHeadset_Glasses {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
|
||||
// Oakleys - Ember
|
||||
class CUP_G_Oakleys_Embr: None {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Black_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Tan_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Tropical_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_Facewrap_Winter_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_PMC_RadioHeadset_Glasses_Ember: CUP_G_PMC_RadioHeadset_Glasses {
|
||||
ace_color[] = {1, 0, 0};
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
|
||||
// Shades - Dark
|
||||
class CUP_G_Beard_Shades_Black: None {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
class CUP_G_Beard_Shades_Blonde: CUP_G_Beard_Shades_Black {
|
||||
ace_resistance = 1;
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
|
||||
// Shades - Clear
|
||||
class CUP_G_Grn_Scarf_Shades: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Grn_Scarf_Shades_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Grn_Scarf_Shades_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Grn_Scarf_Shades_GPS: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Grn_Scarf_Shades_GPS_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Grn_Scarf_Shades_GPS_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Grn_Scarf_Shades_GPSCombo: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Grn_Scarf_Shades_GPSCombo_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Grn_Scarf_Shades_GPSCombo_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Tan_Scarf_Shades: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Tan_Scarf_Shades_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Tan_Scarf_Shades_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Tan_Scarf_Shades_GPS: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Tan_Scarf_Shades_GPS_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Tan_Scarf_Shades_GPS_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Tan_Scarf_Shades_GPSCombo: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Tan_Scarf_Shades_GPSCombo_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_Tan_Scarf_Shades_GPSCombo_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_White_Scarf_Shades: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_White_Scarf_Shades_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_White_Scarf_Shades_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_White_Scarf_Shades_GPS: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_White_Scarf_Shades_GPS_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_White_Scarf_Shades_GPS_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_White_Scarf_Shades_GPSCombo: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_White_Scarf_Shades_GPSCombo_Beard: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
class CUP_G_White_Scarf_Shades_GPSCombo_Beard_Blonde: None {
|
||||
ace_protection = 1;
|
||||
ace_resistance = 1;
|
||||
};
|
||||
|
||||
// Thug - Dark
|
||||
class CUP_PMC_G_thug: None {
|
||||
ace_tintAmount = 8;
|
||||
};
|
||||
};
|
@ -15,4 +15,5 @@ class CfgPatches {
|
||||
};
|
||||
};
|
||||
|
||||
#include "CfgGlasses.hpp"
|
||||
#include "CfgWeapons.hpp"
|
||||
|
@ -65,7 +65,7 @@ class CfgVehicles {
|
||||
class ace_csw {
|
||||
enabled = 1;
|
||||
proxyWeapon = "CUP_proxy_DSHKM";
|
||||
magazineLocation = "_target selectionPosition 'magazine'";
|
||||
magazineLocation = "_target selectionPosition 'otocvez'";
|
||||
disassembleWeapon = "CUP_DSHKM_carry";
|
||||
disassembleTurret = "ace_csw_kordTripod";
|
||||
desiredAmmo = 100;
|
||||
@ -119,7 +119,7 @@ class CfgVehicles {
|
||||
class ace_csw {
|
||||
enabled = 1;
|
||||
proxyWeapon = "CUP_proxy_MK19";
|
||||
magazineLocation = "_target selectionPosition 'magazine'";
|
||||
magazineLocation = "_target selectionPosition 'otochlaven'";
|
||||
disassembleWeapon = "CUP_MK19_carry";
|
||||
disassembleTurret = "ace_csw_m3TripodLow";
|
||||
desiredAmmo = 48;
|
||||
@ -165,7 +165,7 @@ class CfgVehicles {
|
||||
class ace_csw {
|
||||
enabled = 1;
|
||||
proxyWeapon = "CUP_proxy_SPG9";
|
||||
magazineLocation = "_target selectionPosition 'otochlaven'";
|
||||
magazineLocation = "_target selectionPosition 'handle'";
|
||||
disassembleWeapon = "CUP_SPG9_carry";
|
||||
disassembleTurret = "ace_csw_spg9Tripod";
|
||||
desiredAmmo = 1;
|
||||
|
@ -6,42 +6,60 @@
|
||||
<Japanese>[CSW] AGS30 ベルト</Japanese>
|
||||
<Russian>[CSW] Лента AGS 30</Russian>
|
||||
<Korean>[CSW] AGS-30 벨트</Korean>
|
||||
<German>[CSW] AGS30 Gurt</German>
|
||||
<Spanish>[CSW] Cinta de AGS30</Spanish>
|
||||
<Italian>[CSW] Nastro AGS30</Italian>
|
||||
<Portuguese>[CSW] Cinto de AGS30</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_MK19_displayName">
|
||||
<English>[CSW] MK19 Belt</English>
|
||||
<Japanese>[CSW] Mk19 ベルト</Japanese>
|
||||
<Russian>[CSW] Лента Mk19</Russian>
|
||||
<Korean>[CSW] Mk.19 벨트</Korean>
|
||||
<German>[CSW] MK19 Gurt</German>
|
||||
<Spanish>[CSW] Cinta de MK19</Spanish>
|
||||
<Italian>[CSW] Nastro MK19</Italian>
|
||||
<Portuguese>[CSW] Cinto de MK19</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_TOW_displayName">
|
||||
<English>[CSW] TOW Tube</English>
|
||||
<Japanese>[CSW] TOW チューブ</Japanese>
|
||||
<Russian>[CSW] Туба TOW</Russian>
|
||||
<Korean>[CSW] TOW 튜브</Korean>
|
||||
<German>[CSW] TOW Rohr</German>
|
||||
<Spanish>[CSW] Tubo de TOW</Spanish>
|
||||
<Italian>[CSW] Tubo TOW</Italian>
|
||||
<Portuguese>[CSW] Tubo de TOW</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_TOW2_displayName">
|
||||
<English>[CSW] TOW2 Tube</English>
|
||||
<Japanese>[CSW] TOW2 チューブ</Japanese>
|
||||
<Russian>[CSW] Туба TOW-2</Russian>
|
||||
<Korean>[CSW] TOW2 튜브</Korean>
|
||||
<German>[CSW] TOW2 Rohr</German>
|
||||
<Spanish>[CSW] Tubo de TOW2</Spanish>
|
||||
<Italian>[CSW] Tubo TOW2</Italian>
|
||||
<Portuguese>[CSW] Tubo de TOW2</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_PG9_displayName">
|
||||
<English>[CSW] PG-9 Round</English>
|
||||
<Japanese>[CSW] PG-9 砲弾</Japanese>
|
||||
<Russian>[CSW] Снаряд ПГ-9</Russian>
|
||||
<Korean>[CSW] PG-9 대전차고폭탄</Korean>
|
||||
<German>[CSW] PG-9 Rakete</German>
|
||||
<Spanish>[CSW] Carga de PG-9</Spanish>
|
||||
<Italian>[CSW] Razzo PG-9</Italian>
|
||||
<Portuguese>[CSW] Cartucho PG-9</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_OG9_displayName">
|
||||
<English>[CSW] OG-9 Round</English>
|
||||
<Japanese>[CSW] OG-9 砲弾</Japanese>
|
||||
<Russian>[CSW] Снаряд OГ-9</Russian>
|
||||
<Korean>[CSW] OG-9 고폭파편탄</Korean>
|
||||
<German>[CSW] OG-9 Rakete</German>
|
||||
<Spanish>[CSW] Carga de OG-9</Spanish>
|
||||
<Italian>[CSW] Razzo OG-9</Italian>
|
||||
<Portuguese>[CSW] Cartucho OG-9</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_M1HE_displayName">
|
||||
<English>[CSW] M1 HE</English>
|
||||
@ -49,7 +67,9 @@
|
||||
<Russian>[CSW] M1 HE</Russian>
|
||||
<Korean>[CSW] M1 고폭탄</Korean>
|
||||
<French>[CSW] M1 HE</French>
|
||||
<German>[CSW] M1 HE</German>
|
||||
<Spanish>[CSW] HE de M1</Spanish>
|
||||
<Italian>[CSW] M1 HE</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_M84Smoke_displayName">
|
||||
<English>[CSW] M84 Smoke</English>
|
||||
@ -57,7 +77,10 @@
|
||||
<Russian>[CSW] M84 Дымовая</Russian>
|
||||
<Korean>[CSW] M84 연막탄</Korean>
|
||||
<French>[CSW] M84 Fumigène</French>
|
||||
<German>[CSW] M84 Rauch</German>
|
||||
<Spanish>[CSW] Humo M84</Spanish>
|
||||
<Italian>[CSW] M84 Fumogeno</Italian>
|
||||
<Portuguese>[CSW] M84 Fumígeno</Portuguese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_M60A2_displayName">
|
||||
<English>[CSW] M60A2 WP</English>
|
||||
@ -65,7 +88,9 @@
|
||||
<Russian>[CSW] M60A2 WP</Russian>
|
||||
<Korean>[CSW] M60A2 백린연막탄</Korean>
|
||||
<French>[CSW] M60A2 WP</French>
|
||||
<German>[CSW] M60A2 WP</German>
|
||||
<Spanish>[CSW] M60A2 WP</Spanish>
|
||||
<Italian>[CSW] M60A2 WP</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_M67AT_displayName">
|
||||
<English>[CSW] M67 AT Laser Guided</English>
|
||||
@ -73,7 +98,9 @@
|
||||
<Russian>[CSW] M67 AT Laser Guided</Russian>
|
||||
<Korean>[CSW] M67 레이저유도 대전차탄</Korean>
|
||||
<French>[CSW] M67 AT Guidé laser</French>
|
||||
<German>[CSW] M67 AT Lasergelenkt</German>
|
||||
<Spanish>[CSW] AT Guiado por Láser M67</Spanish>
|
||||
<Italian>[CSW] M67 AT Laserguidato</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_M314Illum_displayName">
|
||||
<English>[CSW] M314 Illumination</English>
|
||||
@ -81,7 +108,9 @@
|
||||
<Russian>[CSW] M314 Осветительная</Russian>
|
||||
<Korean>[CSW] M314 조명탄</Korean>
|
||||
<French>[CSW] M314 Illumination</French>
|
||||
<German>[CSW] M314 Beleuchtung</German>
|
||||
<Spanish>[CSW] Iluminación M314</Spanish>
|
||||
<Italian>[CSW] M314 Illuminante</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_3OF56_displayName">
|
||||
<English>[CSW] 3OF56 HE</English>
|
||||
@ -89,7 +118,9 @@
|
||||
<Russian>[CSW] 3OF56 HE</Russian>
|
||||
<Korean>[CSW] 3OF56 고폭탄</Korean>
|
||||
<French>[CSW] 3OF56 HE</French>
|
||||
<German>[CSW] 3OF56 HE</German>
|
||||
<Spanish>[CSW] HE de 3OF56</Spanish>
|
||||
<Italian>[CSW] 3OF56 HE</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_3OF69M_displayName">
|
||||
<English>[CSW] 3OF69M Laser Guided</English>
|
||||
@ -97,7 +128,9 @@
|
||||
<Russian>[CSW] 3OF69M Laser Guided</Russian>
|
||||
<Korean>[CSW] 3OF69M 레이저유도탄</Korean>
|
||||
<French>[CSW] 3OF69M Guidé laser</French>
|
||||
<German>[CSW] 3OF69M Lasergelenkt</German>
|
||||
<Spanish>[CSW] 3OF69M Guiado por Láser</Spanish>
|
||||
<Italian>[CSW] 3OF69M Laserguidato</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_122mmWP_displayName">
|
||||
<English>[CSW] 122mm WP</English>
|
||||
@ -105,7 +138,9 @@
|
||||
<Russian>[CSW] 122mm WP</Russian>
|
||||
<Korean>[CSW] 122mm 백린탄</Korean>
|
||||
<French>[CSW] 122mm WP</French>
|
||||
<German>[CSW] 122mm WP</German>
|
||||
<Spanish>[CSW] WP de 122mm</Spanish>
|
||||
<Italian>[CSW] 122mm WP</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_122mmSmoke_displayName">
|
||||
<English>[CSW] D-462 Smoke</English>
|
||||
@ -113,7 +148,9 @@
|
||||
<Russian>[CSW] D-462 Дымовая</Russian>
|
||||
<Korean>[CSW] D-462 연막탄</Korean>
|
||||
<French>[CSW] D-462 Fumigène</French>
|
||||
<German>[CSW] D-462 Rauch</German>
|
||||
<Spanish>[CSW] Humo D-462</Spanish>
|
||||
<Italian>[CSW] D-462 Fumogeno</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_122mmIllum_displayName">
|
||||
<English>[CSW] S-463 Illumination</English>
|
||||
@ -121,7 +158,9 @@
|
||||
<Russian>[CSW] S-463 Осветительная</Russian>
|
||||
<Korean>[CSW] S-463 조명탄</Korean>
|
||||
<French>[CSW] S-463 Eclairante</French>
|
||||
<German>[CSW] S-463 Beleuchtung</German>
|
||||
<Spanish>[CSW] Iluminación S-463</Spanish>
|
||||
<Italian>[CSW] S-463 Illuminante</Italian>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_122mmAT_displayName">
|
||||
<English>[CSW] BK-6M HEAT</English>
|
||||
@ -129,7 +168,9 @@
|
||||
<Russian>[CSW] BK-6M HEAT</Russian>
|
||||
<Korean>[CSW] BK-6M 대전차고폭탄</Korean>
|
||||
<French>[CSW] BK-6M HEAT</French>
|
||||
<German>[CSW] BK-6M HEAT</German>
|
||||
<Spanish>[CSW] BK-6M HEAT</Spanish>
|
||||
<Italian>[CSW] BK-6M HEAT</Italian>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
|
@ -37,7 +37,7 @@
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_nightvision_CUP_NVG_PVS15_tan_WP">
|
||||
<English>AN/PVS-15 (Tan, WP)</English>
|
||||
<Japanese>AN/PVS-15 (タン, 白色蛍光)</Japanese>
|
||||
<Italian>AN/PVS-15 (Marroncina, FB)</Italian>
|
||||
<Italian>AN/PVS-15 (Marroncino, FB)</Italian>
|
||||
<Polish>AN/PVS-15 (Jasnobrązowa, WP)</Polish>
|
||||
<German>AN/PVS-15 (Hellbraun, WP)</German>
|
||||
<Korean>AN/PVS-15 (황갈색, 백색광)</Korean>
|
||||
@ -48,9 +48,11 @@
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_nightvision_CUP_NVG_PVS15_winter_WP">
|
||||
<English>AN/PVS-15 (Winter, WP)</English>
|
||||
<Japanese>AN/PVS-15 (冬季迷彩, WP)</Japanese>
|
||||
<Italian>AN/PVS-15 (Invernale, FB)</Italian>
|
||||
<Korean>AN/PVS-15 (설상, 백색광)</Korean>
|
||||
<Russian>AN/PVS-15 (Белый, БФ)</Russian>
|
||||
<French>AN/PVS-15 (Blanc, WP)</French>
|
||||
<German>AN/PVS-15 (Winter, WP)</German>
|
||||
<Spanish>AN/PVS-15 (Blancas, WP)</Spanish>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_nightvision_CUP_NVG_GPNVG_black_WP">
|
||||
@ -67,7 +69,7 @@
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_nightvision_CUP_NVG_GPNVG_tan_WP">
|
||||
<English>GPNVG (Tan, WP)</English>
|
||||
<Japanese>GPNVG (タン, 白色蛍光)</Japanese>
|
||||
<Italian>GPNVG (Marroncina, FB)</Italian>
|
||||
<Italian>GPNVG (Marroncino, FB)</Italian>
|
||||
<Polish>GPNVG (Jasnobrązowa, WP)</Polish>
|
||||
<German>GPNVG (Hellbraun, WP)</German>
|
||||
<Korean>GPNVG (황갈색, 백색광)</Korean>
|
||||
@ -89,9 +91,11 @@
|
||||
<Key ID="STR_ACE_Compat_CUP_Weapons_nightvision_CUP_NVG_GPNVG_winter_WP">
|
||||
<English>GPNVG (Winter, WP)</English>
|
||||
<Japanese>GPNVG (冬季迷彩, WP)</Japanese>
|
||||
<Italian>GPNVG (Invernale, FB)</Italian>
|
||||
<Korean>GPNVG (설상, 백색광)</Korean>
|
||||
<Russian>AN/PVS-15 (Белый, БФ)</Russian>
|
||||
<French>GPNVG (Blanc, WP)</French>
|
||||
<German>GPNVG (Winter, WP)</German>
|
||||
<Spanish>GPNVG (Blancas, WP)</Spanish>
|
||||
</Key>
|
||||
</Package>
|
||||
|
@ -2,7 +2,6 @@ class CfgMagazines {
|
||||
// Explosives
|
||||
class gm_explosive_petn_charge_base;
|
||||
class gm_explosive_petn_charge: gm_explosive_petn_charge_base {
|
||||
EGVAR(explosives,DelayTime) = 1;
|
||||
EGVAR(explosives,Placeable) = 1;
|
||||
EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_explosive_petn);
|
||||
useAction = 0;
|
||||
@ -21,7 +20,6 @@ class CfgMagazines {
|
||||
|
||||
class gm_explosive_plnp_charge_base;
|
||||
class gm_explosive_plnp_charge: gm_explosive_plnp_charge_base {
|
||||
EGVAR(explosives,DelayTime) = 1;
|
||||
EGVAR(explosives,Placeable) = 1;
|
||||
EGVAR(explosives,SetupObject) =QEGVAR(explosives,Place_gm_explosive_plnp);
|
||||
useAction = 0;
|
||||
|
1
addons/compat_rf/$PBOPREFIX$
Normal file
1
addons/compat_rf/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
z\ace\addons\compat_rf
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user