Merge branch 'master' into pr/10017

This commit is contained in:
johnb432
2024-06-26 09:15:17 +02:00
443 changed files with 8168 additions and 3974 deletions

View File

@ -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 {};

View File

@ -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");

View File

@ -9,3 +9,4 @@ PREP(handleStaminaBar);
PREP(mainLoop);
PREP(moduleSettings);
PREP(removeDutyFactor);
PREP(renderDebugLines);

View File

@ -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);
};

View File

@ -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;

View File

@ -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>

View File

@ -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
};

View File

@ -1,44 +1,44 @@
#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));
playSound (QGVAR(breathLow) + str (floor random 6));
};
case (_fatigue < 0.85): {
playSound (QGVAR(breathMid) + str(floor random 6));
playSound (QGVAR(breathMid) + str (floor random 6));
};
default {
playSound (QGVAR(breathMax) + str(floor random 6));
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 {
TRACE_1("reset",getAnimSpeedCoef _unit);
_unit setAnimSpeedCoef 1;
};
// 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);
[_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set);
} else {
if (isForcedWalk _unit && {_fatigue < 0.7}) 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 {
if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then {
// 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}) then {
if (!isSprintAllowed _unit && _fatigue < 0.6 && abs _fwdAngle < 20 && abs _sideAngle < 20) then {
[_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set);
};
};

View File

@ -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;

View File

@ -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;

View 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]];
}];

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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];

View File

@ -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 {
// 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";
};
// 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 = (uiNamespace getVariable QGVAR(ammoMagLookup)) getOrDefault [typeOf _activeThrowable, "HandGrenade"];
};
// Some throwables have different classname for magazine and ammo

View File

@ -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)

View File

@ -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);
};

View File

@ -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);

View File

@ -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)}];

View File

@ -382,6 +382,9 @@ switch (GVAR(currentLeftPanel)) do {
};
GVAR(currentItems) set [IDX_CURR_VEST, _item];
[GVAR(center), ""] call BIS_fnc_setUnitInsignia;
[GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia;
};
TOGGLE_RIGHT_PANEL_CONTAINER
@ -420,6 +423,9 @@ switch (GVAR(currentLeftPanel)) do {
};
GVAR(currentItems) set [IDX_CURR_BACKPACK, _item];
[GVAR(center), ""] call BIS_fnc_setUnitInsignia;
[GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia;
};
TOGGLE_RIGHT_PANEL_CONTAINER

View File

@ -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
};

View File

@ -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

View File

@ -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">

View File

@ -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"];

View File

@ -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), []];

View File

@ -41,8 +41,15 @@ _mags = _mags apply {
private _initSpeed = getNumber (_magCfg >> _x >> "initSpeed");
_magParamsArray pushBackUnique _initSpeed;
private _airFriction = 0;
if (_advCorrection) then {
_airFriction = if (isNumber (_magCfg >> _x >> QGVAR(airFriction))) then { getNumber (_magCfg >> _x >> QGVAR(airFriction)) } else { DEFAULT_AIR_FRICTION };
private _magAirFriction = getNumber (_magCfg >> _x >> QGVAR(airFriction));
if (_magAirFriction <= 0) then {
if (_advCorrection) then {
_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]

View File

@ -15,7 +15,5 @@ private _categoryName = [format ["ACE %1", localize "str_a3_cfgmarkers_nato_art"
[LSTRING(disableArtilleryComputer_displayName), LSTRING(disableArtilleryComputer_description)],
_categoryName,
false, // default value
true, // isGlobal
{[QGVAR(disableArtilleryComputer), _this] call EFUNC(common,cbaSettings_settingChanged)},
false // Needs mission restart
true // isGlobal
] call CBA_fnc_addSetting;

View File

@ -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);

View File

@ -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;

View File

@ -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)];

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 {

View File

@ -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;
};

View File

@ -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;

View File

@ -44,7 +44,7 @@ if (_state) then {
};
};
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;

View File

@ -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);

View File

@ -81,7 +81,7 @@ 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;
};
};

View File

@ -41,6 +41,8 @@ if (_item isEqualType "") then {
TRACE_1("loaded",_loaded);
// Invoke listenable event
["ace_cargoAdded", [_item, _vehicle, _loaded]] call CBA_fnc_globalEvent;
if (_loaded > 0) then {
["ace_cargoAdded", [_item, _vehicle, _loaded]] call CBA_fnc_globalEvent;
};
_loaded // return

View File

@ -6,8 +6,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
[LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)],
_category,
true,
1,
{[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}
1
] call CBA_fnc_addSetting;
[
@ -16,8 +15,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
[LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)],
_category,
[0, 10, 5, 1],
1,
{[QGVAR(loadTimeCoefficient), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
1
] call CBA_fnc_addSetting;
[
@ -26,8 +24,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
[LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)],
_category,
[0, 10, 2.5, 1],
1,
{[QGVAR(paradropTimeCoefficent), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
1
] call CBA_fnc_addSetting;
[
@ -44,9 +41,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
"LIST",
[LSTRING(openAfterUnload), LSTRING(openAfterUnload_description)],
_category,
[[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0],
0,
{[QGVAR(openAfterUnload), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
[[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0]
] call CBA_fnc_addSetting;
[
@ -54,9 +49,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
"CHECKBOX",
[LSTRING(carryAfterUnload), LSTRING(carryAfterUnload_description)],
_category,
true,
0,
{[QGVAR(carryAfterUnload), _this] call EFUNC(common,cbaSettings_settingChanged)}
true
] call CBA_fnc_addSetting;
[
@ -65,8 +58,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
[LSTRING(enableDeploy), LSTRING(enableDeploy_description)],
_category,
true,
1,
{[QGVAR(enableDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)}
1
] call CBA_fnc_addSetting;
[
@ -74,7 +66,5 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)];
"CHECKBOX",
[LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)],
_category,
true,
0,
{[QGVAR(enableRename), _this, true] call EFUNC(common,cbaSettings_settingChanged)}
true
] call CBA_fnc_addSetting;

View File

@ -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&lt;br/&gt;could not be loaded</English>
@ -509,7 +512,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>
@ -593,6 +596,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">
@ -602,6 +606,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>

View File

@ -30,6 +30,7 @@ PREP(changeProjectileDirection);
PREP(checkFiles);
PREP(checkFiles_diagnoseACE);
PREP(checkPBOs);
PREP(checkVersionNumber);
PREP(claim);
PREP(claimSafeServer);
PREP(codeToString);
@ -103,6 +104,7 @@ PREP(getWeaponAzimuthAndInclination);
PREP(getWeaponIndex);
PREP(getWeaponState);
PREP(getWeight);
PREP(getWheelHitPointsWithSelections);
PREP(getWindDirection);
PREP(getZoom);
PREP(goKneeling);
@ -161,6 +163,7 @@ PREP(sendRequest);
PREP(serverLog);
PREP(setAimCoef);
PREP(setApproximateVariablePublic);
PREP(setDead);
PREP(setDefinedVariable);
PREP(setDisableUserInputStatus);
PREP(setHearingCapability);
@ -264,6 +267,7 @@ PREP(_handleRequestAllSyncedEvents);
PREP(addActionEventHandler);
PREP(addActionMenuEventHandler);
PREP(addMapMarkerCreatedEventHandler);
PREP(addPlayerEH);
PREP(removeActionEventHandler);
PREP(removeActionMenuEventHandler);

View File

@ -145,7 +145,7 @@ if (isServer) then {
INFO_3("[%1] DC - Was Zeus [%2] while controlling unit [%3] - manually clearing `bis_fnc_moduleRemoteControl_owner`",[_x] call FUNC(getName),_dcPlayer,_x);
_x setVariable ["bis_fnc_moduleRemoteControl_owner", nil, true];
};
} forEach (curatorEditableObjects _zeusLogic);
} forEach (curatorEditableObjects _zeusLogic);
};
}];
};
@ -191,6 +191,7 @@ if (isServer) then {
[QGVAR(switchMove), {(_this select 0) switchMove (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(setVectorDirAndUp), {(_this select 0) setVectorDirAndUp (_this select 1)}] call CBA_fnc_addEventHandler;
[QGVAR(addWeaponItem), {(_this select 0) addWeaponItem [(_this select 1), (_this select 2)]}] call CBA_fnc_addEventHandler;
[QGVAR(removeMagazinesTurret), {(_this select 0) removeMagazinesTurret [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler;
[QGVAR(setVanillaHitPointDamage), {
params ["_object", "_hitPointAnddamage"];
@ -222,6 +223,9 @@ if (isServer) then {
[QGVAR(claimSafe), LINKFUNC(claimSafeServer)] call CBA_fnc_addEventHandler;
};
["CBA_SettingChanged", {
["ace_settingChanged", _this] call CBA_fnc_localEvent;
}] call CBA_fnc_addEventHandler;
//////////////////////////////////////////////////
// Set up remote execution

View File

@ -10,6 +10,7 @@ PREP_RECOMPILE_END;
GVAR(syncedEvents) = createHashMap;
GVAR(showHudHash) = createHashMap;
GVAR(vehicleIconCache) = createHashMap; // for getVehicleIcon
GVAR(wheelSelections) = createHashMap;
GVAR(blockItemReplacement) = false;

View File

@ -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;
};

View File

@ -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

View 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];

View File

@ -2,22 +2,33 @@
/*
* Author: commy2, johnb43
* Adds weapon to unit without taking a magazine.
* Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items.
* Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items by default.
*
* Arguments:
* 0: Unit to add the weapon to <OBEJCT>
* 0: Unit to add the weapon to <OBJECT>
* 1: Weapon to add <STRING>
* 2: If linked items should be removed or not <BOOL> (default: false)
* 3: Magazines that should be added to the weapon <ARRAY> (default: [])
* - 0: Magazine classname <STRING>
* - 1: Ammo count <NUMBER>
*
* Return Value:
* None
*
* Example:
* [player, "arifle_AK12_F"] call ace_common_fnc_addWeapon
* [player, "arifle_MX_GL_F", true, [["30Rnd_65x39_caseless_mag", 30], ["1Rnd_HE_Grenade_shell", 1]]] call ace_common_fnc_addWeapon
*
* Public: Yes
*/
params ["_unit", "_weapon"];
params [
["_unit", objNull, [objNull]],
["_weapon", "", [""]],
["_removeLinkedItems", false, [false]],
["_magazines", [], [[]]]
];
if (isNull _unit || {_weapon == ""}) exitWith {};
// Config case
private _compatibleMagazines = compatibleMagazines _weapon;
@ -45,6 +56,35 @@ private _backpackMagazines = (magazinesAmmoCargo _backpack) select {
// Add weapon
_unit addWeapon _weapon;
// This doesn't remove magazines, but linked items can't be magazines, so it's fine
if (_removeLinkedItems) then {
switch (_weapon call FUNC(getConfigName)) do {
case (primaryWeapon _unit): {
removeAllPrimaryWeaponItems _unit;
};
case (secondaryWeapon _unit): {
removeAllSecondaryWeaponItems _unit;
};
case (handgunWeapon _unit): {
removeAllHandgunItems _unit;
};
case (binocular _unit): {
removeAllBinocularItems _unit;
};
};
};
// Add magazines directly now, so that AI don't reload
if (_magazines isNotEqualTo []) then {
{
_x params [["_magazine", "", [""]], ["_ammoCount", -1, [0]]];
if (_magazine != "" && {_ammoCount > -1}) then {
_unit addWeaponItem [_weapon, [_magazine, _ammoCount], true];
};
} forEach _magazines;
};
// Add all magazines back
{
_uniform addMagazineAmmoCargo [_x select 0, 1, _x select 1];

View File

@ -1,8 +1,8 @@
#include "..\script_component.hpp"
/*
* Author: PabstMirror
* Function for handeling a cba setting being changed.
* Adds warning if global setting is changed after ace_settingsInitialized
* Function for handling a cba setting being changed.
* Adds warning if global setting is changed after ace_settingsInitialized.
*
* Arguments:
* 0: Setting Name <STRING>
@ -21,9 +21,7 @@
params ["_settingName", "_newValue", ["_canBeChanged", false]];
TRACE_2("",_settingName,_newValue);
["ace_settingChanged", [_settingName, _newValue]] call CBA_fnc_localEvent;
if (!((toLower _settingName) in CBA_settings_needRestart)) exitWith {};
if !((toLower _settingName) in CBA_settings_needRestart) exitWith {};
if (_canBeChanged) exitWith {WARNING_1("update cba setting [%1] to use correct Need Restart param",_settingName);};
if (!GVAR(settingsInitFinished)) exitWith {}; // Ignore changed event before CBA_settingsInitialized

View File

@ -15,15 +15,20 @@
* Public: No
*/
///////////////
// check addons
///////////////
private _mainCfg = configFile >> "CfgPatches" >> "ace_main";
private _mainVersion = getText (_mainCfg >> "versionStr");
private _mainSource = configSourceMod _mainCfg;
// Don't execute in scheduled environment
if (canSuspend) exitWith {
[FUNC(checkFiles), nil] call CBA_fnc_directCall;
};
//CBA Versioning check - close main display if using incompatible version
private _cbaVersionAr = getArray (configFile >> "CfgPatches" >> "cba_main" >> "versionAr");
///////////////
// Check addons
///////////////
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 (_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;
};
_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 ", ")];
_oldAddons = _oldAddons apply {format ["%1.pbo", _x]};
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;
};
};
};

View File

@ -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,43 +16,59 @@
*/
// 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];
private _errorMsg = format ["%1 loading from unexpected modDir [%2]", _x, _actualModDir];
systemChat _errorMsg;
WARNING_1("%1",_errorMsg);
};
} 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];
private _errorMsg = format ["%1 [%2] unexpected workshopID [%3]", _modDir, _modName, _actualID];
systemChat _errorMsg;
WARNING_1("%1",_errorMsg);
};
} forEach _allMods;
_allMods
_allMods // return

View File

@ -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;
};
};
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;
} else {
// Kick
["[ACE] ERROR", composeText [_errorMsg]] call FUNC(errorMessage);
};
};
[_this select 1] call CBA_fnc_removePerFrameHandler;
}, 1, [_mode, _checkAll, _whitelist]] call CBA_fnc_addPerFrameHandler;
}, [_mode]] call CBA_fnc_addEventHandlerArgs;
};
if (_checkAll) then {
0 spawn COMPILE_FILE(scripts\checkVersionNumber); // @todo
};
// Check file version numbers
[_whitelist] call FUNC(checkVersionNumber);

View 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;
};

View File

@ -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);
};

View File

@ -143,11 +143,7 @@ if (_state) then {
_ctrl ctrlSetEventHandler ["ButtonClick", toString {
closeDialog 0;
if (["ace_medical"] call FUNC(isModLoaded)) then {
[player, "respawn_button"] call EFUNC(medical_status,setDead);
} else {
player setDamage 1;
};
[player, "respawn_button"] call FUNC(setDead);
[false] call FUNC(disableUserInput);
}];

View File

@ -1,147 +1,141 @@
#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;
params ["_textHeader", "_textMessage", ["_onOK", {}], ["_onCancel", {}]];
private _mainDisplay = if (!isNull _curatorDisplay) then {
_curatorDisplay
} else {
call BIS_fnc_displayMission
};
if (_textMessage isEqualType "") then {
_textMessage = parseText _textMessage;
};
if (_textMessage isEqualType "") then {
_textMessage = parseText _textMessage;
};
ARR_SELECT(_this,4,call BIS_fnc_displayMission) createDisplay "RscDisplayCommonMessagePause";
private _display = _mainDisplay createDisplay "RscDisplayCommonMessagePause";
private _display = uiNamespace getVariable "RscDisplayCommonMessage_display";
private _ctrlRscMessageBox = _display displayCtrl 2351;
private _ctrlBcgCommonTop = _display displayCtrl 235100;
private _ctrlBcgCommon = _display displayCtrl 235101;
private _ctrlText = _display displayCtrl 235102;
private _ctrlBackgroundButtonOK = _display displayCtrl 235103;
private _ctrlBackgroundButtonMiddle = _display displayCtrl 235104;
private _ctrlBackgroundButtonCancel = _display displayCtrl 235105;
private _ctrlButtonOK = _display displayCtrl 235106;
private _ctrlButtonCancel = _display displayCtrl 235107;
if (isNull _display) exitWith {};
_ctrlBcgCommonTop ctrlSetText _textHeader;
private _ctrlRscMessageBox = _display displayCtrl 2351;
private _ctrlBcgCommonTop = _display displayCtrl 235100;
private _ctrlBcgCommon = _display displayCtrl 235101;
private _ctrlText = _display displayCtrl 235102;
private _ctrlBackgroundButtonOK = _display displayCtrl 235103;
private _ctrlBackgroundButtonMiddle = _display displayCtrl 235104;
private _ctrlBackgroundButtonCancel = _display displayCtrl 235105;
private _ctrlButtonOK = _display displayCtrl 235106;
private _ctrlButtonCancel = _display displayCtrl 235107;
private _ctrlButtonOKPos = ctrlPosition _ctrlButtonOK;
private _ctrlBcgCommonPos = ctrlPosition _ctrlBcgCommon;
private _bottomSpaceY = (_ctrlButtonOKPos select 1) - ((_ctrlBcgCommonPos select 1) + (_ctrlBcgCommonPos select 3));
_ctrlBcgCommonTop ctrlSetText _textHeader;
private _ctrlTextPos = ctrlPosition _ctrlText;
private _marginX = (_ctrlTextPos select 0) - (_ctrlBcgCommonPos select 0);
private _marginY = (_ctrlTextPos select 1) - (_ctrlBcgCommonPos select 1);
private _ctrlButtonOKPos = ctrlPosition _ctrlButtonOK;
private _ctrlBcgCommonPos = ctrlPosition _ctrlBcgCommon;
private _bottomSpaceY = (_ctrlButtonOKPos select 1) - ((_ctrlBcgCommonPos select 1) + (_ctrlBcgCommonPos select 3));
_ctrlText ctrlSetStructuredText _textMessage;
private _ctrlTextPosH = ctrlTextHeight _ctrlText;
private _ctrlTextPos = ctrlPosition _ctrlText;
private _marginX = (_ctrlTextPos select 0) - (_ctrlBcgCommonPos select 0);
private _marginY = (_ctrlTextPos select 1) - (_ctrlBcgCommonPos select 1);
_ctrlBcgCommon ctrlSetPosition [
_ctrlBcgCommonPos select 0,
_ctrlBcgCommonPos select 1,
_ctrlBcgCommonPos select 2,
_ctrlTextPosH + _marginY * 2
];
_ctrlBcgCommon ctrlCommit 0;
_ctrlText ctrlSetStructuredText _textMessage;
private _ctrlTextPosH = ctrlTextHeight _ctrlText;
_ctrlText ctrlSetPosition [
(_ctrlBcgCommonPos select 0) + _marginX,
(_ctrlBcgCommonPos select 1) + _marginY,
(_ctrlBcgCommonPos select 2) - _marginX * 2,
_ctrlTextPosH
];
_ctrlText ctrlCommit 0;
_ctrlBcgCommon ctrlSetPosition [
_ctrlBcgCommonPos select 0,
_ctrlBcgCommonPos select 1,
_ctrlBcgCommonPos select 2,
_ctrlTextPosH + _marginY * 2
];
_ctrlBcgCommon ctrlCommit 0;
private _bottomPosY = (_ctrlBcgCommonPos select 1) + _ctrlTextPosH + (_marginY * 2) + _bottomSpaceY;
_ctrlText ctrlSetPosition [
(_ctrlBcgCommonPos select 0) + _marginX,
(_ctrlBcgCommonPos select 1) + _marginY,
(_ctrlBcgCommonPos select 2) - _marginX * 2,
_ctrlTextPosH
];
_ctrlText ctrlCommit 0;
{
private _xPos = ctrlPosition _x;
private _bottomPosY = (_ctrlBcgCommonPos select 1) + _ctrlTextPosH + (_marginY * 2) + _bottomSpaceY;
_xPos set [1, _bottomPosY];
_x ctrlSetPosition _xPos;
_x ctrlCommit 0;
} forEach [
_ctrlBackgroundButtonOK,
_ctrlBackgroundButtonMiddle,
_ctrlBackgroundButtonCancel,
_ctrlButtonOK,
_ctrlButtonCancel
];
{
private _xPos = ctrlPosition _x;
private _ctrlRscMessageBoxPos = ctrlPosition _ctrlRscMessageBox;
private _ctrlRscMessageBoxPosH = _bottomPosY + (_ctrlButtonOKPos select 3);
_xPos set [1, _bottomPosY];
_x ctrlSetPosition _xPos;
_x ctrlCommit 0;
} forEach [
_ctrlBackgroundButtonOK,
_ctrlBackgroundButtonMiddle,
_ctrlBackgroundButtonCancel,
_ctrlButtonOK,
_ctrlButtonCancel
];
_ctrlRscMessageBox ctrlSetPosition [
0.5 - (_ctrlBcgCommonPos select 2) / 2,
0.5 - _ctrlRscMessageBoxPosH / 2,
(_ctrlBcgCommonPos select 2) + 0.5,
_ctrlRscMessageBoxPosH
];
private _ctrlRscMessageBoxPos = ctrlPosition _ctrlRscMessageBox;
private _ctrlRscMessageBoxPosH = _bottomPosY + (_ctrlButtonOKPos select 3);
_ctrlRscMessageBox ctrlEnable true;
_ctrlRscMessageBox ctrlCommit 0;
_ctrlRscMessageBox ctrlSetPosition [
0.5 - (_ctrlBcgCommonPos select 2) / 2,
0.5 - _ctrlRscMessageBoxPosH / 2,
(_ctrlBcgCommonPos select 2) + 0.5,
_ctrlRscMessageBoxPosH
];
if (_onOK isEqualTo {}) then {
_ctrlButtonOK ctrlEnable false;
_ctrlButtonOK ctrlSetFade 0;
_ctrlButtonOK ctrlSetText "";
_ctrlButtonOK ctrlCommit 0;
} else {
_ctrlRscMessageBox ctrlEnable true;
_ctrlRscMessageBox ctrlCommit 0;
// 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;

View File

@ -32,7 +32,6 @@ scopeName "main";
if (_x select 0 == _name) then {
_x breakOut "main";
};
false
} count GVAR(settings);
} forEach GVAR(settings);
[]

View 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

View File

@ -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 {

View File

@ -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;

View File

@ -0,0 +1,44 @@
#include "..\script_component.hpp"
/*
* Author: johnb43
* Kills a unit without changing visual appearance.
*
* Arguments:
* 0: Unit <ARRAY>
* 1: Reason for death (only used if ace_medical is loaded) <STRING> (default: "")
* 2: Killer (vehicle that killed unit) <ARRAY> (default: objNull)
* 3: Instigator (unit who pulled trigger) <ARRAY> (default: objNull)
*
* Return Value:
* None
*
* Example:
* [cursorObject, "", player, player] call ace_common_fnc_setDead;
*
* Public: Yes
*/
params [["_unit", objNull, [objNull]], ["_reason", "", [""]], ["_source", objNull, [objNull]], ["_instigator", objNull, [objNull]]];
if (!local _unit) exitWith {
WARNING_1("setDead executed on non-local unit - %1",_this);
};
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
// (#8803) Reenable damage if disabled to prevent having live units in dead state
// Keep this after death event for compatibility with third party hooks
if (!isDamageAllowed _unit) then {
WARNING_1("setDead executed on unit with damage blocked - %1",_this);
_unit allowDamage true;
};
private _currentDamage = _unit getHitPointDamage "HitHead";
_unit setHitPointDamage ["HitHead", 1, true, _source, _instigator];
_unit setHitPointDamage ["HitHead", _currentDamage, true, _source, _instigator];
};

View File

@ -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;

View File

@ -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];
};

View File

@ -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>

View 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;
};
};

View File

@ -15,4 +15,5 @@ class CfgPatches {
};
};
#include "CfgGlasses.hpp"
#include "CfgWeapons.hpp"

View File

@ -6,42 +6,54 @@
<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>
</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>
</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>
</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>
</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>
</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>
</Key>
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_M1HE_displayName">
<English>[CSW] M1 HE</English>
@ -49,7 +61,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 +71,9 @@
<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>
</Key>
<Key ID="STR_ACE_Compat_CUP_Weapons_CSW_mag_M60A2_displayName">
<English>[CSW] M60A2 WP</English>
@ -65,7 +81,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 +91,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 +101,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 +111,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 +121,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 +131,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 +141,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 +151,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 +161,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>

View File

@ -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>

View File

@ -0,0 +1 @@
z\ace\addons\compat_rf

View File

@ -0,0 +1,42 @@
class CfgWeapons {
// Ballistics
class Pistol_Base_F;
class hgun_Glock19_RF: Pistol_Base_F {
ace_barrelTwist = 254;
ace_barrelLength = 102;
ace_twistDirection = 1;
};
class hgun_DEagle_RF: Pistol_Base_F {
ace_barrelTwist = 482;
ace_barrelLength = 127;
ace_twistDirection = 1;
};
class Rifle_Long_Base_F;
class srifle_h6_base_rf: Rifle_Long_Base_F {
ace_barrelTwist = 228.6;
ace_barrelLength = 460;
ace_twistDirection = 1;
};
class Rifle_Base_F;
class arifle_ash12_base_RF: Rifle_Base_F {
ace_barrelTwist = 228.6;
ace_barrelLength = 400;
ace_twistDirection = 1;
};
class arifle_ash12_LR_base_RF: arifle_ash12_base_RF {
ace_barrelLength = 450;
};
// Hearing
class H_HelmetIA;
class H_HelmetIA_sb_arid_RF: H_HelmetIA {
ace_hearing_protection = 0.75;
};
class H_HelmetIA_sb_digital_RF: H_HelmetIA {
ace_hearing_protection = 0.75;
};
};

View File

@ -0,0 +1,12 @@
// Generated using ace_nouniformrestrictions_fnc_exportConfig
class CfgVehicles {
class B_Helipilot_F;
class C_Helipilot_Green_UniformHolder_RF;
class C_Helipilot_Rescue_UniformHolder_RF: B_Helipilot_F {
modelSides[] = {6};
};
class B_Helipilot_Green_UniformHolder_RF: C_Helipilot_Green_UniformHolder_RF {
modelSides[] = {6};
};
};

View File

@ -0,0 +1,21 @@
#include "script_component.hpp"
class CfgPatches {
class SUBADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {
"RF_Data_Loadorder",
"ace_nouniformrestrictions"
};
skipWhenMissingDependencies = 1;
author = ECSTRING(common,ACETeam);
authors[] = {"Mike"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};
#include "CfgVehicles.hpp"

View File

@ -0,0 +1,3 @@
#define SUBCOMPONENT nouniformrestrictions
#define SUBCOMPONENT_BEAUTIFIED No Uniform Restrictions
#include "..\script_component.hpp"

View File

@ -0,0 +1,41 @@
class optic_MRD;
class optic_MRD_khk_RF: optic_MRD {
displayName = SUBCSTRING(optic_mrd_khk_Name);
};
class optic_MRD_tan_RF: optic_MRD {
displayName = SUBCSTRING(optic_mrd_tan_Name);
};
class optic_ACO_grn;
class optic_ACO_grn_desert_RF: optic_ACO_grn {
displayName = SUBCSTRING(optic_aco_grn_desert_Name);
};
class optic_ACO_grn_wood_RF: optic_ACO_grn {
displayName = SUBCSTRING(optic_aco_grn_wood_Name);
};
class optic_Aco;
class optic_ACO_desert_RF: optic_Aco {
displayName = SUBCSTRING(optic_aco_desert_Name);
};
class optic_ACO_wood_RF: optic_Aco {
displayName = SUBCSTRING(optic_aco_wood_Name);
};
class ItemCore;
class optic_rds_RF: ItemCore {
displayName = SUBCSTRING(optic_rds_Name);
};
class optic_VRCO_RF: ItemCore {
displayName = SUBCSTRING(optic_vrco_Name);
};
class optic_VRCO_tan_RF: optic_VRCO_RF {
displayName = SUBCSTRING(optic_vrco_tan_Name);
};
class optic_VRCO_khk_RF: optic_VRCO_RF {
displayName = SUBCSTRING(optic_vrco_khk_Name);
};
class optic_VRCO_pistol_RF: optic_VRCO_RF {
displayName = SUBCSTRING(optic_vrco_pistol_Name);
};

View File

@ -0,0 +1,24 @@
class CfgMagazines {
class CA_Magazine;
class 1Rnd_RC40_shell_RF: CA_Magazine {
displayName = SUBCSTRING(rc40_Name);
};
class 1Rnd_RC40_HE_shell_RF: 1Rnd_RC40_shell_RF {
displayName = SUBCSTRING(rc40_he_Name);
};
class 1Rnd_RC40_SmokeWhite_shell_RF: 1Rnd_RC40_shell_RF {
displayName = SUBCSTRING(rc40_white_Name);
};
class 1Rnd_RC40_SmokeBlue_shell_RF: 1Rnd_RC40_shell_RF {
displayName = SUBCSTRING(rc40_blue_Name);
};
class 1Rnd_RC40_SmokeRed_shell_RF: 1Rnd_RC40_shell_RF {
displayName = SUBCSTRING(rc40_red_Name);
};
class 1Rnd_RC40_SmokeGreen_shell_RF: 1Rnd_RC40_shell_RF {
displayName = SUBCSTRING(rc40_green_Name);
};
class 1Rnd_RC40_SmokeOrange_shell_RF: 1Rnd_RC40_shell_RF {
displayName = SUBCSTRING(rc40_orange_Name);
};
};

View File

@ -0,0 +1,152 @@
class CfgVehicles {
class Heli_light_03_dynamicLoadout_base_F;
class B_Heli_light_03_dynamicLoadout_RF: Heli_light_03_dynamicLoadout_base_F {
displayName = SUBCSTRING(heli_light_03_Name);
};
class Heli_light_03_unarmed_base_F;
class B_Heli_light_03_unarmed_RF: Heli_light_03_unarmed_base_F {
displayName = SUBCSTRING(heli_light_03_unarmed_Name);
};
class I_Heli_light_03_dynamicLoadout_RF;
class I_E_Heli_light_03_dynamicLoadout_RF: I_Heli_light_03_dynamicLoadout_RF {
displayName = SUBCSTRING(heli_light_03_Name);
};
class I_Heli_light_03_unarmed_RF;
class I_E_Heli_light_03_unarmed_RF: I_Heli_light_03_unarmed_RF {
displayName = SUBCSTRING(heli_light_03_unarmed_Name);
};
// H240 Transport, Gendarmerie/ION Transport
class Helicopter_Base_H;
class Heli_EC_01_base_RF: Helicopter_Base_H {
displayName = SUBCSTRING(ec_01_base_Name);
};
// H240C Transport, CIV Transport
class Heli_EC_01_civ_base_RF: Heli_EC_01_base_RF {
displayName = SUBCSTRING(ec_01_civ_base_Name);
};
// H235 Transport, CIV Transport Float-less (not used)
class Heli_EC_01A_base_RF: Heli_EC_01_base_RF {
displayName = SUBCSTRING(ec_01a_base_Name);
};
// H235C Transport, CIV Transport Float-less
class Heli_EC_01A_civ_base_RF: Heli_EC_01A_base_RF {
displayName = SUBCSTRING(ec_01a_civ_base_Name);
};
// RAI-350M Cougar (Unarmed), IND/UNA Transport Float-less
class Heli_EC_01A_military_base_RF: Heli_EC_01A_base_RF {
displayName = SUBCSTRING(ec_01a_military_base_Name);
};
// RAI-360M Cougar, IND/OPF SOCAT Float-less
class Heli_EC_02_base_RF: Heli_EC_01_base_RF {
displayName = SUBCSTRING(ec_02_base_Name);
};
// MH-360M Cougar, NATO SOCAT (not used) Float-less
class B_Heli_EC_02_RF: Heli_EC_02_base_RF {
displayName = SUBCSTRING(ec_02_nato_Name);
};
// MH-245 Cougar, NATO Combat Type
class Heli_EC_03_base_RF: Heli_EC_01_base_RF {
displayName = SUBCSTRING(ec_03_base_Name);
};
// H245 SAR, CIV SAR Type
class Heli_EC_04_base_RF: Heli_EC_01_base_RF {
displayName = SUBCSTRING(ec_04_base_Name);
};
// MH-245 Cougar (Unarmed), NATO Transport Type (Maybe SAR?)
class Heli_EC_04_military_base_RF: Heli_EC_04_base_RF {
displayName = SUBCSTRING(ec_04_military_base_Name);
};
// HEMTT
class B_Truck_01_fuel_F;
class C_Truck_01_water_rf: B_Truck_01_fuel_F {
displayName = SUBCSTRING(truck_01_water_Name);
};
// Typhoon
class O_Truck_03_fuel_F;
class C_Truck_03_water_rf: O_Truck_03_fuel_F {
displayName = SUBCSTRING(truck_03_water_Name);
};
// RAM 1500 (Pickup)
class Offroad_01_unarmed_base_F;
class Pickup_01_base_rf: Offroad_01_unarmed_base_F {
displayName = SUBCSTRING(pickup_01_Name);
};
class Pickup_fuel_base_rf: Pickup_01_base_rf {
displayName = SUBCSTRING(pickup_01_fuel_Name);
};
class Pickup_service_base_rf: Pickup_01_base_rf {
displayName = SUBCSTRING(pickup_01_service_Name);
};
class Pickup_repair_base_rf: Pickup_service_base_rf {
displayName = SUBCSTRING(pickup_01_repair_Name);
};
class Pickup_comms_base_rf: Pickup_service_base_rf {
displayName = SUBCSTRING(pickup_01_comms_Name);
};
class Pickup_repair_ig_base_rf: Pickup_repair_base_rf {
displayName = SUBCSTRING(pickup_01_repair_Name);
};
class Pickup_01_hmg_base_rf: Pickup_01_base_rf {
displayName = SUBCSTRING(pickup_01_hmg_Name);
};
class Pickup_01_mmg_base_rf: Pickup_01_base_rf {
displayName = SUBCSTRING(pickup_01_mmg_Name);
};
class Pickup_01_mrl_base_rf: Pickup_01_base_rf {
displayName = SUBCSTRING(pickup_01_mrl_Name);
};
class Pickup_01_aat_base_rf: Pickup_01_base_rf {
displayName = SUBCSTRING(pickup_01_aa_Name);
};
class Pickup_covered_base_rf: Pickup_service_base_rf {
displayName = SUBCSTRING(pickup_01_covered_Name);
};
class C_IDAP_Pickup_rf;
class C_IDAP_Pickup_water_rf: C_IDAP_Pickup_rf {
displayName = SUBCSTRING(pickup_01_water_Name);
};
class StaticMortar;
class CommandoMortar_base_RF: StaticMortar {
displayName = SUBCSTRING(commando_Name);
};
class StaticMGWeapon;
class TwinMortar_base_RF: StaticMGWeapon {
displayName = SUBCSTRING(twinmortar_Name);
};
class Helicopter_Base_F;
class UAV_RC40_Base_RF: Helicopter_Base_F {
displayName = SUBCSTRING(rc40_base_Name);
};
class UAV_RC40_Base_Sensor_RF: UAV_RC40_Base_RF {
displayName = SUBCSTRING(rc40_Name);
};
class UAV_RC40_Base_HE_RF: UAV_RC40_Base_RF {
displayName = SUBCSTRING(rc40_he_Name);
};
class UAV_RC40_Base_SmokeWhite_RF: UAV_RC40_Base_HE_RF {
displayName = SUBCSTRING(rc40_white_Name);
};
class UAV_RC40_Base_SmokeBlue_RF: UAV_RC40_Base_HE_RF {
displayName = SUBCSTRING(rc40_blue_Name);
};
class UAV_RC40_Base_SmokeRed_RF: UAV_RC40_Base_HE_RF {
displayName = SUBCSTRING(rc40_red_Name);
};
class UAV_RC40_Base_SmokeGreen_RF: UAV_RC40_Base_HE_RF {
displayName = SUBCSTRING(rc40_green_Name);
};
class UAV_RC40_Base_SmokeOrange_RF: UAV_RC40_Base_HE_RF {
displayName = SUBCSTRING(rc40_orange_Name);
};
};

View File

@ -0,0 +1,111 @@
class CfgWeapons {
#include "Attachments.hpp"
class Pistol_Base_F;
class hgun_Glock19_RF: Pistol_Base_F {
displayName = SUBCSTRING(glock19_Name);
};
class hgun_Glock19_khk_RF: hgun_Glock19_RF {
displayName = SUBCSTRING(glock19_khk_Name);
};
class hgun_Glock19_Tan_RF: hgun_Glock19_RF {
displayName = SUBCSTRING(glock19_tan_Name);
};
class hgun_Glock19_auto_RF: hgun_Glock19_RF {
displayName = SUBCSTRING(glock19_auto_Name);
};
class hgun_Glock19_auto_khk_RF: hgun_Glock19_auto_RF {
displayName = SUBCSTRING(glock19_auto_khk_Name);
};
class hgun_Glock19_auto_Tan_RF: hgun_Glock19_auto_RF {
displayName = SUBCSTRING(glock19_auto_tan_Name);
};
class hgun_DEagle_RF: Pistol_Base_F {
displayName = SUBCSTRING(deagle_Name);
};
class hgun_DEagle_classic_RF: hgun_DEagle_RF {
displayName = SUBCSTRING(deagle_classic_Name);
};
class hgun_DEagle_bronze_RF: hgun_DEagle_RF {
displayName = SUBCSTRING(deagle_bronze_Name);
};
class hgun_DEagle_copper_RF: hgun_DEagle_RF {
displayName = SUBCSTRING(deagle_copper_Name);
};
class hgun_DEagle_gold_RF: hgun_DEagle_RF {
displayName = SUBCSTRING(deagle_gold_Name);
};
class srifle_h6_base_rf;
class srifle_h6_tan_rf: srifle_h6_base_rf {
displayName = SUBCSTRING(h6_tan_Name);
};
class srifle_h6_oli_rf: srifle_h6_tan_rf {
displayName = SUBCSTRING(h6_oli_Name);
};
class srifle_h6_blk_rf: srifle_h6_tan_rf {
displayName = SUBCSTRING(h6_blk_Name);
};
class srifle_h6_digi_rf: srifle_h6_tan_rf {
displayName = SUBCSTRING(h6_digi_Name);
};
class srifle_h6_gold_rf: srifle_h6_tan_rf {
displayName = SUBCSTRING(h6_gold_Name);
};
class srifle_DMR_01_F;
class srifle_DMR_01_black_RF: srifle_DMR_01_F {
displayName = SUBCSTRING(dmr_01_black_Name);
};
class srifle_DMR_01_tan_RF: srifle_DMR_01_black_RF {
displayName = SUBCSTRING(dmr_01_tan_Name);
};
class SMG_01_F;
class SMG_01_black_RF: SMG_01_F {
displayName = SUBCSTRING(smg_01_black_Name);
};
class arifle_ash12_base_RF;
class arifle_ash12_blk_RF: arifle_ash12_base_RF {
displayName = SUBCSTRING(ash12_blk_Name);
};
class arifle_ash12_desert_RF: arifle_ash12_base_RF {
displayName = SUBCSTRING(ash12_desert_Name);
};
class arifle_ash12_urban_RF: arifle_ash12_base_RF {
displayName = SUBCSTRING(ash12_urban_Name);
};
class arifle_ash12_wood_RF: arifle_ash12_base_RF {
displayName = SUBCSTRING(ash12_wood_Name);
};
class arifle_ash12_GL_base_RF;
class arifle_ash12_GL_blk_RF: arifle_ash12_GL_base_RF {
displayName = SUBCSTRING(ash12_gl_blk_Name);
};
class arifle_ash12_GL_desert_RF: arifle_ash12_GL_blk_RF {
displayName = SUBCSTRING(ash12_gl_desert_Name);
};
class arifle_ash12_GL_urban_RF: arifle_ash12_GL_blk_RF {
displayName = SUBCSTRING(ash12_gl_urban_Name);
};
class arifle_ash12_GL_wood_RF: arifle_ash12_GL_blk_RF {
displayName = SUBCSTRING(ash12_gl_wood_Name);
};
class arifle_ash12_LR_base_RF;
class arifle_ash12_LR_blk_RF: arifle_ash12_LR_base_RF {
displayName = SUBCSTRING(ash12_lr_blk_Name);
};
class arifle_ash12_LR_desert_RF: arifle_ash12_LR_blk_RF {
displayName = SUBCSTRING(ash12_lr_desert_Name);
};
class arifle_ash12_LR_urban_RF: arifle_ash12_LR_blk_RF {
displayName = SUBCSTRING(ash12_lr_urban_Name);
};
class arifle_ash12_LR_wood_RF: arifle_ash12_LR_blk_RF {
displayName = SUBCSTRING(ash12_lr_wood_Name);
};
};

View File

@ -0,0 +1,23 @@
#include "script_component.hpp"
class CfgPatches {
class SUBADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {
"RF_Data_Loadorder",
"ace_realisticnames"
};
skipWhenMissingDependencies = 1;
author = ECSTRING(common,ACETeam);
authors[] = {"Mike", "Marc"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};
#include "CfgMagazines.hpp"
#include "CfgWeapons.hpp"
#include "CfgVehicles.hpp"

View File

@ -0,0 +1,3 @@
#define SUBCOMPONENT realisticnames
#define SUBCOMPONENT_BEAUTIFIED Realistic Names
#include "..\script_component.hpp"

View File

@ -0,0 +1,548 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="ACE">
<Package name="Compat_RF_RealisticNames">
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_mrd_khk_Name">
<English>EOTech MRDS (Khaki)</English>
<Japanese>EOTech MRDS (カーキ)</Japanese>
<Korean>이오텍 MRDS (카키)</Korean>
<German>EOTech MRDS (Khaki)</German>
<Italian>EOTech MRDS (Cachi)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_mrd_tan_Name">
<English>EOTech MRDS (Tan)</English>
<Japanese>EOTech MRDS (タン)</Japanese>
<Korean>이오텍 MRDS (황갈)</Korean>
<German>EOTech MRDS (Hellbraun)</German>
<Italian>EOTech MRDS (Marroncino)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_aco_grn_desert_Name">
<English>C-More Railway (Green, Desert)</English>
<Japanese>C-More レイルウェイ (グリーン、砂漠迷彩)</Japanese>
<Korean>씨모어 레일웨이 (녹색, 사막)</Korean>
<German>C-More Railway (Grün, Wüste)</German>
<Italian>C-More Railway (Verde, Deserto)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_aco_grn_wood_Name">
<English>C-More Railway (Green, Woodland)</English>
<Japanese>C-More レイルウェイ (グリーン、森林迷彩)</Japanese>
<Korean>씨모어 레일웨이 (녹색, 수풀 위장)</Korean>
<German>C-More Railway (Grün, Grünes Tarnmuster)</German>
<Italian>C-More Railway (Verde, Boschivo)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_aco_desert_Name">
<English>C-More Railway (Red, Desert)</English>
<Japanese>C-More レイルウェイ (グリーン、砂漠迷彩)</Japanese>
<Korean>씨모어 레일웨이 (빨강, 사막)</Korean>
<German>C-More Railway (Rot, Wüste)</German>
<Italian>C-More Railway (Rosso, Desert)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_aco_wood_Name">
<English>C-More Railway (Red, Woodland)</English>
<Japanese>C-More レイルウェイ (グリーン、森林迷彩)</Japanese>
<Korean>씨모어 레일웨이 (빨강, 수풀)</Korean>
<German>C-More Railway (Rot, Grünes Tarnmuster)</German>
<Italian>C-More Railway (Rosso, Boschivo)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_rds_Name">
<English>Aimpoint Micro R-1</English>
<Japanese>Aimpoint マイクロ R-1</Japanese>
<Korean>에임포인트 마이크로 R-1</Korean>
<German>Aimpoint Micro R-1</German>
<Italian>Aimpoint Micro R-1</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_vrco_Name">
<English>Vortex Spitfire Prism</English>
<Japanese>Vortex スピットファイア プリズム</Japanese>
<Korean>버텍스 스핏파이어 프리즘</Korean>
<German>Vortex Spitfire Prism</German>
<Italian>Vortex Spitfire Prism</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_vrco_tan_Name">
<English>Vortex Spitfire Prism (Tan)</English>
<Japanese>Vortex スピットファイア プリズム (タン)</Japanese>
<Korean>버텍스 스핏파이어 프리즘 (황갈)</Korean>
<German>Vortex Spitfire Prism (Hellbraun)</German>
<Italian>Vortex Spitfire Prism (Marroncino)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_vrco_khk_Name">
<English>Vortex Spitfire Prism (Khaki)</English>
<Japanese>Vortex スピットファイア プリズム (カーキ)</Japanese>
<Korean>버텍스 스핏파이어 프리즘 (카키)</Korean>
<German>Vortex Spitfire Prism (Khaki)</German>
<Italian>Vortex Spitfire Prism (Cachi)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_optic_vrco_pistol_Name">
<English>Vortex Spitfire Prism (Pistol)</English>
<Japanese>Vortex スピットファイア プリズム (ピストル用)</Japanese>
<Korean>버텍스 스핏파이어 프리즘 (권총용)</Korean>
<German>Vortex Spitfire Prism (Pistole)</German>
<Italian>Vortex Spitfire Prism (Pistola)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_glock19_Name">
<English>Glock 19X</English>
<Japanese>グロック 19X</Japanese>
<Korean>글록 19X</Korean>
<German>Glock 19X</German>
<Italian>Glock 19X</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_glock19_khk_Name">
<English>Glock 19X (Khaki)</English>
<Japanese>グロック 19X (カーキ)</Japanese>
<Korean>글록 19X (카키)</Korean>
<German>Glock 19X (Khaki)</German>
<Italian>Glock 19X (Cachi)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_glock19_tan_Name">
<English>Glock 19X (Tan)</English>
<Japanese>グロック 19X (タン)</Japanese>
<Korean>글록 19X (황갈)</Korean>
<German>Glock 19X (Hellbraun)</German>
<Italian>Glock 19X (Marroncino)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_glock19_auto_Name">
<English>Glock 19X Auto</English>
<Japanese>グロック 19X オート</Japanese>
<Korean>글록 19X 기관권총</Korean>
<German>Glock 19X Auto</German>
<Italian>Glock 19X Auto</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_glock19_auto_khk_Name">
<English>Glock 19X Auto (Khaki)</English>
<Japanese>グロック 19X オート (カーキ)</Japanese>
<Korean>글록 19X 기관권총 (카키)</Korean>
<German>Glock 19X Auto (Khaki)</German>
<Italian>Glock 19X Auto (Cachi)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_glock19_auto_tan_Name">
<English>Glock 19X Auto (Tan)</English>
<Japanese>グロック 19X オート (タン)</Japanese>
<Korean>글록 19X 기관권총 (황갈)</Korean>
<German>Glock 19X Auto (Hellbraun)</German>
<Italian>Glock 19X Auto (Marroncino)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_deagle_Name">
<English>Desert Eagle Mark XIX L5</English>
<Japanese>デザートイーグル Mark XIX L5</Japanese>
<Korean>데저트 이글 마크 XIX L5</Korean>
<German>Desert Eagle Mark XIX L5</German>
<Italian>Desert Eagle Mark XIX L5</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_deagle_classic_Name">
<English>Desert Eagle Mark XIX L5 (Classic)</English>
<Japanese>デザートイーグル Mark XIX L5 (クラシック)</Japanese>
<Korean>데저트 이글 마크 XIX L5 (클래식)</Korean>
<German>Desert Eagle Mark XIX L5 (Klassisch)</German>
<Italian>Desert Eagle Mark XIX L5 (Classico)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_deagle_bronze_Name">
<English>Desert Eagle Mark XIX L5 (Bronze)</English>
<Japanese>デザートイーグル Mark XIX L5 (ブロンズ)</Japanese>
<Korean>데저트 이글 마크 XIX L5 (브론즈)</Korean>
<German>Desert Eagle Mark XIX L5 (Bronze)</German>
<Italian>Desert Eagle Mark XIX L5 (Bronzo)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_deagle_copper_Name">
<English>Desert Eagle Mark XIX L5 (Copper)</English>
<Japanese>デザートイーグル Mark XIX L5 (カッパー)</Japanese>
<Korean>데저트 이글 마크 XIX L5 (구리)</Korean>
<German>Desert Eagle Mark XIX L5 (Kupfer)</German>
<Italian>Desert Eagle Mark XIX L5 (Rame)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_deagle_gold_Name">
<English>Desert Eagle Mark XIX L5 (Gold)</English>
<Japanese>デザートイーグル Mark XIX L5 (ゴールド)</Japanese>
<Korean>데저트 이글 마크 XIX L5 (금색)</Korean>
<German>Desert Eagle Mark XIX L5 (Gold)</German>
<Italian>Desert Eagle Mark XIX L5 (Oro)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_h6_tan_Name">
<English>HERA H6 (Tan)</English>
<Japanese>HERA H6 (タン)</Japanese>
<Korean>헤라 H6 (황갈)</Korean>
<German>HERA H6 (Hellbraun)</German>
<Italian>HERA H6 (Marroncino)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_h6_oli_Name">
<English>HERA H6 (Olive)</English>
<Japanese>HERA H6 (オリーブ)</Japanese>
<Korean>헤라 H6 (올리브)</Korean>
<German>HERA H6 (Olivgrün)</German>
<Italian>HERA H6 (Oliva)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_h6_blk_Name">
<English>HERA H6 (Black)</English>
<Japanese>HERA H6 (ブラック)</Japanese>
<Korean>헤라 H6 (검정)</Korean>
<German>HERA H6 (Schwarz)</German>
<Italian>HERA H6 (Nero)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_h6_digi_Name">
<English>HERA H6 (Digital)</English>
<Japanese>HERA H6 (AAF迷彩)</Japanese>
<Korean>헤라 H6 (AAF 디지털)</Korean>
<German>HERA H6 (Digital)</German>
<Italian>HERA H6 (Digitale)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_h6_gold_Name">
<English>HERA H6 (Gold)</English>
<Japanese>HERA H6 (ゴールド)</Japanese>
<Korean>헤라 H6 (금색)</Korean>
<German>HERA H6 (Gold)</German>
<Italian>HERA H6 (Oro)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_dmr_01_black_Name">
<English>VS-121 (Black)</English>
<Japanese>VS-121 (ブラック)</Japanese>
<Korean>VS-121 (검정)</Korean>
<German>VS-121 (Schwarz)</German>
<Italian>VS-121 (Nero)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_dmr_01_tan_Name">
<English>VS-121 (Tan)</English>
<Japanese>VS-121 (タン)</Japanese>
<Korean>VS-121 (황갈)</Korean>
<German>VS-121 (Hellbraun)</German>
<Italian>VS-121 (Marroncino)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_smg_01_black_Name">
<English>Vector SMG (Black)</English>
<Japanese>ベクター SMG (ブラック)</Japanese>
<Korean>벡터 SMG (검정)</Korean>
<German>Vector SMG (Schwarz)</German>
<Italian>Vector SMG (Nero)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_blk_Name">
<English>ASh-12 (Black)</English>
<Japanese>ASh-12 (ブラック)</Japanese>
<Korean>ASh-12 (검정)</Korean>
<German>ASh-12 (Schwarz)</German>
<Italian>ASh-12 (Nero)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_desert_Name">
<English>ASh-12 (Desert)</English>
<Japanese>ASh-12 (砂漠迷彩)</Japanese>
<Korean>ASh-12 (사막)</Korean>
<German>ASh-12 (Wüste)</German>
<Italian>ASh-12 (Deserto)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_urban_Name">
<English>ASh-12 (Urban)</English>
<Japanese>ASh-12 (市街地迷彩)</Japanese>
<Korean>ASh-12 (도심)</Korean>
<German>ASh-12 (Urban)</German>
<Italian>ASh-12 (Urbano)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_wood_Name">
<English>ASh-12 (Woodland)</English>
<Japanese>ASh-12 (森林迷彩)</Japanese>
<Korean>ASh-12 (수풀)</Korean>
<German>ASh-12 (Grünes Tarnmuster)</German>
<Italian>ASh-12 (Boschivo)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_gl_blk_Name">
<English>ASh-12 GL (Black)</English>
<Japanese>ASh-12 GL (ブラック)</Japanese>
<Korean>ASh-12 GL (검정)</Korean>
<German>ASh-12 GL (Schwarz)</German>
<Italian>ASh-12 GL (Nero)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_gl_desert_Name">
<English>ASh-12 GL (Desert)</English>
<Japanese>ASh-12 GL (砂漠迷彩)</Japanese>
<Korean>ASh-12 GL (사막)</Korean>
<German>ASh-12 GL (Wüste)</German>
<Italian>ASh-12 GL (Deserto)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_gl_urban_Name">
<English>ASh-12 GL (Urban)</English>
<Japanese>ASh-12 GL (市街地迷彩)</Japanese>
<Korean>ASh-12 GL (도심)</Korean>
<German>ASh-12 GL (Urban)</German>
<Italian>ASh-12 GL (Urbano)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_gl_wood_Name">
<English>ASh-12 GL (Woodland)</English>
<Japanese>ASh-12 GL (森林迷彩)</Japanese>
<Korean>ASh-12 GL (수풀)</Korean>
<German>ASh-12 GL (Grünes Tarnmuster)</German>
<Italian>ASh-12 GL (Boschivo)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_lr_blk_Name">
<English>ASh-12 LR (Black)</English>
<Japanese>ASh-12 LR (ブラック)</Japanese>
<Korean>ASh-12 LR (검정)</Korean>
<German>ASh-12 LR (Schwarz)</German>
<Italian>ASh-12 LR (Nero)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_lr_desert_Name">
<English>ASh-12 LR (Desert)</English>
<Japanese>ASh-12 LR (砂漠迷彩)</Japanese>
<Korean>ASh-12 LR (사막)</Korean>
<German>ASh-12 LR (Wüste)</German>
<Italian>ASh-12 LR (Deserto)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_lr_urban_Name">
<English>ASh-12 LR (Urban)</English>
<Japanese>ASh-12 LR (市街地迷彩)</Japanese>
<Korean>ASh-12 LR (도심)</Korean>
<German>ASh-12 LR (Urban)</German>
<Italian>ASh-12 LR (Urbano)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ash12_lr_wood_Name">
<English>ASh-12 LR (Woodland)</English>
<Japanese>ASh-12 LR (森林迷彩)</Japanese>
<Korean>ASh-12 LR (수풀)</Korean>
<German>ASh-12 LR (Grünes Tarnmuster)</German>
<Italian>ASh-12 LR (Boschivo)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_heli_light_03_Name">
<English>AW159 Wildcat ASW</English>
<Japanese>AW159 ワイルドキャット ASW</Japanese>
<Korean>AW159 와일드캣 ASW</Korean>
<German>AW159 Wildcat ASW</German>
<Italian>AW159 Wildcat ASW</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_heli_light_03_unarmed_Name">
<English>AW159 Wildcat ASW (Unarmed)</English>
<Japanese>AW159 ワイルドキャット ASW (非武装)</Japanese>
<Korean>AW159 와일드캣 ASW (비무장)</Korean>
<German>AW159 Wildcat ASW (Unbewaffnet)</German>
<Italian>AW159 Wildcat ASW (Disarmato)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ec_01_base_Name">
<English>H225 Super Puma (Transport)</English>
<Japanese>H225 シュペル ピューマ (輸送型)</Japanese>
<Korean>H225 슈퍼 퓨마 (비무장)</Korean>
<German>H225 Super Puma (Transport)</German>
<Italian>H225 Super Puma (Trasporto)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ec_01_civ_base_Name">
<English>H225 Super Puma (Civilian)</English>
<Japanese>H225 シュペル ピューマ (民生型)</Japanese>
<Korean>H225 슈퍼 퓨마 (비무장)</Korean>
<German>H225 Super Puma (Zivil)</German>
<Italian>H225 Super Puma (Civile)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ec_01a_base_Name">
<English>H215 Super Puma (Transport)</English>
<Japanese>H215 シュペル ピューマ (輸送型)</Japanese>
<Korean>H215 슈퍼 퓨마 (비무장)</Korean>
<German>H215 Super Puma (Transport)</German>
<Italian>H215 Super Puma (Trasporto)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ec_01a_civ_base_Name">
<English>H215 Super Puma (Civilian)</English>
<Japanese>H215 シュペル ピューマ (民生型)</Japanese>
<Korean>H215 슈퍼 퓨마 (비무장)</Korean>
<German>H215 Super Puma (Zivil)</German>
<Italian>H215 Super Puma (Civile)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ec_01a_military_base_Name">
<English>H215 Super Puma (Unarmed)</English>
<Japanese>H215 シュペル ピューマ (非武装)</Japanese>
<Korean>H215 슈퍼 퓨마 (비무장)</Korean>
<German>H215 Super Puma (Unbewaffnet)</German>
<Italian>H215 Super Puma (Disarmato)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ec_02_base_Name">
<English>H225M Super Cougar SOCAT</English>
<Japanese>H225M シュペル クーガー SOCAT</Japanese>
<Korean>H225M 슈퍼 쿠거 SOCAT</Korean>
<German>H225M Super Cougar SOCAT</German>
<Italian>H225M Super Cougar SOCAT</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ec_02_nato_Name">
<English>H225M Super Cougar SOCAT</English>
<Japanese>H225M シュペル クーガー SOCAT</Japanese>
<Korean>H225M 슈퍼 쿠거 SOCAT</Korean>
<German>H225M Super Cougar SOCAT</German>
<Italian>H225M Super Cougar SOCAT</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ec_03_base_Name">
<English>H225M Super Cougar</English>
<Japanese>H225M シュペル クーガー</Japanese>
<Korean>H225M 슈퍼 쿠거</Korean>
<German>H225M Super Cougar</German>
<Italian>H225M Super Cougar</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ec_04_base_Name">
<English>H225 Super Puma SAR</English>
<Japanese>H225 シュペル ピューマ 捜索救難型</Japanese>
<Korean>H225 슈퍼 퓨마 SAR</Korean>
<German>H225 Super Puma SAR</German>
<Italian>H225 Super Puma SAR</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_ec_04_military_base_Name">
<English>H225M Super Cougar (Unarmed)</English>
<Japanese>H225M シュペル クーガー (非武装)</Japanese>
<German>H225M Super Cougar (Unbewaffnet)</German>
<Italian>H225M Super Cougar (Disarmato)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_truck_01_water_Name">
<English>HEMTT Fire Truck</English>
<French>HEMTT anti-incendie</French>
<Polish>HEMTT (wersja pożarnicza)</Polish>
<German>HEMTT-Löschfahrzeug</German>
<Spanish>HEMTT (camión de bomberos)</Spanish>
<Russian>Пожарная машина HEMTT</Russian>
<Chinesesimp>HEMTT 消防卡车</Chinesesimp>
<Portuguese>HEMTT contra incêndio</Portuguese>
<Japanese>HEMTT 消防車</Japanese>
<Italian>HEMTT Autobotte</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_truck_03_water_Name">
<English>Typhoon Water</English>
<Japanese>タイフーン 給水</Japanese>
<Korean>타이푼 급수</Korean>
<German>Typhoon Water</German>
<Italian>Typhoon Acqua</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_Name">
<English>Ram 1500</English>
<Japanese>ラム 1500</Japanese>
<Korean>램 1500</Korean>
<German>Ram 1500</German>
<Italian>Ram 1500</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_Fuel_Name">
<English>Ram 1500 (Fuel)</English>
<Japanese>ラム 1500 (燃料)</Japanese>
<Korean>램 1500 (연료)</Korean>
<German>Ram 1500 (Treibstoff)</German>
<Italian>Ram 1500 (Carburante)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_service_Name">
<English>Ram 1500 (Services)</English>
<Japanese>ラム 1500 (サービス)</Japanese>
<Korean>램 1500 (서비스)</Korean>
<German>Ram 1500 (Pannenhilfe)</German>
<Italian>Ram 1500 (Servizi)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_repair_Name">
<English>Ram 1500 (Repair)</English>
<Japanese>ラム 1500 (修理)</Japanese>
<Korean>램 1500 (정비)</Korean>
<German>Ram 1500 (Instandsetzung)</German>
<Italian>Ram 1500 (Riparazioni)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_comms_Name">
<English>Ram 1500 (Comms)</English>
<Japanese>ラム 1500 (通信)</Japanese>
<Korean>램 1500 (통신)</Korean>
<German>Ram 1500 (Kommunikation)</German>
<Italian>Ram 1500 (Comunicazioni)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_hmg_Name">
<English>Ram 1500 (HMG)</English>
<Japanese>ラム 1500 (HMG)</Japanese>
<Korean>램 1500 (중기관총)</Korean>
<German>Ram 1500 (HMG)</German>
<Italian>Ram 1500 (HMG)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_mmg_Name">
<English>Ram 1500 (MMG)</English>
<Japanese>ラム 1500 (MMG)</Japanese>
<Korean>램 1500 (중형기관총)</Korean>
<German>Ram 1500 (MMG)</German>
<Italian>Ram 1500 (MMG)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_mrl_Name">
<English>Ram 1500 (MRL)</English>
<Japanese>ラム 1500 (MRL)</Japanese>
<Korean>램 1500 (다연장로켓)</Korean>
<German>Ram 1500 (MRL)</German>
<Italian>Ram 1500 (MRL)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_aa_Name">
<English>Ram 1500 (AA)</English>
<Japanese>ラム 1500 (対空)</Japanese>
<Korean>램 1500 (대공)</Korean>
<German>Ram 1500 (AA)</German>
<Italian>Ram 1500 (AA)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_covered_Name">
<English>Ram 1500 (Covered)</English>
<Japanese>ラム 1500 (カバー)</Japanese>
<Korean>램 1500 (커버)</Korean>
<German>Ram 1500 (Abgedeckt)</German>
<Italian>Ram 1500 (Coperto)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_pickup_01_water_Name">
<English>Ram 1500 (Water)</English>
<Japanese>ラム 1500 (給水)</Japanese>
<Korean>램 1500 (급수)</Korean>
<German>Ram 1500 (Wasser)</German>
<Italian>Ram 1500 (Acqua)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_commando_Name">
<English>RSG60</English>
<Japanese>RSG60</Japanese>
<Korean>RSG60</Korean>
<German>RSG60</German>
<Italian>RSG60</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_twinmortar_Name">
<English>AMOS Container</English>
<Japanese>AMOS コンテナ</Japanese>
<Korean>AMOS 컨테이너</Korean>
<German>AMOS Container</German>
<Italian>AMOS Container</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_rc40_base_Name">
<English>Drone40</English>
<Japanese>ドローン40</Japanese>
<Korean>드론40</Korean>
<German>Drone40</German>
<Italian>Drone40</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_rc40_Name">
<English>Drone40 Scout</English>
<Japanese>ドローン40 偵察型</Japanese>
<Korean>드론40 정찰</Korean>
<German>Drone40 Scout</German>
<Italian>Drone40 Scout</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_rc40_he_Name">
<English>Drone40 HE</English>
<Japanese>ドローン40 榴弾</Japanese>
<Korean>드론40 고폭</Korean>
<German>Drone40 HE</German>
<Italian>Drone40 HE</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_rc40_white_Name">
<English>Drone40 Smoke (White)</English>
<Japanese>ドローン40 発煙弾 (白)</Japanese>
<Korean>드론40 연막 (백색)</Korean>
<German>Drone40 Smoke (Weiß)</German>
<Italian>Drone40 Smoke (Bianco)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_rc40_blue_Name">
<English>Drone40 Smoke (Blue)</English>
<Japanese>ドローン40 発煙弾 (青)</Japanese>
<Korean>드론40 연막 (청색)</Korean>
<German>Drone40 Smoke (Blau)</German>
<Italian>Drone40 Smoke (Blu)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_rc40_red_Name">
<English>Drone40 Smoke (Red)</English>
<Japanese>ドローン40 発煙弾 (赤)</Japanese>
<Korean>드론40 연막 (적색)</Korean>
<German>Drone40 Smoke (Rot)</German>
<Italian>Drone40 Smoke (Rosso)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_rc40_green_Name">
<English>Drone40 Smoke (Green)</English>
<Japanese>ドローン40 発煙弾 (緑)</Japanese>
<Korean>드론40 연막 (녹색)</Korean>
<German>Drone40 Smoke (Grün)</German>
<Italian>Drone40 Smoke (Verde)</Italian>
</Key>
<Key ID="STR_ACE_Compat_RF_RealisticNames_rc40_orange_Name">
<English>Drone40 Smoke (Orange)</English>
<Japanese>ドローン40 発煙弾 (橙)</Japanese>
<Korean>드론40 연막 (주황색)</Korean>
<German>Drone40 Smoke (Orange)</German>
<Italian>Drone40 Smoke (Arancione)</Italian>
</Key>
</Package>
</Project>

View File

@ -0,0 +1,18 @@
#include "script_component.hpp"
class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"RF_Data_Loadorder"};
skipWhenMissingDependencies = 1;
author = ECSTRING(common,ACETeam);
authors[] = {"Mike"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};
#include "CfgWeapons.hpp"

View File

@ -0,0 +1,6 @@
#define COMPONENT compat_rf
#define COMPONENT_BEAUTIFIED Reaction Forces Compatibility
#include "\z\ace\addons\main\script_mod.hpp"
#include "\z\ace\addons\main\script_macros.hpp"

View File

@ -219,6 +219,10 @@ class CfgAmmo {
EGVAR(frag,force) = 0;
};
class SmokeShell;
class rhs_ammo_rdg2_white: SmokeShell {
EGVAR(grenades,rollVectorDirAndUp)[] = {{0, 1, 0}, {0, 0, 1}};
};
class Sh_125mm_APFSDS;
class Sh_125mm_HE;

View File

@ -1,11 +0,0 @@
class CfgMagazineWells {
class ace_hellfire_K {
ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_k)};
};
class ace_hellfire_N {
ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_n)};
};
class ace_hellfire_L {
ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_l)};
};
};

View File

@ -38,21 +38,4 @@ class cfgMagazines {
EGVAR(overpressure,range) = 0;
EGVAR(overpressure,damage) = 0;
};
class rhs_mag_AGM114K_2;
class GVAR(pylon_mag_2rnd_hellfire_k): rhs_mag_AGM114K_2 {
displayName = "2x AGM-114K [ACE]";
pylonWeapon = "ace_hellfire_launcher";
ammo = "ACE_Hellfire_AGM114K";
};
class GVAR(pylon_mag_2rnd_hellfire_n): rhs_mag_AGM114K_2 {
displayName = "2x AGM-114N [ACE]";
pylonWeapon = "ace_hellfire_launcher_N";
ammo = "ACE_Hellfire_AGM114N";
};
class GVAR(pylon_mag_2rnd_hellfire_l): rhs_mag_AGM114K_2 {
displayName = "2x AGM-114L [ACE]";
pylonWeapon = "ace_hellfire_launcher_L";
ammo = "ACE_Hellfire_AGM114L";
};
};

View File

@ -0,0 +1,8 @@
class CfgAmmo {
// Use RHS Hellfire 3D Model on ACE Hellfires
class M_Scalpel_AT;
class ACE_Hellfire_AGM114K: M_Scalpel_AT {
model = "\rhsusf\addons\rhsusf_airweapons\proxyammo\rhsusf_m_AGM114K_fly";
proxyShape = "\rhsusf\addons\rhsusf_airweapons\proxyammo\rhsusf_m_AGM114K";
};
};

View File

@ -0,0 +1,11 @@
class CfgMagazineWells {
class ace_hellfire_K {
ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_k), QGVAR(pylon_mag_4rnd_hellfire_k)};
};
class ace_hellfire_N {
ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_n), QGVAR(pylon_mag_4rnd_hellfire_n)};
};
class ace_hellfire_L {
ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_l), QGVAR(pylon_mag_4rnd_hellfire_l)};
};
};

View File

@ -0,0 +1,37 @@
class CfgMagazines {
// 2x ACE Hellfire racks
class rhs_mag_AGM114K_2;
class GVAR(pylon_mag_2rnd_hellfire_k): rhs_mag_AGM114K_2 {
displayName = "2x AGM-114K [ACE]";
pylonWeapon = "ace_hellfire_launcher";
ammo = "ACE_Hellfire_AGM114K";
};
class GVAR(pylon_mag_2rnd_hellfire_n): rhs_mag_AGM114K_2 {
displayName = "2x AGM-114N [ACE]";
pylonWeapon = "ace_hellfire_launcher_N";
ammo = "ACE_Hellfire_AGM114N";
};
class GVAR(pylon_mag_2rnd_hellfire_l): rhs_mag_AGM114K_2 {
displayName = "2x AGM-114L [ACE]";
pylonWeapon = "ace_hellfire_launcher_L";
ammo = "ACE_Hellfire_AGM114L";
};
// 4x ACE Hellfire racks that align better on RHS Apaches and Blackhawks than the standard ACE 4x racks
class rhs_mag_AGM114K_4;
class GVAR(pylon_mag_4rnd_hellfire_k): rhs_mag_AGM114K_4 {
displayName = "4x AGM-114K [ACE]";
pylonWeapon = "ace_hellfire_launcher";
ammo = "ACE_Hellfire_AGM114K";
};
class GVAR(pylon_mag_4rnd_hellfire_n): rhs_mag_AGM114K_4 {
displayName = "4x AGM-114N [ACE]";
pylonWeapon = "ace_hellfire_launcher_N";
ammo = "ACE_Hellfire_AGM114N";
};
class GVAR(pylon_mag_4rnd_hellfire_l): rhs_mag_AGM114K_4 {
displayName = "4x AGM-114L [ACE]";
pylonWeapon = "ace_hellfire_launcher_L";
ammo = "ACE_Hellfire_AGM114L";
};
};

View File

@ -0,0 +1,25 @@
#include "script_component.hpp"
class CfgPatches {
class SUBADDON {
name = COMPONENT_NAME;
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {
"rhsusf_main_loadorder",
"ace_hellfire"
};
skipWhenMissingDependencies = 1;
author = ECSTRING(common,ACETeam);
authors[] = {};
url = ECSTRING(main,URL);
VERSION_CONFIG;
addonRootClass = QUOTE(ADDON);
};
};
#include "CfgAmmo.hpp"
#include "CfgMagazines.hpp"
#include "CfgMagazineWells.hpp"

View File

@ -0,0 +1,3 @@
#define SUBCOMPONENT hellfire
#define SUBCOMPONENT_BEAUTIFIED Hellfire
#include "..\script_component.hpp"

View File

@ -19,7 +19,6 @@ class CfgPatches {
#include "CfgAmmo.hpp"
#include "CfgEventHandlers.hpp"
#include "CfgMagazines.hpp"
#include "CfgMagazineWells.hpp"
#include "CfgWeapons.hpp"
#include "CfgVehicles.hpp"
#include "CfgGlasses.hpp"

View File

@ -4,6 +4,13 @@ class vn_molotov_grenade_ammo: vn_grenadehand {
EGVAR(frag,enabled) = 0;
};
class vn_t67_grenade_ammo: vn_grenadehand {
EGVAR(grenades,rollVectorDirAndUp)[] = {{-1, 0, 0}, {0, 0, 1}};
};
class vn_chicom_grenade_ammo: vn_grenadehand {
EGVAR(grenades,rollVectorDirAndUp)[] = {{1, 0, 0}, {0, 0, 1}};
};
class SmokeShell;
class vn_m14_grenade_ammo: SmokeShell {
EGVAR(grenades,incendiary) = 1;

View File

@ -32,6 +32,16 @@ class Extended_InitPost_EventHandlers {
init = QUOTE((_this select 0) setMass 1e-12);
};
};
class Land_vn_canisterfuel_f {
class ADDON {
init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})]));
};
};
class Land_vn_fuelcan {
class ADDON {
init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})]));
};
};
class vn_bicycle_base {
class ADDON {
init = QUOTE(call FUNC(disableCookoff));

View File

@ -1,18 +1,19 @@
#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};}
// fuel pumps
class Land_vn_commercial_base;
class Land_vn_fuelstation_01_pump_f: Land_vn_commercial_base {
transportFuel = 0;
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}};
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
};
class Land_vn_fuelstation_02_pump_f: Land_vn_commercial_base {
transportFuel = 0;
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}};
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
};
class Land_vn_fuelstation_feed_f: Land_vn_commercial_base {
transportFuel = 0;
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}};
EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL;
};
@ -20,13 +21,47 @@ class Land_vn_fuelstation_feed_f: Land_vn_commercial_base {
// fuel objects
class Land_vn_building_b_base;
class Land_vn_usaf_fueltank_75_01: Land_vn_building_b_base {
transportFuel = 0;
EGVAR(refuel,hooks)[] = {{0, -0.4, -0.5}};
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{-2.52, -2.2, -2.05}, {2.5, 0, -1.3}};
EGVAR(refuel,fuelCargo) = 2840; // 750 * 3.785
};
class Land_vn_b_prop_fuelbladder_01: Land_vn_usaf_fueltank_75_01 {
EGVAR(refuel,hooks)[] = {{-1.75, -6.7, -1}};
EGVAR(refuel,fuelCargo) = 3785; // 1000 * 3.785
};
class Land_vn_b_prop_fuelbladder_03: Land_vn_b_prop_fuelbladder_01 {
EGVAR(refuel,hooks)[] = {{-1.55, -6.5, -1}};
};
class Land_vn_building_industrial_base;
class Land_vn_fuel_tank_stairs: Land_vn_building_industrial_base {
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{0, 0.4, -1.3}, {0, -0.4, -1.3}};
EGVAR(refuel,fuelCargo) = 10000; // reference is B_Slingload_01_Fuel_F
};
class Land_vn_object_b_base;
class Land_vn_b_prop_fueldrum_01: Land_vn_object_b_base {
transportFuel = 0;
EGVAR(refuel,hooks)[] = {{0, 0, 0.5}}; // reference is Land_FlexibleTank_01_F
XEH_INHERITED;
EGVAR(refuel,hooks)[] = {{0, 0, 0}};
EGVAR(refuel,fuelCargo) = 300; // reference is Land_FlexibleTank_01_F
};
class Land_vn_b_prop_fueldrum_02: Land_vn_b_prop_fueldrum_01 {
EGVAR(refuel,hooks)[] = {{0, -1.3, -0.15}, {2.3, 1.25, -0.15}};
EGVAR(refuel,fuelCargo) = 14100; // (23 + 24) * 300
};
class vn_b_ammobox_supply_07;
class vn_b_ammobox_supply_09: vn_b_ammobox_supply_07 { // just a pallet
XEH_INHERITED;
};
class vn_object_c_base_02;
class Land_vn_canisterfuel_f: vn_object_c_base_02 {
EGVAR(cargo,size) = 1;
EGVAR(cargo,canLoad) = 1;
EGVAR(cargo,noRename) = 1;
};
class Land_vn_object_c_base;
class Land_vn_fuelcan: Land_vn_object_c_base {
XEH_INHERITED;
EGVAR(cargo,size) = 1;
EGVAR(cargo,canLoad) = 1;
EGVAR(cargo,noRename) = 1;
};

View File

@ -1,5 +1,4 @@
#include "script_component.hpp"
// ToDo: move refuel to subconfig
#include "\z\ace\addons\refuel\defines.hpp"
#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp"
@ -47,6 +46,8 @@ class CfgPatches {
};
};
class CBA_Extended_EventHandlers;
#include "ACE_CSW_Groups.hpp"
#include "ACE_Medical_Injuries.hpp"
#include "ACE_Triggers.hpp"

View File

@ -14,8 +14,10 @@
*
* Public: No
*/
params ["_trap"];
if (!(["ace_medical"] call EFUNC(common,isModLoaded))) exitWith {};
if !(GETEGVAR(medical,enabled,false)) exitWith {};
private _radius = getNumber (configOf _trap >> "indirectHitRange");
private _affectedUnits = _trap nearEntities ["CAManBase", _radius];

View File

@ -18,8 +18,6 @@
* Public: No
*/
#define BURN_THRESHOLD 1
params ["_unit", "_damages"];
TRACE_2("woundsHandlerIncendiary",_unit,_damages);
@ -32,9 +30,7 @@ private _fireDamage = 0;
private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true];
TRACE_2("",_intensity,_fireDamage);
if (_intensity > BURN_THRESHOLD) then {
TRACE_2("Setting unit ablaze",_intensity,BURN_THRESHOLD);
["ace_fire_burn", [_unit, _intensity]] call CBA_fnc_globalEvent;
};
// Let fire handle if unit is set ablaze or not
[QEGVAR(fire,burn), [_unit, _intensity]] call CBA_fnc_localEvent;
_this // return

View File

@ -1,13 +1,11 @@
class CfgVehicles {
class SPE_Halftrack_base;
class SPE_US_M3_Halftrack_Fuel: SPE_Halftrack_base {
transportFuel = 0;
EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}};
EGVAR(refuel,fuelCargo) = 2000;
};
class SPE_OpelBlitz_base;
class SPE_OpelBlitz_Fuel: SPE_OpelBlitz_base {
transportFuel = 0;
EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}};
EGVAR(refuel,fuelCargo) = 2000;
};

Some files were not shown because too many files have changed in this diff Show More