diff --git a/.github/workflows/arma.yml b/.github/workflows/arma.yml index da5fa29835..d0649a0ade 100644 --- a/.github/workflows/arma.yml +++ b/.github/workflows/arma.yml @@ -48,7 +48,7 @@ jobs: - name: Rename build folder run: mv .hemttout/build .hemttout/@ace - name: Upload Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ace3-${{ github.sha }}-nobin path: .hemttout/@* diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 4140138f1e..cc6aba0a99 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -47,7 +47,7 @@ jobs: destination: docs/_site/ - name: Upload Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: jekyll-site path: docs/_site/ @@ -63,7 +63,7 @@ jobs: steps: - name: Download Artifacts - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: jekyll-site path: _site/ diff --git a/.github/workflows/extensions.yml b/.github/workflows/extensions.yml index 84ea189cca..9693d2df22 100644 --- a/.github/workflows/extensions.yml +++ b/.github/workflows/extensions.yml @@ -23,7 +23,7 @@ jobs: cd build cmake .. && cmake --build . - name: Upload Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ace3_extensions-${{ matrix.os }}-debug path: extensions/build diff --git a/.github/workflows/hemtt.yml b/.github/workflows/hemtt.yml index ffe8894986..e606852285 100644 --- a/.github/workflows/hemtt.yml +++ b/.github/workflows/hemtt.yml @@ -38,7 +38,7 @@ jobs: - name: Rename build folder run: mv .hemttout/build .hemttout/@ace - name: Upload Artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: ace3-${{ github.sha }} path: .hemttout/@* diff --git a/.github/workflows/pboproject.yml b/.github/workflows/pboproject.yml index be578c0e27..71e36eb12b 100644 --- a/.github/workflows/pboproject.yml +++ b/.github/workflows/pboproject.yml @@ -67,18 +67,19 @@ jobs: xcopy /e /h /q z\ace\tools\pDummies\gm gm\ xcopy /e /h /q z\ace\tools\pDummies\vn vn\ xcopy /e /h /q z\ace\tools\pDummies\WW2 WW2\ + xcopy /e /h /q z\ace\tools\pDummies\CUP CUP\ - name: Build run: py P:\z\ace\tools\make.py ci env: PYTHONUNBUFFERED: 1 - name: Archive logs - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: ${{ always() }} with: name: logs path: temp/*.log - name: Archive @ace - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: '@ace3-${{ github.sha }}' path: z\ace\release\@ace diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index fa0dbe292a..2130398964 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -11,6 +11,6 @@ jobs: steps: - name: Release Drafter if: github.repository == 'acemod/ACE3' - uses: release-drafter/release-drafter@v5 + uses: release-drafter/release-drafter@v6 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 8a7e6945a6..4ad0a5e1eb 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ CHANGELOG.md sqfvm.exe ArmaScriptCompiler.exe *.sqfc +!extras/**/*.zip diff --git a/AUTHORS.txt b/AUTHORS.txt index a11e39d78e..27dad9464e 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -6,6 +6,7 @@ # request, preferably including an email address. # CORE TEAM +BaerMitUmlaut Brett Mayson bux578 commy2 @@ -25,6 +26,7 @@ Kieran kymckay mharis001 MikeMF +MiszczuZPolski NouberNou PabstMirror Ruthberg @@ -56,7 +58,6 @@ Arcanum417 Arkhir ARV187 aka Spark23 Asgar Serran -BaerMitUmlaut Bamse Barman75 Bla1337 diff --git a/README.md b/README.md index 4951848123..feb9194d65 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@

- ACE3 Version + ACE3 Version ACE3 Issues diff --git a/addons/advanced_ballistics/XEH_postInit.sqf b/addons/advanced_ballistics/XEH_postInit.sqf index e6417f9a02..f9d78b5045 100644 --- a/addons/advanced_ballistics/XEH_postInit.sqf +++ b/addons/advanced_ballistics/XEH_postInit.sqf @@ -1,7 +1,5 @@ #include "script_component.hpp" -#include "initKeybinds.inc.sqf" - GVAR(currentbulletID) = -1; GVAR(Protractor) = false; @@ -11,6 +9,8 @@ GVAR(currentGrid) = 0; if (!hasInterface) exitWith {}; +#include "initKeybinds.inc.sqf" + ["CBA_settingsInitialized", { //If not enabled, dont't add PFEH if (!GVAR(enabled)) exitWith {}; diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index 57b57dcf22..ff09464901 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -2,35 +2,6 @@ if (!hasInterface) exitWith {}; -["baseline", { - private _fatigue = ACE_player getVariable [QGVAR(aimFatigue), 0]; - switch (stance ACE_player) do { - case ("CROUCH"): { - (1.0 + _fatigue ^ 2 * 0.1) - }; - case ("PRONE"): { - (1.0 + _fatigue ^ 2 * 2.0) - }; - default { - (1.5 + _fatigue ^ 2 * 3.0) - }; - }; -}, QUOTE(ADDON)] call EFUNC(common,addSwayFactor); - -["multiplier", { - switch (true) do { - case (isWeaponRested ACE_player): { - GVAR(swayFactor) * GVAR(restedSwayFactor) - }; - case (isWeaponDeployed ACE_player): { - GVAR(swayFactor) * GVAR(deployedSwayFactor) - }; - default { - GVAR(swayFactor) - }; - }; -}, QUOTE(ADDON)] call EFUNC(common,addSwayFactor); - // 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; @@ -39,6 +10,35 @@ if (!hasInterface) exitWith {}; ["CBA_settingsInitialized", { if (!GVAR(enabled)) exitWith {}; + ["baseline", { + private _fatigue = ACE_player getVariable [QGVAR(aimFatigue), 0]; + switch (stance ACE_player) do { + case ("CROUCH"): { + (1.0 + _fatigue ^ 2 * 0.1) + }; + case ("PRONE"): { + (1.0 + _fatigue ^ 2 * 2.0) + }; + default { + (1.5 + _fatigue ^ 2 * 3.0) + }; + }; + }, QUOTE(ADDON)] call EFUNC(common,addSwayFactor); + + ["multiplier", { + switch (true) do { + case (isWeaponRested ACE_player): { + GVAR(swayFactor) * GVAR(restedSwayFactor) + }; + case (isWeaponDeployed ACE_player): { + GVAR(swayFactor) * GVAR(deployedSwayFactor) + }; + default { + GVAR(swayFactor) + }; + }; + }, QUOTE(ADDON)] call EFUNC(common,addSwayFactor); + // - Post process effect ------------------------------------------------------ GVAR(ppeBlackout) = ppEffectCreate ["ColorCorrections", 4220]; GVAR(ppeBlackout) ppEffectEnable true; @@ -60,7 +60,7 @@ if (!hasInterface) exitWith {}; }, true] call CBA_fnc_addPlayerEventHandler; // - Duty factors ------------------------------------------------------------- - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GVAR(medicalLoaded)) then { [QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1 linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true]; }] call FUNC(addDutyFactor); diff --git a/addons/advanced_fatigue/XEH_preInit.sqf b/addons/advanced_fatigue/XEH_preInit.sqf index 643b7b0be0..9f58e44fdf 100644 --- a/addons/advanced_fatigue/XEH_preInit.sqf +++ b/addons/advanced_fatigue/XEH_preInit.sqf @@ -13,5 +13,6 @@ GVAR(dutyList) = createHashMap; GVAR(setAnimExclusions) = []; GVAR(inertia) = 0; GVAR(inertiaCache) = createHashMap; +GVAR(medicalLoaded) = ["ace_medical"] call EFUNC(common,isModLoaded); ADDON = true; diff --git a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf index 8903bab495..da469b6d21 100644 --- a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf +++ b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf @@ -23,6 +23,12 @@ if (!alive ACE_player) exitWith { _staminaBarContainer ctrlCommit 1; }; + +private _oxygen = 0.9; // Default AF oxygen saturation +if (GVAR(medicalLoaded) && {EGVAR(medical_vitals,simulateSpo2)}) then { + _oxygen = (ACE_player getVariable [QEGVAR(medical,spo2), 97]) / 100; +}; + private _currentWork = REE; private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6; @@ -42,8 +48,8 @@ GVAR(muscleDamage) = (GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3. private _muscleIntegritySqrt = sqrt (1 - GVAR(muscleDamage)); // Calculate available power -private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt; -private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt; +private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * _oxygen * _muscleIntegritySqrt; +private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * _oxygen * _muscleIntegritySqrt; // Calculate how much power is consumed from each reserve private _ae1Power = _currentWork min _ae1PathwayPowerFatigued; @@ -58,8 +64,8 @@ GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP; GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1; // Aerobic ATP reserve recovery -GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + OXYGEN * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0; -GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + OXYGEN * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0; +GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + _oxygen * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0; +GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + _oxygen * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0; // Anaerobic ATP reserver and fatigue recovery GVAR(anReserve) = ((GVAR(anReserve) @@ -70,9 +76,9 @@ GVAR(anFatigue) = ((GVAR(anFatigue) - (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor) ) min 1) max 0; -private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2; -private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE; -private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage); +GVAR(aeReservePercentage) = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2; +GVAR(anReservePercentage) = GVAR(anReserve) / AN_MAXRESERVE; +private _perceivedFatigue = 1 - (GVAR(anReservePercentage) min GVAR(aeReservePercentage)); [ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects); diff --git a/addons/advanced_fatigue/stringtable.xml b/addons/advanced_fatigue/stringtable.xml index dc68259db8..502ed12efd 100644 --- a/addons/advanced_fatigue/stringtable.xml +++ b/addons/advanced_fatigue/stringtable.xml @@ -44,7 +44,7 @@ Influenza la prestazione generale di tutti i giocatori smuniti di un fattore personalizzato. Maggiore significa migliore. 影響所有玩家的體力表現,值越高代表體力越好 影响所有玩家的体力表现,值越高代表体力越好 - Влияет на общую производительность игроков, у которых не задано персональное значение. + Влияет на общую производительность игроков, у которых не задано персональное значение. Чем выше, тем лучше. Influencia na performance geral de todos os jogadores sem nenhum fator personalizado. Quanto maior, melhor. Ovlivňuje celkový výkon všech hráčů bez vlastního faktoru. Vyšší znamená lépe. @@ -59,7 +59,7 @@ Influenza la prestazione personalizzata di questa unità. Maggiore significa migliore. 影響這個單位的體力表現,值越高代表體力越好 影响这个单位的体力表现,值越高代表体力越好 - Влияет на общую производительность юнита. + Влияет на общую производительность юнита.Чем выше, тем лучше. Influencia na performance geral dessa unidade. Quanto maior, melhor. Ovlivňuje celkový výkon této jednotky. Vyšší znamená lépe. @@ -192,6 +192,7 @@ Verwacklungsfaktor, wenn aufgelegt Fattore di Oscillazione Appoggiato 静止時の手ぶれ係数 + Коэффициент колебания прицела в состоянии покоя Influences the amount of weapon sway while weapon is rested. @@ -201,6 +202,7 @@ Beeinflusst, wie ruhig man die Waffe hält, während sie aufgelegt ist. Determina la quantità di oscillazione dell'arma quando questa è appoggiata. 静止している時の武器の手ぶれの量に影響します。 + Влияет на величину колебания прицела оружия в состоянии покоя. Deployed sway factor @@ -210,6 +212,7 @@ Verwacklungsfaktor, wenn Zweibein aufgestellt ist. Fattore di Oscillazione su Bipode 展開時の手ぶれ係数 + Коэффициент колебания прицела при развертывании Influences the amount of weapon sway while weapon is deployed. @@ -219,6 +222,7 @@ Beeinflusst, wie ruhig man die Waffen hält, während das Zweibein aufgestellt ist. Determina la quantità di oscillazione dell'arma quando questa è stabilizzata usando il bipode. 武器の展開(Cキー)時の武器の手ぶれの量に影響します。 + Влияет на величину колебания прицела оружия при его развертывании. Enabled @@ -246,7 +250,7 @@ Abilita/Disabilita la Fatica Avanzata. 啟用/關閉進階體力. 启用/关闭进阶体力。 - Включает / Отключает Продвинутую усталость + Включает/отключает Продвинутую усталость Ativa/Desativa Fadiga Avançada. Aktivuje / deaktivuje Pokročilou únavu. diff --git a/addons/advanced_throwing/functions/fnc_getMuzzle.sqf b/addons/advanced_throwing/functions/fnc_getMuzzle.sqf index e0c55daba6..eab95825e4 100644 --- a/addons/advanced_throwing/functions/fnc_getMuzzle.sqf +++ b/addons/advanced_throwing/functions/fnc_getMuzzle.sqf @@ -17,9 +17,9 @@ params ["_magazineClassname"]; -_magazineClassname = toLower _magazineClassname; +_magazineClassname = toLowerANSI _magazineClassname; private _throwMuzzles = getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); -_throwMuzzles = _throwMuzzles select {_magazineClassname in ((getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")) apply {toLower _x})}; +_throwMuzzles = _throwMuzzles select {_magazineClassname in ((getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")) apply {toLowerANSI _x})}; [_throwMuzzles select 0, ""] select (_throwMuzzles isEqualTo []) diff --git a/addons/ai/stringtable.xml b/addons/ai/stringtable.xml index 12c9c8d73f..11a686f6b2 100644 --- a/addons/ai/stringtable.xml +++ b/addons/ai/stringtable.xml @@ -90,6 +90,7 @@ Equipement JVN automatique Equipar NVGs automaticamente 暗視装置の自動装備 + Автоматическое оснащение ПНВ Equips NVG in inventory during night time and unequips it during day time.\nDoes not add NVGs to inventory! @@ -100,6 +101,7 @@ Equipe des JVN pendant la nuit et les déséquipe le jour.\nN'ajoute pas les JVN dans l'intenvaire ! Equipa o NVG do inventário durante a noite e desequipa durante o dia.\nNão adiciona NVGs ao inventário! インベントリ内の暗視装置を夜間に装備し、日中は解除し収納します。\nこれはNVGをインベントリに追加しません。 + Экипирует ПНВ в ночное время и отключает его в дневное время.\nНе добавляет ПНВ в инвентарь! diff --git a/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf b/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf index 868a0d0f8b..b85e556587 100644 --- a/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf +++ b/addons/aircraft/functions/fnc_droneModifyWaypoint.sqf @@ -17,13 +17,13 @@ * * Public: No */ - + params ["_vehicle", "_group", "_type", "_value"]; TRACE_4("droneModifyWaypoint",_vehicle,_group,_type,_value); private _index = (currentWaypoint _group) min count waypoints _group; private _waypoint = [_group, _index]; -switch (toLower _type) do { +switch (toLowerANSI _type) do { case ("height"): { private _pos = waypointPosition _waypoint; _pos set [2, _value]; diff --git a/addons/arsenal/ACE_Arsenal_Stats.hpp b/addons/arsenal/ACE_Arsenal_Stats.hpp index 7748d1bdc5..0856685447 100644 --- a/addons/arsenal/ACE_Arsenal_Stats.hpp +++ b/addons/arsenal/ACE_Arsenal_Stats.hpp @@ -123,7 +123,9 @@ class GVAR(stats) { stats[] = {"maximumLoad"}; displayName = "$STR_a3_rscdisplayarsenal_stat_load"; showBar = 1; + showText = 1; barStatement = QUOTE([ARR_3((_this select 0) select 0,_this select 1,[ARR_3([ARR_2(0,500)],[ARR_2(0.01,1)],false)])] call FUNC(statBarStatement_default)); + textStatement = QUOTE(call FUNC(statTextStatement_load)); tabs[] = {{3,4,5}, {}}; }; class ACE_smokeChemTTL: statBase { diff --git a/addons/arsenal/Cfg3DEN.hpp b/addons/arsenal/Cfg3DEN.hpp index f119af364b..1cec4a9c75 100644 --- a/addons/arsenal/Cfg3DEN.hpp +++ b/addons/arsenal/Cfg3DEN.hpp @@ -110,7 +110,7 @@ class Cfg3DEN { h = QUOTE(65 * ATTRIBUTE_H); drawSideArrows = 1; disableOverflow = 1; - columns[] = {0.05, 0.15, 0.85}; + columns[] = {0.05, 0.15, 0.83, 0.87}; }; class ArrowLeft: ctrlButton { idc = IDC_ATTRIBUTE_LIST_LEFT; diff --git a/addons/arsenal/XEH_PREP.hpp b/addons/arsenal/XEH_PREP.hpp index ca34487c97..94d4739b60 100644 --- a/addons/arsenal/XEH_PREP.hpp +++ b/addons/arsenal/XEH_PREP.hpp @@ -16,6 +16,8 @@ PREP(attributeKeyDown); PREP(attributeLoad); PREP(attributeMode); PREP(attributeSelect); +PREP(baseAttachment); +PREP(baseOptic); PREP(baseWeapon); PREP(buttonActionsPage); PREP(buttonCargo); @@ -96,6 +98,7 @@ PREP(statBarStatement_rateOfFIre); PREP(statTextStatement_accuracy); PREP(statTextStatement_explosionTime); PREP(statTextStatement_illuminators); +PREP(statTextStatement_load); PREP(statTextStatement_magCount); PREP(statTextStatement_mass); PREP(statTextStatement_rateOfFire); diff --git a/addons/arsenal/XEH_postInit.sqf b/addons/arsenal/XEH_postInit.sqf index 33646a25d7..7c7c677819 100644 --- a/addons/arsenal/XEH_postInit.sqf +++ b/addons/arsenal/XEH_postInit.sqf @@ -70,7 +70,7 @@ GVAR(lastSortDirectionRight) = DESCENDING; if (!isNil QGVAR(currentLoadoutsTab) && {GVAR(currentLoadoutsTab) == IDC_buttonSharedLoadouts}) then { private _curSelData = _contentPanelCtrl lnbData [lnbCurSelRow _contentPanelCtrl, 1]; - ([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"]; + ([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"]; _extendedLoadout params ["_loadout"]; private _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName]; @@ -81,10 +81,10 @@ GVAR(lastSortDirectionRight) = DESCENDING; _contentPanelCtrl lnbSetData [[_newRow, 1], _playerName + _loadoutName]; // Set color of row, depending if items are unavailable/missing - if (_nullItemsAmount > 0) then { + if (_nullItemsList isNotEqualTo []) then { _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; } else { - if (_unavailableItemsAmount > 0) then { + if (_unavailableItemsList isNotEqualTo []) then { _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; }; }; @@ -108,24 +108,16 @@ GVAR(lastSortDirectionRight) = DESCENDING; private _face = _extendedInfo getOrDefault [QGVAR(face), ""]; if (_face != "") then { - if (isMultiplayer) then { - private _id = [QGVAR(broadcastFace), [_unit, _face], QGVAR(centerFace_) + netId _unit] call CBA_fnc_globalEventJIP; - [_id, _unit] call CBA_fnc_removeGlobalEventJIP; - } else { - _unit setFace _face; - }; + private _id = [QGVAR(broadcastFace), [_unit, _face], QGVAR(centerFace_) + hashValue _unit] call CBA_fnc_globalEventJIP; + [_id, _unit] call CBA_fnc_removeGlobalEventJIP; }; // Set voice private _voice = _extendedInfo getOrDefault [QGVAR(voice), ""]; if (_voice != "") then { - if (isMultiplayer) then { - private _id = [QGVAR(broadcastVoice), [_unit, _voice], QGVAR(centerVoice_) + netId _unit] call CBA_fnc_globalEventJIP; - [_id, _unit] call CBA_fnc_removeGlobalEventJIP; - } else { - _unit setSpeaker _voice; - }; + private _id = [QGVAR(broadcastVoice), [_unit, _voice], QGVAR(centerVoice_) + hashValue _unit] call CBA_fnc_globalEventJIP; + [_id, _unit] call CBA_fnc_removeGlobalEventJIP; }; // Set insignia @@ -147,7 +139,7 @@ GVAR(lastSortDirectionRight) = DESCENDING; // Set voice if enabled if (GVAR(loadoutsSaveVoice)) then { - _extendedInfo set [QGVAR(voice), speaker _unit]; + _extendedInfo set [QGVAR(voice), (speaker _unit) call EFUNC(common,getConfigName)]; }; // Set insignia if enabled diff --git a/addons/arsenal/XEH_preInit.sqf b/addons/arsenal/XEH_preInit.sqf index 7002886f77..10cc3989e9 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -36,7 +36,59 @@ call FUNC(compileStats); EGVAR(common,blockItemReplacement) = false; }] call CBA_fnc_addEventHandler; +[QGVAR(cargoChanged), { + params ["_display"]; + // Only update actions if necessary, this can get performance-intensive using the arrow keys + if (!GVAR(updateActionsOnCargoChange)) exitWith {}; + private _actionInfo = [_display]; + _actionInfo append GVAR(actionInfo); + [QGVAR(displayActions), _actionInfo] call CBA_fnc_localEvent; +}] call CBA_fnc_addEventHandler; + // Setup Tools tab [keys (uiNamespace getVariable [QGVAR(configItemsTools), createHashMap]), LLSTRING(toolsTab), TOOLS_TAB_ICON, -1, true] call FUNC(addRightPanelButton); +// TODO: make IDCs able to match IDX with simple math? +GVAR(idxMap) = createHashMapFromArray [ + [IDC_buttonPrimaryWeapon, IDX_VIRT_PRIMARY_WEAPONS], + [IDC_buttonHandgun, IDX_VIRT_HANDGUN_WEAPONS], + [IDC_buttonSecondaryWeapon, IDX_VIRT_SECONDARY_WEAPONS], + [IDC_buttonHeadgear, IDX_VIRT_HEADGEAR], + [IDC_buttonUniform, IDX_VIRT_UNIFORM], + [IDC_buttonVest, IDX_VIRT_VEST], + [IDC_buttonBackpack, IDX_VIRT_BACKPACK], + [IDC_buttonGoggles, IDX_VIRT_GOGGLES], + [IDC_buttonNVG, IDX_VIRT_NVG], + [IDC_buttonBinoculars, IDX_VIRT_BINO], + [IDC_buttonMap, IDX_VIRT_MAP], + [IDC_buttonGPS, IDX_VIRT_COMMS], + [IDC_buttonRadio, IDX_VIRT_RADIO], + [IDC_buttonCompass, IDX_VIRT_COMPASS], + [IDC_buttonWatch, IDX_VIRT_WATCH] +]; + +// Make new hashmaps for face/voice/insignia so mission makers can disable them +// Copies of hashmaps aren't final +GVAR(faceCache) = +(uiNamespace getVariable QGVAR(faceCache)); +GVAR(voiceCache) = +(uiNamespace getVariable QGVAR(voiceCache)); +GVAR(insigniaCache) = +(uiNamespace getVariable QGVAR(insigniaCache)); + +// Get mission/campaign insignias +// BIS_fnc_setUnitInsignia will look in mission config, then campaign, then global config last, so overwrite accordingly +private _insigniaCondition = toString { + if (isNumber (_x >> "scope")) then { + getNumber (_x >> "scope") == 2 + } else { + true + }; +}; + +// Ref fnc_addListBoxItem, 0/nil = configFile, 1 = campaignConfigFile, 2 = missionConfigFile +{ + GVAR(insigniaCache) set [_x, 1]; +} forEach (_insigniaCondition configClasses (campaignConfigFile >> "CfgUnitInsignia")); +{ + GVAR(insigniaCache) set [_x, 2]; +} forEach (_insigniaCondition configClasses (missionConfigFile >> "CfgUnitInsignia")); + ADDON = true; diff --git a/addons/arsenal/defines.hpp b/addons/arsenal/defines.hpp index 73116dde76..cd6d937426 100644 --- a/addons/arsenal/defines.hpp +++ b/addons/arsenal/defines.hpp @@ -155,6 +155,8 @@ #define IDC_statsNextPage 53 #define IDC_statsCurrentPage 54 #define IDC_actionsBox 90 +#define IDC_actionsBackground1 90010 +#define IDC_actionsBackground2 90011 #define IDC_actionsText1 9001 #define IDC_actionsButton1 9002 #define IDC_actionsText2 9003 @@ -268,6 +270,7 @@ #define IDX_VIRT_UNIQUE_UNKNOWN_ITEMS 25 // Indexes of current items array +// Should match IDX_VIRT_X macros for any left panel tabs #define IDX_CURR_PRIMARY_WEAPON 0 #define IDX_CURR_SECONDARY_WEAPON 1 #define IDX_CURR_HANDGUN_WEAPON 2 @@ -487,3 +490,6 @@ if (!isNil QGVAR(customRightPanelButtons)) then {\ _contentPanelCtrl lnbSetPicture [[_newRow, 7], getText (configFile >> "CfgVehicles" >> (_loadout select IDX_LOADOUT_BACKPACK) select 0 >> "picture")];\ _contentPanelCtrl lnbSetPicture [[_newRow, 8], getText (_cfgWeapons >> _loadout select IDX_LOADOUT_HEADGEAR >> "picture")];\ _contentPanelCtrl lnbSetPicture [[_newRow, 9], getText (configFile >> "CfgGlasses" >> _loadout select IDX_LOADOUT_GOGGLES >> "picture")]; + +#define ACTION_TYPE_TEXT 0 +#define ACTION_TYPE_BUTTON 1 diff --git a/addons/arsenal/functions/fnc_addAction.sqf b/addons/arsenal/functions/fnc_addAction.sqf index 9f69d2d51f..b04d56729a 100644 --- a/addons/arsenal/functions/fnc_addAction.sqf +++ b/addons/arsenal/functions/fnc_addAction.sqf @@ -1,4 +1,5 @@ #include "..\script_component.hpp" +#include "..\defines.hpp" /* * Author: johnb43 * Adds custom action buttons. @@ -10,6 +11,7 @@ * 3: Actions * 4: Condition (default: {true}) * 5: Scope editor (default: 2) + * 6: Update when cargo content changes (default: false) * * Return Value: * 0: Array of IDs @@ -30,7 +32,8 @@ params [ ["_title", "", [""]], ["_actions", [], [[]]], ["_rootCondition", {true}, [{}]], - ["_scopeEditor", 2, [0]] + ["_scopeEditor", 2, [0]], + ["_updateOnCargoChange", false, [false]] ]; // Compile actions from config (in case this is called before preInit) @@ -119,4 +122,8 @@ private _group = []; }; } forEach _tabs; +if (_updateOnCargoChange) then { + GVAR(updateActionsOnCargoChange) = true; +}; + _return diff --git a/addons/arsenal/functions/fnc_addListBoxItem.sqf b/addons/arsenal/functions/fnc_addListBoxItem.sqf index 2852aa7232..777b1efe87 100644 --- a/addons/arsenal/functions/fnc_addListBoxItem.sqf +++ b/addons/arsenal/functions/fnc_addListBoxItem.sqf @@ -6,9 +6,10 @@ * * Arguments: * 0: Config category, must be "CfgWeapons", "CfgVehicles", "CfgMagazines", "CfgVoice" or "CfgUnitInsignia" - * 1: Classname + * 1: Classname (must be in config case) * 2: Panel control * 3: Name of the picture entry in that Cfg class (default: "picture") + * 4: Config root (default: 0 -> configFile) * * Return Value: * None @@ -19,9 +20,9 @@ * Public: Yes */ -params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]]]; +params ["_configCategory", "_className", "_ctrlPanel", ["_pictureEntryName", "picture", [""]], ["_configRoot", 0, [0]]]; -private _skip = GVAR(favoritesOnly) && {!(_className in GVAR(currentItems))} && {!((toLower _className) in GVAR(favorites))}; +private _skip = GVAR(favoritesOnly) && {!(_className in GVAR(currentItems))} && {!((toLowerANSI _className) in GVAR(favorites))}; if (_skip) then { switch (GVAR(currentLeftPanel)) do { case IDC_buttonPrimaryWeapon: { @@ -41,10 +42,10 @@ if (_skip) then { if (_skip) exitWith {}; -// Sanitise key, as it's public; If not in cache, find info and cache it for later use -((uiNamespace getVariable QGVAR(addListBoxItemCache)) getOrDefaultCall [_configCategory + _className, { +// If not in cache, find info and cache it for later use +((uiNamespace getVariable QGVAR(addListBoxItemCache)) getOrDefaultCall [_configCategory + _className + str _configRoot, { // Get classname (config case), display name, picture and DLC - private _configPath = configFile >> _configCategory >> _className; + private _configPath = ([configFile, campaignConfigFile, missionConfigFile] select _configRoot) >> _configCategory >> _className; private _dlcName = _configPath call EFUNC(common,getAddon); // If _pictureEntryName is empty, then this item has no picture (e.g. faces) @@ -57,7 +58,7 @@ _ctrlPanel lbSetPicture [_lbAdd, _itemPicture]; _ctrlPanel lbSetPictureRight [_lbAdd, ["", _modPicture] select GVAR(enableModIcons)]; _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; -if ((toLower _className) in GVAR(favorites)) then { +if ((toLowerANSI _className) in GVAR(favorites)) then { _ctrlPanel lbSetColor [_lbAdd, FAVORITES_COLOR]; _ctrlPanel lbSetSelectColor [_lbAdd, FAVORITES_COLOR]; }; diff --git a/addons/arsenal/functions/fnc_addRightPanelButton.sqf b/addons/arsenal/functions/fnc_addRightPanelButton.sqf index 6e1035a86a..a1bdb09d1d 100644 --- a/addons/arsenal/functions/fnc_addRightPanelButton.sqf +++ b/addons/arsenal/functions/fnc_addRightPanelButton.sqf @@ -66,7 +66,8 @@ _items = _items select { _x isKindOf ["CBA_MiscItem", _cfgWeapons] && {getNumber (_configItemInfo >> "type") in [TYPE_MUZZLE, TYPE_OPTICS, TYPE_FLASHLIGHT, TYPE_BIPOD]} || {getNumber (_configItemInfo >> "type") in [TYPE_FIRST_AID_KIT, TYPE_MEDIKIT, TYPE_TOOLKIT]} || {getText (_cfgWeapons >> _x >> "simulation") == "ItemMineDetector"} || - {getNumber (_cfgMagazines >> _x >> "ACE_isUnique") == 1} + {getNumber (_cfgMagazines >> _x >> "ACE_isUnique") == 1} || + {getNumber (_cfgMagazines >> _x >> "ACE_asItem") == 1} }; GVAR(customRightPanelButtons) set [_position, [_items apply {_x call EFUNC(common,getConfigName)}, _picture, _tooltip, _moveOnOverwrite]]; diff --git a/addons/arsenal/functions/fnc_attributeAddItems.sqf b/addons/arsenal/functions/fnc_attributeAddItems.sqf index 5457a920a2..612e894a15 100644 --- a/addons/arsenal/functions/fnc_attributeAddItems.sqf +++ b/addons/arsenal/functions/fnc_attributeAddItems.sqf @@ -46,6 +46,7 @@ private _cfgWeapons = configFile >> "CfgWeapons"; private _cfgMagazines = configFile >> "CfgMagazines"; private _cfgVehicles = configFile >> "CfgVehicles"; private _cfgGlasses = configFile >> "CfgGlasses"; +private _dlcName = ""; // Exit with current items (no specific category) if (_category == IDX_CAT_ALL) exitWith { @@ -73,6 +74,12 @@ if (_category == IDX_CAT_ALL) exitWith { _listbox lnbSetData [[_index, 1], _x]; _listbox lnbSetPicture [[_index, 0], getText (_config >> "picture")]; _listbox lnbSetTooltip [[_index, 0], _x]; + + _dlcName = _config call EFUNC(common,getAddon); + + if (_dlcName != "") then { + _listbox lnbSetPicture [[_index, 2], (modParams [_dlcName, ["logo"]]) param [0, ""]]; + }; }; } forEach _attributeItems; @@ -130,12 +137,20 @@ private _config = _cfgClass; _alpha = 0.5; }; - _index = _listbox lnbAddRow ["", _displayName, _symbol]; + _index = _listbox lnbAddRow ["", _displayName, "", _symbol]; _listbox lnbSetData [[_index, 1], _x]; _listbox lnbSetPicture [[_index, 0], getText (_config >> _x >> "picture")]; _listbox lnbSetTooltip [[_index, 0], _x]; _listbox lnbSetColor [[_index, 1], [1, 1, 1, _alpha]]; - _listbox lnbSetColor [[_index, 2], [1, 1, 1, _alpha]]; + _listbox lnbSetColor [[_index, 3], [1, 1, 1, _alpha]]; + + // Mod icon is in column 2 + _dlcName = (_config >> _x) call EFUNC(common,getAddon); + + if (_dlcName != "") then { + _listbox lnbSetPicture [[_index, 2], (modParams [_dlcName, ["logo"]]) param [0, ""]]; + _listbox lnbSetPictureColor [[_index, 2], [1, 1, 1, _alpha]]; + }; }; } forEach (keys _categoryItems); diff --git a/addons/arsenal/functions/fnc_attributeSelect.sqf b/addons/arsenal/functions/fnc_attributeSelect.sqf index 5aeb46c5a4..2f9df7775e 100644 --- a/addons/arsenal/functions/fnc_attributeSelect.sqf +++ b/addons/arsenal/functions/fnc_attributeSelect.sqf @@ -35,9 +35,10 @@ if (_addItem && {_itemIndex == -1}) exitWith { _attributeItems pushBack _itemClassname; // Change symbol and increase alpha - _listbox lnbSetText [[_currentRow, 2], [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode]; + _listbox lnbSetText [[_currentRow, 3], [SYMBOL_ITEM_VIRTUAL, SYMBOL_ITEM_REMOVE] select _attributeMode]; _listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 1]]; - _listbox lnbSetColor [[_currentRow, 2], [1, 1, 1, 1]]; + _listbox lnbSetPictureColor [[_currentRow, 2], [1, 1, 1, 1]]; // mod icon is in column 2 + _listbox lnbSetColor [[_currentRow, 3], [1, 1, 1, 1]]; }; // Remove item if in list @@ -45,7 +46,8 @@ if (!_addItem && {_itemIndex != -1}) exitWith { _attributeItems deleteAt _itemIndex; // Change symbol and reduce alpha - _listbox lnbSetText [[_currentRow, 2], SYMBOL_ITEM_NONE]; + _listbox lnbSetText [[_currentRow, 3], SYMBOL_ITEM_NONE]; _listbox lnbSetColor [[_currentRow, 1], [1, 1, 1, 0.5]]; - _listbox lnbSetColor [[_currentRow, 2], [1, 1, 1, 0.5]]; + _listbox lnbSetPictureColor [[_currentRow, 2], [1, 1, 1, 0.5]]; // mod icon is in column 2 + _listbox lnbSetColor [[_currentRow, 3], [1, 1, 1, 0.5]]; }; diff --git a/addons/arsenal/functions/fnc_baseAttachment.sqf b/addons/arsenal/functions/fnc_baseAttachment.sqf new file mode 100644 index 0000000000..2cee699ba6 --- /dev/null +++ b/addons/arsenal/functions/fnc_baseAttachment.sqf @@ -0,0 +1,51 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas, LinkIsGrim + * Returns base attachment for CBA scripted attachment + * Adapted from CBA_fnc_switchableAttachments + * + * Arguments: + * 0: Attachment + * + * Return Value: + * Base attachment + * + * Example: + * "ACE_acc_pointer_green_IR" call ace_arsenal_fnc_baseAttachment + * + * Public: Yes + */ + +params [["_item", "", [""]]]; + +TRACE_1("looking up base attachment",_item); + +private _switchableClasses = []; + +private _cfgWeapons = configfile >> "CfgWeapons"; +private _config = _cfgWeapons >> _item; +_item = configName _config; + +while { + _config = _cfgWeapons >> getText (_config >> "MRT_SwitchItemNextClass"); + isClass _config && {_switchableClasses pushBackUnique configName _config != -1} +} do {}; + +_config = _cfgWeapons >> _item; +private _backward = []; +while { + _config = _cfgWeapons >> getText (_config >> "MRT_SwitchItemPrevClass"); + isClass _config && {_backward pushBackUnique configName _config != -1} +} do {}; + +_switchableClasses append _backward; +_switchableClasses = _switchableClasses arrayIntersect _switchableClasses; + +{ + if (getNumber (_cfgWeapons >> _x >> "scope") == 2) exitWith { + TRACE_2("found class",_item,_x); + _item = _x; + }; +} forEach _switchableClasses; + +_item diff --git a/addons/arsenal/functions/fnc_baseOptic.sqf b/addons/arsenal/functions/fnc_baseOptic.sqf new file mode 100644 index 0000000000..c3eb5e811a --- /dev/null +++ b/addons/arsenal/functions/fnc_baseOptic.sqf @@ -0,0 +1,32 @@ +#include "..\script_component.hpp" +/* + * Author: Jonpas, LinkIsGrim + * Returns base optic for CBA scripted optics (PIP and 2D) + * + * Arguments: + * 0: Optic + * + * Return Value: + * Base optic + * + * Example: + * "CUP_optic_Elcan_SpecterDR_black_PIP" call ace_arsenal_fnc_baseOptic + * + * Public: Yes + */ + +params [["_optic", "", [""]]]; + +// PIP +private _baseClasses = configProperties [configFile >> "CBA_PIPItems", "getText _x == _optic"]; + +// Carry Handle +{ + _baseClasses append (configProperties [_x, "getText _x == _optic"]); +} forEach configProperties [configFile >> "CBA_CarryHandleTypes"]; + +if (_baseClasses isNotEqualTo []) then { + _optic = configName (_baseClasses select 0); +}; + +_optic diff --git a/addons/arsenal/functions/fnc_baseWeapon.sqf b/addons/arsenal/functions/fnc_baseWeapon.sqf index f166af94ce..abeb0e0ab9 100644 --- a/addons/arsenal/functions/fnc_baseWeapon.sqf +++ b/addons/arsenal/functions/fnc_baseWeapon.sqf @@ -19,7 +19,7 @@ params [["_weapon", "", [""]]]; // Check if item is cached -(uiNamespace getVariable QGVAR(baseWeaponNameCache)) getOrDefaultCall [toLower _weapon, { +(uiNamespace getVariable QGVAR(baseWeaponNameCache)) getOrDefaultCall [toLowerANSI _weapon, { private _cfgWeapons = configfile >> "CfgWeapons"; private _config = _cfgWeapons >> _weapon; diff --git a/addons/arsenal/functions/fnc_compileActions.sqf b/addons/arsenal/functions/fnc_compileActions.sqf index 6eda62ac65..9001a5558a 100644 --- a/addons/arsenal/functions/fnc_compileActions.sqf +++ b/addons/arsenal/functions/fnc_compileActions.sqf @@ -1,4 +1,5 @@ #include "..\script_component.hpp" +#include "..\defines.hpp" /* * Author: Brett Mayson * Create the internal actions arrays when needed for the first time. @@ -37,6 +38,8 @@ private _actionList = [ private _configGroupEntries = "true" configClasses (configFile >> QGVAR(actions)); +GVAR(updateActionsOnCargoChange) = false; + { private _scopeEditor = getNumber (_x >> "scopeEditor"); @@ -48,6 +51,10 @@ private _configGroupEntries = "true" configClasses (configFile >> QGVAR(actions) private _rootDisplayName = getText (_x >> "displayName"); private _rootCondition = getText (_x >> "condition"); private _rootTabs = getArray (_x >> "tabs"); + private _updateOnCargoChanged = getNumber (_x >> "updateOnCargoChanged"); + if (_updateOnCargoChanged > 0) then { + GVAR(updateActionsOnCargoChange) = true; + }; if (_rootCondition != "") then { _rootCondition = compile _rootCondition; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf index 26f872dfdf..1eb98d29ec 100644 --- a/addons/arsenal/functions/fnc_fillLeftPanel.sqf +++ b/addons/arsenal/functions/fnc_fillLeftPanel.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe, johnb43 + * Author: Alganthe, johnb43, LinkIsGrim * Fills left panel. * * Arguments: @@ -17,21 +17,28 @@ params ["_display", "_control", ["_animate", true]]; +private _ctrlIDC = ctrlIDC _control; +private _ctrlPanel = _display displayCtrl IDC_leftTabContent; +private _idxVirt = GVAR(idxMap) getOrDefault [_ctrlIDC, -1, true]; + // Fade old control background if (!isNil QGVAR(currentLeftPanel)) then { private _previousCtrlBackground = _display displayCtrl (GVAR(currentLeftPanel) - 1); _previousCtrlBackground ctrlSetFade 1; _previousCtrlBackground ctrlCommit ([0, FADE_DELAY] select _animate); + + // When switching tabs, clear searchbox + if (GVAR(currentLeftPanel) != _ctrlIDC) then { + (_display displayCtrl IDC_leftSearchbar) ctrlSetText ""; + (_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; + }; }; // Show new control background -private _ctrlIDC = ctrlIDC _control; private _ctrlBackground = _display displayCtrl (_ctrlIDC - 1); _ctrlBackground ctrlSetFade 0; _ctrlBackground ctrlCommit ([0, FADE_DELAY] select _animate); -private _ctrlPanel = _display displayCtrl IDC_leftTabContent; - // Force a "refresh" animation of the panel if (_animate) then { _ctrlPanel ctrlSetFade 1; @@ -41,212 +48,82 @@ if (_animate) then { }; _ctrlPanel lbSetCurSel -1; +// Purge old data +lbClear _ctrlPanel; -// Handle icons and filling -private _selectedItem = switch (true) do { - // Primary weapons, secondary weapons, handgun weapons - case (_ctrlIDC in [IDC_buttonPrimaryWeapon, IDC_buttonHandgun, IDC_buttonSecondaryWeapon]): { - // Purge old data - lbClear _ctrlPanel; - - // Add "Empty" entry - private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"]; - _ctrlPanel lbSetValue [_addEmpty, -1]; - - // Add selected tab's weapons - private _index = [IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun] find _ctrlIDC; - - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys ((GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _index)); - - GVAR(currentItems) select _index - }; - // Uniforms, vests, backpacks - case (_ctrlIDC in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]): { - // Purge old data - lbClear _ctrlPanel; - - // Add "Empty" entry - private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"]; - _ctrlPanel lbSetValue [_addEmpty, -1]; - - switch (_ctrlIDC) do { - // Add uniforms - case IDC_buttonUniform: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIFORM)); - - GVAR(currentItems) select IDX_CURR_UNIFORM - }; - // Add vests - case IDC_buttonVest: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_VEST)); - - GVAR(currentItems) select IDX_CURR_VEST - }; - // Add backpacks - case IDC_buttonBackpack: { - { - ["CfgVehicles", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_BACKPACK)); - - GVAR(currentItems) select IDX_CURR_BACKPACK - }; - }; - }; - // Other - default { - // Don't reset right panel selection if left tab is binos - if (_ctrlIDC != IDC_buttonBinoculars) then { - GVAR(currentRightPanel) = nil; - }; - - lbClear _ctrlPanel; - - // For every left tab except faces and voices, add "Empty" entry - if !(_ctrlIDC in [IDC_buttonFace, IDC_buttonVoice]) then { - private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"]; - _ctrlPanel lbSetValue [_addEmpty, -1]; - }; - - switch (_ctrlIDC) do { - // Headgear - case IDC_buttonHeadgear: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_HEADGEAR)); - - GVAR(currentItems) select IDX_CURR_HEADGEAR - }; - // Facewear - case IDC_buttonGoggles: { - { - ["CfgGlasses", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_GOGGLES)); - - GVAR(currentItems) select IDX_CURR_GOGGLES - }; - // NVGs - case IDC_buttonNVG: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_NVG)); - - GVAR(currentItems) select IDX_CURR_NVG - }; - // Binoculars - case IDC_buttonBinoculars: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_BINO)); - - GVAR(currentItems) select IDX_CURR_BINO - }; - // Maps - case IDC_buttonMap: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_MAP)); - - GVAR(currentItems) select IDX_CURR_MAP - }; - // Compasses - case IDC_buttonCompass: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_COMPASS)); - - GVAR(currentItems) select IDX_CURR_COMPASS - }; - // Radios - case IDC_buttonRadio: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_RADIO)); - - GVAR(currentItems) select IDX_CURR_RADIO - }; - // Watches - case IDC_buttonWatch: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_WATCH)); - - GVAR(currentItems) select IDX_CURR_WATCH - }; - // GPS and UAV Terminals - case IDC_buttonGPS: { - { - ["CfgWeapons", _x, _ctrlPanel] call FUNC(addListBoxItem); - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_COMMS)); - - GVAR(currentItems) select IDX_CURR_COMMS - }; - // Faces - case IDC_buttonFace: { - private _lbAdd = -1; - - { - _y params ["_displayName", "_modPicture"]; - - _lbAdd = _ctrlPanel lbAdd _displayName; - _ctrlPanel lbSetData [_lbAdd, _x]; - _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _x]]; - _ctrlPanel lbSetPictureRight [_lbAdd, ["", _modPicture] select GVAR(enableModIcons)]; - } forEach (uiNamespace getVariable QGVAR(faceCache)); - - GVAR(currentFace) - }; - // Voices - case IDC_buttonVoice: { - { - ["CfgVoice", _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem); - } forEach (uiNamespace getVariable QGVAR(voiceCache)); - - GVAR(currentVoice) - }; - // Insignia - case IDC_buttonInsignia: { - // Insignia from config - { - ["CfgUnitInsignia", _x, _ctrlPanel, "texture"] call FUNC(addListBoxItem); - } forEach (uiNamespace getVariable QGVAR(insigniaCache)); - - private _displayName = ""; - private _className = ""; - private _lbAdd = -1; - - // Insignia from mission file - { - _className = configName _x; - _displayName = getText (_x >> "displayName"); - _lbAdd = _ctrlPanel lbAdd _displayName; - - _ctrlPanel lbSetData [_lbAdd, _className]; - _ctrlPanel lbSetPicture [_lbAdd, getText (_x >> "texture")]; - _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _className]]; - } forEach ("(if (isNumber (_x >> 'scope')) then {getNumber (_x >> 'scope')} else {2}) == 2" configClasses (missionConfigFile >> "CfgUnitInsignia")); - - GVAR(currentInsignia) - }; - // Unknown - default {""}; - }; - }; +// For every left tab except faces and voices, add "Empty" entry +if !(_ctrlIDC in [IDC_buttonFace, IDC_buttonVoice]) then { + private _addEmpty = _ctrlPanel lbAdd format [" <%1>", localize "str_empty"]; + _ctrlPanel lbSetValue [_addEmpty, -1]; }; -// When switching tabs, clear searchbox -if (GVAR(currentLeftPanel) != _ctrlIDC) then { - (_display displayCtrl IDC_leftSearchbar) ctrlSetText ""; - (_display displayCtrl IDC_rightSearchbar) ctrlSetText ""; +// Don't reset the current right panel for weapons, binos and containers +if !(_idxVirt in [IDX_VIRT_PRIMARY_WEAPONS, IDX_VIRT_SECONDARY_WEAPONS, IDX_VIRT_HANDGUN_WEAPONS, IDX_VIRT_BINO, IDX_VIRT_UNIFORM, IDX_VIRT_VEST, IDX_VIRT_BACKPACK]) then { + GVAR(currentRightPanel) = nil; +}; +GVAR(currentLeftPanel) = _ctrlIDC; + +// Add items to the listbox +private _selectedItem = if (_idxVirt != -1) then { // Items + private _configParent = switch (_idxVirt) do { + case IDX_VIRT_GOGGLES: {"CfgGlasses"}; + case IDX_VIRT_BACKPACK: {"CfgVehicles"}; + default {"CfgWeapons"}; + }; + + private _items = if (_idxVirt < IDX_VIRT_HEADGEAR) then { + keys ((GVAR(virtualItems) get IDX_VIRT_WEAPONS) get _idxVirt) + } else { + keys (GVAR(virtualItems) get _idxVirt) + }; + + { + [_configParent, _x, _ctrlPanel] call FUNC(addListBoxItem); + } forEach _items; + + GVAR(currentItems) select _idxVirt +} else { // Special cases + switch (_ctrlIDC) do { + // Faces + case IDC_buttonFace: { + private _lbAdd = -1; // micro-optimization + // Faces need to be added like this because their config path is + // configFile >> "CfgFaces" >> face category >> className + { + _y params ["_displayName", "_modPicture"]; + _lbAdd = _ctrlPanel lbAdd _displayName; + _ctrlPanel lbSetData [_lbAdd, _x]; + _ctrlPanel lbSetTooltip [_lbAdd, format ["%1\n%2", _displayName, _x]]; + _ctrlPanel lbSetPictureRight [_lbAdd, ["", _modPicture] select GVAR(enableModIcons)]; + } forEach GVAR(faceCache); // HashMap, not array + + GVAR(currentFace) + }; + // Voices + case IDC_buttonVoice: { + { + ["CfgVoice", _x, _ctrlPanel, "icon"] call FUNC(addListBoxItem); + } forEach (keys GVAR(voiceCache)); + + GVAR(currentVoice) + }; + // Insignia + case IDC_buttonInsignia: { + { + ["CfgUnitInsignia", _x, _ctrlPanel, "texture", _y] call FUNC(addListBoxItem); + } forEach GVAR(insigniaCache); + + GVAR(currentInsignia) + }; + // Unknown + default { + WARNING_1("Unknown arsenal left panel with IDC %1, update ace_arsenal_idxMap and relevant macros if adding a new tab",_ctrlIDC); + "" + }; + }; }; // Trigger event -GVAR(currentLeftPanel) = _ctrlIDC; [QGVAR(leftPanelFilled), [_display, _ctrlIDC, GVAR(currentRightPanel)]] call CBA_fnc_localEvent; // Sort diff --git a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf index 7d5152dfdd..6174193b73 100644 --- a/addons/arsenal/functions/fnc_fillLoadoutsList.sqf +++ b/addons/arsenal/functions/fnc_fillLoadoutsList.sqf @@ -1,12 +1,16 @@ #include "..\script_component.hpp" #include "..\defines.hpp" /* - * Author: Alganthe, johnb43 - * Fill loadouts list. + * Author: Alganthe, johnb43, LinkIsGrim + * Fill loadouts list over multiple frames. LOADOUTS_PER_FRAME macro does what it says on the tin. + * Should only ever be called by display load (with optional params as default) and by itself. + * Listen to ace_arsenal_loadoutsListFilled event if you need to iterate over the loadouts list. * * Arguments: * 0: Loadouts display * 1: Tab control + * 2: Current frame filling loadouts list (default: 0) + * 3: Frames necessary to fill loadouts list (default: -1) * * Return Value: * None @@ -14,29 +18,46 @@ * Public: No */ -params ["_display", "_control"]; +// Can just be modified directly, no further setup needed +#define LOADOUTS_PER_FRAME 10 -(_display displayCtrl IDC_textEditBox) ctrlSetText ""; +params ["_display", "_control", ["_currentFrame", 0], ["_framesToFill", -1]]; + +if (isNull _display) exitWith { + TRACE_2("display closed, aborting",_currentFrame,_framesToFill); +}; private _contentPanelCtrl = _display displayCtrl IDC_contentPanel; +if (_currentFrame == 0) then { + (_display displayCtrl IDC_textEditBox) ctrlSetText ""; -// Force a "refresh" animation of the panel -_contentPanelCtrl ctrlSetFade 1; -_contentPanelCtrl ctrlCommit 0; -_contentPanelCtrl ctrlSetFade 0; -_contentPanelCtrl ctrlCommit FADE_DELAY; + // Force a "refresh" animation of the panel + _contentPanelCtrl ctrlSetFade 1; + _contentPanelCtrl ctrlCommit 0; + _contentPanelCtrl ctrlSetFade 0; + _contentPanelCtrl ctrlCommit FADE_DELAY; -_contentPanelCtrl lnbSetCurSelRow -1; -lnbClear _contentPanelCtrl; + _contentPanelCtrl lnbSetCurSelRow -1; + lnbClear _contentPanelCtrl; +}; private _sharedLoadoutsVars = GVAR(sharedLoadoutsNamespace) getVariable QGVAR(sharedLoadoutsVars); -private _cfgWeapons = configFile >> "CfgWeapons"; +private _cfgWeapons = configFile >> "CfgWeapons"; // Used by ADD_LOADOUTS_LIST_PICTURES macro, do not remove private _newRow = -1; if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { private _loadoutNameAndTab = ""; private _loadoutCachedInfo = ""; private _sharingEnabled = GVAR(allowSharedLoadouts) && {isMultiplayer}; + private _loadouts = [ + profileNamespace getVariable [QGVAR(saved_loadouts), []], + GVAR(defaultLoadoutsList) + ] select (ctrlIDC _control == IDC_buttonDefaultLoadouts); + if (_currentFrame == 0) then { + _framesToFill = floor ((count _loadouts) / LOADOUTS_PER_FRAME); + TRACE_2("filling loadouts list",_currentFrame,_framesToFill); + _this set [3, _framesToFill]; + }; // Add all loadouts to loadout list { @@ -50,15 +71,16 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { _loadoutCachedInfo = [_loadoutData] call FUNC(verifyLoadout); _contentPanelCtrl setVariable [_loadoutNameAndTab, _loadoutCachedInfo]; - _loadoutCachedInfo params ["", "_nullItemsAmount", "_unavailableItemsAmount", "_nullItemsList", "_unavailableItemsList"]; + _loadoutCachedInfo params ["", "_nullItemsList", "_unavailableItemsList", "_missingExtendedInfo"]; // Log missing / nil items to RPT (only once per arsenal session) - if (GVAR(EnableRPTLog) && {(_nullItemsAmount > 0) || {_unavailableItemsAmount > 0}}) then { + if (GVAR(EnableRPTLog) && {(_nullItemsList isNotEqualTo []) || {_unavailableItemsList isNotEqualTo [] || {_missingExtendedInfo isNotEqualTo []}}}) then { private _printComponent = "ACE_Arsenal - Loadout:"; private _printNullItemsList = ["Missing items:", str _nullItemsList] joinString " "; private _printUnavailableItemsList = ["Unavailable items:", str _unavailableItemsList] joinString " "; + private _printMissingExtendedInfo = ["Missing extended loadout:", str _missingExtendedInfo] joinString " "; - diag_log text (format ["%1%5 %2%5 %3%5 %4", _printComponent, "Name: " + _loadoutName, _printNullItemsList, _printUnavailableItemsList, endl]); + diag_log text (format ["%1%6 %2%6 %3%6 %4%6 %5", _printComponent, "Name: " + _loadoutName, _printNullItemsList, _printUnavailableItemsList, _printMissingExtendedInfo, endl]); }; }; @@ -69,18 +91,18 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { _contentPanelCtrl lnbSetColumnsPos [0, 0.05, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; }; - _loadoutCachedInfo params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"]; - _extendedLoadout params ["_loadout"]; + _loadoutCachedInfo params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"]; + _extendedLoadout params ["_loadout"]; // Used by ADD_LOADOUTS_LIST_PICTURES macro, do not remove _newRow = _contentPanelCtrl lnbAddRow ["", _loadoutName]; ADD_LOADOUTS_LIST_PICTURES // Change color on loadout lines that have items that aren't available or don't exist - if (_nullItemsAmount > 0) then { + if (_nullItemsList isNotEqualTo []) then { _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red } else { - if (_unavailableItemsAmount > 0) then { + if (_unavailableItemsList isNotEqualTo []) then { _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray }; }; @@ -90,10 +112,16 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { _contentPanelCtrl lnbSetPicture [[_newRow, 0], QPATHTOF(data\iconPublic.paa)]; _contentPanelCtrl lnbSetValue [[_newRow, 0], 1]; }; - } forEach ([profileNamespace getVariable [QGVAR(saved_loadouts), []], GVAR(defaultLoadoutsList)] select (ctrlIDC _control == IDC_buttonDefaultLoadouts)); + } forEach (_loadouts select [_currentFrame * LOADOUTS_PER_FRAME, [LOADOUTS_PER_FRAME, count _loadouts] select is3DEN]); } else { private _allPlayerNames = allPlayers apply {name _x}; + private _loadouts = _sharedLoadoutsVars apply {GVAR(sharedLoadoutsNamespace) getVariable _x}; private _loadoutVar = ""; + if (_currentFrame == 0) then { + _framesToFill = floor ((count _loadouts) / LOADOUTS_PER_FRAME); + TRACE_2("filling loadouts list",_currentFrame,_framesToFill); + _this set [3, _framesToFill]; + }; { _x params ["_playerName", "_loadoutName", "_loadoutData"]; @@ -107,8 +135,8 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { [QGVAR(loadoutUnshared), [_contentPanelCtrl, profileName, _loadoutName]] call CBA_fnc_remoteEvent; } else { - ([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsAmount", "_unavailableItemsAmount"]; - _extendedLoadout params ["_loadout"]; + ([_loadoutData] call FUNC(verifyLoadout)) params ["_extendedLoadout", "_nullItemsList", "_unavailableItemsList"]; + _extendedLoadout params ["_loadout"]; // Used by ADD_LOADOUTS_LIST_PICTURES macro, do not remove _contentPanelCtrl lnbSetColumnsPos [0, 0.15, 0.40, 0.50, 0.60, 0.70, 0.75, 0.80, 0.85, 0.90]; _newRow = _contentPanelCtrl lnbAddRow [_playerName, _loadoutName]; @@ -118,17 +146,23 @@ if (GVAR(currentLoadoutsTab) != IDC_buttonSharedLoadouts) then { _contentPanelCtrl lnbSetData [[_newRow, 1], _loadoutVar]; // Change color on loadout lines that have items that aren't available or don't exist - if (_nullItemsAmount > 0) then { + if (_nullItemsList isNotEqualTo []) then { _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 0, 0, 0.8]]; // Red } else { - if (_unavailableItemsAmount > 0) then { + if (_unavailableItemsList isNotEqualTo []) then { _contentPanelCtrl lnbSetColor [[_newRow, 1], [1, 1, 1, 0.25]]; // Gray }; }; }; - } forEach (_sharedLoadoutsVars apply {GVAR(sharedLoadoutsNamespace) getVariable _x}); + } forEach (_loadouts select [_currentFrame * LOADOUTS_PER_FRAME, [LOADOUTS_PER_FRAME, count _loadouts] select is3DEN]); }; +if (!is3DEN && _currentFrame != _framesToFill) exitWith { + _this set [2, _currentFrame + 1]; + [FUNC(fillLoadoutsList), _this] call CBA_fnc_execNextFrame; +}; +TRACE_3("finished",_currentFrame,_framesToFill,lnbSize _contentPanelCtrl); + [QGVAR(loadoutsListFilled), [_display, _control]] call CBA_fnc_localEvent; // Sort loadouts alphabetically diff --git a/addons/arsenal/functions/fnc_fillRightPanel.sqf b/addons/arsenal/functions/fnc_fillRightPanel.sqf index 09f986708d..d8dc7e2403 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -53,7 +53,7 @@ if (GVAR(favoritesOnly)) then { private _fnc_fillRightContainer = { params ["_configCategory", "_className", ["_isUnique", false, [false]], ["_unknownOrigin", false, [false]]]; - if (GVAR(favoritesOnly) && {!(_className in _currentCargo)} && {!((toLower _className) in GVAR(favorites))}) exitWith {}; + if (GVAR(favoritesOnly) && {!(_className in _currentCargo)} && {!((toLowerANSI _className) in GVAR(favorites))}) exitWith {}; // If item is not in the arsenal, it must be unique if (!_isUnique && {!(_className in GVAR(virtualItemsFlat))}) then { @@ -89,7 +89,7 @@ private _fnc_fillRightContainer = { _ctrlPanel lnbSetPicture [[_lbAdd, 0], _picture]; _ctrlPanel lnbSetValue [[_lbAdd, 2], parseNumber _isUnique]; _ctrlPanel lnbSetTooltip [[_lbAdd, 0], format ["%1\n%2", _displayName, _className]]; - if ((toLower _className) in GVAR(favorites)) then { + if ((toLowerANSI _className) in GVAR(favorites)) then { _ctrlPanel lnbSetColor [[_lbAdd, 1], FAVORITES_COLOR]; _ctrlPanel lnbSetColorRight [[_lbAdd, 1], FAVORITES_COLOR]; }; diff --git a/addons/arsenal/functions/fnc_handleActions.sqf b/addons/arsenal/functions/fnc_handleActions.sqf index f89b4f1259..03c25f77df 100644 --- a/addons/arsenal/functions/fnc_handleActions.sqf +++ b/addons/arsenal/functions/fnc_handleActions.sqf @@ -15,7 +15,6 @@ * * Public: No */ - params ["_display", "_control", "_curSel", "_itemCfg"]; GVAR(actionsInfo) = [_control, _curSel, _itemCfg]; @@ -46,13 +45,12 @@ private _groups = (GVAR(actionList) select _panel) select { }; private _show = _groups isNotEqualTo []; -private _ctrl = _display displayCtrl IDC_actionsBox; -_ctrl ctrlShow _show; -_ctrl ctrlCommit 0.15; +private _actionsBoxCtrl = _display displayCtrl IDC_actionsBox; +_actionsBoxCtrl ctrlShow _show; +_actionsBoxCtrl ctrlCommit FADE_DELAY; if (!_show) exitWith {}; -private _actionsBoxCtrl = _display displayCtrl IDC_actionsBox; private _actionsCurrentPageCtrl = _display displayCtrl IDC_actionsCurrentPage; private _currentPage = GVAR(currentActionPage); @@ -79,33 +77,29 @@ private _items = _group select 3 select { }; _actionsCurrentPageCtrl ctrlSetText (_group select 1); -_actionsCurrentPageCtrl ctrlSetFade 0; _actionsCurrentPageCtrl ctrlShow true; _actionsCurrentPageCtrl ctrlCommit 0; +private _activeCtrls = []; { _x params ["", "_type", "_label", "_statement"]; - private _idc = 9001 + _forEachIndex * 2; - private _actionTextCtrl = _display displayCtrl _idc; - private _actionButtonCtrl = _display displayCtrl (_idc + 1); + private _idc = IDC_actionsText1 + _type + _forEachIndex * 2; + private _actionCtrl = _display displayCtrl _idc; switch (_type) do { case ACTION_TYPE_BUTTON: { - _actionButtonCtrl ctrlRemoveAllEventHandlers "ButtonClick"; - _actionButtonCtrl ctrlAddEventHandler ["ButtonClick", { + _actionCtrl ctrlRemoveAllEventHandlers "ButtonClick"; + _actionCtrl ctrlAddEventHandler ["ButtonClick", { if (is3DEN) exitWith {[true] call FUNC(refresh)}; [{ [true] call FUNC(refresh); }] call CBA_fnc_execNextFrame; }]; - _actionButtonCtrl ctrlAddEventHandler ["ButtonClick", _statement]; - _actionButtonCtrl ctrlSetText _label; - _actionButtonCtrl ctrlSetFade 0; - _actionButtonCtrl ctrlEnable true; - _actionButtonCtrl ctrlCommit 0; - _actionTextCtrl ctrlSetFade 1; - _actionTextCtrl ctrlCommit 0; + + _actionCtrl ctrlAddEventHandler ["ButtonClick", _statement]; + _actionCtrl ctrlSetText _label; + _actionCtrl ctrlEnable true; }; case ACTION_TYPE_TEXT: { private _text = call _statement; @@ -113,38 +107,43 @@ _actionsCurrentPageCtrl ctrlCommit 0; if (isNil "_text") then { _text = ""; }; + if (_text isEqualType []) then { + _text = _text joinString endl; + }; - _actionTextCtrl ctrlSetText _text; - _actionTextCtrl ctrlSetFade 0; - _actionTextCtrl ctrlCommit 0; - _actionButtonCtrl ctrlSetFade 1; - _actionButtonCtrl ctrlEnable false; - _actionButtonCtrl ctrlCommit 0; - }; - default { - _actionTextCtrl ctrlSetFade 1; - _actionTextCtrl ctrlCommit 0; - _actionButtonCtrl ctrlSetFade 1; - _actionButtonCtrl ctrlEnable false; - _actionButtonCtrl ctrlCommit 0; + _actionCtrl ctrlSetText _text; + _actionCtrl ctrlSetPositionH (ctrlTextHeight _actionCtrl); + _actionCtrl ctrlEnable false; }; }; + + if (_activeCtrls isNotEqualTo []) then { + (ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"]; + _actionCtrl ctrlSetPositionY (_lastPosY + _lastPosH + GRID_H); + } else { + _actionCtrl ctrlSetPositionY ((5 + _type) * GRID_H); + }; + + _actionCtrl ctrlShow true; + _actionCtrl ctrlCommit 0; + _activeCtrls pushBack _actionCtrl; } forEach _items; -private _actionCount = count _items; - { - private _idc = 9001 + _x * 2; - private _actionTextCtrl = _display displayCtrl _idc; - private _actionButtonCtrl = _display displayCtrl (_idc + 1); + private _idc = ctrlIDC _x; + if (_idc < IDC_actionsText1 || _idc > IDC_actionsButton5) then {continue}; - _actionTextCtrl ctrlSetFade 1; - _actionTextCtrl ctrlCommit 0; - _actionButtonCtrl ctrlSetFade 1; - _actionButtonCtrl ctrlCommit 0; -} forEach ([0, 1, 2, 3, 4] select [_actionCount, 5]); + _x ctrlShow false; + _x ctrlEnable false; + _x ctrlSetPositionY 0; + _x ctrlCommit 0; +} forEach ((allControls _actionsBoxCtrl) select {!(_x in _activeCtrls)}); -private _pos = ctrlPosition _actionsBoxCtrl; -_pos set [3, ([11, (5 * _actionCount) + 6] select (_actionCount > 0)) * GRID_H]; -_actionsBoxCtrl ctrlSetPosition _pos; +(ctrlPosition (_activeCtrls select -1)) params ["", "_lastPosY", "", "_lastPosH"]; +private _actionsBoxHeight = _lastPosY + _lastPosH + GRID_H; +_actionsBoxCtrl ctrlSetPositionH _actionsBoxHeight; _actionsBoxCtrl ctrlCommit 0; + +private _background = _display displayCtrl IDC_actionsBackground1; +_background ctrlSetPositionH _actionsBoxHeight; +_background ctrlCommit 0; diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index 2cce9b13ee..f2316bc9d5 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -78,10 +78,10 @@ if (!isNull curatorCamera) then { // Make face and voice selection JIP compatible; 3DEN doesn't need this though if (isMultiplayer && {!is3DEN}) then { - private _id = [QGVAR(broadcastFace), [GVAR(center), GVAR(currentFace)], QGVAR(centerFace_) + netId GVAR(center)] call CBA_fnc_globalEventJIP; + private _id = [QGVAR(broadcastFace), [GVAR(center), GVAR(currentFace)], QGVAR(centerFace_) + hashValue GVAR(center)] call CBA_fnc_globalEventJIP; [_id, GVAR(center)] call CBA_fnc_removeGlobalEventJIP; - _id = [QGVAR(broadcastVoice), [GVAR(center), GVAR(currentVoice)], QGVAR(centerVoice_) + netId GVAR(center)] call CBA_fnc_globalEventJIP; + _id = [QGVAR(broadcastVoice), [GVAR(center), GVAR(currentVoice)], QGVAR(centerVoice_) + hashValue GVAR(center)] call CBA_fnc_globalEventJIP; [_id, GVAR(center)] call CBA_fnc_removeGlobalEventJIP; }; diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index 9077a13a7a..f307c932b1 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -68,7 +68,7 @@ if (isNil QGVAR(virtualItems)) then { GVAR(virtualItemsFlatAll) = +GVAR(virtualItemsFlat); GVAR(currentFace) = face GVAR(center); -GVAR(currentVoice) = speaker GVAR(center); +GVAR(currentVoice) = (speaker GVAR(center)) call EFUNC(common,getConfigName); GVAR(currentInsignia) = GVAR(center) call BIS_fnc_getUnitInsignia; GVAR(currentAction) = "Stand"; diff --git a/addons/arsenal/functions/fnc_onPanelDblClick.sqf b/addons/arsenal/functions/fnc_onPanelDblClick.sqf index 032d87534b..07287d74ce 100644 --- a/addons/arsenal/functions/fnc_onPanelDblClick.sqf +++ b/addons/arsenal/functions/fnc_onPanelDblClick.sqf @@ -27,9 +27,9 @@ private _favorited = false; // Favorites/blacklist will always be lowercase to handle configCase changes private _item = ""; if (_isLnB) then { - _item = toLower (_control lnbData [_curSel, 0]); + _item = toLowerANSI (_control lnbData [_curSel, 0]); } else { - _item = toLower (_control lbData _curSel); + _item = toLowerANSI (_control lbData _curSel); }; if (_item in GVAR(favorites)) then { diff --git a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf index 3d356fc207..5bf08245c8 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -683,14 +683,19 @@ switch (GVAR(currentLeftPanel)) do { TOGGLE_RIGHT_PANEL_HIDE - private _unitInsigniaConfig = configFile >> "CfgUnitInsignia" >> _item; + // Check for correct config: First mission, then campaign and finally regular config + private _itemCfg = missionConfigFile >> "CfgUnitInsignia" >> _item; + + if (isNull _itemCfg) then { + _itemCfg = campaignConfigFile >> "CfgUnitInsignia" >> _item; + }; + + if (isNull _itemCfg) then { + _itemCfg = configFile >> "CfgUnitInsignia" >> _item; + }; // Display new items's info on the bottom right - if (isNull _unitInsigniaConfig) then { - [_display, _control, _curSel, missionConfigFile >> "CfgUnitInsignia" >> _item] call FUNC(itemInfo); - } else { - [_display, _control, _curSel, _unitInsigniaConfig] call FUNC(itemInfo); - }; + [_display, _control, _curSel, _itemCfg] call FUNC(itemInfo); }; }; diff --git a/addons/arsenal/functions/fnc_removeSort.sqf b/addons/arsenal/functions/fnc_removeSort.sqf index 3957257a6d..a5e9fb1d77 100644 --- a/addons/arsenal/functions/fnc_removeSort.sqf +++ b/addons/arsenal/functions/fnc_removeSort.sqf @@ -31,7 +31,7 @@ private _tabToChange = []; _stringCount = count _currentID; // Make sure to keep at least 1 sort per category, so make default sort not deletable - if ("ace_alphabetically" in toLower (_currentID select [0, _stringCount - 3])) then { + if ("ace_alphabetically" in toLowerANSI (_currentID select [0, _stringCount - 3])) then { continue; }; diff --git a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf index cbbe02666e..061180beaa 100644 --- a/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf +++ b/addons/arsenal/functions/fnc_replaceUniqueItemsLoadout.sqf @@ -25,7 +25,6 @@ if (count _loadout == 2) then { if (count _loadout != 10) exitWith {[]}; -private _weapon = ""; private _weaponsInfo = []; private _uniqueBaseCfgText = ""; private _cfgWeapons = configFile >> "CfgWeapons"; @@ -43,7 +42,7 @@ private _cfgVehicles = configFile >> "CfgVehicles"; // Check weapon & weapon attachments { - // Magazines + // Magazines in weapons have 2 entries: Name and ammo count if (_forEachIndex in [4, 5]) then { _x params [["_magazine", ""], "_count"]; @@ -69,23 +68,69 @@ private _cfgVehicles = configFile >> "CfgVehicles"; _x params [["_containerClass", ""], ["_items", []]]; if (_containerClass != "") then { - _uniqueBaseCfgText = (getText ([_cfgWeapons, _cfgVehicles] select (_forEachIndex == IDX_LOADOUT_BACKPACK) >> _containerClass >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + if (_forEachIndex == IDX_LOADOUT_BACKPACK) then { + // Check for non-preset first + _uniqueBaseCfgText = [_containerClass, "CfgVehicles"] call CBA_fnc_getNonPresetClass; - if (_uniqueBaseCfgText != "") then { - (_x select 0) set [0, _uniqueBaseCfgText]; + if (_uniqueBaseCfgText != "") then { + _containerClass = _uniqueBaseCfgText; + }; + + // Check if non-preset backpack has a unique base + _uniqueBaseCfgText = (getText (_cfgVehicles >> _containerClass >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _containerClass = _uniqueBaseCfgText; + }; + + _x set [0, _containerClass]; + } else { + _uniqueBaseCfgText = (getText (_cfgWeapons >> _containerClass >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _x set [0, _uniqueBaseCfgText]; + }; }; // Check if container has items that need replacing with a defined base { switch (true) do { // Containers have 2 entries: Name and isBackpack - case (_x isEqualTypeArray ["", false]); + case (_x isEqualTypeArray ["", false]): { + _x params ["_containerClass", "_isBackpack"]; + + if (_containerClass != "") then { + if (_isBackpack) then { + // Check for non-preset first + _uniqueBaseCfgText = [_containerClass, "CfgVehicles"] call CBA_fnc_getNonPresetClass; + + if (_uniqueBaseCfgText != "") then { + _containerClass = _uniqueBaseCfgText; + }; + + // Check if non-preset backpack has a unique base + _uniqueBaseCfgText = (getText (_cfgVehicles >> _containerClass >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _containerClass = _uniqueBaseCfgText; + }; + + _x set [0, _containerClass]; + } else { + _uniqueBaseCfgText = (getText (_cfgWeapons >> _containerClass >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + + if (_uniqueBaseCfgText != "") then { + _x set [0, _uniqueBaseCfgText]; + }; + }; + }; + }; // Misc. items have 2 entries: Name and amount case (_x isEqualTypeArray ["", 0]): { - _x params ["_item", "_arg"]; + _x params ["_item"]; if (_item != "") then { - _uniqueBaseCfgText = (getText ([_cfgWeapons, _cfgVehicles] select ((_arg isEqualType false) && {_arg}) >> _item >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); + _uniqueBaseCfgText = (getText (_cfgWeapons >> _item >> QGVAR(uniqueBase))) call EFUNC(common,getConfigName); if (_uniqueBaseCfgText != "") then { _x set [0, _uniqueBaseCfgText]; @@ -94,7 +139,7 @@ private _cfgVehicles = configFile >> "CfgVehicles"; }; // Weapons have 2 entries: Weapon info array and amount case (_x isEqualTypeArray [[], 0]): { - _weaponsInfo = _x select 0; + _x params ["_weaponsInfo"]; // Check weapon & weapon attachments { diff --git a/addons/arsenal/functions/fnc_scanConfig.sqf b/addons/arsenal/functions/fnc_scanConfig.sqf index 8f11b6fc47..fef97e8bd8 100644 --- a/addons/arsenal/functions/fnc_scanConfig.sqf +++ b/addons/arsenal/functions/fnc_scanConfig.sqf @@ -160,7 +160,7 @@ private _magazineMiscItems = createHashMap; { _magazineMiscItems set [configName _x, nil]; -} forEach ((toString {getNumber (_x >> "ACE_isUnique") == 1}) configClasses _cfgMagazines); +} forEach ((toString {getNumber (_x >> "ACE_isUnique") == 1 || getNumber (_x >> "ACE_asItem") == 1}) configClasses _cfgMagazines); // Remove invalid/non-existent entries _grenadeList deleteAt ""; @@ -282,11 +282,42 @@ uiNamespace setVariable [QGVAR(CBAdisposableLaunchers), compileFinal _launchers] uiNamespace setVariable [QGVAR(configItemsTools), compileFinal _toolList]; // Compatibility: Override baseWeapon for RHS optics -// No good way to do this via script for other attachments, needs manual compat +// No good way to do this via script for other RHS attachments, needs manual compat private _baseWeaponCache = uiNamespace getVariable QGVAR(baseWeaponNameCache); { private _baseAttachment = configName (_cfgWeapons >> getText (_x >> "rhs_optic_base")); if (_baseAttachment != "") then { - _baseWeaponCache set [toLower configName _x, _baseAttachment]; + _baseWeaponCache set [toLowerANSI configName _x, _baseAttachment]; }; } forEach ("getText (_x >> 'rhs_optic_base') != ''" configClasses _cfgWeapons); + +// Compatibility: Override baseWeapon for CBA Scripted Optics +// Adapted from https://github.com/Theseus-Aegis/Mods/blob/master/addons/armory/functions/fnc_getBaseVariant.sqf +private _isScriptedOptic = toString { + isClass (_x >> "CBA_ScriptedOptic") || + {(getText (_x >> "weaponInfoType")) regexMatch "CBA_scriptedOptic.*?"} +}; + +{ + private _xClass = toLowerANSI configName _x; + private _baseOptic = _xClass call FUNC(baseOptic); + if (_baseOptic != "" && {_baseOptic != _xClass}) then { + TRACE_2("updating baseOptic",_xClass,_baseOptic); + _baseWeaponCache set [_xClass, _baseOptic]; + }; +} forEach (_isScriptedOptic configClasses _cfgWeapons); + +// Compatibility: Override baseWeapon for CBA Scripted Attachments +private _isScriptedAttachment = toString { + getText (_x >> "MRT_SwitchItemNextClass") != "" || + {getText (_x >> "MRT_SwitchItemPrevClass") != ""} +}; + +{ + private _xClass = toLowerANSI configName _x; + private _baseAttachment = _xClass call FUNC(baseAttachment); + if (_baseAttachment != "" && {_baseAttachment != _xClass}) then { + TRACE_2("updating baseAttachment",_xClass,_baseAttachment); + _baseWeaponCache set [_xClass, _baseAttachment]; + }; +} forEach (_isScriptedAttachment configClasses _cfgWeapons); diff --git a/addons/arsenal/functions/fnc_sortPanel.sqf b/addons/arsenal/functions/fnc_sortPanel.sqf index bbe48d6e35..f9803a429e 100644 --- a/addons/arsenal/functions/fnc_sortPanel.sqf +++ b/addons/arsenal/functions/fnc_sortPanel.sqf @@ -15,6 +15,10 @@ params ["_control"]; +// https://community.bistudio.com/wiki/toString, see comment +// However, using 55295 did not work as expected, 55291 was found by trial and error +#define HIGHEST_VALUE_CHAR 55291 + // When filling the sorting panel, FUNC(sortPanel) is called twice, so ignore first call if (GVAR(ignoreFirstSortPanelCall)) exitWith { GVAR(ignoreFirstSortPanelCall) = false; @@ -29,6 +33,7 @@ private _sortDirectionCtrl = _display displayCtrl ([IDC_sortLeftTabDirection, ID private _cfgMagazines = configFile >> "CfgMagazines"; private _cfgFaces = configFile >> "CfgFaces"; private _cfgUnitInsignia = configFile >> "CfgUnitInsignia"; +private _cfgUnitInsigniaCampaign = campaignConfigFile >> "CfgUnitInsignia"; private _cfgUnitInsigniaMission = missionConfigFile >> "CfgUnitInsignia"; if (_rightSort) then { @@ -126,7 +131,6 @@ private _selected = if (_right) then { _panel lbData _curSel }; -private _originalNames = createHashMap; private _item = ""; private _quantity = ""; private _itemCfg = configNull; @@ -136,12 +140,8 @@ private _fillerChar = toString [1]; private _magazineMiscItems = uiNamespace getVariable QGVAR(magazineMiscItems); private _sortCache = uiNamespace getVariable QGVAR(sortCache); - -private _faceCache = if (_cfgClass == _cfgFaces) then { - uiNamespace getVariable [QGVAR(faceCache), createHashMap] -} else { - createHashMap -}; +private _faceCache = uiNamespace getVariable QGVAR(faceCache); +private _insigniaCache = uiNamespace getVariable QGVAR(insigniaCache); private _countColumns = if (_right) then { count lnbGetColumnsPosition _panel @@ -150,9 +150,9 @@ private _countColumns = if (_right) then { }; private _for = if (_right) then { - for '_i' from 0 to (lnbSize _panel select 0) - 1 + for "_i" from 0 to (lnbSize _panel select 0) - 1 } else { - for '_i' from 0 to (lbSize _panel) - 1 + for "_i" from 0 to (lbSize _panel) - 1 }; _for do { @@ -163,6 +163,14 @@ _for do { _panel lbData _i }; + // Check if entry is "Empty" + if (!_right && {(_panel lbValue _i) == -1}) then { + // Set to lowest/highest lexicographical value, so that "Empty" is always at the top + _panel lbSetTextRight [_i, ["", toString [HIGHEST_VALUE_CHAR, HIGHEST_VALUE_CHAR, HIGHEST_VALUE_CHAR, HIGHEST_VALUE_CHAR, HIGHEST_VALUE_CHAR]] select (_sortDirection == ASCENDING)]; + + continue; + }; + // Get item's count _quantity = if (_right) then { parseNumber (_panel lnbText [_i, 2]) @@ -179,18 +187,22 @@ _for do { _itemCfg = if !(_cfgClass in [_cfgFaces, _cfgUnitInsignia]) then { _cfgClass >> _item } else { - // If insignia, check both config and mission file + // If insignia, check for correct config: First mission, then campaign and finally regular config if (_cfgClass == _cfgUnitInsignia) then { - _itemCfg = _cfgClass >> _item; + _itemCfg = _cfgUnitInsigniaMission >> _item; if (isNull _itemCfg) then { - _itemCfg = _cfgUnitInsigniaMission >> _item; + _itemCfg = _cfgUnitInsigniaCampaign >> _item; + }; + + if (isNull _itemCfg) then { + _itemCfg = _cfgUnitInsignia >> _item; }; _itemCfg } else { // If face, check correct category - _cfgClass >> (_faceCache get _item) param [2, "Man_A3"] >> _item + _cfgClass >> (_faceCache getOrDefault [_item, []]) param [2, "Man_A3"] >> _item }; }; @@ -216,37 +228,29 @@ _for do { _value }, true]; - // Save the current row's item's name in a cache and set text to it's sorting value + // Set the right text temporarily, so it can be used for sorting if (_right) then { - _name = _panel lnbText [_i, 1]; - _originalNames set [_item, _name]; - // Use value, display name and classname to sort, which means a fixed alphabetical order is guaranteed - // Filler char has lowest lexicographical order possible - _panel lnbSetText [[_i, 1], format ["%1%2%4%3", _value, _name, _item, _fillerChar]]; + // Filler char has lowest lexicographical value possible + _panel lnbSetTextRight [[_i, 1], format ["%1%2%4%3", _value, _panel lnbText [_i, 1], _item, _fillerChar]]; } else { if (_item != "") then { - _name = _panel lbText _i; - _originalNames set [_item, _name]; - // Use value, display name and classname to sort, which means a fixed alphabetical order is guaranteed - // Filler char has lowest lexicographical order possible - _panel lbSetText [_i, format ["%1%2%4%3", _value, _name, _item, _fillerChar]]; + // Filler char has lowest lexicographical value possible + _panel lbSetTextRight [_i, format ["%1%2%4%3", _value, _panel lbText _i, _item, _fillerChar]]; }; }; }; -// Sort alphabetically, find the previously selected item, select it again and reset text to original text +// Sort alphabetically, find the previously selected item and select it again if (_right) then { - _panel lnbSort [1, _sortDirection == ASCENDING]; + [_panel, 1] lnbSortBy ["TEXT", _sortDirection == ASCENDING, false, true, true]; // do not support unicode, as it's much more performance intensive (~3x more) _for do { - _item = _panel lnbData [_i, 0]; + // Remove sorting text, as it blocks the item name otherwise + _panel lnbSetTextRight [[_i, 1], ""]; - _panel lnbSetText [[_i, 1], _originalNames get _item]; - - // Set selection after text, otherwise item info box on the right side shows invalid name - if (_curSel != -1 && {_item == _selected}) then { + if (_curSel != -1 && {(_panel lnbData [_i, 0]) == _selected}) then { _panel lnbSetCurSelRow _i; // To avoid unnecessary checks after previsouly selected item was found @@ -254,17 +258,17 @@ if (_right) then { }; }; } else { - lbSort [_panel, ["DESC", "ASC"] select _sortDirection]; + _panel lbSortBy ["TEXT", _sortDirection == ASCENDING, false, true, true]; // do not support unicode, as it's much more performance intensive (~3x more) _for do { _item = _panel lbData _i; // Check if valid item (problems can be caused when searching) if (_item != "") then { - _panel lbSetText [_i, _originalNames get _item]; + // Remove sorting text, as it blocks the item name otherwise + _panel lbSetTextRight [_i, ""]; }; - // Set selection after text, otherwise item info box on the right side shows invalid name if (_curSel != -1 && {_item == _selected}) then { _panel lbSetCurSel _i; diff --git a/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf b/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf index 6da45345f4..df4260ba1a 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_binoVisionMode.sqf @@ -17,7 +17,7 @@ params ["", "_config"]; TRACE_1("statTextStatement_binoVisionMode",_config); private _text = []; -private _visionModes = getArray (_config >> "visionMode") apply {toLower _x}; +private _visionModes = getArray (_config >> "visionMode") apply {toLowerANSI _x}; { if (_x in _visionModes) then { _text pushBack (localize ([LSTRING(VisionNormal), LSTRING(VisionNight), LSTRING(VisionThermal)] select _forEachIndex)); diff --git a/addons/arsenal/functions/fnc_statTextStatement_load.sqf b/addons/arsenal/functions/fnc_statTextStatement_load.sqf new file mode 100644 index 0000000000..032019f582 --- /dev/null +++ b/addons/arsenal/functions/fnc_statTextStatement_load.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Text statement for the load stat. + * + * Arguments: + * 0: Stats + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Public: No +*/ + +params ["_stats", "_config"]; +TRACE_2("statTextStatement_load",_stats,_config); + +if (!isNull (_config >> "ItemInfo" >> "containerClass")) then { // Uniform/Vest + _config = configfile >> "CfgVehicles" >> getText (_config >> "ItemInfo" >> "containerClass"); +}; + +private _load = getNumber (_config >> (_stats # 0)); + +if (_load <= 0) exitWith { LELSTRING(common,none) }; +format ["%1kg (%2lb)", (_load * 0.1 * (1 / 2.2046)) toFixed 2, (_load * 0.1) toFixed 2] diff --git a/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf b/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf index b4de06e772..7348be5bc3 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_scopeVisionMode.sqf @@ -17,7 +17,7 @@ params ["", "_config"]; TRACE_1("statTextStatement_scopeVisionMode",_config); private _opticsModes = ("true" configClasses (_config >> "ItemInfo" >> "OpticsModes")) apply { - private _visionMode = getArray (_x >> "visionMode") apply {toLower _x}; + private _visionMode = getArray (_x >> "visionMode") apply {toLowerANSI _x}; [ getNumber (_x >> "useModelOptics") == 1, // Is in optics _visionMode isEqualTo [], // Optional NVG diff --git a/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf index 0b1af5d465..0dcf3866b9 100644 --- a/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateCurrentItemsList.sqf @@ -63,8 +63,12 @@ private _indexCurrentItems = -1; }; // Backpack case IDX_LOADOUT_BACKPACK: { - GVAR(currentItems) set [IDX_CURR_BACKPACK, _x param [0, ""]]; - GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, _x param [1, []]]; + _x params [["_backpack", ""], ["_items", []]]; + if (_backpack != "") then { + _backpack = [_backpack, "CfgVehicles"] call CBA_fnc_getNonPresetClass; + }; + GVAR(currentItems) set [IDX_CURR_BACKPACK, _backpack]; + GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, _items]; }; // Helmet case IDX_LOADOUT_HEADGEAR: { diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index fddc9b3b9c..9b7eb6327a 100644 --- a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf +++ b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf @@ -101,6 +101,11 @@ private _fnc_uniqueEquipment = { case IDX_LOADOUT_BACKPACK: { _x params [["_containerClass", ""]]; + // Handle preset (loaded/AI) backpacks + if (_containerClass != "" && _forEachIndex == IDX_LOADOUT_BACKPACK) then { + _containerClass = [_containerClass, "CfgVehicles"] call CBA_fnc_getNonPresetClass; + }; + // Remove all unique equipment in tab; Add container as a unique equipment [GVAR(virtualItems) get (_forEachIndex + 1), _containerClass] call _fnc_uniqueEquipment; }; diff --git a/addons/arsenal/functions/fnc_verifyLoadout.sqf b/addons/arsenal/functions/fnc_verifyLoadout.sqf index adc76f391a..53e7221e3a 100644 --- a/addons/arsenal/functions/fnc_verifyLoadout.sqf +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -13,285 +13,93 @@ * Public: No */ +#define NOT_IN_ARSENAL !(_name in GVAR(virtualItemsFlat)) + params ["_loadout"]; private _extendedInfo = createHashMap; // Check if the provided loadout is a CBA extended loadout if (count _loadout == 2) then { - _extendedInfo = _loadout select 1; + _extendedInfo = +(_loadout select 1); // Copy the hashmap to prevent events from modifiyng the profileNamespace extendedInfo _loadout = _loadout select 0; }; -private _cfgWeapons = configFile >> "CfgWeapons"; -private _cfgMagazines = configFile >> "CfgMagazines"; -private _cfgVehicles = configFile >> "CfgVehicles"; -private _cfgGlasses = configFile >> "CfgGlasses"; - -private _weapons = GVAR(virtualItems) get IDX_VIRT_WEAPONS; -private _attachments = GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS; - private _name = ""; -private _nullItemsAmount = 0; -private _unavailableItemsAmount = 0; +private _itemArray = []; private _nullItemsList = []; private _unavailableItemsList = []; +private _missingExtendedInfo = []; -// Search for all items and turn them into config case; Don't touch other value types -private _fnc_toConfigCase = { +// Search for all items and check their availability +private _fnc_filterLoadout = { _this apply { - if (_x isEqualType "") then { - if (_x != "") then { - _name = _x call EFUNC(common,getConfigName); + if (_x isEqualType "" && {_x != ""}) then { + _name = _x call EFUNC(common,getConfigName); - // If item doesn't exist in config, "" is returned - // Just return unaltered item name in that case, so it can be documented as being unavailable - [_x, _name] select (_name != ""); + // If item doesn't exist in config, "" is returned + if (_name == "") then { + _nullItemsList pushBack _x; } else { - _x + // Check if item or its base weapon exist in the arsenal + if NOT_IN_ARSENAL then { + _name = _name call FUNC(baseWeapon); + if NOT_IN_ARSENAL then { + // This could be a backpack + private _temp = [_name, "CfgVehicles"] call CBA_fnc_getNonPresetClass; + if (_temp == "") then { // It's not + _unavailableItemsList pushBack _name; + _name = ""; + } else { // It is + _name = _temp; + // Check if it's available again + if NOT_IN_ARSENAL then { + _unavailableItemsList pushBack _name; + _name = ""; + }; + }; + }; + }; }; + + _name } else { // Handle arrays if (_x isEqualType []) then { - _x call _fnc_toConfigCase + _itemArray = _x call _fnc_filterLoadout; + // If "" is given as a container, an error is thrown, therefore, filter out all unavailable/null containers + if (count _itemArray == 2 && {(_itemArray select 0) isEqualTo ""} && {(_itemArray select 1) isEqualType []}) then { + _itemArray = []; + }; + _itemArray } else { - // All other types + // All other types and empty strings _x }; }; }; }; -// Convert loadout to config case +// Convert loadout to config case and replace null/unavailable items // Loadout might come from a different modpack, which might have different config naming -_loadout = _loadout call _fnc_toConfigCase; +_loadout = _loadout call _fnc_filterLoadout; -// Check a weapon, with its attachments and magazines, if items are available -private _fnc_weaponCheck = { - params ["_weaponArray", ["_index", -1]]; +{ + private _class = _extendedInfo getOrDefault [_x, ""]; + private _cache = missionNamespace getVariable (_x + "Cache"); - { - // Weapons and attachments - if (_x isEqualType "") then { - if (_x != "") then { - // Check if item exists - if (isClass (_cfgWeapons >> _x)) then { - // Get base weapon - _x = _x call FUNC(baseWeapon); - - // Check if item is available in arsenal - if !( - // Weapon class name is at the very start of the array - if (_forEachIndex == 0) then { - // If the type of weapon is known, only look through that array - if (_index != -1) then { - // If binos, choose differently - if (_index == IDX_LOADOUT_BINO) then { - _x in (GVAR(virtualItems) get IDX_VIRT_BINO) - } else { - _x in (_weapons get _index) - }; - } else { - _x in (_weapons get IDX_VIRT_PRIMARY_WEAPONS) || - {_x in (_weapons get IDX_VIRT_SECONDARY_WEAPONS)} || - {_x in (_weapons get IDX_VIRT_HANDGUN_WEAPONS)} || - {_x in (GVAR(virtualItems) get IDX_VIRT_BINO)} - }; - } else { - _x in (_attachments get IDX_VIRT_OPTICS_ATTACHMENTS) || - {_x in (_attachments get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)} || - {_x in (_attachments get IDX_VIRT_MUZZLE_ATTACHMENTS)} || - {_x in (_attachments get IDX_VIRT_BIPOD_ATTACHMENTS)} - } - ) then { - _unavailableItemsList pushBackUnique _x; - _weaponArray set [_forEachIndex, ""]; - INC(_unavailableItemsAmount); - }; - } else { - _nullItemsList pushBackUnique _x; - _weaponArray set [_forEachIndex, ""]; - INC(_nullItemsAmount); - }; - }; - } else { - // Magazines - if (_x isNotEqualTo []) then { - _x params ["_magazine"]; - - // Check if item exists - if (isClass (_cfgMagazines >> _magazine)) then { - // Check if item is available in arsenal - if !(_magazine in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) then { - _unavailableItemsList pushBackUnique _magazine; - _weaponArray set [_forEachIndex, []]; - INC(_unavailableItemsAmount); - }; - } else { - _nullItemsList pushBackUnique _magazine; - _weaponArray set [_forEachIndex, []]; - INC(_nullItemsAmount); - }; - }; - }; - } forEach _weaponArray; -}; - -private _item = ""; - -// Go through entire loadout to check if items are available in current arsenal -for "_dataIndex" from IDX_LOADOUT_PRIMARY_WEAPON to IDX_LOADOUT_ASSIGNEDITEMS do { - switch (_dataIndex) do { - // Primary weapon, Secondary weapon, Handgun weapon, Binoculars - case IDX_LOADOUT_PRIMARY_WEAPON; - case IDX_LOADOUT_SECONDARY_WEAPON; - case IDX_LOADOUT_HANDGUN_WEAPON; - case IDX_LOADOUT_BINO: { - [_loadout select _dataIndex, _dataIndex] call _fnc_weaponCheck; - }; - // Uniform, vest, backpack - case IDX_LOADOUT_UNIFORM; - case IDX_LOADOUT_VEST; - case IDX_LOADOUT_BACKPACK: { - (_loadout select _dataIndex) params [["_item", ""], ["_containerItems", []]]; - - if (_item != "") then { - // Check if item exists - if (isClass (_cfgVehicles >> _item) || {isClass (_cfgWeapons >> _item)}) then { - // Check if item is available in arsenal - if !(_item in (GVAR(virtualItems) get (_dataIndex + 1))) then { - _unavailableItemsList pushBackUnique _item; - _loadout set [_dataIndex, []]; - INC(_unavailableItemsAmount); - } else { - { - switch (true) do { - // Magazines have each 3 entries: Name, number of magazines and ammo count - case (_x isEqualTypeArray ["", 0, 0]): { - _x params ["_item"]; - - // Check if item exists - if (isClass (_cfgMagazines >> _item)) then { - // Check if item is available in arsenal - if !( - _item in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL) || - {_item in (GVAR(virtualItems) get IDX_VIRT_GRENADES)} || - {_item in (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES)} || - {_item in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)} - ) then { - _unavailableItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; - INC(_unavailableItemsAmount); - }; - } else { - _nullItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; - INC(_nullItemsAmount); - }; - }; - // Weapons have 2 entries: Weapon info array and amount - case (_x isEqualTypeArray [[], 0]): { - [_x select 0] call _fnc_weaponCheck; - }; - // Misc. items have 2 entries: Name and amount, containers have 2 entries: Name and isBackpack - default { - _x params ["_item"]; - - // Check if item exists - if ( - isClass (_cfgWeapons >> _item) || - {isClass (_cfgMagazines >> _item)} || - {isClass (_cfgGlasses >> _item)} || - {isClass (_cfgVehicles >> _item)} - ) then { - // Check if item is available in arsenal - if !(_item in GVAR(virtualItemsFlat)) then { - _unavailableItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; - INC(_unavailableItemsAmount); - }; - } else { - _nullItemsList pushBackUnique _item; - ((_loadout select _dataIndex) select 1) set [_forEachIndex, []]; - INC(_nullItemsAmount); - }; - }; - - }; - } forEach _containerItems; - }; - } else { - _nullItemsList pushBackUnique _item; - _loadout set [_dataIndex, []]; - INC(_nullItemsAmount); - }; - }; - }; - // Headgear - case IDX_LOADOUT_HEADGEAR: { - _item = _loadout select _dataIndex; - - if (_item != "") then { - // Check if item exists - if (isClass (_cfgWeapons >> _item)) then { - // Check if item is available in arsenal - if !(_item in (GVAR(virtualItems) get IDX_VIRT_HEADGEAR)) then { - _unavailableItemsList pushBackUnique _item; - _loadout set [_dataIndex, ""]; - INC(_unavailableItemsAmount); - }; - } else { - _nullItemsList pushBackUnique _item; - _loadout set [_dataIndex, ""]; - INC(_nullItemsAmount); - }; - }; - }; - // Facewear - case IDX_LOADOUT_GOGGLES: { - _item = _loadout select _dataIndex; - - if (_item != "") then { - // Check if item exists - if (isClass (_cfgGlasses >> _item)) then { - // Check if item is available in arsenal - if !(_item in (GVAR(virtualItems) get IDX_VIRT_GOGGLES)) then { - _unavailableItemsList pushBackUnique _item; - _loadout set [_dataIndex, ""]; - INC(_unavailableItemsAmount); - }; - } else { - _nullItemsList pushBackUnique _item; - _loadout set [_dataIndex, ""]; - INC(_nullItemsAmount); - }; - }; - }; - // Assigned items: Map, Compass, Watch, GPS / UAV Terminal, Radio, NVGs - case IDX_LOADOUT_ASSIGNEDITEMS: { - private _assignedItems = _loadout select _dataIndex; - - for "_subIndex" from 0 to 5 do { - _item = _assignedItems select _subIndex; - - if (_item != "") then { - // Check if item exists - if (isClass (_cfgWeapons >> _item)) then { - // Check if item is available in arsenal - if !(_item in (GVAR(virtualItems) get (IDX_VIRT_NVG + ([2, 6, 4, 3, 5, 0] select _subIndex)))) then { - _unavailableItemsList pushBackUnique _item; - _assignedItems set [_subIndex, ""]; - INC(_unavailableItemsAmount); - }; - } else { - _nullItemsList pushBackUnique _item; - _assignedItems set [_subIndex, ""]; - INC(_nullItemsAmount); - }; - }; - }; - }; + // Previously voices were stored in lower case (speaker command returns lower case), so this is to make old loadouts compatible + if (_class != "" && {_x == QGVAR(voice)}) then { + _class = _class call EFUNC(common,getConfigName); }; -}; + if (_class != "" && {!(_class in _cache)}) then { + _missingExtendedInfo pushBack [_x, _class]; + _extendedInfo deleteAt _x; + }; +} forEach [QGVAR(insignia), QGVAR(face), QGVAR(voice)]; -[[_loadout, _extendedInfo], _nullItemsAmount, _unavailableItemsAmount, _nullItemsList, _unavailableItemsList] +// Raise event for 3rd party: mostly for handling extended info +// Pass all items, including duplicates +[QGVAR(loadoutVerified), [_loadout, _extendedInfo, _nullItemsList, _unavailableItemsList, _missingExtendedInfo]] call CBA_fnc_localEvent; + +[[_loadout, _extendedInfo], _nullItemsList arrayIntersect _nullItemsList, _unavailableItemsList arrayIntersect _unavailableItemsList, _missingExtendedInfo] diff --git a/addons/arsenal/script_component.hpp b/addons/arsenal/script_component.hpp index 0f7348b9db..2eb9c3f170 100644 --- a/addons/arsenal/script_component.hpp +++ b/addons/arsenal/script_component.hpp @@ -15,6 +15,3 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" - -#define ACTION_TYPE_BUTTON 0 -#define ACTION_TYPE_TEXT 1 diff --git a/addons/arsenal/stringtable.xml b/addons/arsenal/stringtable.xml index f308765540..a469f39888 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -1240,11 +1240,15 @@ Thermal integrated + Termico integrato 熱画像装置内蔵 + Интегрирован тепловизор. Thermal & Primary integrated + Termico e Primario integrato 熱画像装置内蔵・プライマリに内蔵 + Интегрирован тепловизор и осн.прицел. Not Supported @@ -1600,6 +1604,7 @@ 내림차순 Décroissant Decrescente + Нисходящий Ascending @@ -1610,6 +1615,7 @@ 오름차순 Croissant Crescente + Восходящий Tools @@ -1636,6 +1642,7 @@ 장탄 수 Nombre de munitions Quantidade de munição + Количество боеприпасов Illuminators @@ -1645,6 +1652,7 @@ 조명 Iluminadores イルミネーター + Осветители Default to Favorites @@ -1655,6 +1663,7 @@ 즐겨찾기 기본값 Favoris par défaut Favoritos por padrão + По умолчанию - Избранное Controls whether the ACE Arsenal defaults to showing all items or favorites. @@ -1665,6 +1674,7 @@ ACE 아스널이 기본적으로 모든 아이템 또는 즐겨찾기를 표시할 지 여부를 조정합니다. Contrôle si l'arsenal ACE affiche par défaut tous les éléments ou les favoris. Controla se o Arsenal ACE exibe por padrão todos os itens ou favoritos. + Определяет, будет ли в арсенале ACE по умолчанию отображаться все предметы или избранное. Favorites Color @@ -1675,6 +1685,7 @@ 즐겨찾기 색상 Couleurs favorites Cor dos favoritos + Избранный цвет Highlight color for favorited items. @@ -1685,6 +1696,7 @@ 즐겨찾기한 아이템을 색상으로 강조합니다. Met en surbrillance les éléments favoris. Cor de destaque para itens favoritados. + Выделите цветом любимые предметы. Switch between displaying all items or your favorites.\nDouble click while holding Shift to add or remove an item. @@ -1695,6 +1707,7 @@ 모든 아이템을 표시하거나 즐겨찾기를 표시할 때 전환합니다\nShift 키를 누른 상태에서 두 번 클릭하여 아이템을 추가하거나 제거합니다. Change entre l'affichage de tous les éléments ou de vos favoris.\nDouble-cliquez en maintenant la touche Maj enfoncée pour ajouter ou supprimer un élément. Alterna entre a exibição de todos os itens ou seus favoritos.\nClique duas vezes enquanto mantém pressionada a tecla Shift para adicionar ou remover um item. + Переключайтесь между отображением всех элементов или ваших избранных.\nДважды щелкните, удерживая Shift, чтобы добавить или удалить элемент. Search\nCTRL + Click to enable live results @@ -1702,6 +1715,7 @@ Cerca\nCTRL + Click per modificare i risultati mentre scrivi 検索\nCTRL + クリックで検索結果の即時表示を有効化 검색\nCtrl + 클릭으로 실시간 검색 결과를 활성화 + Поиск\nCtrl + Click для включения результатов в реальном времени diff --git a/addons/arsenal/ui/RscAttributes.hpp b/addons/arsenal/ui/RscAttributes.hpp index 0265e86f3f..dc70caa0c2 100644 --- a/addons/arsenal/ui/RscAttributes.hpp +++ b/addons/arsenal/ui/RscAttributes.hpp @@ -450,24 +450,23 @@ class GVAR(display) { h = QUOTE(55 * GRID_H); class controls { class actionsStaticBackground1: ctrlStaticBackground { - idc = -1; + idc = IDC_actionsBackground1; x = QUOTE(0); y = QUOTE(0); w = QUOTE(47 * GRID_W); - h = QUOTE(56 * GRID_H); + h = QUOTE(55 * GRID_H); colorBackground[]={0.1,0.1,0.1,0.5}; }; class actionsStaticBackground2: ctrlStaticBackground { - idc = -1; + idc = IDC_actionsBackground2; x = QUOTE(0); y = QUOTE(0); w = QUOTE(47 * GRID_W); h = QUOTE(5 * GRID_H); colorBackground[]={0.1,0.1,0.1,0.8}; }; - class actionsText1: RscText { + class actionsText1: RscTextMulti { idc = IDC_actionsText1; - fade = 1; x = QUOTE(0 * GRID_W); y = QUOTE(5 * GRID_H); w = QUOTE(45 * GRID_W); @@ -479,7 +478,6 @@ class GVAR(display) { }; class actionsButton1: ctrlButton { idc = IDC_actionsButton1; - fade = 1; text = ""; x = QUOTE(1 * GRID_W); y = QUOTE(6 * GRID_H); @@ -566,6 +564,7 @@ class GVAR(display) { colorSelect[] = {1,1,1,1}; colorSelect2[] = {1,1,1,1}; colorPictureRightSelected[] = {1,1,1,1}; + colorTextRight[] = {0.5, 0.5, 0.5, 0}; onLBSelChanged = QUOTE(_this call FUNC(onSelChangedLeft)); onLBDblClick = QUOTE(_this call FUNC(onPanelDblClick)); onSetFocus = QUOTE(GVAR(leftTabFocus) = true); @@ -596,6 +595,7 @@ class GVAR(display) { colorSelect[] = {1,1,1,1}; colorSelect2[] = {1,1,1,1}; colorPictureRightSelected[] = {1,1,1,1}; + colorTextRight[] = {0.5, 0.5, 0.5, 0}; columns[] = {0.07, 0.15, 0.75}; idcLeft = IDC_arrowMinus; idcRIght = IDC_arrowPlus; diff --git a/addons/arsenal/ui/script_component.hpp b/addons/arsenal/ui/script_component.hpp deleted file mode 100644 index fcf9da9867..0000000000 --- a/addons/arsenal/ui/script_component.hpp +++ /dev/null @@ -1 +0,0 @@ -#include "..\script_component.hpp" diff --git a/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf b/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf index 56135025ae..3e50f9d7ad 100644 --- a/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf +++ b/addons/artillerytables/functions/fnc_rangeTableUpdate.sqf @@ -22,10 +22,10 @@ private _ctrlElevationHigh = _dialog displayCtrl IDC_BUTTON_ELEV_HIGH; private _ctrlElevationLow = _dialog displayCtrl IDC_BUTTON_ELEV_LOW; GVAR(lastElevationMode) = param [0, GVAR(lastElevationMode)]; // update if passed a new value -GVAR(lastCharge) = lbCurSel _ctrlChargeList; +GVAR(lastTablePage) = lbCurSel _ctrlChargeList; // get data for currently selected mag/mode combo: -(GVAR(magModeData) select GVAR(lastCharge)) params [["_muzzleVelocity", -1], ["_airFriction", 0]]; +(GVAR(magModeData) select GVAR(lastTablePage)) params [["_muzzleVelocity", -1], ["_airFriction", 0]]; private _elevMin = _dialog getVariable [QGVAR(elevMin), 0]; private _elevMax = _dialog getVariable [QGVAR(elevMax), 0]; _ctrlElevationHigh ctrlSetTextColor ([[0.25,0.25,0.25,1],[1,1,1,1]] select GVAR(lastElevationMode)); diff --git a/addons/atragmx/XEH_postInit.sqf b/addons/atragmx/XEH_postInit.sqf index 62d45555b1..7914657b08 100644 --- a/addons/atragmx/XEH_postInit.sqf +++ b/addons/atragmx/XEH_postInit.sqf @@ -1,5 +1,7 @@ #include "script_component.hpp" +if (!hasInterface) exitWith {}; + #include "initKeybinds.inc.sqf" GVAR(active) = false; diff --git a/addons/attach/functions/fnc_detach.sqf b/addons/attach/functions/fnc_detach.sqf index ec87f96dd0..d953b02bd1 100644 --- a/addons/attach/functions/fnc_detach.sqf +++ b/addons/attach/functions/fnc_detach.sqf @@ -57,7 +57,7 @@ if (!_isChemlight) then { _unit addItem _itemName; }; -if (toLower _itemName in ["b_ir_grenade", "o_ir_grenade", "i_ir_grenade"]) then { +if (toLowerANSI _itemName in ["b_ir_grenade", "o_ir_grenade", "i_ir_grenade"]) then { // Hack for dealing with X_IR_Grenade effect not dissapearing on deleteVehicle detach _attachedObject; _attachedObject setPos ((getPos _unit) vectorAdd [0, 0, -1000]); diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index 40385e9680..aa746e543f 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -3539,6 +3539,7 @@ 인공지능 사용 Utilisation de l'IA Utilização por IA + Использование ИИ Illum @@ -3549,6 +3550,7 @@ 조명탄 Fusées éclairantes Sinalizadoras + Осветители Smoke @@ -3559,6 +3561,7 @@ 연막탄 Fumigènes Fumígenas + Дым Inf @@ -3569,6 +3572,7 @@ 보병 Infanterie Infantaria + Пехота Veh @@ -3579,6 +3583,7 @@ 차량 Véhicule Veículo + Техника Armor @@ -3589,6 +3594,7 @@ 기갑 Blindage Blindagem + Бронетехника Air @@ -3599,6 +3605,7 @@ 항공 Aviation Aeronaves + Авиация diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index c12a02a574..174022ea11 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -145,6 +145,7 @@ Załóż opaskę na oczy 포로 눈 가리기 目隠しをする + Завязать глаза пленному Remove blindfold @@ -154,6 +155,7 @@ Zdejmij opaskę z oczu 눈가리개 풀기 目隠しを外す + Снять повязку с глаз Cable Tie @@ -484,7 +486,7 @@ 设置在光标下的单位成俘虏状态。 커서의 병력을 포박합니다. Ustawia jednostkę pod kursorem jako jeniec. - Арестовывает указанный курсором юнит + Арестовывает указанный курсором юнит. Torna a unidade sob o cursor um prisioneiro Capture l'unité sous le curseur. Nastaví jednotku pod kurzorem jako zajatce. diff --git a/addons/cargo/CfgEventHandlers.hpp b/addons/cargo/CfgEventHandlers.hpp index f6503c2479..29a0c6b277 100644 --- a/addons/cargo/CfgEventHandlers.hpp +++ b/addons/cargo/CfgEventHandlers.hpp @@ -15,3 +15,17 @@ class Extended_PostInit_EventHandlers { init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; + +class Extended_Killed_EventHandlers { + class CAManBase { + class ADDON { + killed = QUOTE((_this select 0) call FUNC(handleDeployInterrupt)); + }; + }; +}; + +class Extended_DisplayLoad_EventHandlers { + class RscDisplayMission { + ADDON = QUOTE(_this call COMPILE_SCRIPT(XEH_missionDisplayLoad)); + }; +}; diff --git a/addons/cargo/XEH_PREP.hpp b/addons/cargo/XEH_PREP.hpp index 2d77fc90de..10281e2967 100644 --- a/addons/cargo/XEH_PREP.hpp +++ b/addons/cargo/XEH_PREP.hpp @@ -2,10 +2,15 @@ PREP(addCargoItem); PREP(addCargoVehiclesActions); PREP(canLoadItemIn); PREP(canUnloadItem); +PREP(deployCancel); +PREP(deployConfirm); PREP(getCargoSpaceLeft); PREP(getNameItem); +PREP(getSelectedItem); PREP(getSizeItem); PREP(handleDestroyed); +PREP(handleDeployInterrupt); +PREP(handleScrollWheel); PREP(initObject); PREP(initVehicle); PREP(loadItem); @@ -16,6 +21,7 @@ PREP(removeCargoItem); PREP(renameObject); PREP(setSize); PREP(setSpace); +PREP(startDeploy); PREP(startLoadIn); PREP(startUnload); PREP(unloadCarryItem); diff --git a/addons/cargo/XEH_missionDisplayLoad.sqf b/addons/cargo/XEH_missionDisplayLoad.sqf new file mode 100644 index 0000000000..7bdea7571f --- /dev/null +++ b/addons/cargo/XEH_missionDisplayLoad.sqf @@ -0,0 +1,11 @@ +#include "script_component.hpp" + +params ["_display"]; + +_display displayAddEventHandler ["MouseZChanged", {(_this select 1) call FUNC(handleScrollWheel)}]; +_display displayAddEventHandler ["MouseButtonDown", { + // Right clicking cancels deployment + if (_this select 1 == 1) then { + ACE_player call FUNC(handleDeployInterrupt); + }; +}]; diff --git a/addons/cargo/XEH_postInit.sqf b/addons/cargo/XEH_postInit.sqf index 1848a1e77b..94cb2afc87 100644 --- a/addons/cargo/XEH_postInit.sqf +++ b/addons/cargo/XEH_postInit.sqf @@ -17,10 +17,10 @@ }] call CBA_fnc_addEventHandler; ["ace_unloadCargo", { - params ["_item", "_vehicle", ["_unloader", objNull]]; - TRACE_3("UnloadCargo EH",_item,_vehicle,_unloader); + params ["_item", "_vehicle", ["_unloader", objNull], ["_place", []]]; + TRACE_4("UnloadCargo EH",_item,_vehicle,_unloader,_place); - private _unloaded = [_item, _vehicle, _unloader] call FUNC(unloadItem); // returns true if successful + private _unloaded = [_item, _vehicle, _unloader, _place] call FUNC(unloadItem); // returns true if successful // Show hint as feedback private _hint = [LSTRING(unloadingFailed), LSTRING(unloadedItem)] select _unloaded; @@ -36,13 +36,25 @@ }; }] call CBA_fnc_addEventHandler; +// Direction must be set before setting position according to wiki +[QGVAR(setDirAndUnload), { + params ["_item", "_emptyPosAGL", "_direction"]; + + _item setDir _direction; + + [QGVAR(serverUnload), [_item, _emptyPosAGL]] call CBA_fnc_serverEvent; +}] call CBA_fnc_addEventHandler; + +// hideObjectGlobal must be executed before setPos to ensure light objects are rendered correctly +// Do both on server to ensure they are executed in the correct order [QGVAR(serverUnload), { params ["_item", "_emptyPosAGL"]; _item hideObjectGlobal false; _item setPosASL (AGLtoASL _emptyPosAGL); - [_item, "blockDamage", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + // Let objects remain invulernable for a short while after placement + [EFUNC(common,statusEffect_set), [_item, "blockDamage", QUOTE(ADDON), false], 2] call CBA_fnc_waitAndExecute; }] call CBA_fnc_addEventHandler; [QGVAR(paradropItem), { @@ -166,3 +178,38 @@ if (isServer) then { _bodyBag setVariable [QGVAR(customName), [_target, false, true] call EFUNC(common,getName), true]; }] call CBA_fnc_addEventHandler; }; + +// Set variables, even on machines without interfaces, just to be safe +GVAR(selectedItem) = objNull; +GVAR(itemPreviewObject) = objNull; +GVAR(deployPFH) = -1; +GVAR(deployDistance) = -1; +GVAR(deployDirection) = 0; +GVAR(deployHeight) = 0; +GVAR(canDeploy) = false; + +if (!hasInterface) exitWith {}; + +// Cancel object deployment if interact menu opened +["ace_interactMenuOpened", {ACE_player call FUNC(handleDeployInterrupt)}] call CBA_fnc_addEventHandler; + +// Cancel deploy on player change. This does work when returning to lobby, but not when hard disconnecting +["unit", LINKFUNC(handleDeployInterrupt)] call CBA_fnc_addPlayerEventHandler; +["vehicle", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; +["weapon", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; + +// When changing feature cameras, stop deployment +["featureCamera", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addPlayerEventHandler; + +// Handle falling unconscious while trying to deploy +["ace_unconscious", {(_this select 0) call FUNC(handleDeployInterrupt)}] call CBA_fnc_addEventHandler; + +// Handle surrendering and handcuffing +["ace_captiveStatusChanged", { + params ["_unit", "_state"]; + + // If surrendered or handcuffed, stop deployment + if (_state) then { + _unit call FUNC(handleDeployInterrupt); + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/cargo/functions/fnc_deployCancel.sqf b/addons/cargo/functions/fnc_deployCancel.sqf new file mode 100644 index 0000000000..50ee62c457 --- /dev/null +++ b/addons/cargo/functions/fnc_deployCancel.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: Garth 'L-H' de Wet, Ruthberg, commy2, Smith + * Cancels unloading when deploying. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_cargo_fnc_deployCancel + * + * Public: No + */ + +if (GVAR(deployPFH) == -1) exitWith {}; + +// Remove deployment pfh +GVAR(deployPFH) call CBA_fnc_removePerFrameHandler; +GVAR(deployPFH) = -1; + +params ["_unit"]; + +// Enable running again +[_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + +// Delete placement dummy +deleteVehicle GVAR(itemPreviewObject); + +// Remove mouse button actions +call EFUNC(interaction,hideMouseHint); + +[_unit, "DefaultAction", _unit getVariable [QGVAR(deploy), -1]] call EFUNC(common,removeActionEventHandler); +_unit setVariable [QGVAR(deploy), -1]; + +_unit setVariable [QGVAR(isDeploying), false, true]; diff --git a/addons/cargo/functions/fnc_deployConfirm.sqf b/addons/cargo/functions/fnc_deployConfirm.sqf new file mode 100644 index 0000000000..27674b0515 --- /dev/null +++ b/addons/cargo/functions/fnc_deployConfirm.sqf @@ -0,0 +1,56 @@ +#include "..\script_component.hpp" +/* + * Author: Garth 'L-H' de Wet, Ruthberg, commy2, Smith + * Confirms unloading when deploying. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_cargo_fnc_deployConfirm + * + * Public: No + */ + +if (GVAR(deployPFH) == -1) exitWith {}; + +params ["_unit"]; + +// Delete placement dummy and unload real item from cargo at dummy position +if (!isNull GVAR(itemPreviewObject) && {[GVAR(selectedItem), GVAR(interactionVehicle), _unit, false, true] call FUNC(canUnloadItem)}) then { + // Position is AGL for unloading event + private _position = ASLToAGL getPosASL GVAR(itemPreviewObject); + private _direction = getDir GVAR(itemPreviewObject); + private _duration = GVAR(loadTimeCoefficient) * (GVAR(selectedItem) call FUNC(getSizeItem)); + + // If unload time is 0, don't show a progress bar + if (_duration <= 0) exitWith { + ["ace_unloadCargo", [GVAR(selectedItem), GVAR(interactionVehicle), _unit, [_position, _direction]]] call CBA_fnc_localEvent; + }; + + [ + _duration, + [GVAR(selectedItem), GVAR(interactionVehicle), _unit, [_position, _direction]], + { + TRACE_1("deploy finish",_this); + + ["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent; + }, + { + TRACE_1("deploy fail",_this); + }, + format [LLSTRING(unloadingItem), [GVAR(selectedItem), true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")], + { + (_this select 0) params ["_item", "_vehicle", "_unit"]; + + [_item, _vehicle, _unit, false, true] call FUNC(canUnloadItem) // don't check for a suitable unloading position when deploying + }, + ["isNotSwimming"] + ] call EFUNC(common,progressBar); +}; + +// Cleanup EHs and preview object +_unit call FUNC(deployCancel); diff --git a/addons/cargo/functions/fnc_getSelectedItem.sqf b/addons/cargo/functions/fnc_getSelectedItem.sqf new file mode 100644 index 0000000000..a6f9141ae1 --- /dev/null +++ b/addons/cargo/functions/fnc_getSelectedItem.sqf @@ -0,0 +1,29 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, Smith + * Get selected item from cargo menu. + * + * Arguments: + * None + * + * Return Value: + * Classname of selected item or selected object or (default: nil) + * + * Example: + * call ace_cargo_fnc_getSelectedItem + * + * Public: No + */ + +disableSerialization; + +private _display = uiNamespace getVariable QGVAR(menuDisplay); + +if (isNil "_display") exitWith {}; + +private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; + +if (_loaded isEqualTo []) exitWith {}; + +// This can be an object or a classname string +_loaded param [lbCurSel (_display displayCtrl 100), nil] diff --git a/addons/cargo/functions/fnc_handleDeployInterrupt.sqf b/addons/cargo/functions/fnc_handleDeployInterrupt.sqf new file mode 100644 index 0000000000..2cb712b5e0 --- /dev/null +++ b/addons/cargo/functions/fnc_handleDeployInterrupt.sqf @@ -0,0 +1,30 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, Smith + * Handle various interruption types. + * + * Arguments: + * 0: (New) unit + * 1: Old unit (for player change) (default: objNull) + * + * Return Value: + * None + * + * Example: + * player call ace_cargo_fnc_handleDeployInterrupt + * + * Public: No +*/ + +params ["_newPlayer", ["_oldPlayer", objNull]]; +TRACE_2("params",_newPlayer,_oldPlayer); + +if (!local _newPlayer) exitWith {}; + +if (_newPlayer getVariable [QGVAR(isDeploying), false]) then { + _newPlayer call FUNC(deployCancel); +}; + +if (_oldPlayer getVariable [QGVAR(isDeploying), false]) then { + _oldPlayer call FUNC(deployCancel); +}; diff --git a/addons/cargo/functions/fnc_handleScrollWheel.sqf b/addons/cargo/functions/fnc_handleScrollWheel.sqf new file mode 100644 index 0000000000..9ec2c498e6 --- /dev/null +++ b/addons/cargo/functions/fnc_handleScrollWheel.sqf @@ -0,0 +1,58 @@ +#include "..\script_component.hpp" +/* + * Author: L-H, commy2, Smith + * Handles rotation of object to unload. + * + * Arguments: + * 0: Scroll amount + * + * Return Value: + * If the scroll was handled + * + * Example: + * 1.2 call ace_cargo_fnc_handleScrollWheel + * + * Public: No + */ + +if (GVAR(deployPFH) == -1) exitWith {false}; + +params ["_scrollAmount"]; + +private _deployedItem = GVAR(itemPreviewObject); + +if (!CBA_events_control) then { + private _unit = ACE_player; + + // Raise/lower + // Move deployed item 15 cm per scroll interval + _scrollAmount = _scrollAmount * 0.15; + + private _position = getPosASL _deployedItem; + private _maxHeight = (_unit modelToWorldVisualWorld [0, 0, 0]) select 2; + + _position set [2, ((_position select 2) + _scrollAmount min (_maxHeight + 1.5)) max _maxHeight]; + + // Move up/down object and reattach at current position + detach _deployedItem; + + // Uses this method of selecting position because setPosATL did not have immediate effect + private _positionChange = _position vectorDiff (getPosASL _deployedItem); + private _selectionPosition = _unit worldToModel (ASLtoAGL getPosWorld _deployedItem); + _selectionPosition = _selectionPosition vectorAdd _positionChange; + _deployedItem attachTo [_unit, _selectionPosition]; + + // Reset the deploy direction + private _direction = _deployedItem getVariable [QGVAR(deployDirection_temp), 0]; + _deployedItem setDir _direction; +} else { + // Rotate + private _direction = _deployedItem getVariable [QGVAR(deployDirection_temp), 0]; + _scrollAmount = _scrollAmount * 10; + _direction = _direction + _scrollAmount; + + _deployedItem setDir _direction; + _deployedItem setVariable [QGVAR(deployDirection_temp), _direction]; +}; + +true diff --git a/addons/cargo/functions/fnc_initVehicle.sqf b/addons/cargo/functions/fnc_initVehicle.sqf index 3361897e50..ec432ea91f 100644 --- a/addons/cargo/functions/fnc_initVehicle.sqf +++ b/addons/cargo/functions/fnc_initVehicle.sqf @@ -22,11 +22,17 @@ private _type = typeOf _vehicle; private _config = configOf _vehicle; // If vehicle had space given to it via eden/public, then override config hasCargo setting -private _hasCargoPublic = _vehicle getVariable [QGVAR(hasCargo), false]; +private _hasCargoPublic = _item getVariable QGVAR(hasCargo); +private _hasCargoPublicDefined = !isNil "_canLoadPublic"; + +if (_hasCargoPublicDefined && {!(_hasCargoPublic isEqualType false)}) then { + WARNING_4("%1[%2] - Variable %3 is %4 - Should be bool",_item,_type,QGVAR(hasCargo),_hasCargoPublic); +}; + private _hasCargoConfig = getNumber (_config >> QGVAR(hasCargo)) == 1; // Nothing to do here if vehicle has no cargo space -if !(_hasCargoConfig || _hasCargoPublic) exitWith {}; +if !((_hasCargoPublicDefined && {_hasCargoPublic in [true, 1]}) || {!_hasCargoPublicDefined && {_hasCargoConfig}}) exitWith {}; // Check if cargo is in cargo holder types (checked when trying to search for loadable objects) private _addCargoType = GVAR(cargoHolderTypes) findIf {_type isKindOf _x} == -1; diff --git a/addons/cargo/functions/fnc_onMenuOpen.sqf b/addons/cargo/functions/fnc_onMenuOpen.sqf index b0f7e7ffb9..f99999aabf 100644 --- a/addons/cargo/functions/fnc_onMenuOpen.sqf +++ b/addons/cargo/functions/fnc_onMenuOpen.sqf @@ -25,6 +25,9 @@ if (GVAR(interactionParadrop)) then { (_display displayCtrl 12) ctrlSetText LLSTRING(paradropButton); }; +// Disable deploy option if paradropping or in Zeus +(_display displayCtrl 13) ctrlEnable (GVAR(enableDeploy) && !GVAR(interactionParadrop) && {isNull curatorCamera}); + [{ params ["_vehicle", "_pfhID"]; @@ -33,7 +36,6 @@ if (GVAR(interactionParadrop)) then { private _display = uiNamespace getVariable QGVAR(menuDisplay); if (isNil "_display") exitWith { - GVAR(interactionVehicle) = nil; GVAR(interactionParadrop) = nil; _pfhID call CBA_fnc_removePerFrameHandler; @@ -41,18 +43,18 @@ if (GVAR(interactionParadrop)) then { // Close menu if in invalid state if ( - !alive _vehicle || + !alive ACE_player || + {!alive _vehicle} || {locked _vehicle >= 2} || {!(_vehicle getVariable [QGVAR(hasCargo), true])} || // if the cargo menu could be opened, the vehicle has QGVAR(hasCargo) in its config or the variable is set using FUNC(setSpace) { - isNull findDisplay 312 && // if in Zeus, ignore the following checks + isNull curatorCamera && // if in Zeus, ignore the checks that follow {([ACE_player, _vehicle] call EFUNC(interaction,getInteractionDistance)) >= MAX_LOAD_DISTANCE} && {(vehicle ACE_player) != _vehicle} } ) exitWith { closeDialog 0; - GVAR(interactionVehicle) = nil; GVAR(interactionParadrop) = nil; _pfhID call CBA_fnc_removePerFrameHandler; diff --git a/addons/cargo/functions/fnc_startDeploy.sqf b/addons/cargo/functions/fnc_startDeploy.sqf new file mode 100644 index 0000000000..185f71c712 --- /dev/null +++ b/addons/cargo/functions/fnc_startDeploy.sqf @@ -0,0 +1,86 @@ +#include "..\script_component.hpp" +/* + * Author: Garth 'L-H' de Wet, Ruthberg, commy2, Smith + * Starts the deploy process for unloading an object. + * + * Arguments: + * 0: Unit deploying + * + * Return Value: + * None + * + * Example: + * player call ace_cargo_fnc_startDeploy + * + * Public: No + */ + +// Deny creating preview item as it will destroy player vehicle instantly by collision +if (GVAR(interactionParadrop)) exitWith {}; + +params ["_unit"]; + +// Don't allow deploying if already deploying +if (_unit getVariable [QGVAR(isDeploying), false]) exitWith {}; + +// This can be an object or a classname string +private _item = call FUNC(getSelectedItem); + +if (isNil "_item") exitWith {}; + +// Close opened cargo menu +closeDialog 0; + +GVAR(selectedItem) = _item; + +private _classname = _item; + +if (_classname isEqualType objNull) then { + _classname = typeOf _classname; +}; + +// Prevent the placing unit from running +[_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + +// Create a local preview object +private _itemPreviewObject = createVehicleLocal [_classname, [0, 0, 0], [], 0, "CAN_COLLIDE"]; + +GVAR(itemPreviewObject) = _itemPreviewObject; + +// Prevent collisions with object +_itemPreviewObject disableCollisionWith _unit; +_itemPreviewObject enableSimulation false; +_itemPreviewObject setMass 1e-12; + +// Detect radius of zone where collision can damage the player +private _itemPreviewObjectRadius = 1 max ((boundingBoxReal [_itemPreviewObject, "FireGeometry"]) select 2); + +// Add height offset of model +private _offset = ((_itemPreviewObject modelToWorldVisual [0, 0, 0]) select 2) - ((_unit modelToWorldVisual [0, 0, 0]) select 2) + 1; + +// Attach object +_itemPreviewObject attachTo [_unit, [0, 1.5 * _itemPreviewObjectRadius, _offset]]; + +// PFH that runs while the deployment is in progress +GVAR(deployPFH) = [{ + (_this select 0) params ["_unit", "_vehicle", "_item", "_itemPreviewObject"]; + + if !( + !isNull _itemPreviewObject && + {[_item, _vehicle, _unit, false, true] call FUNC(canUnloadItem)} // don't check for a suitable unloading position when deploying + ) exitWith { + _unit call FUNC(deployCancel); + }; +}, 0.5, [_unit, GVAR(interactionVehicle), _item, _itemPreviewObject]] call CBA_fnc_addPerFrameHandler; + +// Add mouse button action and hint +[LLSTRING(unloadObject), localize "STR_DISP_CANCEL", LLSTRING(scrollAction)] call EFUNC(interaction,showMouseHint); + +_unit setVariable [QGVAR(deploy), [ + _unit, "DefaultAction", + {GVAR(deployPFH) != -1}, + {[_this select 0] call FUNC(deployConfirm)} +] call EFUNC(common,addActionEventHandler)]; + +_unit setVariable [QGVAR(isDeploying), true, true]; diff --git a/addons/cargo/functions/fnc_startUnload.sqf b/addons/cargo/functions/fnc_startUnload.sqf index d662bd3f73..39dbf59f48 100644 --- a/addons/cargo/functions/fnc_startUnload.sqf +++ b/addons/cargo/functions/fnc_startUnload.sqf @@ -15,18 +15,8 @@ * Public: No */ -disableSerialization; - -private _display = uiNamespace getVariable QGVAR(menuDisplay); - -if (isNil "_display") exitWith {}; - -private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; - -if (_loaded isEqualTo []) exitWith {}; - // This can be an object or a classname string -private _item = _loaded param [lbCurSel (_display displayCtrl 100), nil]; +private _item = call FUNC(getSelectedItem); if (isNil "_item") exitWith {}; @@ -60,11 +50,11 @@ if (GVAR(interactionParadrop)) exitWith { }, format [LLSTRING(unloadingItem), [_item, true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")], { - (_this select 0) params ["", "_target"]; + (_this select 0) params ["", "_vehicle"]; - if ((acos ((vectorUp _target) select 2)) > 30) exitWith {false}; // check flight level - if (((getPos _target) select 2) < 25) exitWith {false}; // check height - if ((speed _target) < -5) exitWith {false}; // check reverse + if ((acos ((vectorUp _vehicle) select 2)) > 30) exitWith {false}; // check flight level + if (((getPos _vehicle) select 2) < 25) exitWith {false}; // check height + if ((speed _vehicle) < -5) exitWith {false}; // check reverse true }, @@ -74,7 +64,7 @@ if (GVAR(interactionParadrop)) exitWith { }; // If in zeus -if (!isNull findDisplay 312) exitWith { +if (!isNull curatorCamera) exitWith { // Do not check distance to unit, but do check for valid position if !([_item, GVAR(interactionVehicle), objNull, true] call FUNC(canUnloadItem)) exitWith { [[LSTRING(unloadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured); diff --git a/addons/cargo/functions/fnc_unloadItem.sqf b/addons/cargo/functions/fnc_unloadItem.sqf index c18e89361e..f32215fdd7 100644 --- a/addons/cargo/functions/fnc_unloadItem.sqf +++ b/addons/cargo/functions/fnc_unloadItem.sqf @@ -7,6 +7,9 @@ * 0: Item to be unloaded or (default: "") * 1: Holder object (vehicle) (default: objNull) * 2: Unloader (default: objNull) + * 3: Deploy parameters (default: []) + * - 0: Position AGL + * - 1: Direction * * Return Value: * Object unloaded @@ -17,8 +20,10 @@ * Public: Yes */ -params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_unloader", objNull, [objNull]]]; -TRACE_3("params",_item,_vehicle,_unloader); +params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_unloader", objNull, [objNull]], ["_deploy", []]]; +_deploy params ["_emptyPosAGL", "_direction"]; + +TRACE_4("params",_item,_vehicle,_unloader,_deploy); // Get config sensitive case name if (_item isEqualType "") then { @@ -41,9 +46,18 @@ if (_itemSize < 0) exitWith { false // return }; -// This covers testing vehicle stability and finding a safe position -private _emptyPosAGL = [_vehicle, _item, _unloader] call EFUNC(common,findUnloadPosition); -TRACE_1("findUnloadPosition",_emptyPosAGL); +private _deployed = _deploy isNotEqualTo []; + +if (!_deployed) then { + // This covers testing vehicle stability and finding a safe position + for "_i" from 1 to 3 do { + _emptyPosAGL = [_vehicle, _item, _unloader] call EFUNC(common,findUnloadPosition); + + if (_emptyPosAGL isNotEqualTo []) exitWith {}; + }; + + TRACE_1("findUnloadPosition",_emptyPosAGL); +}; if (_emptyPosAGL isEqualTo []) exitWith { // Display text saying there are no safe places to exit the vehicle @@ -67,9 +81,12 @@ private _object = _item; if (_object isEqualType objNull) then { detach _object; - // hideObjectGlobal must be executed before setPos to ensure light objects are rendered correctly - // Do both on server to ensure they are executed in the correct order - [QGVAR(serverUnload), [_object, _emptyPosAGL]] call CBA_fnc_serverEvent; + // If player unloads via deployment, set direction first, then unload + if (_deployed) then { + [QGVAR(setDirAndUnload), [_object, _emptyPosAGL, _direction], _object] call CBA_fnc_targetEvent; + } else { + [QGVAR(serverUnload), [_object, _emptyPosAGL]] call CBA_fnc_serverEvent; + }; if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { // Get which curators had this object as editable @@ -81,6 +98,12 @@ if (_object isEqualType objNull) then { }; } else { _object = createVehicle [_item, _emptyPosAGL, [], 0, "NONE"]; + + // If player unloads via deployment, set direction. Must happen before setPosASL command according to wiki + if (_deployed) then { + _object setDir _direction; + }; + _object setPosASL (AGLtoASL _emptyPosAGL); [QEGVAR(common,fixCollision), _object] call CBA_fnc_localEvent; @@ -88,7 +111,9 @@ if (_object isEqualType objNull) then { }; // Dragging integration -[_unloader, _object] call FUNC(unloadCarryItem); +if (!_deployed) then { + [_unloader, _object] call FUNC(unloadCarryItem); +}; // Invoke listenable event ["ace_cargoUnloaded", [_object, _vehicle, "unload"]] call CBA_fnc_globalEvent; diff --git a/addons/cargo/initSettings.inc.sqf b/addons/cargo/initSettings.inc.sqf index 2f9fd94024..029a845a25 100644 --- a/addons/cargo/initSettings.inc.sqf +++ b/addons/cargo/initSettings.inc.sqf @@ -6,7 +6,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)], _category, true, - true, + 1, {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)} ] call CBA_fnc_addSetting; @@ -16,7 +16,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)], _category, [0, 10, 5, 1], - true, + 1, {[QGVAR(loadTimeCoefficient), _this, true] call EFUNC(common,cbaSettings_settingChanged)} ] call CBA_fnc_addSetting; @@ -26,7 +26,7 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)], _category, [0, 10, 2.5, 1], - true, + 1, {[QGVAR(paradropTimeCoefficent), _this, true] call EFUNC(common,cbaSettings_settingChanged)} ] call CBA_fnc_addSetting; @@ -36,26 +36,36 @@ private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; [LSTRING(openAfterUnload), LSTRING(openAfterUnload_description)], _category, [[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0], - false, + 0, {[QGVAR(openAfterUnload), _this, true] call EFUNC(common,cbaSettings_settingChanged)} ] call CBA_fnc_addSetting; -[ - QGVAR(enableRename), - "CHECKBOX", - [LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)], - _category, - true, - false, - {[QGVAR(enableRename), _this, true] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_fnc_addSetting; - [ QGVAR(carryAfterUnload), "CHECKBOX", [LSTRING(carryAfterUnload), LSTRING(carryAfterUnload_description)], _category, true, - false, + 0, {[QGVAR(carryAfterUnload), _this] call EFUNC(common,cbaSettings_settingChanged)} ] call CBA_fnc_addSetting; + +[ + QGVAR(enableDeploy), + "CHECKBOX", + [LSTRING(enableDeploy), LSTRING(enableDeploy_description)], + _category, + true, + 1, + {[QGVAR(enableDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_fnc_addSetting; + +[ + QGVAR(enableRename), + "CHECKBOX", + [LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)], + _category, + true, + 0, + {[QGVAR(enableRename), _this, true] call EFUNC(common,cbaSettings_settingChanged)} +] call CBA_fnc_addSetting; diff --git a/addons/cargo/menu.hpp b/addons/cargo/menu.hpp index 8c41fc43a5..1811369d7d 100644 --- a/addons/cargo/menu.hpp +++ b/addons/cargo/menu.hpp @@ -17,7 +17,7 @@ class GVAR(menu) { }; class CenterBackground: HeaderBackground { y = "2.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; - h = "13.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + h = "14.2 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; text = "#(argb,8,8,3)color(0,0,0,0.8)"; colorText[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; colorBackground[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; @@ -72,7 +72,7 @@ class GVAR(menu) { idc = 11; x = "13.1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; y = "14.1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; - w = "5 * (((safezoneW / safezoneH) min 1.2) / 40)"; + w = "6 * (((safezoneW / safezoneH) min 1.2) / 40)"; h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; size = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.7)"; @@ -96,8 +96,15 @@ class GVAR(menu) { class btnUnload: btnCancel { text = CSTRING(unloadObject); idc = 12; - x = "20.9 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; + x = "19.9 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; action = QUOTE(ACE_player call FUNC(startUnload)); }; + class btnPlace: btnUnload { + text = CSTRING(deployObject); + idc = 13; + y = "15.2 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; + action = QUOTE(ACE_player call FUNC(startDeploy)); + colorDisabled[] = {0.25, 0.25, 0.25, 1}; + }; }; }; diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index 73a83ac387..0a52bde972 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -33,6 +33,43 @@ 卸载 Boşalt + + Deploy + Piazza + Разместить + 配置する + + + Raise/Lower | (Ctrl + Scroll) Rotate + Heben/Senken | (Strg + Scrollen) Drehen + Alza/Abbassa | (Ctrl + Rotellina) Ruota + Lever/Baisser | (Ctrl + Scroll) Rotation + 上げる/下げる | (Ctrl + スクロール) 回転 + Zvednout/Snížit | (Ctrl + Kolečko myši) Otáčet + Поднять/опустить | (Ctrl + Скролл) Крутить + Wyżej/niżej | (Ctrl + Kółko myszy) obracanie + Yükselt/Alçalt | (Ctrl + Tekerlek) Döndür + Subir/Bajar | (Ctrl + Scroll) Rotar + 抬起/放低 |(Ctrl + 鼠标滚轮)旋转 + 높이기/내리기 | (컨트롤 + 스크롤) 회전 + Subir/Abaixar | (Ctrl + Scroll) Rotacionar + + + Blocked + Obstruido + Bloqueado + Заблокировано + Blokováno + Zablokowany + Bloccato + Blockiert + Bloqué + 配置不可 + 막힘 + 断开 + 斷開 + Bloke Edilmiş + Renamed to:<br/>%1 名前を次に変更:<br/>%1 @@ -243,12 +280,16 @@ Loading %1 into %2... Cargando %1 en %2... + Caricando %1 in %2... %1 を %2 に積み込んでいます・・・ + Загружаем %1 в %2... Unloading %1 from %2... Descargando %1 de %2... + Scaricando %1 da %2... %1 を %2 から降ろしています・・・ + Выгружаем %1 из %2... %1<br/>could not be loaded @@ -289,6 +330,7 @@ Ne peut pas être déchargé 荷降ろし不可能です 하역할 수가 없습니다 + Не может быть выгружен Cargo Size: %1 @@ -297,6 +339,7 @@ Encombrement fret: %1 貨物のサイズ: %1 화물 크기: %1 + Размер груза: %1 Custom Name @@ -467,7 +510,7 @@ 貨物の積み込み/積み下ろしに掛かる時間を変更します。\n時間 (秒) は、貨物のサイズにこの値を掛けたものです。 Modyfikuje, jak długo zajmuje załadowywanie/wyładowywanie przedmiotów. \nCzasem, w sekundach, jest wielkość przedmiotu razy jego wartość. Modifica il tempo impiegato per caricare o scaricare gli oggetti.\nIl tempo, in secondi, equivale alla dimensione dell'oggetto moltiplicata per questo valore - Изменяет время для загрузки/выгрузки предметов. \n Время (сек) - это размер предмета, умноженный на это значение. + Изменяет время для загрузки/выгрузки предметов. \nВремя (сек) - это размер предмета, умноженный на это значение. Coeficiente de quanto tempo leva para carregar/descarregar itens.\nTempo, em segundos, é o tamanho do objeto multiplicado por esse valor. Modifie le temps nécessaire pour charger/décharger des objets.\nLe temps, en secondes, est calculé en multipliant la taille de l'élément par ce coefficient. 修改要花多長時間來裝載/卸載物品。\n時間,以秒為單位,而物品的大小數值與這個係數成比。 @@ -528,5 +571,17 @@ Active si les éléments de cargaison sont portés ou traînés après le déchargement. Controla se os itens de carga são carregados ou arrastados após a descarga. + + Enable deploy + Abilita Piazzamento + Включить размещение + 配置機能を有効化 + + + Controls whether cargo items can be unloaded via the deploy method. + Determina se oggetti in carico possono essere scaricati e piazzati direttamente. + Определяет, можно ли выгружать грузы с помощью метода размещения. + 配置機能を介して貨物アイテムを降ろすことが出来るかどうかを制御します。 + diff --git a/addons/common/CfgMoves.hpp b/addons/common/CfgMoves.hpp index 14686526e9..3c51140fed 100644 --- a/addons/common/CfgMoves.hpp +++ b/addons/common/CfgMoves.hpp @@ -1,5 +1,9 @@ class CfgMovesBasic { - class Default; + // Idle affects legs when weapon switching - fixes units sliding when holstering weapons + class Default { + idle = ""; + }; + // From ACRE class ManActions { GVAR(stop) = QGVAR(stop); diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index ce6ac334ee..fb64d464df 100644 --- a/addons/common/XEH_PREP.hpp +++ b/addons/common/XEH_PREP.hpp @@ -13,6 +13,7 @@ PREP(addLineToDebugDraw); PREP(addSwayFactor); PREP(addToInventory); PREP(addWeapon); +PREP(adjustMagazineAmmo); PREP(assignedItemFix); PREP(assignObjectsInList); PREP(ambientBrightness); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index af4b33d49b..cf1f4b6fe0 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -361,7 +361,7 @@ addMissionEventHandler ["PlayerViewChanged", { private _position = [player] call FUNC(getUavControlPosition); private _seatAI = objNull; private _turret = []; - switch (toLower _position) do { + switch (toLowerANSI _position) do { case (""): { _UAV = objNull; // set to objNull if not actively controlling }; diff --git a/addons/common/define.hpp b/addons/common/define.hpp index 9e9e92ecb5..ce8765ec9f 100644 --- a/addons/common/define.hpp +++ b/addons/common/define.hpp @@ -1,124 +1,106 @@ - #ifndef ACE_DEFINE_H #define ACE_DEFINE_H // define.hpp -#define true 1 -#define false 0 +#define true 1 +#define false 0 -#define CT_STATIC 0 -#define CT_BUTTON 1 -#define CT_EDIT 2 -#define CT_SLIDER 3 -#define CT_COMBO 4 -#define CT_LISTBOX 5 -#define CT_TOOLBOX 6 -#define CT_CHECKBOXES 7 -#define CT_PROGRESS 8 -#define CT_HTML 9 -#define CT_STATIC_SKEW 10 -#define CT_ACTIVETEXT 11 -#define CT_TREE 12 +#define CT_STATIC 0 +#define CT_BUTTON 1 +#define CT_EDIT 2 +#define CT_SLIDER 3 +#define CT_COMBO 4 +#define CT_LISTBOX 5 +#define CT_TOOLBOX 6 +#define CT_CHECKBOXES 7 +#define CT_PROGRESS 8 +#define CT_HTML 9 +#define CT_STATIC_SKEW 10 +#define CT_ACTIVETEXT 11 +#define CT_TREE 12 #define CT_STRUCTURED_TEXT 13 -#define CT_CONTEXT_MENU 14 -#define CT_CONTROLS_GROUP 15 -#define CT_SHORTCUTBUTTON 16 -#define CT_XKEYDESC 40 -#define CT_XBUTTON 41 -#define CT_XLISTBOX 42 -#define CT_XSLIDER 43 -#define CT_XCOMBO 44 +#define CT_CONTEXT_MENU 14 +#define CT_CONTROLS_GROUP 15 +#define CT_SHORTCUTBUTTON 16 +#define CT_XKEYDESC 40 +#define CT_XBUTTON 41 +#define CT_XLISTBOX 42 +#define CT_XSLIDER 43 +#define CT_XCOMBO 44 #define CT_ANIMATED_TEXTURE 45 -#define CT_OBJECT 80 -#define CT_OBJECT_ZOOM 81 +#define CT_OBJECT 80 +#define CT_OBJECT_ZOOM 81 #define CT_OBJECT_CONTAINER 82 #define CT_OBJECT_CONT_ANIM 83 -#define CT_LINEBREAK 98 -#define CT_ANIMATED_USER 99 -#define CT_MAP 100 -#define CT_MAP_MAIN 101 -#define CT_LISTNBOX 102 +#define CT_LINEBREAK 98 +#define CT_ANIMATED_USER 99 +#define CT_MAP 100 +#define CT_MAP_MAIN 101 +#define CT_LISTNBOX 102 // Static styles -#define ST_POS 0x0F -#define ST_HPOS 0x03 -#define ST_VPOS 0x0C -#define ST_LEFT 0x00 -#define ST_RIGHT 0x01 -#define ST_CENTER 0x02 -#define ST_DOWN 0x04 -#define ST_UP 0x08 -#define ST_VCENTER 0x0c +#define ST_POS 0x0F +#define ST_HPOS 0x03 +#define ST_VPOS 0x0C +#define ST_LEFT 0x00 +#define ST_RIGHT 0x01 +#define ST_CENTER 0x02 +#define ST_DOWN 0x04 +#define ST_UP 0x08 +#define ST_VCENTER 0x0C -#define ST_TYPE 0xF0 -#define ST_SINGLE 0 -#define ST_MULTI 16 -#define ST_TITLE_BAR 32 -#define ST_PICTURE 48 -#define ST_FRAME 64 -#define ST_BACKGROUND 80 -#define ST_GROUP_BOX 96 -#define ST_GROUP_BOX2 112 -#define ST_HUD_BACKGROUND 128 -#define ST_TILE_PICTURE 144 -#define ST_WITH_RECT 160 -#define ST_LINE 176 +#define ST_TYPE 0xF0 +#define ST_SINGLE 0 +#define ST_MULTI 16 +#define ST_TITLE_BAR 32 +#define ST_PICTURE 48 +#define ST_FRAME 64 +#define ST_BACKGROUND 80 +#define ST_GROUP_BOX 96 +#define ST_GROUP_BOX2 112 +#define ST_HUD_BACKGROUND 128 +#define ST_TILE_PICTURE 144 +#define ST_WITH_RECT 160 +#define ST_LINE 176 -#define ST_SHADOW 0x100 -#define ST_NO_RECT 0x200 // this style works for CT_STATIC in conjunction with ST_MULTI -#define ST_KEEP_ASPECT_RATIO 0x800 +#define ST_SHADOW 0x100 +#define ST_NO_RECT 0x200 // this style works for CT_STATIC in conjunction with ST_MULTI +#define ST_KEEP_ASPECT_RATIO 0x800 -#define ST_TITLE ST_TITLE_BAR + ST_CENTER +#define ST_TITLE ST_TITLE_BAR + ST_CENTER // Slider styles -#define SL_DIR 0x400 -#define SL_VERT 0 -#define SL_HORZ 0x400 +#define SL_DIR 0x400 +#define SL_VERT 0 +#define SL_HORZ 0x400 -#define SL_TEXTURES 0x10 +#define SL_TEXTURES 0x10 // Listbox styles -#define LB_TEXTURES 0x10 -#define LB_MULTI 0x20 -#define FONT_ACE "RobotoCondensed" +#define LB_TEXTURES 0x10 +#define LB_MULTI 0x20 +#define FONT_ACE "RobotoCondensed" class ACE_gui_backgroundBase { - type = CT_STATIC; - idc = -1; - style = ST_PICTURE; - colorBackground[] = {0,0,0,0}; - colorText[] = {1, 1, 1, 1}; - font = FONT_ACE; - text = ""; - sizeEx = 0.032; + type = CT_STATIC; + idc = -1; + style = ST_PICTURE; + colorBackground[] = {0, 0, 0, 0}; + colorText[] = {1, 1, 1, 1}; + font = FONT_ACE; + text = ""; + sizeEx = 0.032; }; + class ACE_gui_editBase { type = 2; x = 0; y = 0; h = 0.04; w = 0.2; - colorBackground[] = - { - 0, - 0, - 0, - 1 - }; - colorText[] = - { - 0.95, - 0.95, - 0.95, - 1 - }; - colorSelection[] = - { - "(profilenamespace getVariable ['GUI_BCG_RGB_R',0.3843])", - "(profilenamespace getVariable ['GUI_BCG_RGB_G',0.7019])", - "(profilenamespace getVariable ['GUI_BCG_RGB_B',0.8862])", - 1 - }; + colorBackground[] = {0, 0, 0, 1}; + colorText[] = {0.95, 0.95, 0.95, 1}; + colorSelection[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.3843])", "(profilenamespace getVariable ['GUI_BCG_RGB_G',0.7019])", "(profilenamespace getVariable ['GUI_BCG_RGB_B',0.8862])", 1}; autocomplete = ""; text = ""; size = 0.2; @@ -126,629 +108,621 @@ class ACE_gui_editBase { font = "RobotoCondensed"; shadow = 2; sizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; - colorDisabled[] = - { - 1, - 1, - 1, - 0.25 + colorDisabled[] = {1, 1, 1, 0.25}; +}; + +class ACE_gui_buttonBase { + idc = -1; + type = 16; + style = ST_LEFT; + text = ""; + action = ""; + x = 0; + y = 0; + w = 0.25; + h = 0.04; + size = 0.03921; + sizeEx = 0.03921; + color[] = {1, 1, 1, 1}; + color2[] = {1, 1, 1, 1}; + colorBackground[] = {1, 1, 1, 0.95}; + colorbackground2[] = {1, 1, 1, 0.95}; + colorDisabled[] = {1, 1, 1, 0.6}; + colorFocused[] = {1, 1, 1, 1}; + colorBackgroundFocused[] = {1, 1, 1, 1}; + periodFocus = 1.2; + periodOver = 0.8; + default = 0; + + class HitZone { + left = 0; + top = 0; + right = 0; + bottom = 0; + }; + class ShortcutPos { + left = 0; + top = 0; + w = 0; + h = 0; + }; + class TextPos { + left = 0.002; + top = 0.0004; + right = 0; + bottom = 0; + }; + + textureNoShortcut = ""; + animTextureNormal = "#(argb,8,8,3)color(0,0,0,0.9)"; + animTextureDisabled = "#(argb,8,8,3)color(0,0,0,0.8)"; + animTextureOver = "#(argb,8,8,3)color(1,1,1,1)"; + animTextureFocused = "#(argb,8,8,3)color(1,1,1,1)"; + animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; + animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; + period = 0.5; + font = FONT_ACE; + soundClick[] = {"\A3\ui_f\data\sound\RscButton\soundClick", 0.09, 1}; + soundPush[] = {"\A3\ui_f\data\sound\RscButton\soundPush", 0, 0}; + soundEnter[] = {"\A3\ui_f\data\sound\RscButton\soundEnter", 0.07, 1}; + soundEscape[] = {"\A3\ui_f\data\sound\RscButton\soundEscape", 0.09, 1}; + + class Attributes { + font = FONT_ACE; + color = "#E5E5E5"; + align = "center"; + shadow = "true"; + }; + class AttributesImage { + font = FONT_ACE; + color = "#E5E5E5"; + align = "left"; + shadow = "true"; }; }; - - -class ACE_gui_buttonBase { - idc = -1; - type = 16; - style = ST_LEFT; - text = ""; - action = ""; - x = 0.0; - y = 0.0; - w = 0.25; - h = 0.04; - size = 0.03921; - sizeEx = 0.03921; - color[] = {1.0, 1.0, 1.0, 1}; - color2[] = {1.0, 1.0, 1.0, 1}; - colorBackground[] = {1,1,1,0.95}; - colorbackground2[] = {1,1,1,0.95}; - colorDisabled[] = {1,1,1,0.6}; - colorFocused[] = {1,1,1,1}; - colorBackgroundFocused[] = {1,1,1,1}; - periodFocus = 1.2; - periodOver = 0.8; - default = 0; - class HitZone { - left = 0.00; - top = 0.00; - right = 0.00; - bottom = 0.00; - }; - - class ShortcutPos { - left = 0.00; - top = 0.00; - w = 0.00; - h = 0.00; - }; - - class TextPos { - left = 0.002; - top = 0.0004; - right = 0.0; - bottom = 0.00; - }; - textureNoShortcut = ""; - animTextureNormal = "#(argb,8,8,3)color(0,0,0,0.9)"; - animTextureDisabled = "#(argb,8,8,3)color(0,0,0,0.8)"; - animTextureOver = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureFocused = "#(argb,8,8,3)color(1,1,1,1)"; - animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; - animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; - period = 0.5; - font = FONT_ACE; - soundClick[] = {"\A3\ui_f\data\sound\RscButton\soundClick",0.09,1}; - soundPush[] = {"\A3\ui_f\data\sound\RscButton\soundPush",0.0,0}; - soundEnter[] = {"\A3\ui_f\data\sound\RscButton\soundEnter",0.07,1}; - soundEscape[] = {"\A3\ui_f\data\sound\RscButton\soundEscape",0.09,1}; - class Attributes { - font = FONT_ACE; - color = "#E5E5E5"; - align = "center"; - shadow = "true"; - }; - class AttributesImage { - font = FONT_ACE; - color = "#E5E5E5"; - align = "left"; - shadow = "true"; - }; -}; - class ACE_gui_RscProgress { - type = 8; - style = 0; - colorFrame[] = {1,1,1,0.7}; - colorBar[] = {1,1,1,0.7}; - texture = "#(argb,8,8,3)color(1,1,1,0.7)"; - x = "1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; - y = "10 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; - w = "38 * (((safezoneW / safezoneH) min 1.2) / 40)"; - h = "0.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + type = 8; + style = 0; + colorFrame[] = {1, 1, 1, 0.7}; + colorBar[] = {1, 1, 1, 0.7}; + texture = "#(argb,8,8,3)color(1,1,1,0.7)"; + x = "1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; + y = "10 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) + (safezoneY + (safezoneH - (((safezoneW / safezoneH) min 1.2) / 1.2))/2)"; + w = "38 * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "0.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; }; - class ACE_gui_staticBase { - idc = -1; - type = CT_STATIC; - x = 0.0; - y = 0.0; - w = 0.183825; - h = 0.104575; - style = ST_LEFT; - font = FONT_ACE; - sizeEx = 0.03921; - colorText[] = {0.95, 0.95, 0.95, 1.0}; - colorBackground[] = {0, 0, 0, 0}; - text = ""; + idc = -1; + type = CT_STATIC; + x = 0; + y = 0; + w = 0.183825; + h = 0.104575; + style = ST_LEFT; + font = FONT_ACE; + sizeEx = 0.03921; + colorText[] = {0.95, 0.95, 0.95, 1}; + colorBackground[] = {0, 0, 0, 0}; + text = ""; }; class RscListBox; class ACE_gui_listBoxBase: RscListBox { - type = CT_LISTBOX; - style = ST_MULTI; - font = FONT_ACE; - sizeEx = 0.03921; - color[] = {1, 1, 1, 1}; - colorText[] = {0.543, 0.5742, 0.4102, 1.0}; - colorScrollbar[] = {0.95, 0.95, 0.95, 1}; - colorSelect[] = {0.95, 0.95, 0.95, 1}; - colorSelect2[] = {0.95, 0.95, 0.95, 1}; - colorSelectBackground[] = {0, 0, 0, 1}; - colorSelectBackground2[] = {0.543, 0.5742, 0.4102, 1.0}; - colorDisabled[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.69])","(profilenamespace getVariable ['GUI_BCG_RGB_G',0.75])","(profilenamespace getVariable ['GUI_BCG_RGB_B',0.5])", 0.25}; - period = 1.2; - rowHeight = 0.03; - colorBackground[] = {0, 0, 0, 1}; - maxHistoryDelay = 1.0; - autoScrollSpeed = -1; - autoScrollDelay = 5; - autoScrollRewind = 0; - soundSelect[] = {"",0.1,1}; - soundExpand[] = {"",0.1,1}; - soundCollapse[] = {"",0.1,1}; - class ListScrollBar { - arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; - arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; - autoScrollDelay = 5; - autoScrollEnabled = 0; - autoScrollRewind = 0; + type = CT_LISTBOX; + style = ST_MULTI; + font = FONT_ACE; + sizeEx = 0.03921; + color[] = {1, 1, 1, 1}; + colorText[] = {0.543, 0.5742, 0.4102, 1}; + colorScrollbar[] = {0.95, 0.95, 0.95, 1}; + colorSelect[] = {0.95, 0.95, 0.95, 1}; + colorSelect2[] = {0.95, 0.95, 0.95, 1}; + colorSelectBackground[] = {0, 0, 0, 1}; + colorSelectBackground2[] = {0.543, 0.5742, 0.4102, 1}; + colorDisabled[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.69])", "(profilenamespace getVariable ['GUI_BCG_RGB_G',0.75])", "(profilenamespace getVariable ['GUI_BCG_RGB_B',0.5])", 0.25}; + period = 1.2; + rowHeight = 0.03; + colorBackground[] = {0, 0, 0, 1}; + maxHistoryDelay = 1; autoScrollSpeed = -1; - border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; - color[] = {1,1,1,0.6}; - colorActive[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,0.3}; - height = 0; - scrollSpeed = 0.06; - shadow = 0; - thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; - width = 0; - }; - class ScrollBar { - color[] = {1, 1, 1, 0.6}; - colorActive[] = {1, 1, 1, 1}; - colorDisabled[] = {1, 1, 1, 0.3}; - thumb = ""; - arrowFull = ""; - arrowEmpty = ""; - border = ""; - }; -}; + autoScrollDelay = 5; + autoScrollRewind = 0; + soundSelect[] = {"", 0.1, 1}; + soundExpand[] = {"", 0.1, 1}; + soundCollapse[] = {"", 0.1, 1}; + class ListScrollBar { + arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; + arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; + autoScrollDelay = 5; + autoScrollEnabled = 0; + autoScrollRewind = 0; + autoScrollSpeed = -1; + border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; + color[] = {1, 1, 1, 0.6}; + colorActive[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 0.3}; + height = 0; + scrollSpeed = 0.06; + shadow = 0; + thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; + width = 0; + }; + class ScrollBar { + color[] = {1, 1, 1, 0.6}; + colorActive[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 0.3}; + thumb = ""; + arrowFull = ""; + arrowEmpty = ""; + border = ""; + }; +}; class ACE_gui_listNBox { - type = CT_LISTNBOX;// 102; - style =ST_MULTI; - w = 0.4; - h = 0.4; - font = FONT_ACE; - sizeEx = 0.031; + type = CT_LISTNBOX; // 102; + style = ST_MULTI; + w = 0.4; + h = 0.4; + font = FONT_ACE; + sizeEx = 0.031; - autoScrollSpeed = -1; - autoScrollDelay = 5; - autoScrollRewind = 0; - arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; - arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; - columns[] = {0.0}; - color[] = {1, 1, 1, 1}; - - rowHeight = 0.03; - colorBackground[] = {0, 0, 0, 0.2}; - colorText[] = {1,1, 1, 1.0}; - colorScrollbar[] = {0.95, 0.95, 0.95, 1}; - colorSelect[] = {0.95, 0.95, 0.95, 1}; - colorSelect2[] = {0.95, 0.95, 0.95, 1}; - colorSelectBackground[] = {0, 0, 0, 0.0}; - colorSelectBackground2[] = {0.0, 0.0, 0.0, 0.5}; - colorActive[] = {0,0,0,1}; - colorDisabled[] = {0,0,0,0.3}; - rows = 1; - - drawSideArrows = 0; - idcLeft = -1; - idcRight = -1; - maxHistoryDelay = 1; - soundSelect[] = {"", 0.1, 1}; - period = 1; - shadow = 2; - class ScrollBar { - arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; - arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; - border = "#(argb,8,8,3)color(1,1,1,1)"; - color[] = {1,1,1,0.6}; - colorActive[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,0.3}; - thumb = "#(argb,8,8,3)color(1,1,1,1)"; - }; - class ListScrollBar { - arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; - arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; - autoScrollDelay = 5; - autoScrollEnabled = 0; - autoScrollRewind = 0; autoScrollSpeed = -1; - border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; - color[] = {1,1,1,0.6}; - colorActive[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,0.3}; - height = 0; - scrollSpeed = 0.06; - shadow = 0; - thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; - width = 0; - }; -}; + autoScrollDelay = 5; + autoScrollRewind = 0; + arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; + arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; + columns[] = {0}; + color[] = {1, 1, 1, 1}; + rowHeight = 0.03; + colorBackground[] = {0, 0, 0, 0.2}; + colorText[] = {1, 1, 1, 1}; + colorScrollbar[] = {0.95, 0.95, 0.95, 1}; + colorSelect[] = {0.95, 0.95, 0.95, 1}; + colorSelect2[] = {0.95, 0.95, 0.95, 1}; + colorSelectBackground[] = {0, 0, 0, 0}; + colorSelectBackground2[] = {0, 0, 0, 0.5}; + colorActive[] = {0, 0, 0, 1}; + colorDisabled[] = {0, 0, 0, 0.3}; + rows = 1; + + drawSideArrows = 0; + idcLeft = -1; + idcRight = -1; + maxHistoryDelay = 1; + soundSelect[] = {"", 0.1, 1}; + period = 1; + shadow = 2; + + class ScrollBar { + arrowEmpty = "#(argb,8,8,3)color(1,1,1,1)"; + arrowFull = "#(argb,8,8,3)color(1,1,1,1)"; + border = "#(argb,8,8,3)color(1,1,1,1)"; + color[] = {1, 1, 1, 0.6}; + colorActive[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 0.3}; + thumb = "#(argb,8,8,3)color(1,1,1,1)"; + }; + class ListScrollBar { + arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; + arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; + autoScrollDelay = 5; + autoScrollEnabled = 0; + autoScrollRewind = 0; + autoScrollSpeed = -1; + border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; + color[] = {1, 1, 1, 0.6}; + colorActive[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 0.3}; + height = 0; + scrollSpeed = 0.06; + shadow = 0; + thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; + width = 0; + }; +}; class RscCombo; class ACE_gui_comboBoxBase: RscCombo { - idc = -1; - type = 4; - style = "0x10 + 0x200"; - x = 0; - y = 0; - w = 0.3; - h = 0.035; - color[] = {0,0,0,0.6}; - colorActive[] = {1,0,0,1}; - colorBackground[] = {0,0,0,1}; - colorDisabled[] = {1,1,1,0.25}; - colorScrollbar[] = {1,0,0,1}; - colorSelect[] = {0,0,0,1}; - colorSelectBackground[] = {1,1,1,0.7}; - colorText[] = {1,1,1,1}; + idc = -1; + type = 4; + style = "0x10 + 0x200"; + x = 0; + y = 0; + w = 0.3; + h = 0.035; + color[] = {0, 0, 0, 0.6}; + colorActive[] = {1, 0, 0, 1}; + colorBackground[] = {0, 0, 0, 1}; + colorDisabled[] = {1, 1, 1, 0.25}; + colorScrollbar[] = {1, 0, 0, 1}; + colorSelect[] = {0, 0, 0, 1}; + colorSelectBackground[] = {1, 1, 1, 0.7}; + colorText[] = {1, 1, 1, 1}; - arrowEmpty = ""; - arrowFull = ""; - wholeHeight = 0.45; - font = FONT_ACE; - sizeEx = 0.031; - soundSelect[] = {"\A3\ui_f\data\sound\RscCombo\soundSelect",0.1,1}; - soundExpand[] = {"\A3\ui_f\data\sound\RscCombo\soundExpand",0.1,1}; - soundCollapse[] = {"\A3\ui_f\data\sound\RscCombo\soundCollapse",0.1,1}; - maxHistoryDelay = 1.0; - class ScrollBar { - color[] = {0.3,0.3,0.3,0.6}; - colorActive[] = {0.3,0.3,0.3,1}; - colorDisabled[] = {0.3,0.3,0.3,0.3}; - thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; - arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; - arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; - border = ""; - }; - class ComboScrollBar { - arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; - arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; - autoScrollDelay = 5; - autoScrollEnabled = 0; - autoScrollRewind = 0; - autoScrollSpeed = -1; - border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; - color[] = {0.3,0.3,0.3,0.6}; - colorActive[] = {0.3,0.3,0.3,1}; - colorDisabled[] = {0.3,0.3,0.3,0.3}; - height = 0; - scrollSpeed = 0.06; - shadow = 0; - thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; - width = 0; - }; + arrowEmpty = ""; + arrowFull = ""; + wholeHeight = 0.45; + font = FONT_ACE; + sizeEx = 0.031; + soundSelect[] = {"\A3\ui_f\data\sound\RscCombo\soundSelect", 0.1, 1}; + soundExpand[] = {"\A3\ui_f\data\sound\RscCombo\soundExpand", 0.1, 1}; + soundCollapse[] = {"\A3\ui_f\data\sound\RscCombo\soundCollapse", 0.1, 1}; + maxHistoryDelay = 1; + + class ScrollBar { + color[] = {0.3, 0.3, 0.3, 0.6}; + colorActive[] = {0.3, 0.3, 0.3, 1}; + colorDisabled[] = {0.3, 0.3, 0.3, 0.3}; + thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; + arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; + arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; + border = ""; + }; + class ComboScrollBar { + arrowEmpty = "\A3\ui_f\data\gui\cfg\scrollbar\arrowEmpty_ca.paa"; + arrowFull = "\A3\ui_f\data\gui\cfg\scrollbar\arrowFull_ca.paa"; + autoScrollDelay = 5; + autoScrollEnabled = 0; + autoScrollRewind = 0; + autoScrollSpeed = -1; + border = "\A3\ui_f\data\gui\cfg\scrollbar\border_ca.paa"; + color[] = {0.3, 0.3, 0.3, 0.6}; + colorActive[] = {0.3, 0.3, 0.3, 1}; + colorDisabled[] = {0.3, 0.3, 0.3, 0.3}; + height = 0; + scrollSpeed = 0.06; + shadow = 0; + thumb = "\A3\ui_f\data\gui\cfg\scrollbar\thumb_ca.paa"; + width = 0; + }; }; - - class ACE_gui_mapBase { - moveOnEdges = 1; - x = "SafeZoneXAbs"; - y = "SafeZoneY + 1.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - w = "SafeZoneWAbs"; - h = "SafeZoneH - 1.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - type = 100; // Use 100 to hide markers - style = 48; - shadow = 0; + moveOnEdges = 1; + x = "SafeZoneXAbs"; + y = "SafeZoneY + 1.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + w = "SafeZoneWAbs"; + h = "SafeZoneH - 1.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + type = 100; // Use 100 to hide markers + style = 48; + shadow = 0; - ptsPerSquareSea = 5; - ptsPerSquareTxt = 3; - ptsPerSquareCLn = 10; - ptsPerSquareExp = 10; - ptsPerSquareCost = 10; - ptsPerSquareFor = 9; - ptsPerSquareForEdge = 9; - ptsPerSquareRoad = 6; - ptsPerSquareObj = 9; - showCountourInterval = 0; - scaleMin = 0.001; - scaleMax = 1.0; - scaleDefault = 0.16; - maxSatelliteAlpha = 0.85; - alphaFadeStartScale = 0.35; - alphaFadeEndScale = 0.4; - colorBackground[] = {0.969,0.957,0.949,1.0}; - colorSea[] = {0.467,0.631,0.851,0.5}; - colorForest[] = {0.624,0.78,0.388,0.5}; - colorForestBorder[] = {0.0,0.0,0.0,0.0}; - colorRocks[] = {0.0,0.0,0.0,0.3}; - colorRocksBorder[] = {0.0,0.0,0.0,0.0}; - colorLevels[] = {0.286,0.177,0.094,0.5}; - colorMainCountlines[] = {0.572,0.354,0.188,0.5}; - colorCountlines[] = {0.572,0.354,0.188,0.25}; - colorMainCountlinesWater[] = {0.491,0.577,0.702,0.6}; - colorCountlinesWater[] = {0.491,0.577,0.702,0.3}; - colorPowerLines[] = {0.1,0.1,0.1,1.0}; - colorRailWay[] = {0.8,0.2,0.0,1.0}; - colorNames[] = {0.1,0.1,0.1,0.9}; - colorInactive[] = {1.0,1.0,1.0,0.5}; - colorOutside[] = {0.0,0.0,0.0,1.0}; - colorTracks[] = {0.84,0.76,0.65,0.15}; - colorTracksFill[] = {0.84,0.76,0.65,1.0}; - colorRoads[] = {0.7,0.7,0.7,1.0}; - colorRoadsFill[] = {1.0,1.0,1.0,1.0}; - colorMainRoads[] = {0.9,0.5,0.3,1.0}; - colorMainRoadsFill[] = {1.0,0.6,0.4,1.0}; - colorGrid[] = {0.1,0.1,0.1,0.6}; - colorGridMap[] = {0.1,0.1,0.1,0.6}; - colorText[] = {1, 1, 1, 0.85}; -font = "RobotoCondensed"; -sizeEx = 0.0270000; -stickX[] = {0.20, {"Gamma", 1.00, 1.50} }; -stickY[] = {0.20, {"Gamma", 1.00, 1.50} }; -onMouseButtonClick = ""; -onMouseButtonDblClick = ""; + ptsPerSquareSea = 5; + ptsPerSquareTxt = 3; + ptsPerSquareCLn = 10; + ptsPerSquareExp = 10; + ptsPerSquareCost = 10; + ptsPerSquareFor = 9; + ptsPerSquareForEdge = 9; + ptsPerSquareRoad = 6; + ptsPerSquareObj = 9; + showCountourInterval = 0; + scaleMin = 0.001; + scaleMax = 1; + scaleDefault = 0.16; + maxSatelliteAlpha = 0.85; + alphaFadeStartScale = 0.35; + alphaFadeEndScale = 0.4; + colorBackground[] = {0.969, 0.957, 0.949, 1}; + colorSea[] = {0.467, 0.631, 0.851, 0.5}; + colorForest[] = {0.624, 0.78, 0.388, 0.5}; + colorForestBorder[] = {0, 0, 0, 0}; + colorRocks[] = {0, 0, 0, 0.3}; + colorRocksBorder[] = {0, 0, 0, 0}; + colorLevels[] = {0.286, 0.177, 0.094, 0.5}; + colorMainCountlines[] = {0.572, 0.354, 0.188, 0.5}; + colorCountlines[] = {0.572, 0.354, 0.188, 0.25}; + colorMainCountlinesWater[] = {0.491, 0.577, 0.702, 0.6}; + colorCountlinesWater[] = {0.491, 0.577, 0.702, 0.3}; + colorPowerLines[] = {0.1, 0.1, 0.1, 1}; + colorRailWay[] = {0.8, 0.2, 0, 1}; + colorNames[] = {0.1, 0.1, 0.1, 0.9}; + colorInactive[] = {1, 1, 1, 0.5}; + colorOutside[] = {0, 0, 0, 1}; + colorTracks[] = {0.84, 0.76, 0.65, 0.15}; + colorTracksFill[] = {0.84, 0.76, 0.65, 1}; + colorRoads[] = {0.7, 0.7, 0.7, 1}; + colorRoadsFill[] = {1, 1, 1, 1}; + colorMainRoads[] = {0.9, 0.5, 0.3, 1}; + colorMainRoadsFill[] = {1, 0.6, 0.4, 1}; + colorGrid[] = {0.1, 0.1, 0.1, 0.6}; + colorGridMap[] = {0.1, 0.1, 0.1, 0.6}; + colorText[] = {1, 1, 1, 0.85}; + font = "RobotoCondensed"; + sizeEx = 0.027; + stickX[] = {0.2, {"Gamma", 1, 1.5}}; + stickY[] = {0.2, {"Gamma", 1, 1.5}}; + onMouseButtonClick = ""; + onMouseButtonDblClick = ""; - fontLabel = "RobotoCondensed"; - sizeExLabel = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; - fontGrid = "TahomaB"; - sizeExGrid = 0.02; - fontUnits = "TahomaB"; - sizeExUnits = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; - fontNames = "RobotoCondensed"; - sizeExNames = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8) * 2"; - fontInfo = "RobotoCondensed"; - sizeExInfo = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; - fontLevel = "TahomaB"; - sizeExLevel = 0.02; - text = "#(argb,8,8,3)color(1,1,1,1)"; - class ActiveMarker { - color[] = {0.30, 0.10, 0.90, 1.00}; - size = 50; - }; - class Legend { - x = "SafeZoneX + ( ((safezoneW / safezoneH) min 1.2) / 40)"; - y = "SafeZoneY + safezoneH - 4.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - w = "10 * ( ((safezoneW / safezoneH) min 1.2) / 40)"; - h = "3.5 * ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; - font = "RobotoCondensed"; - sizeEx = "( ( ( ((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; - colorBackground[] = {1,1,1,0.5}; - color[] = {0,0,0,1}; - }; - class Task { - icon = "\A3\ui_f\data\map\mapcontrol\taskIcon_CA.paa"; - iconCreated = "\A3\ui_f\data\map\mapcontrol\taskIconCreated_CA.paa"; - iconCanceled = "\A3\ui_f\data\map\mapcontrol\taskIconCanceled_CA.paa"; - iconDone = "\A3\ui_f\data\map\mapcontrol\taskIconDone_CA.paa"; - iconFailed = "\A3\ui_f\data\map\mapcontrol\taskIconFailed_CA.paa"; - color[] = {"(profilenamespace getVariable ['IGUI_TEXT_RGB_R',0])","(profilenamespace getVariable ['IGUI_TEXT_RGB_G',1])","(profilenamespace getVariable ['IGUI_TEXT_RGB_B',1])","(profilenamespace getVariable ['IGUI_TEXT_RGB_A',0.8])"}; - colorCreated[] = {1,1,1,1}; - colorCanceled[] = {0.7,0.7,0.7,1}; - colorDone[] = {0.7,1,0.3,1}; - colorFailed[] = {1,0.3,0.2,1}; - size = 27; - importance = 1; - coefMin = 1; - coefMax = 1; - }; - class Waypoint { - icon = "\A3\ui_f\data\map\mapcontrol\waypoint_ca.paa"; - color[] = {0,0,0,1}; - size = 20; - importance = "1.2 * 16 * 0.05"; - coefMin = 0.900000; - coefMax = 4; - }; - class WaypointCompleted { - icon = "\A3\ui_f\data\map\mapcontrol\waypointCompleted_ca.paa"; - color[] = {0,0,0,1}; - size = 20; - importance = "1.2 * 16 * 0.05"; - coefMin = 0.900000; - coefMax = 4; - }; - class CustomMark { - icon = "\A3\ui_f\data\map\mapcontrol\custommark_ca.paa"; - size = 24; - importance = 1; - coefMin = 1; - coefMax = 1; - color[] = {0,0,0,1}; - }; - class Command { - icon = "\A3\ui_f\data\map\mapcontrol\waypoint_ca.paa"; - size = 18; - importance = 1; - coefMin = 1; - coefMax = 1; - color[] = {1,1,1,1}; - }; - class Bush { - icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; - color[] = {0.45,0.64,0.33,0.4}; - size = "14/2"; - importance = "0.2 * 14 * 0.05 * 0.05"; - coefMin = 0.25; - coefMax = 4; - }; - class Rock { - icon = "\A3\ui_f\data\map\mapcontrol\rock_ca.paa"; - color[] = {0.1,0.1,0.1,0.8}; - size = 12; - importance = "0.5 * 12 * 0.05"; - coefMin = 0.25; - coefMax = 4; - }; - class SmallTree { - icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; - color[] = {0.45,0.64,0.33,0.4}; - size = 12; - importance = "0.6 * 12 * 0.05"; - coefMin = 0.25; - coefMax = 4; - }; - class Tree { - icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; - color[] = {0.45,0.64,0.33,0.4}; - size = 12; - importance = "0.9 * 16 * 0.05"; - coefMin = 0.25; - coefMax = 4; - }; - class busstop { - icon = "\A3\ui_f\data\map\mapcontrol\busstop_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class fuelstation { - icon = "\A3\ui_f\data\map\mapcontrol\fuelstation_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class hospital { - icon = "\A3\ui_f\data\map\mapcontrol\hospital_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class church { - icon = "\A3\ui_f\data\map\mapcontrol\church_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class lighthouse { - icon = "\A3\ui_f\data\map\mapcontrol\lighthouse_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class power { - icon = "\A3\ui_f\data\map\mapcontrol\power_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class powersolar { - icon = "\A3\ui_f\data\map\mapcontrol\powersolar_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class powerwave { - icon = "\A3\ui_f\data\map\mapcontrol\powerwave_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class powerwind { - icon = "\A3\ui_f\data\map\mapcontrol\powerwind_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class quay { - icon = "\A3\ui_f\data\map\mapcontrol\quay_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class shipwreck { - icon = "\A3\ui_f\data\map\mapcontrol\shipwreck_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class transmitter { - icon = "\A3\ui_f\data\map\mapcontrol\transmitter_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class watertower { - icon = "\A3\ui_f\data\map\mapcontrol\watertower_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {1,1,1,1}; - }; - class Cross { - icon = "\A3\ui_f\data\map\mapcontrol\Cross_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {0,0,0,1}; - }; - class Chapel { - icon = "\A3\ui_f\data\map\mapcontrol\Chapel_CA.paa"; - size = 24; - importance = 1; - coefMin = 0.85; - coefMax = 1.0; - color[] = {0,0,0,1}; - }; - class Bunker { - icon = "\A3\ui_f\data\map\mapcontrol\bunker_ca.paa"; - size = 14; - importance = "1.5 * 14 * 0.05"; - coefMin = 0.25; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class Fortress { - icon = "\A3\ui_f\data\map\mapcontrol\bunker_ca.paa"; - size = 16; - importance = "2 * 16 * 0.05"; - coefMin = 0.25; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class Fountain { - icon = "\A3\ui_f\data\map\mapcontrol\fountain_ca.paa"; - size = 11; - importance = "1 * 12 * 0.05"; - coefMin = 0.25; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class Ruin { - icon = "\A3\ui_f\data\map\mapcontrol\ruin_ca.paa"; - size = 16; - importance = "1.2 * 16 * 0.05"; - coefMin = 1; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class Stack { - icon = "\A3\ui_f\data\map\mapcontrol\stack_ca.paa"; - size = 20; - importance = "2 * 16 * 0.05"; - coefMin = 0.9; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class Tourism { - icon = "\A3\ui_f\data\map\mapcontrol\tourism_ca.paa"; - size = 16; - importance = "1 * 16 * 0.05"; - coefMin = 0.7; - coefMax = 4; - color[] = {0,0,0,1}; - }; - class ViewTower { - icon = "\A3\ui_f\data\map\mapcontrol\viewtower_ca.paa"; - size = 16; - importance = "2.5 * 16 * 0.05"; - coefMin = 0.5; - coefMax = 4; - color[] = {0,0,0,1}; - }; + fontLabel = "RobotoCondensed"; + sizeExLabel = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + fontGrid = "TahomaB"; + sizeExGrid = 0.02; + fontUnits = "TahomaB"; + sizeExUnits = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + fontNames = "RobotoCondensed"; + sizeExNames = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8) * 2"; + fontInfo = "RobotoCondensed"; + sizeExInfo = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + fontLevel = "TahomaB"; + sizeExLevel = 0.02; + text = "#(argb,8,8,3)color(1,1,1,1)"; + + class ActiveMarker { + color[] = {0.3, 0.1, 0.9, 1}; + size = 50; + }; + class Legend { + x = "SafeZoneX + (((safezoneW / safezoneH) min 1.2) / 40)"; + y = "SafeZoneY + safezoneH - 4.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + w = "10 * (((safezoneW / safezoneH) min 1.2) / 40)"; + h = "3.5 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; + font = "RobotoCondensed"; + sizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 0.8)"; + colorBackground[] = {1, 1, 1, 0.5}; + color[] = {0, 0, 0, 1}; + }; + class Task { + icon = "\A3\ui_f\data\map\mapcontrol\taskIcon_CA.paa"; + iconCreated = "\A3\ui_f\data\map\mapcontrol\taskIconCreated_CA.paa"; + iconCanceled = "\A3\ui_f\data\map\mapcontrol\taskIconCanceled_CA.paa"; + iconDone = "\A3\ui_f\data\map\mapcontrol\taskIconDone_CA.paa"; + iconFailed = "\A3\ui_f\data\map\mapcontrol\taskIconFailed_CA.paa"; + color[] = {"(profilenamespace getVariable ['IGUI_TEXT_RGB_R',0])", "(profilenamespace getVariable ['IGUI_TEXT_RGB_G',1])", "(profilenamespace getVariable ['IGUI_TEXT_RGB_B',1])", "(profilenamespace getVariable ['IGUI_TEXT_RGB_A',0.8])"}; + colorCreated[] = {1, 1, 1, 1}; + colorCanceled[] = {0.7, 0.7, 0.7, 1}; + colorDone[] = {0.7, 1, 0.3, 1}; + colorFailed[] = {1, 0.3, 0.2, 1}; + size = 27; + importance = 1; + coefMin = 1; + coefMax = 1; + }; + class Waypoint { + icon = "\A3\ui_f\data\map\mapcontrol\waypoint_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 20; + importance = "1.2 * 16 * 0.05"; + coefMin = 0.9; + coefMax = 4; + }; + class WaypointCompleted { + icon = "\A3\ui_f\data\map\mapcontrol\waypointCompleted_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 20; + importance = "1.2 * 16 * 0.05"; + coefMin = 0.9; + coefMax = 4; + }; + class CustomMark { + icon = "\A3\ui_f\data\map\mapcontrol\custommark_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 24; + importance = 1; + coefMin = 1; + coefMax = 1; + }; + class Command { + icon = "\A3\ui_f\data\map\mapcontrol\waypoint_ca.paa"; + color[] = {1, 1, 1, 1}; + size = 18; + importance = 1; + coefMin = 1; + coefMax = 1; + }; + class Bush { + icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; + color[] = {0.45, 0.64, 0.33, 0.4}; + size = "14/2"; + importance = "0.2 * 14 * 0.05 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Rock { + icon = "\A3\ui_f\data\map\mapcontrol\rock_ca.paa"; + color[] = {0.1, 0.1, 0.1, 0.8}; + size = 12; + importance = "0.5 * 12 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class SmallTree { + icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; + color[] = {0.45, 0.64, 0.33, 0.4}; + size = 12; + importance = "0.6 * 12 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Tree { + icon = "\A3\ui_f\data\map\mapcontrol\bush_ca.paa"; + color[] = {0.45, 0.64, 0.33, 0.4}; + size = 12; + importance = "0.9 * 16 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class busstop { + icon = "\A3\ui_f\data\map\mapcontrol\busstop_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class fuelstation { + icon = "\A3\ui_f\data\map\mapcontrol\fuelstation_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class hospital { + icon = "\A3\ui_f\data\map\mapcontrol\hospital_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class church { + icon = "\A3\ui_f\data\map\mapcontrol\church_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class lighthouse { + icon = "\A3\ui_f\data\map\mapcontrol\lighthouse_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class power { + icon = "\A3\ui_f\data\map\mapcontrol\power_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class powersolar { + icon = "\A3\ui_f\data\map\mapcontrol\powersolar_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class powerwave { + icon = "\A3\ui_f\data\map\mapcontrol\powerwave_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class powerwind { + icon = "\A3\ui_f\data\map\mapcontrol\powerwind_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class quay { + icon = "\A3\ui_f\data\map\mapcontrol\quay_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class shipwreck { + icon = "\A3\ui_f\data\map\mapcontrol\shipwreck_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class transmitter { + icon = "\A3\ui_f\data\map\mapcontrol\transmitter_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class watertower { + icon = "\A3\ui_f\data\map\mapcontrol\watertower_CA.paa"; + color[] = {1, 1, 1, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class Cross { + icon = "\A3\ui_f\data\map\mapcontrol\Cross_CA.paa"; + color[] = {0, 0, 0, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class Chapel { + icon = "\A3\ui_f\data\map\mapcontrol\Chapel_CA.paa"; + color[] = {0, 0, 0, 1}; + size = 24; + importance = 1; + coefMin = 0.85; + coefMax = 1; + }; + class Bunker { + icon = "\A3\ui_f\data\map\mapcontrol\bunker_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 14; + importance = "1.5 * 14 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Fortress { + icon = "\A3\ui_f\data\map\mapcontrol\bunker_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 16; + importance = "2 * 16 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Fountain { + icon = "\A3\ui_f\data\map\mapcontrol\fountain_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 11; + importance = "1 * 12 * 0.05"; + coefMin = 0.25; + coefMax = 4; + }; + class Ruin { + icon = "\A3\ui_f\data\map\mapcontrol\ruin_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 16; + importance = "1.2 * 16 * 0.05"; + coefMin = 1; + coefMax = 4; + }; + class Stack { + icon = "\A3\ui_f\data\map\mapcontrol\stack_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 20; + importance = "2 * 16 * 0.05"; + coefMin = 0.9; + coefMax = 4; + }; + class Tourism { + icon = "\A3\ui_f\data\map\mapcontrol\tourism_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 16; + importance = "1 * 16 * 0.05"; + coefMin = 0.7; + coefMax = 4; + }; + class ViewTower { + icon = "\A3\ui_f\data\map\mapcontrol\viewtower_ca.paa"; + color[] = {0, 0, 0, 1}; + size = 16; + importance = "2.5 * 16 * 0.05"; + coefMin = 0.5; + coefMax = 4; + }; }; #endif diff --git a/addons/common/dev/test_cfgPatches.sqf b/addons/common/dev/test_cfgPatches.sqf index 281c16eca3..e2ce10b2c6 100644 --- a/addons/common/dev/test_cfgPatches.sqf +++ b/addons/common/dev/test_cfgPatches.sqf @@ -13,7 +13,7 @@ private _allPatches = "(configName _x) select [0,3] == 'ace'" configClasses (con // Get all units[] private _allUnits = []; { - _allUnits append ((getArray (_x >> "units")) apply { toLower _x }); + _allUnits append ((getArray (_x >> "units")) apply { toLowerANSI _x }); } forEach _allPatches; { private _class = configFile >> "CfgVehicles" >> _x; @@ -31,7 +31,7 @@ private _allUnits = []; // Get all weapons[] private _allWeapons = []; { - _allWeapons append ((getArray (_x >> "weapons")) apply { toLower _x }); + _allWeapons append ((getArray (_x >> "weapons")) apply { toLowerANSI _x }); } forEach _allPatches; { private _class = configFile >> "CfgWeapons" >> _x; @@ -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 (!((toLower 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; }; @@ -60,9 +60,9 @@ private _vics = "(configName _x) select [0,3] == 'ace'" configClasses (configFil // Check if all public weapons are defined in a cfgPatch private _weapons = "(configName _x) select [0,3] == 'ace'" configClasses (configFile >> "CfgWeapons"); { - private _type = toLower configName _x; + private _type = toLowerANSI configName _x; if (((getNumber (_x >> "scope")) == 2) || {((getNumber (_x >> "scopeCurator")) == 2)}) then { - if (!((toLower 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; }; diff --git a/addons/common/dev/test_vehicleInventory.sqf b/addons/common/dev/test_vehicleInventory.sqf index 7fdd0159c0..9fb24fc1d6 100644 --- a/addons/common/dev/test_vehicleInventory.sqf +++ b/addons/common/dev/test_vehicleInventory.sqf @@ -14,7 +14,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _glassesConfig = configFile >> "CfgGlasses" >> _name; if (((!isClass _weaponConfig) || {(getNumber (_weaponConfig >> "type")) in [1,2,4]}) && {!isClass _glassesConfig}) then { diag_log text format ["%1 -> TransportItems -> %2 = Bad", _vehType, _name]; - if ("ace" in toLower (_vehType + _name)) then { _testPass = false; }; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; }; } forEach (configProperties [_x >> "TransportItems", "isClass _x", true]); @@ -23,7 +23,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _weaponConfig = configFile >> "CfgWeapons" >> _name; if ((!isClass _weaponConfig) || {!((getNumber (_weaponConfig >> "type")) in [1,2,4])}) then { diag_log text format ["%1 -> TransportWeapons -> %2 = Bad", _vehType, _name]; - if ("ace" in toLower (_vehType + _name)) then { _testPass = false; }; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; } forEach (configProperties [_x >> "TransportWeapons", "isClass _x", true]); { @@ -31,7 +31,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _magConfig = configFile >> "CfgMagazines" >> _name; if ((!isClass _magConfig)) then { diag_log text format ["%1 -> TransportMagazines -> %2 = Bad", _vehType, _name]; - if ("ace" in toLower (_vehType + _name)) then { _testPass = false; }; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; } forEach (configProperties [_x >> "TransportMagazines", "isClass _x", true]); { @@ -39,7 +39,7 @@ private _vehicles = configProperties [configFile >> "CfgVehicles", "(isClass _x) private _vehConfig = configFile >> "CfgVehicles" >> _name; if ((!isClass _vehConfig)) then { diag_log text format ["%1 -> TransportBackpacks -> %2 = Bad", _vehType, _name]; - if ("ace" in toLower (_vehType + _name)) then { _testPass = false; }; + if ("ace" in toLowerANSI (_vehType + _name)) then { _testPass = false; }; }; } forEach (configProperties [_x >> "TransportBackpacks", "isClass _x", true]); } forEach _vehicles; diff --git a/addons/common/functions/fnc_addCanInteractWithCondition.sqf b/addons/common/functions/fnc_addCanInteractWithCondition.sqf index d9c4e3335d..3dce27cf55 100644 --- a/addons/common/functions/fnc_addCanInteractWithCondition.sqf +++ b/addons/common/functions/fnc_addCanInteractWithCondition.sqf @@ -18,7 +18,7 @@ params ["_conditionName", "_conditionFunc"]; -_conditionName = toLower _conditionName; +_conditionName = toLowerANSI _conditionName; private _conditions = missionNamespace getVariable [QGVAR(InteractionConditions), [[],[]]]; _conditions params ["_conditionNames", "_conditionFuncs"]; diff --git a/addons/common/functions/fnc_addSwayFactor.sqf b/addons/common/functions/fnc_addSwayFactor.sqf index 7a258bc12a..1cdc6fb721 100644 --- a/addons/common/functions/fnc_addSwayFactor.sqf +++ b/addons/common/functions/fnc_addSwayFactor.sqf @@ -18,7 +18,7 @@ */ params ["_type", "_code", "_id"]; -_type = toLower _type; +_type = toLowerANSI _type; if !(_type in ["baseline", "multiplier"]) exitWith { ERROR_2("%1-%2 type unsupported",_type,_id); false }; diff --git a/addons/common/functions/fnc_addToInventory.sqf b/addons/common/functions/fnc_addToInventory.sqf index 39e6903390..dd561ac09e 100644 --- a/addons/common/functions/fnc_addToInventory.sqf +++ b/addons/common/functions/fnc_addToInventory.sqf @@ -112,13 +112,13 @@ switch (_type select 0) do { switch (_container) do { case "vest": { - _unit addItemToVest _classname; //@todo Bug! A full magazine, ignoring ammo. No such command. + (vestContainer _unit) addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; case "backpack": { - _unit addItemToBackpack _classname; //@todo Bug! A full magazine, ignoring ammo. No such command. + (backpackContainer _unit) addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; case "uniform": { - _unit addItemToUniform _classname; //@todo Bug! A full magazine, ignoring ammo. No such command. + (uniformContainer _unit) addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; default { _unit addMagazine [_classname, _ammoCount]; @@ -130,7 +130,7 @@ switch (_type select 0) do { private _pos = _unit modelToWorldVisual [0,1,0.05]; _unit = createVehicle ["WeaponHolder_Single_F", _pos, [], 0, "NONE"]; - _unit addMagazineCargoGlobal [_classname, 1/*_ammoCount*/]; //@todo Bug! This isn't really the ammo, but magazine count. No such command. + _unit addMagazineAmmoCargo [_classname, 1, _ammoCount]; _unit setPosATL _pos; }; }; diff --git a/addons/common/functions/fnc_adjustMagazineAmmo.sqf b/addons/common/functions/fnc_adjustMagazineAmmo.sqf new file mode 100644 index 0000000000..87d5b9e899 --- /dev/null +++ b/addons/common/functions/fnc_adjustMagazineAmmo.sqf @@ -0,0 +1,107 @@ +#include "..\script_component.hpp" +/* + * Author: Katalam, Blue, Brett Mayson, johnb43 + * Handle adjusting a magazine's ammo + * + * Arguments: + * 0: Vehicle or Unit + * 1: Item + * 2: Ammo to adjust by (default: -1) + * + * Return Value: + * How much the ammo was adjusted by + * + * Example: + * [player, "30Rnd_556x45_Stanag", 1] call ace_common_fnc_adjustMagazineAmmo; + * + * Public: No + */ + +params ["_unit", "_magazine", ["_count", -1]]; + +if (_count == 0) exitWith {0}; + +private _containers = if (_unit isKindOf "CAManBase") then { + [uniformContainer _unit, vestContainer _unit, backpackContainer _unit] +} else { + [_unit] +}; + +scopeName "main"; + +private _originalCount = _count; +private _container = objNull; +private _magazinesContainer = []; +private _newAmmoCount = 0; +private _removeAmmo = _count < 0; +private _maxMagazineAmmo = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); + +{ + _container = _x; + + // Get all magazines of _magazine type + _magazinesContainer = (magazinesAmmoCargo _container) select {_x select 0 == _magazine}; + + // Get the ammo count, filter out magazines with 0 ammo + _magazinesContainer = (_magazinesContainer apply {_x select 1}) select {_x != 0}; + + // If there are none, skip to next container + if (_magazinesContainer isEqualTo []) then { + continue; + }; + + // Sort, smallest first when removing, largest first when adding + _magazinesContainer sort _removeAmmo; + + if (_removeAmmo) then { + { + _count = _x + _count; + + _container addMagazineAmmoCargo [_magazine, -1, _x]; + + if (_count >= 0) then { + // Only add magazine back if it's not empty + if (_count != 0) then { + _container addMagazineAmmoCargo [_magazine, 1, _count]; + }; + + _originalCount breakOut "main"; + }; + } forEach _magazinesContainer; + } else { + // This loop only fills up partially filled magazines + { + // Fill the magazine to either its max or until all ammo has been added + _newAmmoCount = (_x + _count) min _maxMagazineAmmo; + + if (_newAmmoCount <= _maxMagazineAmmo) then { + _container addMagazineAmmoCargo [_magazine, -1, _x]; + _container addMagazineAmmoCargo [_magazine, 1, _newAmmoCount]; + }; + + // Remove the ammo that was added + _count = _count - (_newAmmoCount - _x); + + if (_count <= 0) then { + _originalCount breakOut "main"; + }; + } forEach (_magazinesContainer select {_x < _maxMagazineAmmo}); + }; +} forEach _containers; + +// If there is still remaining ammo to add, try add it after having iterated through all containers +if (!_removeAmmo && _count > 0) then { + { + while {_count > 0 && {_x canAdd [_magazine, 1/* 2.18 , true*/]}} do { + _x addMagazineAmmoCargo [_magazine, 1, _count]; + + _count = _count - _maxMagazineAmmo; + }; + } forEach _containers; + + if (_count <= 0) then { + _originalCount breakOut "main"; + }; +}; + +_originalCount - _count diff --git a/addons/common/functions/fnc_cachedCall.sqf b/addons/common/functions/fnc_cachedCall.sqf index 0062aec1f3..dbf81b7676 100644 --- a/addons/common/functions/fnc_cachedCall.sqf +++ b/addons/common/functions/fnc_cachedCall.sqf @@ -9,7 +9,7 @@ * 2: Namespace to store the cache on * 3: Cache uid * 4: Max duration of the cache - * 5: Event that clears the cache (default: nil) + * 5: Events that clear the cache (default: nil) * * Return Value: * Result of the function @@ -20,41 +20,46 @@ * Public: No */ -params ["_params", "_function", "_namespace", "_uid", "_duration", "_event"]; +params ["_params", "_function", "_namespace", "_uid", "_duration", "_events"]; if ((_namespace getVariable [_uid, [-99999]]) select 0 < diag_tickTime) then { _namespace setVariable [_uid, [diag_tickTime + _duration, _params call _function]]; // Does the cache need to be cleared on an event? - if (!isNil "_event") then { - private _varName = format [QGVAR(clearCache_%1), _event]; - private _cacheList = missionNamespace getVariable _varName; - - // If there was no EH to clear these caches, add one - if (isNil "_cacheList") then { - _cacheList = []; - missionNamespace setVariable [_varName, _cacheList]; - - [_event, { - #ifdef DEBUG_MODE_FULL - INFO_1("Clear cached variables on event: %1",_eventName); - #endif - // Get the list of caches to clear - //IGNORE_PRIVATE_WARNING ["_eventName"]; - // _eventName is defined on the function that calls the event - private _varName = format [QGVAR(clearCache_%1), _eventName]; - private _cacheList = missionNamespace getVariable [_varName, []]; - // Erase all the cached results - { - _x call FUNC(eraseCache); - } forEach _cacheList; - // Empty the list - missionNamespace setVariable [_varName, []]; - }] call CBA_fnc_addEventHandler; + if (!isNil "_events") then { + if (_events isEqualType "") then { + _events = [_events]; }; + { + private _event = _x; + private _varName = format [QGVAR(clearCache_%1), _event]; + private _cacheList = missionNamespace getVariable _varName; - // Add this cache to the list of the event - _cacheList pushBack [_namespace, _uid]; + // If there was no EH to clear these caches, add one + if (isNil "_cacheList") then { + _cacheList = []; + missionNamespace setVariable [_varName, _cacheList]; + + [_event, { + #ifdef DEBUG_MODE_FULL + INFO_1("Clear cached variables on event: %1",_eventName); + #endif + // Get the list of caches to clear + //IGNORE_PRIVATE_WARNING ["_eventName"]; + // _eventName is defined on the function that calls the event + private _varName = format [QGVAR(clearCache_%1), _eventName]; + private _cacheList = missionNamespace getVariable [_varName, []]; + // Erase all the cached results + { + _x call FUNC(eraseCache); + } forEach _cacheList; + // Empty the list + missionNamespace setVariable [_varName, []]; + }] call CBA_fnc_addEventHandler; + }; + // Add this cache to the list of the event + _cacheList pushBack [_namespace, _uid]; + } forEach _events; }; #ifdef DEBUG_MODE_FULL diff --git a/addons/common/functions/fnc_canGetInPosition.sqf b/addons/common/functions/fnc_canGetInPosition.sqf index d78e623d7b..777f3103a5 100644 --- a/addons/common/functions/fnc_canGetInPosition.sqf +++ b/addons/common/functions/fnc_canGetInPosition.sqf @@ -24,7 +24,7 @@ params ["_unit", "_vehicle", "_position", ["_checkDistance", false], ["_index", -1]]; -_position = toLower _position; +_position = toLowerANSI _position; // general if (!alive _vehicle || {locked _vehicle > 1}) exitWith {false}; diff --git a/addons/common/functions/fnc_canInteractWith.sqf b/addons/common/functions/fnc_canInteractWith.sqf index 4cbcb1c19d..dd684d0619 100644 --- a/addons/common/functions/fnc_canInteractWith.sqf +++ b/addons/common/functions/fnc_canInteractWith.sqf @@ -19,7 +19,7 @@ params ["_unit", "_target", ["_exceptions", []]]; -_exceptions = _exceptions apply {toLower _x}; +_exceptions = _exceptions apply {toLowerANSI _x}; private _owner = _target getVariable [QGVAR(owner), objNull]; diff --git a/addons/common/functions/fnc_cbaSettings.sqf b/addons/common/functions/fnc_cbaSettings.sqf index 3e6f66fa42..6be8f60505 100644 --- a/addons/common/functions/fnc_cbaSettings.sqf +++ b/addons/common/functions/fnc_cbaSettings.sqf @@ -104,7 +104,7 @@ TRACE_1("Reading settings from missionConfigFile",_countOptions); for "_index" from 0 to (_countOptions - 1) do { private _optionEntry = _missionSettingsConfig select _index; private _settingName = configName _optionEntry; - if ((toLower _settingName) in GVAR(cbaSettings_forcedSettings)) then { + if ((toLowerANSI _settingName) in GVAR(cbaSettings_forcedSettings)) then { WARNING_1("Setting [%1] - Already Forced - ignoring missionConfig",_varName); } else { if ((isNil _settingName) && {(getNumber (_settingsConfig >> _settingName >> "movedToSQF")) == 0}) then { diff --git a/addons/common/functions/fnc_cbaSettings_convertHelper.sqf b/addons/common/functions/fnc_cbaSettings_convertHelper.sqf index b7ef446cf6..02fdfa0193 100644 --- a/addons/common/functions/fnc_cbaSettings_convertHelper.sqf +++ b/addons/common/functions/fnc_cbaSettings_convertHelper.sqf @@ -44,7 +44,7 @@ private _settings = configProperties [configFile >> "ACE_Settings", "(isClass _x private _cbaIsGlobal = (!_isClientSettable) || _isForced; private _warnIfChangedMidMission = _cbaIsGlobal && {(getNumber (_config >> "canBeChanged")) == 0}; - if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLower _varName);}; + if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLowerANSI _varName);}; // Basic handling of setting types CBA doesn't support: if (_typeName == "ARRAY") exitWith { diff --git a/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf b/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf index d3a6f29f84..57b93c9963 100644 --- a/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf +++ b/addons/common/functions/fnc_cbaSettings_loadFromConfig.sqf @@ -34,7 +34,7 @@ private _category = getText (_config >> "category"); private _cbaIsGlobal = (!_isClientSettable) || _isForced; private _warnIfChangedMidMission = _cbaIsGlobal && {(getNumber (_config >> "canBeChanged")) == 0}; -if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLower _varName);}; +if (_isForced) then {GVAR(cbaSettings_forcedSettings) pushBack (toLowerANSI _varName);}; // Basic handling of setting types CBA doesn't support: if (_typeName == "ARRAY") exitWith { @@ -103,4 +103,3 @@ private _return = [_varName, _cbaSettingType, [_localizedName, _localizedDescrip TRACE_1("returned",_return); if ((isNil "_return") || {!_return}) then {ERROR_1("Setting [%1] - CBA Error",_varName);}; _return - diff --git a/addons/common/functions/fnc_checkFiles.sqf b/addons/common/functions/fnc_checkFiles.sqf index 47de2290dd..39e2bac3ac 100644 --- a/addons/common/functions/fnc_checkFiles.sqf +++ b/addons/common/functions/fnc_checkFiles.sqf @@ -40,7 +40,7 @@ if ([_cbaRequiredAr, _cbaVersionAr] call cba_versioning_fnc_version_compare) the }; //private _addons = activatedAddons; // broken with High-Command module, see #2134 -private _addons = (cba_common_addons select {(_x select [0,4]) == "ace_"}) apply {toLower _x}; +private _addons = (cba_common_addons select {(_x select [0,4]) == "ace_"}) apply {toLowerANSI _x}; private _oldAddons = []; private _oldSources = []; private _oldCompats = []; @@ -87,7 +87,7 @@ if (_oldCompats isNotEqualTo []) then { /////////////// // check extensions /////////////// -private _platform = toLower (productVersion select 6); +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"); diff --git a/addons/common/functions/fnc_checkPBOs.sqf b/addons/common/functions/fnc_checkPBOs.sqf index f69f486d5e..cb192c6667 100644 --- a/addons/common/functions/fnc_checkPBOs.sqf +++ b/addons/common/functions/fnc_checkPBOs.sqf @@ -25,7 +25,7 @@ params ["_mode", ["_checkAll", false], ["_whitelist", "", [""]]]; TRACE_3("params",_mode,_checkAll,_whitelist); //lowercase and convert whiteList String into array of strings: -_whitelist = toLower _whitelist; +_whitelist = toLowerANSI _whitelist; _whitelist = _whitelist splitString "[,""']"; TRACE_1("Array",_whitelist); diff --git a/addons/common/functions/fnc_disableUserInput.sqf b/addons/common/functions/fnc_disableUserInput.sqf index 3774a3fc29..8db3c7e811 100644 --- a/addons/common/functions/fnc_disableUserInput.sqf +++ b/addons/common/functions/fnc_disableUserInput.sqf @@ -95,7 +95,7 @@ if (_state) then { // Check if the necessary keys were pressed for a keybind _return = _comboDikPressed && {_mainDevice == "KEYBOARD"} && - {((GVAR(keyboardInputMain) getOrDefault [_mainDik, [false, 0]]) select 1) > ([0, 1] select _isDoubleTap)}; // check how many times the main key was pressed + {((GVAR(keyboardInputMain) getOrDefault [_mainDik, [false, 0]]) select 1) > (parseNumber _isDoubleTap)}; // check how many times the main key was pressed // Keybind was detected if (_return) exitWith { diff --git a/addons/common/functions/fnc_getConfigName.sqf b/addons/common/functions/fnc_getConfigName.sqf index 54ebf84343..3495014d55 100644 --- a/addons/common/functions/fnc_getConfigName.sqf +++ b/addons/common/functions/fnc_getConfigName.sqf @@ -17,7 +17,7 @@ params ["_className"]; -(uiNamespace getVariable QGVAR(configNames)) getOrDefaultCall [toLower _className, { +(uiNamespace getVariable QGVAR(configNames)) getOrDefaultCall [toLowerANSI _className, { private _config = configNull; { diff --git a/addons/common/functions/fnc_getCountOfItem.sqf b/addons/common/functions/fnc_getCountOfItem.sqf index 5667b6c980..5114f375d2 100644 --- a/addons/common/functions/fnc_getCountOfItem.sqf +++ b/addons/common/functions/fnc_getCountOfItem.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Dedmen + * Author: Dedmen, Blue, johnb43 * Return how many items of type _itemType the player has in his containers (Uniform, Vest, Backpack) * Doesn't count assignedItems, weapons, weapon attachments, magazines in weapons * @@ -19,13 +19,17 @@ params ["_unit", "_itemType"]; -private _countItemsInContainer = { - (getItemCargo _this) params ["_itemTypes", "_itemCounts"]; +private _count = 0; +private _isMagazine = isClass (configFile >> "CfgMagazines" >> _itemType); - private _index = _itemTypes find _itemType; - _itemCounts param [_index, 0] -}; +{ + (if (_isMagazine) then { + getMagazineCargo _x + } else { + getItemCargo _x + }) params ["_itemTypes", "_itemCounts"]; -((uniformContainer _unit) call _countItemsInContainer) + -((vestContainer _unit) call _countItemsInContainer) + -((backpackContainer _unit) call _countItemsInContainer) + _count = _count + (_itemCounts param [_itemTypes find _itemType, 0]); +} forEach [uniformContainer _unit, vestContainer _unit, backpackContainer _unit]; + +_count diff --git a/addons/common/functions/fnc_getDefaultAnim.sqf b/addons/common/functions/fnc_getDefaultAnim.sqf index 788fd2b6bd..bd294ba0c0 100644 --- a/addons/common/functions/fnc_getDefaultAnim.sqf +++ b/addons/common/functions/fnc_getDefaultAnim.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -private _anim = toLower animationState _unit; +private _anim = toLowerANSI animationState _unit; // stance is broken for some animations. private _stance = stance _unit; diff --git a/addons/common/functions/fnc_getGunner.sqf b/addons/common/functions/fnc_getGunner.sqf index ffa0334a26..bb3ebb23e9 100644 --- a/addons/common/functions/fnc_getGunner.sqf +++ b/addons/common/functions/fnc_getGunner.sqf @@ -19,7 +19,7 @@ params [["_vehicle", objNull, [objNull]], ["_weapon", "", [""]]]; // on foot -if (gunner _vehicle == _vehicle && {_weapon in weapons _vehicle || {toLower _weapon in ["throw", "put"]}}) exitWith {gunner _vehicle}; +if (gunner _vehicle == _vehicle && {_weapon in weapons _vehicle || {toLowerANSI _weapon in ["throw", "put"]}}) exitWith {gunner _vehicle}; // inside vehicle private _gunner = objNull; diff --git a/addons/common/functions/fnc_getInPosition.sqf b/addons/common/functions/fnc_getInPosition.sqf index fdbad3ee4a..6a95725e6e 100644 --- a/addons/common/functions/fnc_getInPosition.sqf +++ b/addons/common/functions/fnc_getInPosition.sqf @@ -23,7 +23,7 @@ params ["_unit", "_vehicle", "_position", ["_index", -1]]; -_position = toLower _position; +_position = toLowerANSI _position; // general if (!alive _vehicle || {locked _vehicle > 1}) exitWith {false}; diff --git a/addons/common/functions/fnc_getItemType.sqf b/addons/common/functions/fnc_getItemType.sqf index e39605f0cc..49f1b757da 100644 --- a/addons/common/functions/fnc_getItemType.sqf +++ b/addons/common/functions/fnc_getItemType.sqf @@ -67,7 +67,7 @@ switch (true) do { case (_type == TYPE_UNIFORM): {["item", "uniform"]}; case (_type == TYPE_BINOCULAR_AND_NVG): { - switch (toLower _simulation) do { + switch (toLowerANSI _simulation) do { case ("weapon"): {["weapon", "binocular"]}; case ("binocular"): {["weapon", "binocular"]}; case ("nvgoggles"): {["item", "nvgoggles"]}; @@ -78,7 +78,7 @@ switch (true) do { case (_type == TYPE_WEAPON_VEHICLE): {["weapon", "vehicle"]}; case (_type == TYPE_ITEM): { - switch (toLower _simulation) do { + switch (toLowerANSI _simulation) do { case ("itemmap"): {["item", "map"]}; case ("itemgps"): {["item", "gps"]}; case ("itemradio"): {["item", "radio"]}; diff --git a/addons/common/functions/fnc_getMapData.sqf b/addons/common/functions/fnc_getMapData.sqf index b4cb56d75f..379210ec8f 100644 --- a/addons/common/functions/fnc_getMapData.sqf +++ b/addons/common/functions/fnc_getMapData.sqf @@ -16,7 +16,7 @@ */ params ["_map"]; -_map = toLower _map; +_map = toLowerANSI _map; // [latitude, altitude] diff --git a/addons/common/functions/fnc_getMapGridData.sqf b/addons/common/functions/fnc_getMapGridData.sqf index f37e146288..bce6351af0 100644 --- a/addons/common/functions/fnc_getMapGridData.sqf +++ b/addons/common/functions/fnc_getMapGridData.sqf @@ -43,8 +43,8 @@ private _stepY = 1e10; private _letterGrid = false; -if (toLower _formatX find "a" != -1) then {_letterGrid = true}; -if (toLower _formatY find "a" != -1) then {_letterGrid = true}; +if (toLowerANSI _formatX find "a" != -1) then {_letterGrid = true}; +if (toLowerANSI _formatY find "a" != -1) then {_letterGrid = true}; if (_letterGrid) exitWith { WARNING_3("Map Grid Warning (%1) - Map uses letter grids [%2, %3]",worldName,_formatX,_formatY); diff --git a/addons/common/functions/fnc_getVehicleCrew.sqf b/addons/common/functions/fnc_getVehicleCrew.sqf index 00a90b1ab2..3e5e015785 100644 --- a/addons/common/functions/fnc_getVehicleCrew.sqf +++ b/addons/common/functions/fnc_getVehicleCrew.sqf @@ -29,7 +29,7 @@ private _crew = []; }; } else { // otherwise check if we search for that type. toLower, because fullCrew returns "driver" vs. "Turret". - if (toLower (_x select 1) in _types) then { + if (toLowerANSI (_x select 1) in _types) then { _crew pushBack (_x select 0); }; }; diff --git a/addons/common/functions/fnc_getVehicleIcon.sqf b/addons/common/functions/fnc_getVehicleIcon.sqf index 208bb144d8..c63d54a8d8 100644 --- a/addons/common/functions/fnc_getVehicleIcon.sqf +++ b/addons/common/functions/fnc_getVehicleIcon.sqf @@ -32,7 +32,7 @@ if (isNil "_cachedValue") then { private _vehicleIconValue = getText (configfile >> "CfgVehicleIcons" >> _vehicleValue); if (_vehicleIconValue == "") then { - if (_vehicleValue != "" && {((toLower _vehicleValue) find ".paa") > -1}) then { + if (_vehicleValue != "" && {((toLowerANSI _vehicleValue) find ".paa") > -1}) then { _cachedValue = _vehicleValue; } else { _cachedValue = DEFAULT_TEXTURE; diff --git a/addons/common/functions/fnc_playConfigSound3D.sqf b/addons/common/functions/fnc_playConfigSound3D.sqf index 788a2a6b4e..1069cf0f18 100644 --- a/addons/common/functions/fnc_playConfigSound3D.sqf +++ b/addons/common/functions/fnc_playConfigSound3D.sqf @@ -35,7 +35,7 @@ ISNILS(_distance,_cfgDistance); _fileName = _fileName select [1]; // add file extension .wss as default -if !(toLower (_fileName select [count _fileName - 4]) in [".wav", ".ogg", ".wss"]) then { +if !(toLowerANSI (_fileName select [count _fileName - 4]) in [".wav", ".ogg", ".wss"]) then { ADD(_fileName,".wss"); }; TRACE_5("vars",_fileName,_posASL,_volume,_pitch,_distance); diff --git a/addons/common/functions/fnc_removeCanInteractWithCondition.sqf b/addons/common/functions/fnc_removeCanInteractWithCondition.sqf index 9cc3fda3c3..6c5e8b56b6 100644 --- a/addons/common/functions/fnc_removeCanInteractWithCondition.sqf +++ b/addons/common/functions/fnc_removeCanInteractWithCondition.sqf @@ -17,7 +17,7 @@ params ["_conditionName"]; -_conditionName = toLower _conditionName; +_conditionName = toLowerANSI _conditionName; private _conditions = missionNamespace getVariable [QGVAR(InteractionConditions), [[],[]]]; diff --git a/addons/common/functions/fnc_rscObjectHelper.sqf b/addons/common/functions/fnc_rscObjectHelper.sqf index c7d1342de9..95ddb2f74b 100644 --- a/addons/common/functions/fnc_rscObjectHelper.sqf +++ b/addons/common/functions/fnc_rscObjectHelper.sqf @@ -30,7 +30,7 @@ private _bottomRightY = 1; private _return = []; -switch (toLower _func) do { +switch (toLowerANSI _func) do { case ("2d"): { _array params ["_pointX", "_z", "_pointY"]; diff --git a/addons/common/functions/fnc_statusEffect_addType.sqf b/addons/common/functions/fnc_statusEffect_addType.sqf index c7bd61762e..5535b0d914 100644 --- a/addons/common/functions/fnc_statusEffect_addType.sqf +++ b/addons/common/functions/fnc_statusEffect_addType.sqf @@ -32,6 +32,6 @@ GVAR(statusEffect_sendJIP) pushBack _sendJIP; //We add reasons at any time, but more efficenet to add all common ones at one time during init if (isServer && {_commonReasonsArray isNotEqualTo []}) then { //Switch case to lower: - _commonReasonsArray = _commonReasonsArray apply { toLower _x }; + _commonReasonsArray = _commonReasonsArray apply { toLowerANSI _x }; missionNamespace setVariable [(format [QGVAR(statusEffects_%1), _name]), _commonReasonsArray, true]; }; diff --git a/addons/common/functions/fnc_statusEffect_set.sqf b/addons/common/functions/fnc_statusEffect_set.sqf index 6e8a74bd3e..a4bf352a56 100644 --- a/addons/common/functions/fnc_statusEffect_set.sqf +++ b/addons/common/functions/fnc_statusEffect_set.sqf @@ -32,7 +32,7 @@ if (isNull _object) exitWith {TRACE_1("null",_object);}; [_object, true] call FUNC(statusEffect_resetVariables); //Check for mismatch, and set object ref //check ID case and set globally if not already set: -_ID = toLower _ID; +_ID = toLowerANSI _ID; private _statusReasons = missionNamespace getVariable [(format [QGVAR(statusEffects_%1), _effectName]), []]; private _statusIndex = _statusReasons find _ID; if (_statusIndex == -1) then { diff --git a/addons/common/functions/fnc_uniqueItems.sqf b/addons/common/functions/fnc_uniqueItems.sqf index dc783ebbea..204501ca3f 100644 --- a/addons/common/functions/fnc_uniqueItems.sqf +++ b/addons/common/functions/fnc_uniqueItems.sqf @@ -1,37 +1,84 @@ #include "..\script_component.hpp" /* - * Author: mharis001 - * Returns list of unique items in a unit's inventory. - * Items are cached if unit is ACE_player. + * Author: mharis001, Blue, Brett Mayson + * Returns list of unique items in the target's inventory. * * Arguments: - * 0: Unit + * 0: Target + * 1: Include magazines + * 0: No (default) + * 1: Yes + * 2: Only magazines * * Return Value: * Items * * Example: - * [player] call ace_common_fnc_uniqueItems + * [player, 2] call ace_common_fnc_uniqueItems * * Public: No */ -params ["_unit"]; +params ["_target", ["_includeMagazines", 0]]; private _fnc_getItems = { - private _items = (getItemCargo uniformContainer _unit) select 0; - _items append ((getItemCargo vestContainer _unit) select 0); - _items append ((getItemCargo backpackContainer _unit) select 0); + private _items = []; + + private _inventoryItems = (getItemCargo uniformContainer _target) select 0; + _inventoryItems append ((getItemCargo vestContainer _target) select 0); + _inventoryItems append ((getItemCargo backpackContainer _target) select 0); + + _items set [0, _inventoryItems]; + _items set [1, magazines _target]; _items arrayIntersect _items }; -// Use cached items list if unit is ACE_player -if (_unit isEqualTo ACE_player) then { +// Cache items list if unit is ACE_player +if (_target isEqualTo ACE_player) then { if (isNil QGVAR(uniqueItemsCache)) then { GVAR(uniqueItemsCache) = call _fnc_getItems; }; - +GVAR(uniqueItemsCache) + + switch (_includeMagazines) do { + case 0: { + GVAR(uniqueItemsCache) select 0 + }; + case 1: { + (GVAR(uniqueItemsCache) select 1) + (GVAR(uniqueItemsCache) select 0) + }; + case 2: { + GVAR(uniqueItemsCache) select 1 + }; + }; } else { - call _fnc_getItems; + if (_target isKindOf "CAManBase") then { + private _items = call _fnc_getItems; + + switch (_includeMagazines) do { + case 0: { + _items select 0 + }; + case 1: { + (_items select 1) + (_items select 0) + }; + case 2: { + _items select 1 + }; + }; + } else { + private _items = switch (_includeMagazines) do { + case 0: { + itemCargo _target + }; + case 1: { + (magazineCargo _target) + (itemCargo _target) + }; + case 2: { + magazineCargo _target + }; + }; + + _items arrayIntersect _items + }; }; diff --git a/addons/common/scripts/checkVersionNumber.sqf b/addons/common/scripts/checkVersionNumber.sqf index 0f2c055500..3ed51120b6 100644 --- a/addons/common/scripts/checkVersionNumber.sqf +++ b/addons/common/scripts/checkVersionNumber.sqf @@ -5,7 +5,7 @@ private _aceWhitelist = missionNamespace getVariable ["ACE_Version_Whitelist", [ private _files = CBA_common_addons select { (_x select [0,3] != "a3_") && {_x select [0,4] != "ace_"} && - {!((toLower _x) in _aceWhitelist)} + {!((toLowerANSI _x) in _aceWhitelist)} }; private _versions = []; diff --git a/addons/compat_cup_terrains/addon.toml b/addons/compat_cup_terrains/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/compat_cup_terrains/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/compat_cup_terrains/config.cpp b/addons/compat_cup_terrains/config.cpp index a7020be4da..ab58974a32 100644 --- a/addons/compat_cup_terrains/config.cpp +++ b/addons/compat_cup_terrains/config.cpp @@ -1,6 +1,15 @@ #include "script_component.hpp" #include "\z\ace\addons\refuel\defines.hpp" +// Remove after next cup release +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\cup\CUP_Terrains_ACE_compat\config.bin") +#define PATCH_SKIP "CUP_Terrains_ACE_compat" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else class CfgPatches { class ADDON { name = COMPONENT_NAME; @@ -25,3 +34,5 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgEventHandlers.hpp" + +#endif diff --git a/addons/compat_cup_vehicles/$PBOPREFIX$ b/addons/compat_cup_vehicles/$PBOPREFIX$ new file mode 100644 index 0000000000..da4cebbc16 --- /dev/null +++ b/addons/compat_cup_vehicles/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_cup_vehicles diff --git a/addons/compat_cup_vehicles/CfgEventHandlers.hpp b/addons/compat_cup_vehicles/CfgEventHandlers.hpp new file mode 100644 index 0000000000..f6503c2479 --- /dev/null +++ b/addons/compat_cup_vehicles/CfgEventHandlers.hpp @@ -0,0 +1,17 @@ +class Extended_PreStart_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); + }; +}; + +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/compat_cup_vehicles/CfgVehicles.hpp b/addons/compat_cup_vehicles/CfgVehicles.hpp new file mode 100644 index 0000000000..47c7f901f5 --- /dev/null +++ b/addons/compat_cup_vehicles/CfgVehicles.hpp @@ -0,0 +1,152 @@ +class CfgVehicles { + class CUP_MTVR_Base; + class CUP_MTVR_Reammo_Base: CUP_MTVR_Base { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class CUP_V3S_Open_Base; + class CUP_V3S_Rearm_Base: CUP_V3S_Open_Base { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class CUP_Kamaz_5350_Base; + class CUP_Kamaz_5350_ReAmmo_Base: CUP_Kamaz_5350_Base { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class CUP_T810_Unarmed_Base; + class CUP_T810_Reammo_Base: CUP_T810_Unarmed_Base { + EGVAR(rearm,defaultSupply) = 1200; + }; + + class Wheeled_APC_F; + class CUP_BTR80_Common_Base: Wheeled_APC_F { + class ace_viewports { + class view_0 { + camLocation[] = {0.734863, 0.143927, -0.291199}; + camAttach = 45; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_1 { + camLocation[] = {0.950684, -0.00122738, -0.344391}; + camAttach = 90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_2 { + camLocation[] = {0.932129, -0.729811, -0.319}; + camAttach = 90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_3 { + camLocation[] = {-0.963379, -0.749183, -0.351501}; + camAttach = -90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_4 { + camLocation[] = {-0.973145, 0.0148516, -0.364868}; + camAttach = -90; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_5 { + camLocation[] = {-0.73584, 0.119176, -0.291229}; + camAttach = -45; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + }; + }; + class CUP_BTR90_Base: Wheeled_APC_F { + class ace_viewports { + class view_0 { + camLocation[] = {0.533417, 2.4613, -0.309951}; + camAttach = 0; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_1 { + camLocation[] = {0.877106, 2.38684, -0.306068}; + camAttach = 30; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_2 { + camLocation[] = {1.04312, 0.0909424, -0.281996}; + camAttach = 60; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_3 { + type = ""; + camLocation[] = {1.03799, -0.928223, -0.282196}; + camAttach = 80; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_4 { + type = ""; + camLocation[] = {-0.90097, -0.913086, -0.282192}; + camAttach = -80; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + class view_5 { + type = ""; + camLocation[] = {-0.939301, 0.109985, -0.281992}; + camAttach = -60; + compartments[]={"Compartment1"}; + roles[]={"cargo"}; + }; + }; + }; + class CUP_BTR90_HQ_Base: CUP_BTR90_Base { delete ace_viewports; }; // no cargo seats + + class Tank_F; + class CUP_M2Bradley_Base: Tank_F { + ace_hunterkiller = 1; + class ace_viewports { + class view_0 { + camLocation[] = {0.987915, -0.324707, -0.0673385}; + camAttach = 70; + roles[]={"cargo"}; + }; + class view_1 { + camLocation[] = {0.90979, -0.970215, -0.043139}; + camAttach = 120; + roles[]={"cargo"}; + }; + class view_2 { + camLocation[] = {0.328003, -1.87402, -0.0408039}; + camAttach = 160; + roles[]={"cargo"}; + }; + class view_3 { + camLocation[] = {-0.357178, -1.89063, -0.0480237}; + camAttach = 175; + roles[]={"cargo"}; + }; + class view_4 { + camLocation[] = {-0.752075, -1.87061, -0.0522318}; + camAttach = 190; + roles[]={"cargo"}; + }; + class view_5 { + camLocation[] = {-0.936401, -0.0942383, -0.107764}; + camAttach = -75; + roles[]={"cargo"}; + }; + class SLD { // suppose to only be only on A3, but the A2s have the screen on the model? + screenLocation[] = {0.729126,-0.191597,-0.573349}; + maxDistance = 5; + type = "screen"; + camLocation[] = {0,0,0.05}; + camAttach[] = {0,0}; + roles[]={"cargo"}; + }; + }; + }; +}; diff --git a/addons/compat_cup_vehicles/XEH_PREP.hpp b/addons/compat_cup_vehicles/XEH_PREP.hpp new file mode 100644 index 0000000000..20674eee81 --- /dev/null +++ b/addons/compat_cup_vehicles/XEH_PREP.hpp @@ -0,0 +1,4 @@ +PREP(onCutHC3); +PREP(onCutUH1Y); +PREP(onPrepareHC3); +PREP(onPrepareUH1Y); diff --git a/addons/compat_cup_vehicles/XEH_postInit.sqf b/addons/compat_cup_vehicles/XEH_postInit.sqf new file mode 100644 index 0000000000..09bda76106 --- /dev/null +++ b/addons/compat_cup_vehicles/XEH_postInit.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +if (["CUP_Vehicles_ACE_compat"] call EFUNC(common,isModLoaded)) exitWith { + ERROR_WITH_TITLE("Duplicate CUP/ACE Compats","Compats are now part of ACE - Uninstall 'CUP ACE3 Compatibility Addon - Vehicles'"); +}; diff --git a/addons/compat_cup_vehicles/XEH_preInit.sqf b/addons/compat_cup_vehicles/XEH_preInit.sqf new file mode 100644 index 0000000000..b47cf6628d --- /dev/null +++ b/addons/compat_cup_vehicles/XEH_preInit.sqf @@ -0,0 +1,9 @@ +#include "script_component.hpp" + +ADDON = false; + +PREP_RECOMPILE_START; +#include "XEH_PREP.hpp" +PREP_RECOMPILE_END; + +ADDON = true; diff --git a/addons/compat_cup_vehicles/XEH_preStart.sqf b/addons/compat_cup_vehicles/XEH_preStart.sqf new file mode 100644 index 0000000000..022888575e --- /dev/null +++ b/addons/compat_cup_vehicles/XEH_preStart.sqf @@ -0,0 +1,3 @@ +#include "script_component.hpp" + +#include "XEH_PREP.hpp" diff --git a/addons/compat_cup_vehicles/addon.toml b/addons/compat_cup_vehicles/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/compat_cup_vehicles/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/CfgVehicles.hpp b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/CfgVehicles.hpp new file mode 100644 index 0000000000..168fdcc8d2 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/CfgVehicles.hpp @@ -0,0 +1,143 @@ +class CfgVehicles { + class CUP_AH6_BASE; + class CUP_MH6_TRANSPORT: CUP_AH6_BASE { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + }; + class CUP_B_MH6M_OBS_USA: CUP_MH6_TRANSPORT { + EGVAR(fastroping,enabled) = 0; + }; + class CUP_B_MH6J_OBS_USA: CUP_MH6_TRANSPORT { + EGVAR(fastroping,enabled) = 0; + }; + + class Helicopter_Base_H; + class CUP_AW159_Unarmed_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 2; + EGVAR(fastroping,friesType) = "ACE_friesGantry"; + EGVAR(fastroping,friesAttachmentPoint)[] = {1.05, 1, 1.3}; + EGVAR(fastroping,onCut) = QEFUNC(fastroping,onCutCommon); + EGVAR(fastroping,onPrepare) = QEFUNC(fastroping,onPrepareCommon); + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + EQUIP_FRIES_ATTRIBUTE; + + class UserActions { + class CloseRdoor { + condition = QUOTE(this doorPhase 'CargoDoorR' > 0.5 && ((this getCargoIndex player) isEqualTo 0) && !(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])); + }; + }; + }; + + class CUP_CH47F_base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight", "ropeOriginMid"}; + }; + + class CUP_CH53E_base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + + class UserActions { + class RampClose { + condition = QUOTE(this animationPhase 'ramp_bottom' >= 0.56 && player == driver this && !(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])); + }; + }; + }; + + class CUP_Merlin_HC3_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginRight"}; + EGVAR(fastroping,onPrepare) = QEFUNC(compat_cup_vehicles,onPrepareHC3); + EGVAR(fastroping,onCut) = QEFUNC(compat_cup_vehicles,onCutHC3); + + class UserActions { + class CloseRdoor { + condition = QUOTE(this doorPhase 'dvere_p' > 0.5 && {(this getCargoIndex player) isEqualTo 0} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); + }; + class OutWinch { + condition = "false"; + }; + class InWinch { + condition = "false"; + }; + }; + }; + + class CUP_Ka60_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + }; + + class CUP_MH60S_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginRight"}; + + class UserActions { + class OpenDoors; + class CloseDoors: OpenDoors { + condition = QUOTE(this animationPhase 'doors' > 0.5 && driver this == player && alive (this) && !(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])); + }; + }; + }; + + class CUP_Mi8_base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft"}; + }; + + class CUP_Mi8_medevac_base: CUP_Mi8_base { + EGVAR(fastroping,enabled) = 0; + }; + + class CUP_Mi171Sh_Base: CUP_Mi8_base { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + }; + + class CUP_SA330_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + + class UserActions { + class CloseRdoor { + condition = QUOTE(alive this && {this doorPhase 'ofrp_puma_porte_droite' > 0.5} && {(this getCargoIndex player) isEqualTo 0} && {!(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])}); + }; + class CloseLdoor { + condition = QUOTE(alive this && {this doorPhase 'ofrp_puma_porte_gauche' > 0.5} && {(this getCargoIndex player) isEqualTo 1} && !(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])); + }; + }; + }; + + class CUP_UH1H_base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 2; + EGVAR(fastroping,friesType) = "ACE_friesAnchorBar"; + EGVAR(fastroping,friesAttachmentPoint)[] = {0, 1.45, -0.3}; + EGVAR(fastroping,onCut) = QEFUNC(fastroping,onCutCommon); + EGVAR(fastroping,onPrepare) = QEFUNC(fastroping,onPrepareCommon); + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + EQUIP_FRIES_ATTRIBUTE; + }; + + class CUP_B_UH1Y_Base; + class CUP_B_UH1Y_UNA_USMC: CUP_B_UH1Y_Base { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginLeft", "ropeOriginRight"}; + EGVAR(fastroping,onPrepare) = QEFUNC(compat_cup_vehicles,onPrepareUH1Y); + EGVAR(fastroping,onCut) = QEFUNC(compat_cup_vehicles,onCutUH1Y); + }; + class CUP_B_UH1Y_MEV_USMC: CUP_B_UH1Y_UNA_USMC { + EGVAR(fastroping,enabled) = 0; + }; + + class CUP_UH60_Base: Helicopter_Base_H { + EGVAR(fastroping,enabled) = 1; + EGVAR(fastroping,ropeOrigins)[] = {"ropeOriginRight"}; + + class UserActions { + class OpenDoors; + class CloseDoors: OpenDoors { + condition = QUOTE(this animationPhase 'doors' > 0.5 && driver this == player && alive (this) && !(this getVariable [ARR_2(QUOTE(QEGVAR(fastroping,doorsLocked)),false)])); + }; + }; + }; +}; diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp new file mode 100644 index 0000000000..1abe0de6ea --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Vehicles_LoadOrder", + "ace_fastroping" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Community Upgrade Project", "Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/script_component.hpp b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/script_component.hpp new file mode 100644 index 0000000000..a3a1b47a32 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_fastroping/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT fastroping +#define SUBCOMPONENT_BEAUTIFIED Fastroping +#include "..\script_component.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp new file mode 100644 index 0000000000..186690908c --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp @@ -0,0 +1,36 @@ +class CfgVehicles { + class CUP_T810_Unarmed_Base; + class CUP_T810_Refuel_Base: CUP_T810_Unarmed_Base { + transportFuel = 0; + EGVAR(refuel,hooks)[] = {{-1.01, 0.21, -0.5},{1.08, 0.2, -0.5}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + + class Truck_02_fuel_base_F; + class CUP_Kamaz_5350_Refuel_Base: Truck_02_fuel_base_F { + transportFuel = 0; + EGVAR(refuel,hooks)[] = {{-0.02, -3.33, -1.05}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + + class CUP_Ural_Support_Base; + class CUP_Ural_Refuel_Base: CUP_Ural_Support_Base { + transportFuel = 0; + EGVAR(refuel,hooks)[] = {{-0.05, -3.65, -0.42}}; + EGVAR(refuel,fuelCargo) = 10000; + }; + + class CUP_V3S_Open_Base; + class CUP_V3S_Refuel_Base: CUP_V3S_Open_Base { + transportFuel = 0; + EGVAR(refuel,hooks)[] = {{-0.35, -3.35, -0.4},{0.40, -3.35, -0.4}}; + EGVAR(refuel,fuelCargo) = 6500; + }; + + class CUP_MTVR_Base; + class CUP_MTVR_Refuel_Base: CUP_MTVR_Base { + transportFuel = 0; + EGVAR(refuel,hooks)[] = {{-1.09, -0.01, -0.5},{1, -0.01, -0.5}}; + EGVAR(refuel,fuelCargo) = 10000; + }; +}; diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/config.cpp b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/config.cpp new file mode 100644 index 0000000000..f77c9903b9 --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Vehicles_LoadOrder", + "ace_refuel" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Community Upgrade Project", "Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/script_component.hpp b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/script_component.hpp new file mode 100644 index 0000000000..b58db9432d --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT refuel +#define SUBCOMPONENT_BEAUTIFIED Refuel +#include "..\script_component.hpp" diff --git a/addons/compat_cup_vehicles/config.cpp b/addons/compat_cup_vehicles/config.cpp new file mode 100644 index 0000000000..624d411fa4 --- /dev/null +++ b/addons/compat_cup_vehicles/config.cpp @@ -0,0 +1,33 @@ +#include "script_component.hpp" + +// Remove after next cup release +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\cup\CUP_Vehicles_ACE_compat\config.bin") +#define PATCH_SKIP "CUP_Vehicles_ACE_compat" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Vehicles_LoadOrder", + "ace_interaction" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Community Upgrade Project", "Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" + +#endif diff --git a/addons/compat_cup_vehicles/functions/fnc_onCutHC3.sqf b/addons/compat_cup_vehicles/functions/fnc_onCutHC3.sqf new file mode 100644 index 0000000000..8514dd2aed --- /dev/null +++ b/addons/compat_cup_vehicles/functions/fnc_onCutHC3.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Unknown + * Function for retracting the hooks for CUP HC3 helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before cutting ropes + * + * Example: + * [_vehicle] call ace_compat_cup_vehicles_fnc_onCutHC3 + * + * Public: No + */ + +params ["_vehicle"]; + +_vehicle setVariable ["ace_fastroping_doorsLocked", false, true]; + +_vehicle animateSource ["Winchsection", 0]; +_vehicle animateSource ["Winchsection2", 0]; +_vehicle animateDoor ["dvere_p", 1]; + +2 diff --git a/addons/compat_cup_vehicles/functions/fnc_onCutUH1Y.sqf b/addons/compat_cup_vehicles/functions/fnc_onCutUH1Y.sqf new file mode 100644 index 0000000000..82a3eaf8a9 --- /dev/null +++ b/addons/compat_cup_vehicles/functions/fnc_onCutUH1Y.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: Unknown + * Function for retracting the hooks for CUP UH-1Y helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before cutting ropes + * + * Example: + * [_vehicle] call ace_compat_cup_vehicles_fnc_onCutUH1Y + * + * Public: No + */ +params ["_vehicle"]; + +_vehicle setVariable ["ace_fastroping_doorsLocked", false, true]; +_vehicle animateSource ["fries_extend", 0]; + +2 diff --git a/addons/compat_cup_vehicles/functions/fnc_onPrepareHC3.sqf b/addons/compat_cup_vehicles/functions/fnc_onPrepareHC3.sqf new file mode 100644 index 0000000000..aad828a3a0 --- /dev/null +++ b/addons/compat_cup_vehicles/functions/fnc_onPrepareHC3.sqf @@ -0,0 +1,26 @@ +#include "..\script_component.hpp" +/* + * Author: Unknown + * Function for opening doors and extending the hook for HC3 helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before deploying ropes + * + * Example: + * [_vehicle] call ace_compat_cup_vehicles_fnc_onPrepareUH1Y + * + * Public: No + */ + +params ["_vehicle"]; + +_vehicle setVariable ["ace_fastroping_doorsLocked", true, true]; + +_vehicle animateSource ["Winchsection", 1]; +_vehicle animateSource ["Winchsection2", 1]; +_vehicle animateDoor ["dvere_p", 0]; + +2 diff --git a/addons/compat_cup_vehicles/functions/fnc_onPrepareUH1Y.sqf b/addons/compat_cup_vehicles/functions/fnc_onPrepareUH1Y.sqf new file mode 100644 index 0000000000..f17ea79613 --- /dev/null +++ b/addons/compat_cup_vehicles/functions/fnc_onPrepareUH1Y.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: Unknown + * Function for extending the hook for the CUP UH-1Y Helos. + * + * Arguments: + * 0: Helicopter + * + * Return Value: + * Amount of time to wait before deploying ropes + * + * Example: + * [_vehicle] call ace_compat_cup_vehicles_fnc_onPrepareUH1Y + * + * Public: No + */ + +params ["_vehicle"]; + +_vehicle setVariable ["ace_fastroping_doorsLocked", true, true]; +_vehicle animateSource ["fries_extend", 1]; + +2 diff --git a/addons/compat_cup_vehicles/script_component.hpp b/addons/compat_cup_vehicles/script_component.hpp new file mode 100644 index 0000000000..effb2d5534 --- /dev/null +++ b/addons/compat_cup_vehicles/script_component.hpp @@ -0,0 +1,20 @@ +#define COMPONENT compat_cup_vehicles +#define COMPONENT_BEAUTIFIED CUP Vehicles Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" + +// Fries Macro +#define EQUIP_FRIES_ATTRIBUTE \ + class Attributes { \ + class ace_fastroping_equipFRIES { \ + property = "ace_fastroping_equipFRIES"; \ + control = "Checkbox"; \ + displayName = ECSTRING(fastroping,Eden_equipFRIES); \ + tooltip = ECSTRING(fastroping,Eden_equipFRIES_Tooltip); \ + expression = "[_this] call ace_fastroping_fnc_equipFRIES"; \ + typeName = "BOOL"; \ + condition = "objectVehicle"; \ + defaultValue = 0; \ + }; \ + } diff --git a/addons/compat_cup_weapons/$PBOPREFIX$ b/addons/compat_cup_weapons/$PBOPREFIX$ new file mode 100644 index 0000000000..c5368b0a6d --- /dev/null +++ b/addons/compat_cup_weapons/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_cup_weapons diff --git a/addons/compat_cup_weapons/CfgEventHandlers.hpp b/addons/compat_cup_weapons/CfgEventHandlers.hpp new file mode 100644 index 0000000000..9cc1b0427b --- /dev/null +++ b/addons/compat_cup_weapons/CfgEventHandlers.hpp @@ -0,0 +1,5 @@ +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; diff --git a/addons/compat_cup_weapons/CfgMagazines.hpp b/addons/compat_cup_weapons/CfgMagazines.hpp new file mode 100644 index 0000000000..6fd6e2f1cc --- /dev/null +++ b/addons/compat_cup_weapons/CfgMagazines.hpp @@ -0,0 +1,37 @@ +class CfgMagazines { + class CA_LauncherMagazine; + class CUP_NLAW_M: CA_LauncherMagazine { + ammo = "ACE_NLAW"; + }; + + // legacy classes from ACE disposable launchers + class CUP_M136_M; + class ACE_PreloadedMissileDummy_CUP: CUP_M136_M { + scope = 1; + scopeArsenal = 0; + }; + class CUP_RPG18_M; + class ACE_PreloadedMissileDummy_RPG18_CUP: CUP_RPG18_M { + scope = 1; + scopeArsenal = 0; + }; + class CUP_M72A6_M; + class ACE_PreloadedMissileDummy_M72A6_CUP: CUP_M72A6_M { + scope = 1; + scopeArsenal = 0; + }; + class ACE_PreloadedMissileDummy_NLAW_CUP: CUP_NLAW_M { + scope = 1; + scopeArsenal = 0; + }; + class CUP_Stinger_M; + class ACE_PreloadedMissileDummy_Stinger_CUP: CUP_Stinger_M { + scope = 1; + scopeArsenal = 0; + }; + class CUP_Strela_2_M; + class ACE_PreloadedMissileDummy_Strela_2_CUP: CUP_Strela_2_M { + scope = 1; + scopeArsenal = 0; + }; +}; diff --git a/addons/compat_cup_weapons/CfgWeapons.hpp b/addons/compat_cup_weapons/CfgWeapons.hpp new file mode 100644 index 0000000000..e69c75dee5 --- /dev/null +++ b/addons/compat_cup_weapons/CfgWeapons.hpp @@ -0,0 +1,36 @@ +class CfgWeapons { + class Launcher_Base_F; + class CUP_launch_M47: Launcher_Base_F { + ace_overpressure_angle = 45; + ace_overpressure_range = 8; + ace_overpressure_damage = 0.5; + }; + + class CUP_launch_MAAWS: Launcher_Base_F { + ace_overpressure_angle = 60; + ace_overpressure_range = 15; + ace_overpressure_damage = 0.7; + }; + class CUP_launch_MAAWS_Scope: CUP_launch_MAAWS {}; + + class CUP_launch_RPG7V: Launcher_Base_F { + ace_overpressure_angle = 45; + ace_overpressure_range = 6; + ace_overpressure_damage = 0.5; + }; + + class CUP_launch_Mk153Mod0: Launcher_Base_F { + ace_overpressure_angle = 30; + ace_overpressure_range = 15; + ace_overpressure_damage = 0.7; + }; + class CUP_launch_Mk153Mod0_SMAWOptics: CUP_launch_Mk153Mod0 {}; + + class CUP_launch_NLAW_Loaded: Launcher_Base_F { + ace_overpressure_angle = 30; + ace_overpressure_range = 2; + ace_overpressure_damage = 0.5; + ace_nlaw_enabled = 1; + canLock = 1; + }; +}; diff --git a/addons/compat_cup_weapons/XEH_postInit.sqf b/addons/compat_cup_weapons/XEH_postInit.sqf new file mode 100644 index 0000000000..79d81fda26 --- /dev/null +++ b/addons/compat_cup_weapons/XEH_postInit.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +if (["CUP_Weapons_ACE_compat"] call EFUNC(common,isModLoaded)) exitWith { + ERROR_WITH_TITLE("Duplicate CUP/ACE Compats","Compats are now part of ACE - Uninstall 'CUP ACE3 Compatibility Addon - Weapons'"); +}; diff --git a/addons/compat_cup_weapons/addon.toml b/addons/compat_cup_weapons/addon.toml new file mode 100644 index 0000000000..bf39213892 --- /dev/null +++ b/addons/compat_cup_weapons/addon.toml @@ -0,0 +1,3 @@ +[tools] +pboProject_noBinConfig = true +sqfvm_skipConfigChecks = true diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazineGroups.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazineGroups.hpp new file mode 100644 index 0000000000..430a5272ae --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazineGroups.hpp @@ -0,0 +1,56 @@ +class ace_csw_groups { + class CUP_compats_29Rnd_30mm_AGS30_M { + CUP_29Rnd_30mm_AGS30_M = 1; + }; + class CUP_compats_48Rnd_40mm_MK19_M { + CUP_48Rnd_40mm_MK19_M = 1; + }; + class CUP_AT13_M { + CUP_6Rnd_AT13_M = 1; + }; + class CUP_compats_TOW_M { + CUP_6Rnd_TOW_HMMWV_M = 1; + }; + class CUP_compats_TOW2_M { + CUP_6Rnd_TOW2_M = 1; + }; + class CUP_compats_PG9_M { + CUP_16Rnd_PG9_AT_M = 1; + }; + class CUP_compats_OG9_M { + CUP_16Rnd_OG9_HE_M = 1; + }; + class CUP_compats_105mm_he { + CUP_30Rnd_105mmHE_M119_M = 1; + }; + class CUP_compats_105mm_smoke { + CUP_30Rnd_105mmSMOKE_M119_M = 1; + }; + class CUP_compats_105mm_wp { + CUP_30Rnd_105mmWP_M119_M = 1; + }; + class CUP_compats_105mm_laser { + CUP_30Rnd_105mmLASER_M119_M = 1; + }; + class CUP_compats_105mm_illum { + CUP_30Rnd_105mmILLUM_M119_M = 1; + }; + class CUP_compats_122mm_he { + CUP_30Rnd_122mmHE_D30_M = 1; + }; + class CUP_compats_122mm_smoke { + CUP_30Rnd_122mmSMOKE_D30_M = 1; + }; + class CUP_compats_122mm_wp { + CUP_30Rnd_122mmHE_D30_M = 1; + }; + class CUP_compats_122mm_laser { + CUP_30Rnd_122mmLASER_D30_M = 1; + }; + class CUP_compats_122mm_illum { + CUP_30Rnd_122mmILLUM_D30_M = 1; + }; + class CUP_compats_122mm_at { + CUP_30Rnd_122mmAT_D30_M = 1; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazines.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazines.hpp new file mode 100644 index 0000000000..1a37f4d1c9 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgMagazines.hpp @@ -0,0 +1,111 @@ +class CfgMagazines { + class VehicleMagazine; + class CUP_29Rnd_30mm_AGS30_M: VehicleMagazine { + ace_isbelt = 1; + }; + + class CUP_compats_29Rnd_30mm_AGS30_M: CUP_29Rnd_30mm_AGS30_M { + scope = 2; + type = 256; + count = 29; + mass = 40; + displayName = SUBCSTRING(mag_AGS30_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); + }; + + class 200Rnd_40mm_G_belt; + class CUP_48Rnd_40mm_MK19_M: 200Rnd_40mm_G_belt { + ace_isbelt = 1; + }; + + class CUP_compats_48Rnd_40mm_MK19_M: CUP_29Rnd_30mm_AGS30_M { + scope = 2; + type = 256; + count = 48; + mass = 40; + displayname = SUBCSTRING(mag_MK19_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = QPATHTOEF(csw,UI\ammoBox_50bmg_ca.paa); + }; + + class CUP_6Rnd_TOW_HMMWV_M; + class CUP_compats_TOW_M: CUP_6Rnd_TOW_HMMWV_M { + scope = 2; + type = 256; + count = 1; + mass = 200; + displayname = SUBCSTRING(mag_TOW_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = "\A3\Weapons_F_beta\Launchers\titan\Data\UI\gear_titan_missile_at_ca.paa"; + }; + + class CUP_6Rnd_TOW2_M; + class CUP_compats_TOW2_M: CUP_6Rnd_TOW2_M { + scope = 2; + type = 256; + count = 1; + mass = 200; + displayname = SUBCSTRING(mag_TOW2_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + picture = "\A3\Weapons_F_beta\Launchers\titan\Data\UI\gear_titan_missile_at_ca.paa"; + }; + + class CUP_16Rnd_PG9_AT_M; + class CUP_compats_PG9_M: CUP_16Rnd_PG9_AT_M { + displayName = SUBCSTRING(mag_PG9_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + scope = 2; + type = 256; + count = 1; + mass = 80; + picture = "\A3\Weapons_F_Exp\Launchers\RPG7\Data\UI\icon_rocket_RPG7_ca.paa"; + }; + + class CUP_16Rnd_OG9_HE_M; + class CUP_compats_OG9_M: CUP_16Rnd_OG9_HE_M { + displayName = SUBCSTRING(mag_OG9_displayName); + model = "\A3\Structures_F_EPB\Items\Military\Ammobox_rounds_F.p3d"; + scope = 2; + type = 256; + count = 1; + mass = 80; + picture = "\A3\Weapons_F_Exp\Launchers\RPG7\Data\UI\icon_rocket_RPG7_ca.paa"; + }; + + class ACE_1Rnd_82mm_Mo_HE; + class CUP_compats_105mm_he: ACE_1Rnd_82mm_Mo_HE { + displayName = SUBCSTRING(mag_M1HE_displayName); + mass = 120; + }; + class CUP_compats_105mm_smoke: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_M84Smoke_displayName); + }; + class CUP_compats_105mm_wp: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_M60A2_displayName); + }; + class CUP_compats_105mm_laser: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_M67AT_displayName); + }; + class CUP_compats_105mm_illum: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_M314Illum_displayName); + }; + class CUP_compats_122mm_he: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_3OF56_displayName); + }; + class CUP_compats_122mm_laser: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_3OF69M_displayName); + }; + class CUP_compats_122mm_wp: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_122mmWP_displayName); + }; + class CUP_compats_122mm_smoke: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_122mmSmoke_displayName); + }; + class CUP_compats_122mm_illum: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_122mmIllum_displayName); + }; + class CUP_compats_122mm_at: CUP_compats_105mm_he { + displayName = SUBCSTRING(mag_122mmAT_displayName); + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgVehicles.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgVehicles.hpp new file mode 100644 index 0000000000..3924ae0386 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgVehicles.hpp @@ -0,0 +1,200 @@ +class CfgVehicles { + class LandVehicle; + class StaticWeapon: LandVehicle { + class ACE_Actions { + class ACE_MainActions; + }; + }; + + class StaticMortar: StaticWeapon {}; + class CUP_2b14_82mm_Base: StaticMortar { + class ACE_Actions: ACE_Actions { + class ACE_MainActions: ACE_MainActions { + position = ""; + selection = ""; // no good selections for this mortar + }; + }; + class ace_csw { + enabled = 1; + magazineLocation = "_target selectionPosition 'otochlaven'"; + proxyWeapon = "CUP_proxy_mortar_82mm"; + disassembleWeapon = "CUP_2b14_carry"; + disassembleTurret = "ace_csw_mortarBaseplate"; + desiredAmmo = 1; + ammoLoadTime = 3; + ammoUnloadTime = 3; + }; + }; + + class CUP_M252_base: CUP_2b14_82mm_Base { + class ace_csw: ace_csw { + disassembleWeapon = "CUP_m252_carry"; + disassembleTurret = "ace_csw_mortarBaseplate"; + }; + }; + + class CUP_L16A2_base: CUP_M252_base { + class ace_csw: ace_csw { + disassembleWeapon = "CUP_l16a2_carry"; + disassembleTurret = "ace_csw_mortarBaseplate"; + }; + }; + + class StaticMGWeapon; + class CUP_M2StaticMG_base: StaticMGWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_m2"; + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = "CUP_m2_carry"; + disassembleTurret = "ace_csw_m3Tripod"; + desiredAmmo = 100; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class CUP_M2StaticMG_MiniTripod_base: CUP_M2StaticMG_base { + class ace_csw: ace_csw { + enabled = 1; + disassembleTurret = "ace_csw_m3TripodLow"; + }; + }; + + class CUP_DSHKM_base: StaticMGWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_DSHKM"; + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = "CUP_DSHKM_carry"; + disassembleTurret = "ace_csw_kordTripod"; + desiredAmmo = 100; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class CUP_DSHKM_MiniTripod_base: CUP_DSHKM_base { + class ace_csw: ace_csw { + enabled = 1; + disassembleTurret = "ace_csw_kordTripodLow"; + }; + }; + + class CUP_KORD_Base: StaticMGWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_KORD"; + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = "CUP_KORD_carry"; + disassembleTurret = "ace_csw_kordTripod"; + desiredAmmo = 100; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class CUP_KORD_MiniTripod_Base: CUP_KORD_Base { + class ace_csw: ace_csw { + enabled = 1; + disassembleTurret = "ace_csw_kordTripodLow"; + }; + }; + + class StaticGrenadeLauncher; + class CUP_AGS_base: StaticGrenadeLauncher { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_AGS30"; + magazineLocation = "_target selectionPosition 'otochlaven'"; + disassembleWeapon = "CUP_AGS30_carry"; + disassembleTurret = "ace_csw_sag30Tripod"; + desiredAmmo = 29; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class CUP_MK19_TriPod_base: StaticGrenadeLauncher { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_MK19"; + magazineLocation = "_target selectionPosition 'magazine'"; + disassembleWeapon = "CUP_MK19_carry"; + disassembleTurret = "ace_csw_m3TripodLow"; + desiredAmmo = 48; + ammoLoadTime = 10; + ammoUnloadTime = 8; + }; + }; + + class StaticATWeapon; + class CUP_Metis_Base: StaticATWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_AT13"; + magazineLocation = "_target selectionPosition 'gun'"; + disassembleWeapon = "CUP_launch_Metis"; + disassembleTurret = ""; + desiredAmmo = 1; + ammoLoadTime = 7; + ammoUnloadTime = 5; + }; + }; + + class CUP_TOW_TriPod_base: StaticATWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_TOW"; + magazineLocation = "_target selectionPosition 'otochlaven'"; + disassembleWeapon = "CUP_TOW_carry"; + disassembleTurret = "ace_csw_m220Tripod"; + desiredAmmo = 1; + ammoLoadTime = 8; + ammoUnloadTime = 5; + }; + }; + + class CUP_TOW2_TriPod_base: CUP_TOW_TriPod_base { + class ace_csw: ace_csw { + disassembleWeapon = "CUP_TOW2_carry"; + }; + }; + + class CUP_SPG9_base: StaticATWeapon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_SPG9"; + magazineLocation = "_target selectionPosition 'otochlaven'"; + disassembleWeapon = "CUP_SPG9_carry"; + disassembleTurret = "ace_csw_spg9Tripod"; + desiredAmmo = 1; + ammoLoadTime = 5; + ammoUnloadTime = 3; + }; + }; + + class StaticCannon; + class CUP_D30_base: StaticCannon { + class ace_csw { + enabled = 1; + proxyWeapon = "CUP_proxy_D30"; + magazineLocation = "_target selectionPosition 'otochlaven'"; + desiredAmmo = 1; + ammoLoadTime = 5; + ammoUnloadTime = 5; + }; + }; + + class CUP_D30_AT_base: CUP_D30_base { + class ace_csw: ace_csw { + proxyWeapon = "CUP_proxy_D30AT"; + }; + }; + + class CUP_M119_base: CUP_D30_base { + class ace_csw: ace_csw { + proxyWeapon = "CUP_proxy_M119"; + }; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp new file mode 100644 index 0000000000..3e16233568 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp @@ -0,0 +1,290 @@ +class CfgWeapons { + class Launcher; + class Launcher_Base_F: Launcher { + class WeaponSlotsInfo; + }; + + class CUP_2b14_carry: Launcher_Base_F { + displayName = ECSTRING(csw,2b14_tube); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\Podnos\data\ui\podnos_2b14_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 20; + pickupTime = 25; + class assembleTo { + ace_csw_mortarBaseplate = "CUP_O_2b14_82mm_RU"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 670; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_m252_carry: CUP_2b14_carry { + displayName = ECSTRING(csw,m252_tube); + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\M252\data\ui\icomap_mortar_m251_ca.paa"; + class ace_csw: ace_csw { + class assembleTo { + ace_csw_mortarBaseplate = "CUP_B_M252_US"; + }; + }; + }; + + class CUP_l16a2_carry: CUP_2b14_carry { + displayName = ECSTRING(csw,m252_tube); + scope = 1; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\M252\data\ui\icomap_mortar_m251_ca.paa"; + class ace_csw: ace_csw { + class assembleTo { + ace_csw_mortarBaseplate = "CUP_B_L16A2_BAF_MPT"; + }; + }; + }; + + class CUP_m2_carry: Launcher_Base_F { + displayName = ECSTRING(csw,m2_gun); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\M2\data\ui\icomap_M2_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_m3Tripod = "CUP_B_M2StaticMG_US"; + ace_csw_m3TripodLow = "CUP_B_M2StaticMG_MiniTripod_US"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 840; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_DSHKM_carry: Launcher_Base_F { + displayName = ECSTRING(csw,dshk_gun); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\DShKM\data\ui\icomap_DShKM_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_kordTripod = "CUP_O_DSHKM_ChDKZ"; + ace_csw_kordTripodLow = "CUP_O_DSHkM_MiniTriPod_ChDKZ"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 740; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_KORD_carry: Launcher_Base_F { + displayName = ECSTRING(csw,kord_gun); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\KORD\data\ui\icomap_kord_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_kordTripod = "CUP_O_KORD_high_RU"; + ace_csw_kordTripodLow = "CUP_O_KORD_RU"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 550; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_AGS30_carry: Launcher_Base_F { + displayName = ECSTRING(csw,ags30_gun); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\AGS\data\ui\ags_static_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_sag30Tripod = "CUP_O_AGS_RU"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 400; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_MK19_carry: Launcher_Base_F { + displayName = ECSTRING(csw,mk19_gun); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\Mk19\data\ui\icomap_mk19_stat_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_m3TripodLow = "CUP_B_MK19_TriPod_US"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 770; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_launch_Metis: Launcher_Base_F { + ace_overpressure_angle = 45; + ace_overpressure_range = 15; + ace_overpressure_damage = 0.7; + class ace_csw { + type = "mount"; + deployTime = 4; + pickupTime = 4; + deploy = "CUP_O_Metis_RU"; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 300; + }; + }; + + class CUP_TOW_carry: Launcher_Base_F { + displayName = ECSTRING(csw,tow_tube); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\TOW\data\ui\icomap_tow_static_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_m220Tripod = "CUP_B_TOW_TriPod_US"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 500; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class CUP_TOW2_carry: CUP_TOW_carry { + class ace_csw: ace_csw { + class assembleTo { + ace_csw_m220Tripod = "CUP_B_TOW2_TriPod_US"; + }; + }; + }; + + class CUP_SPG9_carry: Launcher_Base_F { + displayName = ECSTRING(csw,spg9_tube); + scope = 2; + model = QPATHTOEF(apl,ACE_CSW_Bag.p3d); + modes[] = {}; + picture = "\CUP\Weapons\CUP_Weapons_StaticWeapons\SPG9\data\ui\icon_spg9_ca.paa"; + class ace_csw { + type = "weapon"; + deployTime = 4; + pickupTime = 4; + class assembleTo { + ace_csw_spg9Tripod = "CUP_B_SPG9_CDF"; + }; + }; + class WeaponSlotsInfo: WeaponSlotsInfo { + mass = 1000; + class MuzzleSlot { + iconScale = 0.1; + }; + }; + }; + + class mortar_82mm; + class CUP_proxy_mortar_82mm: mortar_82mm { + magazineReloadTime = 0.5; + }; + + class CUP_Vhmg_M2_static; + class CUP_proxy_m2: CUP_Vhmg_M2_static { + magazineReloadTime = 0.5; + }; + + class CUP_Vhmg_DSHKM_veh; + class CUP_proxy_DSHKM: CUP_Vhmg_DSHKM_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vhmg_KORD_veh; + class CUP_proxy_KORD: CUP_Vhmg_KORD_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vhmg_AGS30_veh; + class CUP_proxy_AGS30: CUP_Vhmg_AGS30_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vgmg_MK19_veh; + class CUP_proxy_MK19: CUP_Vgmg_MK19_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vmlauncher_AT13_single_veh; + class CUP_proxy_AT13: CUP_Vmlauncher_AT13_single_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vmlauncher_TOW_single_veh; + class CUP_proxy_TOW: CUP_Vmlauncher_TOW_single_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vacannon_SPG9_veh; + class CUP_proxy_SPG9: CUP_Vacannon_SPG9_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vcannon_M119_veh; + class CUP_proxy_M119: CUP_Vcannon_M119_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vcannon_D30_veh; + class CUP_proxy_D30: CUP_Vcannon_D30_veh { + magazineReloadTime = 0.5; + }; + + class CUP_Vcannon_D30AT_veh; + class CUP_proxy_D30AT: CUP_Vcannon_D30AT_veh { + magazineReloadTime = 0.5; + }; +}; + diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/config.cpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/config.cpp new file mode 100644 index 0000000000..ccc2f0baf2 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/config.cpp @@ -0,0 +1,26 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Weapons_loadOrder", + "ace_csw" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgMagazineGroups.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/script_component.hpp b/addons/compat_cup_weapons/compat_cup_weapons_csw/script_component.hpp new file mode 100644 index 0000000000..77a1b484cb --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/script_component.hpp @@ -0,0 +1,5 @@ +#define SUBCOMPONENT csw +#define SUBCOMPONENT_BEAUTIFIED Crew-Served Weapons +#include "..\script_component.hpp" + +#include "\z\ace\addons\csw\script_config_macros_csw.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml new file mode 100644 index 0000000000..b41e11b630 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml @@ -0,0 +1,90 @@ + + + + + [CSW] AGS30 Belt + [CSW] AGS30 ベルト + [CSW] Лента AGS 30 + + + [CSW] MK19 Belt + [CSW] Mk19 ベルト + [CSW] Лента Mk19 + + + [CSW] TOW Tube + [CSW] TOW チューブ + [CSW] Туба TOW + + + [CSW] TOW2 Tube + [CSW] TOW2 チューブ + [CSW] Туба TOW-2 + + + [CSW] PG-9 Round + [CSW] PG-9 砲弾 + [CSW] Снаряд ПГ-9 + + + [CSW] OG-9 Round + [CSW] OG-9 砲弾 + [CSW] Снаряд OГ-9 + + + [CSW] M1 HE + [CSW] M1 榴弾 + [CSW] M1 HE + + + [CSW] M84 Smoke + [CSW] M84 白煙弾 + [CSW] M84 Дымовая + + + [CSW] M60A2 WP + [CSW] M60A2 白リン弾 + [CSW] M60A2 WP + + + [CSW] M67 AT Laser Guided + [CSW] M67 対戦車レーザー誘導弾 + [CSW] M67 AT Laser Guided + + + [CSW] M314 Illumination + [CSW] M314 照明弾 + [CSW] M314 Осветительная + + + [CSW] 3OF56 HE + [CSW] 3OF56 榴弾 + [CSW] 3OF56 HE + + + [CSW] 3OF69M Laser Guided + [CSW] 3OF69M レーザー誘導弾 + [CSW] 3OF69M Laser Guided + + + [CSW] 122mm WP + [CSW] 122mm 白リン弾 + [CSW] 122mm WP + + + [CSW] D-462 Smoke + [CSW] D-462 白煙弾 + [CSW] D-462 Дымовая + + + [CSW] S-463 Illumination + [CSW] S-463 照明弾 + [CSW] S-463 Осветительная + + + [CSW] BK-6M HEAT + [CSW] BK-6M HEAT弾 + [CSW] BK-6M HEAT + + + diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgAmmo.hpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgAmmo.hpp new file mode 100644 index 0000000000..1658715ddb --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgAmmo.hpp @@ -0,0 +1,21 @@ +class CfgAmmo { + class PipeBombBase; + class CUP_TimeBomb_Ammo: PipeBombBase { + hit = 3000; + indirectHit = 3000; + indirectHitRange = 5; + ace_explosives_explodeOnDefuse = 0.02; + }; + class CUP_PipeBomb_Ammo: PipeBombBase { + hit = 3000; + indirectHit = 3000; + indirectHitRange = 5; + ace_explosives_explodeOnDefuse = 0.02; + }; + + class CUP_Mine_Ammo; + class CUP_IED_V1_Ammo: CUP_Mine_Ammo { + ace_explosives_explodeOnDefuse = 0.06; + triggerWhenDestroyed = 1; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgMagazines.hpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgMagazines.hpp new file mode 100644 index 0000000000..15df2f7333 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgMagazines.hpp @@ -0,0 +1,103 @@ +class CfgMagazines { + class CA_Magazine; + class CUP_TimeBomb_M: CA_Magazine { + scope = 1; + ace_explosives_placeable = 1; + useAction = 0; + ace_explosives_setupObject = "ACE_PipeBomb_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone"}; + class Timer { + FuseTime = 0.5; + }; + class Command { + FuseTime = 0.5; + }; + }; + }; + class CUP_Mine_M: CUP_TimeBomb_M { + ace_explosives_placeable = 1; + useAction = 0; + ace_explosives_setupObject = "ACE_Mine_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.08; + }; + }; + }; + class CUP_MineE_M: CUP_TimeBomb_M { + ace_explosives_placeable = 1; + useAction = 0; + ace_explosives_setupObject = "ACE_MineE_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"PressurePlate"}; + class PressurePlate { + digDistance = 0.06; + }; + }; + }; + + class CUP_IED_V1_M: CUP_Mine_M { + ace_explosives_placeable = 1; + useAction = 0; + ace_explosives_setupObject = "ACE_IED_V1_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone", "PressurePlate"}; + }; + }; + class CUP_IED_V2_M: CUP_IED_V1_M { + useAction = 0; + ace_explosives_setupObject = "ACE_IED_V2_place_CUP"; + }; + class CUP_IED_V3_M: CUP_IED_V1_M { + useAction = 0; + ace_explosives_setupObject = "ACE_IED_V3_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone", "PressurePlate"}; + class Timer { + digDistance = 0.06; + }; + class Command { + digDistance = 0.06; + }; + class MK16_Transmitter { + digDistance = 0.06; + }; + class DeadmanSwitch { + digDistance = 0.06; + }; + class Cellphone { + digDistance = 0.06; + }; + class PressurePlate { + digDistance = 0.06; + }; + }; + }; + class CUP_IED_V4_M: CUP_IED_V1_M { + useAction = 0; + ace_explosives_setupObject = "ACE_IED_V4_place_CUP"; + class ACE_Triggers { + SupportedTriggers[] = {"Timer", "Command", "MK16_Transmitter", "DeadmanSwitch", "Cellphone", "PressurePlate"}; + class Timer { + digDistance = 0.08; + }; + class Command { + digDistance = 0.08; + }; + class MK16_Transmitter { + digDistance = 0.08; + }; + class DeadmanSwitch { + digDistance = 0.08; + }; + class Cellphone { + digDistance = 0.08; + }; + class PressurePlate { + digDistance = 0.08; + }; + }; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgVehicles.hpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgVehicles.hpp new file mode 100644 index 0000000000..d10c315c3d --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/CfgVehicles.hpp @@ -0,0 +1,32 @@ +class CfgVehicles { + class ACE_Explosives_Place; + class ACE_PipeBomb_place_CUP: ACE_Explosives_Place { + displayName = "Satchel Charge"; + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_Satchel.p3d"; + ace_explosives_offset[] = {0, 0, 0}; + }; + class ACE_Mine_place_CUP: ACE_Explosives_Place { + displayName = "AT-15 Anti-Tank Mine"; + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_AT15.p3d"; + ace_explosives_offset[] = {0, 0, 0}; + }; + class ACE_MineE_place_CUP: ACE_Explosives_Place { + displayName = "TM46 Anti-Tank Mine"; + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_TM46.p3d"; + ace_explosives_offset[] = {0, 0, 0}; + }; + class ACE_IED_V1_place_CUP: ACE_Explosives_Place { + displayName = "IED"; + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V1.p3d"; + ace_explosives_offset[] = {0, 0, 0}; + }; + class ACE_IED_V2_place_CUP: ACE_IED_V1_place_CUP { + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V2.p3d"; + }; + class ACE_IED_V3_place_CUP: ACE_IED_V1_place_CUP { + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V3.p3d"; + }; + class ACE_IED_V4_place_CUP: ACE_IED_V1_place_CUP { + model = "\CUP\Weapons\CUP_Weapons_Put\CUP_IED_V4.p3d"; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/config.cpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/config.cpp new file mode 100644 index 0000000000..ce16a310a8 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/config.cpp @@ -0,0 +1,25 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Weapons_LoadOrder", + "ace_explosives" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_explosives/script_component.hpp b/addons/compat_cup_weapons/compat_cup_weapons_explosives/script_component.hpp new file mode 100644 index 0000000000..a697aad7f3 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_explosives/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT explosives +#define SUBCOMPONENT_BEAUTIFIED Explosives +#include "..\script_component.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp new file mode 100644 index 0000000000..2632a43e61 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgAmmo.hpp @@ -0,0 +1,26 @@ +class CfgAmmo { + class MissileBase; + class CUP_M_Javelin_AT: MissileBase { + irLock = 1; + laserLock = 0; + airLock = 0; + + class ace_missileguidance { + enabled = 1; + minDeflection = 0.00005; + maxDeflection = 0.025; + incDeflection = 0.00005; + canVanillaLock = 0; + defaultSeekerType = "Optic"; + seekerTypes[] = {"Optic"}; + defaultSeekerLockMode = "LOBL"; + seekerLockModes[] = {"LOBL"}; + seekerAngle = 180; + seekerAccuracy = 1; + seekerMinRange = 0; + seekerMaxRange = 2500; + defaultAttackProfile = "JAV_TOP"; + attackProfiles[] = {"JAV_TOP", "JAV_DIR"}; + }; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgWeapons.hpp b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgWeapons.hpp new file mode 100644 index 0000000000..35b1d2bf09 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_javelin/CfgWeapons.hpp @@ -0,0 +1,14 @@ +class CfgWeapons { + class Launcher_Base_F; + class CUP_launch_Javelin: Launcher_Base_F { + ace_javelin_enabled = 1; + weaponInfoType = "ACE_RscOptics_javelin"; + modelOptics = QPATHTOEF(javelin,data\reticle_titan.p3d); + canLock = 0; + lockingTargetSound[] = {"", 0, 1}; + lockedTargetSound[] = {"", 0, 1}; + ace_overpressure_angle = 30; + ace_overpressure_range = 2; + ace_overpressure_damage = 0.5; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_javelin/config.cpp b/addons/compat_cup_weapons/compat_cup_weapons_javelin/config.cpp new file mode 100644 index 0000000000..8d5eeb37d5 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_javelin/config.cpp @@ -0,0 +1,24 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Weapons_LoadOrder", + "ace_javelin" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_javelin/script_component.hpp b/addons/compat_cup_weapons/compat_cup_weapons_javelin/script_component.hpp new file mode 100644 index 0000000000..d42e0f4f01 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_javelin/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT javelin +#define SUBCOMPONENT_BEAUTIFIED Javelin +#include "..\script_component.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/CfgWeapons.hpp b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/CfgWeapons.hpp new file mode 100644 index 0000000000..04d26b8ead --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/CfgWeapons.hpp @@ -0,0 +1,118 @@ +#define NVG_BINO_PRESET \ + ace_nightvision_bluRadius = 0.13; \ + EGVAR(nightvision,border) = QPATHTOEF(nightvision,data\nvg_mask_binos_4096.paa); \ + EGVAR(nightvision,generation) = 3; \ + modelOptics = "" + +#define NVG_MONO_PRESET(GEN) \ + EGVAR(nightvision,eyeCups) = 1; \ + EGVAR(nightvision,border) = QPATHTOEF(nightvision,data\nvg_mask_4096.paa); \ + EGVAR(nightvision,bluRadius) = 0.13; \ + EGVAR(nightvision,generation) = GEN; \ + modelOptics = "" + +#define NVG_GPNVG_PRESET \ + EGVAR(nightvision,bluRadius) = 0.13; \ + EGVAR(nightvision,border) = QPATHTOEF(nightvision,data\nvg_mask_quad_4096.paa); \ + EGVAR(nightvision,generation) = 4; \ + modelOptics = "" + +#define NVG_GREEN_PRESET EGVAR(nightvision,colorPreset)[] = {0, {0.0, 0.0, 0.0, 0.0}, {1.3, 1.2, 0.0, 0.9}, {6, 1, 1, 0}} +#define NVG_WP_PRESET EGVAR(nightvision,colorPreset)[] = {0, {0.0, 0.0, 0.0, 0.0}, {1.1, 0.8, 1.9, 0.9}, {1, 1, 6, 0}} + +class CfgWeapons { + class NVGoggles; + // Monocular + class CUP_NVG_PVS7: NVGoggles { + NVG_MONO_PRESET(3); + NVG_GREEN_PRESET; + }; + class CUP_NVG_HMNVS: NVGoggles { + NVG_MONO_PRESET(3); + NVG_GREEN_PRESET; + }; + + // Binocular + class CUP_NVG_PVS14: NVGoggles { + NVG_BINO_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_PVS15_black: NVGoggles { + NVG_BINO_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_PVS15_green: NVGoggles { + NVG_BINO_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_PVS15_tan: NVGoggles { + NVG_BINO_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_PVS15_winter: NVGoggles { + NVG_BINO_PRESET; + NVG_GREEN_PRESET; + }; + + // White Phosphor NVGs + class CUP_NVG_PVS14_WP: CUP_NVG_PVS14 { + displayName = SUBCSTRING(CUP_NVG_PVS14_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_PVS15_black_WP: CUP_NVG_PVS15_black { + displayName = SUBCSTRING(CUP_NVG_PVS15_black_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_PVS15_green_WP: CUP_NVG_PVS15_green { + displayName = SUBCSTRING(CUP_NVG_PVS15_green_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_PVS15_tan_WP: CUP_NVG_PVS15_tan { + displayName = SUBCSTRING(CUP_NVG_PVS15_tan_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_PVS15_winter_WP: CUP_NVG_PVS15_winter { + displayName = SUBCSTRING(CUP_NVG_PVS15_winter_WP); + NVG_WP_PRESET; + }; + + // Gen4s + class CUP_NVG_1PN138: NVGoggles { + NVG_MONO_PRESET(4); + NVG_GREEN_PRESET; + }; + class CUP_NVG_GPNVG_black: NVGoggles { + NVG_GPNVG_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_GPNVG_tan: NVGoggles { + NVG_GPNVG_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_GPNVG_green: NVGoggles { + NVG_GPNVG_PRESET; + NVG_GREEN_PRESET; + }; + class CUP_NVG_GPNVG_winter: NVGoggles { + NVG_GPNVG_PRESET; + NVG_GREEN_PRESET; + }; + + // White Phosphor NVGs + class CUP_NVG_GPNVG_black_WP: CUP_NVG_GPNVG_black { + displayName = SUBCSTRING(CUP_NVG_GPNVG_black_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_GPNVG_tan_WP: CUP_NVG_GPNVG_tan { + displayName = SUBCSTRING(CUP_NVG_GPNVG_tan_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_GPNVG_green_WP: CUP_NVG_GPNVG_green { + displayName = SUBCSTRING(CUP_NVG_GPNVG_green_WP); + NVG_WP_PRESET; + }; + class CUP_NVG_GPNVG_winter_WP: CUP_NVG_GPNVG_winter { + displayName = SUBCSTRING(CUP_NVG_GPNVG_winter_WP); + NVG_WP_PRESET; + }; +}; diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/config.cpp b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/config.cpp new file mode 100644 index 0000000000..4730cdf3a9 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/config.cpp @@ -0,0 +1,26 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = { + "CUP_NVG_PVS14_WP", "CUP_NVG_PVS15_black_WP", "CUP_NVG_PVS15_green_WP", "CUP_NVG_PVS15_tan_WP", "CUP_NVG_PVS15_winter_WP", + "CUP_NVG_GPNVG_black_WP", "CUP_NVG_GPNVG_tan_WP", "CUP_NVG_GPNVG_green_WP", "CUP_NVG_GPNVG_winter_WP" + }; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Weapons_LoadOrder", + "ace_nightvision" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/script_component.hpp b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/script_component.hpp new file mode 100644 index 0000000000..85036e02b6 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nightvision +#define SUBCOMPONENT_BEAUTIFIED Night Vision +#include "..\script_component.hpp" diff --git a/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml new file mode 100644 index 0000000000..001ecaf477 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml @@ -0,0 +1,87 @@ + + + + + AN/PVS-14 (WP) + AN/PVS-14 (白色蛍光) + AN/PVS-14 (FB) + AN/PVS-14 (WP) + AN/PVS-14 (WP) + AN/PVS-14 (백색광) + AN/PVS-14 (WP) + AN/PVS-14 (БФ) + + + AN/PVS-15 (Black, WP) + AN/PVS-15 (グリーン, 白色蛍光) + AN/PVS-15 (Verde, FB) + AN/PVS-15 (Zielone, WP) + AN/PVS-15 (grün, WP) + AN/PVS-15 (녹색, 백색광) + AN/PVS-15 (vertes, WP) + AN/PVS-15 (Чёрный, БФ) + + + AN/PVS-15 (Green, WP) + AN/PVS-15 (ブラック、白色蛍光) + AN/PVS-15 (Nero, FB) + AN/PVS-15 (Czarne, WP) + AN/PVS-15 (Schwarz, WP) + AN/PVS-15 (검정, 백색광) + AN/PVS-15 (noires, WP) + AN/PVS-15 (Зелёный, БФ) + + + AN/PVS-15 (Tan, WP) + AN/PVS-15 (タン, 白色蛍光) + AN/PVS-15 (Marroncina, FB) + AN/PVS-15 (jasnobrązowa, WP) + AN/PVS-15 (hellbraun, WP) + AN/PVS-15 (황갈색, 백색광) + AN/PVS-15 (marron clair, WP) + AN/PVS-15 (Желтовато-коричневый, БФ) + + + AN/PVS-15 (Winter, WP) + AN/PVS-15 (冬季迷彩, WP) + AN/PVS-15 (설상, WP) + AN/PVS-15 (Белый, БФ) + + + GPNVG (Black, WP) + GPNVG (グリーン, 白色蛍光) + GPNVG (Verde, FB) + GPNVG (Zielone, WP) + GPNVG (grün, WP) + GPNVG (녹색, 백색광) + GPNVG (vertes, WP) + GPNVG (Чёрный, БФ) + + + GPNVG (Tan, WP) + GPNVG (タン, 白色蛍光) + GPNVG (Marroncina, FB) + GPNVG (jasnobrązowa, WP) + GPNVG (hellbraun, WP) + GPNVG (황갈색, 백색광) + GPNVG (marron clair, WP) + GPNVG (Желтовато-коричневый, БФ) + + + GPNVG (Green, WP) + GPNVG (ブラック、白色蛍光) + GPNVG (Nero, FB) + GPNVG (Czarne, WP) + GPNVG (Schwarz, WP) + GPNVG (검정, 백색광) + GPNVG (noires, WP) + GPNVG (Зелёный, БФ) + + + GPNVG (Winter, WP) + GPNVG (冬季迷彩, WP) + GPNVG (설상, WP) + AN/PVS-15 (Белый, БФ) + + + diff --git a/addons/compat_cup_weapons/config.cpp b/addons/compat_cup_weapons/config.cpp new file mode 100644 index 0000000000..e4c073b084 --- /dev/null +++ b/addons/compat_cup_weapons/config.cpp @@ -0,0 +1,31 @@ +#include "script_component.hpp" + +// Remove after next cup release +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\cup\CUP_Weapons_ACE_compat\config.bin") +#define PATCH_SKIP "CUP_Weapons_ACE_compat" +#endif + +#ifdef PATCH_SKIP +ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) +#else +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"CUP_Weapons_LoadOrder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Community Upgrade Project", "Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "CfgEventHandlers.hpp" + +#endif diff --git a/addons/compat_cup_weapons/script_component.hpp b/addons/compat_cup_weapons/script_component.hpp new file mode 100644 index 0000000000..9fb9892c1d --- /dev/null +++ b/addons/compat_cup_weapons/script_component.hpp @@ -0,0 +1,5 @@ +#define COMPONENT compat_cup_weapons +#define COMPONENT_BEAUTIFIED CUP Weapons Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_spe/CfgAmmo.hpp b/addons/compat_spe/CfgAmmo.hpp index 0917727974..d11510648b 100644 --- a/addons/compat_spe/CfgAmmo.hpp +++ b/addons/compat_spe/CfgAmmo.hpp @@ -3,4 +3,5 @@ class CfgAmmo { #include "CfgAmmo\explosives.hpp" #include "CfgAmmo\grenades.hpp" #include "CfgAmmo\melee.hpp" + #include "CfgAmmo\bullets.hpp" }; diff --git a/addons/compat_spe/CfgAmmo/bullets.hpp b/addons/compat_spe/CfgAmmo/bullets.hpp new file mode 100644 index 0000000000..1e0e22e62d --- /dev/null +++ b/addons/compat_spe/CfgAmmo/bullets.hpp @@ -0,0 +1,12 @@ +class SPE_Bullet_Vehicle_base; + +class SPE_B_127x99_Mixed: SubmunitionBase { + ACE_caliber = 12.954; +}; + +class SPE_B_127x99_Ball: SPE_Bullet_Vehicle_base { + ACE_caliber = 12.954; +}; +class SPE_B_127x99_API: SPE_B_127x99_Ball { + EGVAR(vehicle_damage,incendiary) = 1; +}; diff --git a/addons/compat_spe/CfgMagazines.hpp b/addons/compat_spe/CfgMagazines.hpp index e3ac58ca41..c5e0b54c75 100644 --- a/addons/compat_spe/CfgMagazines.hpp +++ b/addons/compat_spe/CfgMagazines.hpp @@ -1,3 +1,4 @@ class CfgMagazines { #include "CfgMagazines\csw.hpp" + #include "CfgMagazines\flamethrower.hpp" }; diff --git a/addons/compat_spe/CfgMagazines/flamethrower.hpp b/addons/compat_spe/CfgMagazines/flamethrower.hpp new file mode 100644 index 0000000000..fc1d67558d --- /dev/null +++ b/addons/compat_spe/CfgMagazines/flamethrower.hpp @@ -0,0 +1,3 @@ +class SPE_Flamethrower_Mag: CA_Magazine { + type = 256; +}; diff --git a/addons/compat_ws/CfgWeapons.hpp b/addons/compat_ws/CfgWeapons.hpp index 10e4b68eb2..30e6882b08 100644 --- a/addons/compat_ws/CfgWeapons.hpp +++ b/addons/compat_ws/CfgWeapons.hpp @@ -20,11 +20,13 @@ class CfgWeapons { ACE_barrelLength = 550; ACE_barrelTwist = 304.8; ACE_twistDirection = 1; + EGVAR(overheating,allowSwapBarrel) = 1; }; class LMG_S77_Compact_base_lxWS: LMG_S77_base_lxWS { ACE_barrelLength = 500; ACE_barrelTwist = 304.8; ACE_twistDirection = 1; + EGVAR(overheating,allowSwapBarrel) = 1; }; // SLR diff --git a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml index db4dc2b6d5..b38f1a867e 100644 --- a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml +++ b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml @@ -7,6 +7,7 @@ AA12 AA12 AA12 + AA12 AA12 (Sand) @@ -14,6 +15,7 @@ AA12 (Sand) AA12 (Sabbia) AA12 (サンド) + AA12 (Песочный) AA12 (Snake) @@ -21,6 +23,7 @@ AA12 (Schlange) AA12 (Serpe) AA12 (ヘビ柄) + AA12 (Змея) Galil ARM @@ -28,6 +31,7 @@ Galil ARM Galil ARM ガリル ARM + Galil ARM Galil ARM (Old) @@ -35,6 +39,7 @@ Galil ARM (Alt) Galil ARM (Vecchio) ガリル ARM (使い古し) + Galil ARM (Старый) GLX 160 @@ -42,6 +47,7 @@ GLX 160 GLX-160 GLX 160 + GLX 160 GLX 160 (Snake) @@ -49,6 +55,7 @@ GLX 160 (Schlange) GLX-160 (Serpe) GLX 160 (ヘビ柄) + GLX 160 (Змея) GLX 160 (Hex) @@ -56,6 +63,7 @@ GLX 160 (Hex) GLX-160 (Hex) GLX 160 (六角形迷彩) + GLX 160 (Гекс) GLX 160 (Green Hex) @@ -63,6 +71,7 @@ GLX 160 (Grün Hex) GLX-160 (Hex Verde) GLX 160 (緑六角形迷彩) + GLX 160 (Зеленый Гекс) GLX 160 (Camo) @@ -70,6 +79,7 @@ GLX 160 (Tarn) GLX-160 (Mimetica) GLX 160 (迷彩) + GLX 160 (Камуфляж) GLX 160 (Sand) @@ -77,6 +87,7 @@ GLX 160 (Sand) GLX-160 (Sabbia) GLX 160 (サンド) + GLX 160 (Песочный) Mk14 Mod 1 EBR (Black) @@ -84,6 +95,7 @@ Mk14 Mod 1 EBR (Schwarz) Mk14 Mod 1 EBR (Nero) Mk14 Mod 1 EBR (ブラック) + Mk14 Mod 1 EBR (Черный) Mk14 Mod 1 EBR (Snake) @@ -91,12 +103,14 @@ Mk14 Mod 1 EBR (Schlange) Mk14 Mod 1 EBR (Serpe) Mk14 Mod 1 EBR (ヘビ柄) + Mk14 Mod 1 EBR (Змея) Vektor SS-77 벡터 SS-77 Vektor SS-77 ヴェクター SS-77 + Vektor SS-77 Vektor SS-77 (Camo) @@ -104,6 +118,7 @@ Vektor SS-77 (Tarn) Vektor SS-77 (Mimetica) ヴェクター SS-77 (迷彩) + Vektor SS-77 (Камуфляж) Vektor SS-77 (Hex) @@ -111,6 +126,7 @@ Vektor SS-77 (Hex) Vektor SS-77 (Hex) ヴェクター SS-77 (六角形迷彩) + Vektor SS-77 (гекс) Vektor SS-77 (Green Hex) @@ -118,6 +134,7 @@ Vektor SS-77 (Grün Hex) Vektor SS-77 (Hex Verde) ヴェクター SS-77 (緑六角形迷彩) + Vektor SS-77 (зеленый гекс) Vektor SS-77 (Desert) @@ -125,6 +142,7 @@ Vektor SS-77 (Wüste) Vektor SS-77 (Deserto) ヴェクター SS-77 (砂漠迷彩) + Vektor SS-77 (песочныйt) Vektor SS-77 Compact @@ -132,6 +150,7 @@ Vektor SS-77 Kompakt Vektor SS-77 Compatto ヴェクター SS-77 コンパクト + Vektor SS-77 Compact Vektor SS-77 Compact (Snake) @@ -139,6 +158,7 @@ Vektor SS-77 Compact (Schlange) Vektor SS-77 Compatto (Serpe) ヴェクター SS-77 コンパクト (ヘビ柄) + Vektor SS-77 Compact (змея) FN FAL 50.00 (Wood) @@ -146,6 +166,7 @@ FN FAL 50.00 (Holz) FN FAL 50.00 (Legno) FN FAL 50.00 (森林迷彩) + FN FAL 50.00 (лесной) FN FAL 50.00 GL (Wood) @@ -153,6 +174,7 @@ FN FAL 50.00 GL (Holz) FN FAL 50.00 GL (Legno) FN FAL 50.00 GL (森林迷彩) + FN FAL 50.00 GL (лесной) FN FAL 50.00 @@ -160,6 +182,7 @@ FN FAL 50.00 FN FAL 50.00 FN FAL 50.00 + FN FAL 50.00 FN FAL 50.00 GL @@ -167,6 +190,7 @@ FN FAL 50.00 GL FN FAL 50.00 GL FN FAL 50.00 GL + FN FAL 50.00 GL FN FAL 50.00 (Desert) @@ -174,6 +198,7 @@ FN FAL 50.00 (Wüstet) FN FAL 50.00 (Deserto) FN FAL 50.00 (砂漠迷彩) + FN FAL 50.00 (песочный) FN FAL 50.00 (Jungle) @@ -181,6 +206,7 @@ FN FAL 50,00 (Dschungel) FN FAL 50,00 (Giungla) FN FAL 50.00 (熱帯迷彩) + FN FAL 50.00 (джунгли) Vektor R4 @@ -188,6 +214,7 @@ Vektor R4 Vektor R4 ヴェクター R5 + Vektor R4 Vektor R5 Carbine @@ -195,6 +222,7 @@ Vektor R5 Carbine Vektor R5 Carabina ヴェクター R5 カービン + Vektor R5 Carbine Vektor R5 Carbine GL @@ -202,6 +230,7 @@ Vektor R5 Carbine GL Vektor R5 Carabina GL ヴェクター R5 カービン GL + Vektor R5 Carbine GL Vektor R5 Carbine (Snake) @@ -209,6 +238,7 @@ Vektor R5 Carbine (Schlange) Vektor R5 Carabina (Serpe) ヴェクター R5 カービン (ヘビ柄) + Vektor R5 Carbine (Змея) Vektor R5 Carbine GL (Snake) @@ -216,6 +246,7 @@ Vektor R5 Carbine GL (Schlange) Vektor R5 Carabina GL (Serpe) ヴェクター R5 カービン GL (ヘビ柄) + Vektor R5 Carbine GL (Змея) XMS diff --git a/addons/cookoff/functions/fnc_detonateAmmunition.sqf b/addons/cookoff/functions/fnc_detonateAmmunition.sqf index cc39ff43cf..9b3c19ab42 100644 --- a/addons/cookoff/functions/fnc_detonateAmmunition.sqf +++ b/addons/cookoff/functions/fnc_detonateAmmunition.sqf @@ -77,7 +77,7 @@ private _spawnProjectile = { }; private _speed = random (_speedOfAmmo / 10) max 1; -_simType = toLower _simType; +_simType = toLowerANSI _simType; switch (_simType) do { case ("shotbullet"): { [QGVAR(playCookoffSound), [_vehicle, _simType]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_handleDamageBox.sqf b/addons/cookoff/functions/fnc_handleDamageBox.sqf index dfc5cb7267..9368cd3193 100644 --- a/addons/cookoff/functions/fnc_handleDamageBox.sqf +++ b/addons/cookoff/functions/fnc_handleDamageBox.sqf @@ -27,7 +27,7 @@ if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith { private _hitpoint = "#structural"; if (_hitIndex != -1) then { - _hitpoint = toLower ((getAllHitPointsDamage _vehicle param [0, []]) select _hitIndex); + _hitpoint = toLowerANSI ((getAllHitPointsDamage _vehicle param [0, []]) select _hitIndex); }; // get change in damage diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index 76aebcad60..5f764a24b7 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -188,6 +188,7 @@ 쿡오프 후 차량이 항상 파괴되는지 여부를 조정합니다. Contrôle si les véhicules seront toujours détruits après l'auto-inflammation. Define se os veículos serão sempre destruídos após cozinhamento. + Определяет, всегда ли транспортные средства будут уничтожаться после детонации. Enable Cook-Off Vehicle Fire diff --git a/addons/csw/CfgVehicles.hpp b/addons/csw/CfgVehicles.hpp index dd5537f645..424289c077 100644 --- a/addons/csw/CfgVehicles.hpp +++ b/addons/csw/CfgVehicles.hpp @@ -4,7 +4,7 @@ class CfgVehicles { class ACE_SelfActions { class GVAR(deploy) { displayName = CSTRING(PlaceTripod_displayName); - condition = QUOTE(call FUNC(assemble_canDeployTripod)); + condition = QUOTE(call FUNC(canDeployTripod)); statement = QUOTE(call FUNC(assemble_deployTripod)); exceptions[] = {}; }; @@ -36,7 +36,7 @@ class CfgVehicles { condition = "true"; class GVAR(pickUp) { displayName = CSTRING(Pickup_displayName); - condition = QUOTE(call FUNC(assemble_canPickupTripod)); + condition = QUOTE(call FUNC(canPickupTripod)); statement = QUOTE(call FUNC(assemble_pickupTripod)); }; class GVAR(mountWeapon) { @@ -125,10 +125,11 @@ class CfgVehicles { class StaticWeapon: LandVehicle { class ACE_Actions { class ACE_MainActions { + // Workaround for static weapons' Get In memory point being at the front of the gun class GVAR(getIn) { displayName = CSTRING(GetIn_displayName); condition = QUOTE(call FUNC(canGetIn)); - statement = QUOTE(call FUNC(getIn)); + statement = QUOTE(_player moveInTurret [ARR_2(_target,[0])]); }; }; }; diff --git a/addons/csw/XEH_PREP.hpp b/addons/csw/XEH_PREP.hpp index 5966578aca..fed4120c86 100644 --- a/addons/csw/XEH_PREP.hpp +++ b/addons/csw/XEH_PREP.hpp @@ -6,9 +6,9 @@ PREP(ai_handleFired); PREP(ai_handleGetIn); PREP(ai_reload); -PREP(assemble_canDeployTripod); +PREP(canDeployTripod); PREP(assemble_canDeployWeapon); -PREP(assemble_canPickupTripod); +PREP(canPickupTripod); PREP(assemble_canPickupWeapon); PREP(assemble_deployTripod); PREP(assemble_deployWeapon); @@ -17,13 +17,12 @@ PREP(assemble_pickupTripod); PREP(assemble_pickupWeapon); PREP(canGetIn); -PREP(getIn); PREP(getCarryMagazine); PREP(proxyWeapon); -PREP(reload_actionsLoad); -PREP(reload_actionsUnload); +PREP(getLoadActions); +PREP(getUnloadActions); PREP(reload_canLoadMagazine); PREP(reload_canUnloadMagazine); PREP(reload_getLoadableMagazines); @@ -33,5 +32,5 @@ PREP(reload_handleRemoveTurretMag); PREP(reload_handleReturnAmmo); PREP(reload_loadMagazine); -PREP(staticWeaponInit); +PREP(initVehicle); PREP(staticWeaponInit_unloadExtraMags); diff --git a/addons/csw/XEH_postInit.sqf b/addons/csw/XEH_postInit.sqf index 8a0f92ce47..87196f3377 100644 --- a/addons/csw/XEH_postInit.sqf +++ b/addons/csw/XEH_postInit.sqf @@ -6,18 +6,27 @@ GVAR(vehicleMagCache) = createHashMap; TRACE_3("settingsInit",GVAR(defaultAssemblyMode),GVAR(handleExtraMagazines),GVAR(ammoHandling)); ["StaticWeapon", "Init", { // needs a small delay for network syncing, or we end up with duplicate mags with ammo handling - [LINKFUNC(staticWeaponInit), _this, 1] call CBA_fnc_waitAndExecute; + [LINKFUNC(initVehicle), _this, 1] call CBA_fnc_waitAndExecute; }, true, [], true] call CBA_fnc_addClassEventHandler; + + GVAR(quickmountEnabled) = ( + missionNamespace getVariable [QEGVAR(quickmount,enabled), false] && + {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1,3]} + ); }] call CBA_fnc_addEventHandler; +["CBA_SettingChanged", { + GVAR(quickmountEnabled) = ( + missionNamespace getVariable [QEGVAR(quickmount,enabled), false] && + {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1,3]} + ); +}] call CBA_fnc_addEventHandler; // Event handlers: [QGVAR(addTurretMag), LINKFUNC(reload_handleAddTurretMag)] call CBA_fnc_addEventHandler; [QGVAR(removeTurretMag), LINKFUNC(reload_handleRemoveTurretMag)] call CBA_fnc_addEventHandler; [QGVAR(returnAmmo), LINKFUNC(reload_handleReturnAmmo)] call CBA_fnc_addEventHandler; - - #ifdef DEBUG_MODE_FULL call compile preprocessFileLineNumbers QPATHTOF(dev\checkStaticWeapons.sqf); #endif diff --git a/addons/csw/dev/checkStaticWeapons.sqf b/addons/csw/dev/checkStaticWeapons.sqf index 1d7ffe988d..7d9917daa7 100644 --- a/addons/csw/dev/checkStaticWeapons.sqf +++ b/addons/csw/dev/checkStaticWeapons.sqf @@ -7,14 +7,14 @@ INFO("Checking static weapons"); private _staticWeaponConfigs = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(configName _x) isKindOf 'StaticWeapon'}", true]; private _staticPublic = _staticWeaponConfigs select {(getNumber (_x >> "scope")) == 2}; -INFO_2("Static Weapons [%1] - CSW Enabled [%2]",count _staticPublic,{(getNumber (_x >> "ace_csw" >> "enabled")) == 1} count _staticPublic); +INFO_2("Static Weapons [%1] - CSW Enabled [%2]",count _staticPublic,{(getNumber (_x >> QUOTE(ADDON) >> "enabled")) == 1} count _staticPublic); INFO("------ Checking static weapons inheritance ------"); private _explicitBases = []; private _inherited = []; { private _config = _x; - private _configEnabled = (getNumber (_config >> "ace_csw" >> "enabled")) == 1; + private _configEnabled = (getNumber (_config >> QUOTE(ADDON) >> "enabled")) == 1; if (_configEnabled) then { private _configExplicit = (count configProperties [_config, "configName _x == 'ace_csw'", false]) == 1; if (_configExplicit) then { @@ -69,7 +69,7 @@ private _logAll = false; { //IGNORE_PRIVATE_WARNING ["_x", "_y"]; - INFO_2("[%1] has no carry varient - Used in %2",_x,_y); + INFO_2("[%1] has no carry variant - Used in %2",_x,_y); } forEach _hash; INFO("------ End -------"); diff --git a/addons/csw/functions/fnc_ai_handleFired.sqf b/addons/csw/functions/fnc_ai_handleFired.sqf index e6d76f13dc..d92e517091 100644 --- a/addons/csw/functions/fnc_ai_handleFired.sqf +++ b/addons/csw/functions/fnc_ai_handleFired.sqf @@ -12,12 +12,12 @@ * Public: No */ -params ["_staticWeapon", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_gunner"]; -TRACE_8("firedEH:",_staticWeapon,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_gunner); +params ["_vehicle", "_weapon", "", "", "", "_magazine", "", "_gunner"]; +TRACE_4("firedEH:",_vehicle,_weapon,_magazine,_gunner); +if (someAmmo _vehicle) exitWith {}; if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; -if (someAmmo _staticWeapon) exitWith {}; -TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); +TRACE_1("need ammo",magazinesAllTurrets _vehicle); -[_staticWeapon, _gunner, _weapon, _magazine] call FUNC(ai_reload); +[_vehicle, _gunner, _weapon, _magazine] call FUNC(ai_reload); diff --git a/addons/csw/functions/fnc_ai_handleGetIn.sqf b/addons/csw/functions/fnc_ai_handleGetIn.sqf index 26a94b58e3..f14a4ccbc7 100644 --- a/addons/csw/functions/fnc_ai_handleGetIn.sqf +++ b/addons/csw/functions/fnc_ai_handleGetIn.sqf @@ -11,12 +11,13 @@ * * Public: No */ -params ["_staticWeapon", "_role", "_gunner"]; -TRACE_3("getInEH:",_staticWeapon,_role,_gunner); +params ["_vehicle", "", "_gunner"]; +TRACE_2("getInEH:",_vehicle,_gunner); + +if (someAmmo _vehicle) exitWith {}; if ((!local _gunner) || {[_gunner] call EFUNC(common,isPlayer)}) exitWith {}; -if (someAmmo _staticWeapon) exitWith {}; -TRACE_2("need ammo",someAmmo _staticWeapon,magazinesAllTurrets _staticWeapon); +TRACE_1("need ammo",magazinesAllTurrets _vehicle); -[_staticWeapon, _gunner, currentWeapon _staticWeapon] call FUNC(ai_reload); +[_vehicle, _gunner, currentWeapon _vehicle] call FUNC(ai_reload); diff --git a/addons/csw/functions/fnc_ai_reload.sqf b/addons/csw/functions/fnc_ai_reload.sqf index 31d41b0588..d472233bcf 100644 --- a/addons/csw/functions/fnc_ai_reload.sqf +++ b/addons/csw/functions/fnc_ai_reload.sqf @@ -14,6 +14,7 @@ * * Public: No */ + params ["_staticWeapon", "_gunner", "_weapon", ["_magazine", ""]]; private _turretPath = [_gunner] call EFUNC(common,getTurretIndex); diff --git a/addons/csw/functions/fnc_assemble_canDeployTripod.sqf b/addons/csw/functions/fnc_assemble_canDeployTripod.sqf deleted file mode 100644 index 82412b5556..0000000000 --- a/addons/csw/functions/fnc_assemble_canDeployTripod.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author:tcvm - * Checks if the player can deploy the tripod. - * - * Arguments: - * 0: Unit - * - * Return Value: - * Can deploy - * - * Example: - * [player] call ace_csw_fnc_assemble_canDeployTripod - * - * Public: No - */ - -params ["_player"]; - -(getText(configFile >> "CfgWeapons" >> (secondaryWeapon _player) >> QUOTE(ADDON) >> "type") == "mount") - diff --git a/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf b/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf index 897ee6acd0..57f2ce2bc8 100644 --- a/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author:tcvm + * Author: tcvm * Checks if you can deploy a weapon on the tripod * * Arguments: @@ -22,4 +22,3 @@ if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapo // If the current launcher has a config-value that defines the tripod, it is a CSW (alive _target) && {(getText(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> (typeOf _target))) != ""} - diff --git a/addons/csw/functions/fnc_assemble_canPickupTripod.sqf b/addons/csw/functions/fnc_assemble_canPickupTripod.sqf deleted file mode 100644 index 8a7656db83..0000000000 --- a/addons/csw/functions/fnc_assemble_canPickupTripod.sqf +++ /dev/null @@ -1,22 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author:tcvm - * Checks if the player can pick-up the tripod. - * - * Arguments: - * 0: Tripod - * 1: Unit - * - * Return Value: - * Can pickup - * - * Example: - * [tripod, player] call ace_csw_fnc_assemble_canPickupTripod - * - * Public: No - */ - -params ["_tripod", "_player"]; - -((secondaryWeapon _player) isEqualTo "") && {alive _tripod} - diff --git a/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf b/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf index 9665311d9d..40c6b527d3 100644 --- a/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_canPickupWeapon.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author:tcvm + * Author: tcvm * If the CSW is mounted or in use this will not allow you to dismount the weapon * * Arguments: @@ -23,4 +23,3 @@ private _notCrewed = (crew _staticWeapon) isEqualTo []; private _deadCrew = !(alive (gunner _staticWeapon)); // need to eject body??? _assemblyMode && {_notCrewed || _deadCrew} - diff --git a/addons/csw/functions/fnc_assemble_deployTripod.sqf b/addons/csw/functions/fnc_assemble_deployTripod.sqf index d3317a4e40..9c2f3ef725 100644 --- a/addons/csw/functions/fnc_assemble_deployTripod.sqf +++ b/addons/csw/functions/fnc_assemble_deployTripod.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author:tcvm + * Author: tcvm * Deploys the tripod * * Arguments: @@ -40,7 +40,7 @@ _cswTripod setVariable [QGVAR(secondaryWeaponMagazine), _secondaryWeaponMagazine]; }; if (!GVAR(defaultAssemblyMode)) then { - [_cswTripod, "disableWeaponAssembly", "ace_csw", true] call EFUNC(common,statusEffect_set); + [_cswTripod, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); }; private _posATL = _player getRelPos [2, 0]; diff --git a/addons/csw/functions/fnc_assemble_deployWeapon.sqf b/addons/csw/functions/fnc_assemble_deployWeapon.sqf index e34e5d19d8..772cad65d4 100644 --- a/addons/csw/functions/fnc_assemble_deployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_deployWeapon.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author:tcvm + * Author: tcvm * Deploys the current CSW * * Arguments: diff --git a/addons/csw/functions/fnc_assemble_pickupTripod.sqf b/addons/csw/functions/fnc_assemble_pickupTripod.sqf index 449a445dc2..d85f9a3f83 100644 --- a/addons/csw/functions/fnc_assemble_pickupTripod.sqf +++ b/addons/csw/functions/fnc_assemble_pickupTripod.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author:tcvm + * Author: tcvm * Picks up the tripod and adds it to the player launcher slot * * Arguments: @@ -44,4 +44,3 @@ TRACE_3("",_pickupTime,typeOf _tripod,_tripodClassname); [TIME_PROGRESSBAR(_pickupTime), [_tripod, _player, _tripodClassname], _onFinish, {}, localize LSTRING(PickupTripod_progressBar), _condition] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; - diff --git a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf index 99d0229566..4ee01931db 100644 --- a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author:tcvm + * Author: tcvm * Dismounts the weapon from the tripod and drops its backpack beside * * Arguments: @@ -38,14 +38,14 @@ private _weaponDir = getDir _staticWeapon; private _carryWeaponMag = ""; - private _carryWeaponMags = getArray (configFile >> "CfgWeapons" >> _carryWeaponClassname >> "magazines") apply {toLower _x}; + private _carryWeaponMags = getArray (configFile >> "CfgWeapons" >> _carryWeaponClassname >> "magazines") apply {toLowerANSI _x}; LOG("remove ammo"); { _x params ["_xMag", "", "_xAmmo"]; if (_xAmmo == 0) then {continue}; private _carryMag = _xMag call FUNC(getCarryMagazine); - if (_carryWeaponMag isEqualTo "" && {toLower _carryMag in _carryWeaponMags}) then { + if (_carryWeaponMag isEqualTo "" && {toLowerANSI _carryMag in _carryWeaponMags}) then { TRACE_3("Adding mag to secondary weapon",_xMag,_xAmmo,_carryMag); _carryWeaponMag = _carryMag; DEC(_xAmmo); diff --git a/addons/csw/functions/fnc_canDeployTripod.sqf b/addons/csw/functions/fnc_canDeployTripod.sqf new file mode 100644 index 0000000000..8969758e4d --- /dev/null +++ b/addons/csw/functions/fnc_canDeployTripod.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Checks if the unit can deploy a tripod + * + * Arguments: + * 0: Unit + * + * Return Value: + * Can deploy + * + * Example: + * player call ace_csw_fnc_canDeployTripod + * + * Public: No + */ + +params ["_unit"]; + +private _secondaryWeapon = secondaryWeapon _unit; + +_secondaryWeapon != "" && {getText (configFile >> "CfgWeapons" >> _secondaryWeapon >> QUOTE(ADDON) >> "type") == "mount"} // return diff --git a/addons/csw/functions/fnc_canGetIn.sqf b/addons/csw/functions/fnc_canGetIn.sqf index 16ffe29a77..16446c4fb2 100644 --- a/addons/csw/functions/fnc_canGetIn.sqf +++ b/addons/csw/functions/fnc_canGetIn.sqf @@ -1,28 +1,23 @@ #include "..\script_component.hpp" /* - * Author:tcvm - * Checks if the player can get in the weapon + * Author: tcvm + * Checks if it's possible to get in the CSW * * Arguments: - * 0: Static Weapon + * 0: Vehicle * * Return Value: * None * * Example: - * [cursorObject] call ace_csw_fnc_canGetIn + * cursorObject call ace_csw_fnc_canGetIn * * Public: No */ -// hide this action if quick mount is enabled -if ((missionNamespace getVariable [QEGVAR(quickmount,enabled), false]) && {(missionNamespace getVariable [QEGVAR(quickmount,enableMenu), -1]) in [1, 3]}) exitWith { - false -}; +// Hide this action if quick mount is enabled +if (GVAR(quickmountEnabled)) exitWith {false}; -params ["_staticWeapon"]; +params ["_vehicle"]; -alive _staticWeapon -&& {!(alive (gunner _staticWeapon))} -&& {(locked _staticWeapon) < 2} -&& {0.3 < ((vectorUp _staticWeapon) select 2)} +alive _vehicle && {!(alive (gunner _vehicle))} && {(locked _vehicle) < 2} && {!(_vehicle lockedTurret [0])} && {0.3 < ((vectorUp _vehicle) select 2)} // return diff --git a/addons/csw/functions/fnc_canPickupTripod.sqf b/addons/csw/functions/fnc_canPickupTripod.sqf new file mode 100644 index 0000000000..0a9f0f5f90 --- /dev/null +++ b/addons/csw/functions/fnc_canPickupTripod.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Checks if the unit can pickup the tripod + * + * Arguments: + * 0: Tripod + * 1: Unit + * + * Return Value: + * Can pickup + * + * Example: + * [cursorObject, player] call ace_csw_fnc_canPickupTripod + * + * Public: No + */ + +params ["_tripod", "_unit"]; + +((secondaryWeapon _unit) == "") && {alive _tripod} // return diff --git a/addons/csw/functions/fnc_getIn.sqf b/addons/csw/functions/fnc_getIn.sqf deleted file mode 100644 index 61ca962d06..0000000000 --- a/addons/csw/functions/fnc_getIn.sqf +++ /dev/null @@ -1,24 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author:tcvm - * An action for the player to get in the CSW - * Due to the fact that the default static weapons "Get In" memory point is at the front of - * the gun and can't be acssesed from the back, I am implementing this to get around that issue. - * - * Arguments: - * 0: Static Weapon - * 1: Unit - * - * Return Value: - * None - * - * Example: - * [cursorObject, player] call ace_csw_fnc_getIn - * - * Public: No - */ - -params ["_staticWeapon", "_player"]; -TRACE_2("getIn",_staticWeapon,_player); - -_player moveInTurret [_staticWeapon, [0]]; diff --git a/addons/csw/functions/fnc_reload_actionsLoad.sqf b/addons/csw/functions/fnc_getLoadActions.sqf similarity index 68% rename from addons/csw/functions/fnc_reload_actionsLoad.sqf rename to addons/csw/functions/fnc_getLoadActions.sqf index 557811d440..456362a3b6 100644 --- a/addons/csw/functions/fnc_reload_actionsLoad.sqf +++ b/addons/csw/functions/fnc_getLoadActions.sqf @@ -1,42 +1,42 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Gets sub actions for what the player can load into the static weapon + * Gets sub actions for what the unit can load into the CSW * * Arguments: - * 0: Static Weapon - * 1: Player + * 0: Vehicle + * 1: Unit * * Return Value: * Actions * * Example: - * [cursorObject, player] call ace_csw_fnc_reload_actionsLoad + * [cursorObject, player] call ace_csw_fnc_getLoadActions * * Public: No */ -params ["_vehicle", "_player"]; +params ["_vehicle", "_unit"]; -private _actions = []; -private _loadableMagazines = [_vehicle, _player] call FUNC(reload_getLoadableMagazines); +private _loadableMagazines = [_vehicle, _unit] call FUNC(reload_getLoadableMagazines); +if (_loadableMagazines isEqualTo []) exitWith {[]}; private _statement = { - params ["_target", "_player", "_params"]; - _params params ["_carryMag", "_turretPath", "", "_magSource"]; + params ["_target", "_player", "_args"]; + _args params ["_carryMag", "_turretPath", "", "_magSource"]; [_target, _turretPath, _carryMag, _magSource, _player] call FUNC(reload_loadMagazine); }; private _condition = { - params ["_target", "_player", "_params"]; - _params params ["_carryMag", "_turretPath", "", "_magSource"]; + params ["_target", "_player", "_args"]; + _args params ["_carryMag", "_turretPath", "", "_magSource"]; ([_target, _turretPath, _carryMag, _magSource] call FUNC(reload_canLoadMagazine)) select 0 }; private _cfgMagazines = configFile >> "CfgMagazines"; // micro-optimization - +private _actions = []; { _x params ["_carryMag", "", "_loadInfo"]; _loadInfo params ["", "", "", "_isBeltLinking"]; diff --git a/addons/csw/functions/fnc_getUnloadActions.sqf b/addons/csw/functions/fnc_getUnloadActions.sqf new file mode 100644 index 0000000000..32d9cc091a --- /dev/null +++ b/addons/csw/functions/fnc_getUnloadActions.sqf @@ -0,0 +1,74 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Gets sub actions for what can be unloaded from the CSW + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Actions + * + * Example: + * cursorObject call ace_csw_fnc_getUnloadActions + * + * Public: No + */ + +params ["_vehicle"]; + +private _statement = { + params ["_target", "_player", "_args"]; + _args params ["_vehMag", "_turretPath", "_carryMag"]; + TRACE_5("starting unload",_target,_turretPath,_player,_carryMag,_vehMag); + + private _timeToUnload = 1; + if (!isNull (configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime")) then { + _timeToUnload = getNumber (configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime"); + }; + + [ + TIME_PROGRESSBAR(_timeToUnload), + [_target, _turretPath, _player, _carryMag, _vehMag], + { + (_this select 0) params ["_target", "_turretPath", "", "_carryMag", "_vehMag"]; + TRACE_5("unload progressBar finish",_target,_turretPath,_carryMag,_vehMag,_player); + [QGVAR(removeTurretMag), [_target, _turretPath, _carryMag, _vehMag, _player]] call CBA_fnc_globalEvent; + }, + {TRACE_1("unload progressBar fail",_this);}, + format [localize LSTRING(unloadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")], + {(_this select 0) call FUNC(reload_canUnloadMagazine)}, + ["isNotInside"] + ] call EFUNC(common,progressBar); +}; + +private _condition = { + params ["_target", "_player", "_args"]; + _args params ["_vehMag", "_turretPath", "_carryMag"]; + [_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine) +}; + +private _actions = []; +private _handledMagTypes = []; + +private _cfgMagazines = configFile >> "CfgMagazines"; + +// Go through magazines on static weapon and check if any are unloadable +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + + if ((_xAmmo > 0) && {!(_xMag in _handledMagTypes)}) then { + _handledMagTypes pushBack _xMag; + private _carryMag = _xMag call FUNC(getCarryMagazine); + if (_carryMag == "") exitWith {}; + + private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName"); + private _text = format [LLSTRING(unloadX), _displayName]; + private _picture = getText (_cfgMagazines >> _carryMag >> "picture"); + private _action = [format ["unload_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, [_xMag, _xTurret, _carryMag]] call EFUNC(interact_menu,createAction); + _actions pushBack [_action, [], _vehicle]; + }; +} forEach (magazinesAllTurrets _vehicle); + +TRACE_1("unloadActions",count _actions); +_actions diff --git a/addons/csw/functions/fnc_staticWeaponInit.sqf b/addons/csw/functions/fnc_initVehicle.sqf similarity index 60% rename from addons/csw/functions/fnc_staticWeaponInit.sqf rename to addons/csw/functions/fnc_initVehicle.sqf index 6dcbbf52e6..ed882e435c 100644 --- a/addons/csw/functions/fnc_staticWeaponInit.sqf +++ b/addons/csw/functions/fnc_initVehicle.sqf @@ -1,59 +1,63 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Initializes weapon to disable weapon disassembling + * Initializes CSW systems on vehicle * * Arguments: - * 0: Weapon + * 0: Vehicle * * Return Value: * None * * Example: - * [weapon] call ace_csw_fnc_staticWeaponInit + * cursorObject call ace_csw_fnc_initVehicle * * Public: No */ -params ["_staticWeapon"]; -if (isNull _staticWeapon) exitWith { WARNING_1("%1 became null",_staticWeapon) }; -private _typeOf = typeOf _staticWeapon; -private _configOf = configOf _staticWeapon; -private _configEnabled = (getNumber (_configOf >> "ace_csw" >> "enabled")) == 1; -private _assemblyConfig = _configEnabled && {(getText (_configOf >> "ace_csw" >> "disassembleWeapon")) != ""}; -TRACE_4("staticWeaponInit",_staticWeapon,_typeOf,_configEnabled,_assemblyConfig); - -if (_configEnabled && {GVAR(ammoHandling) == 2}) then { - TRACE_1("adding AI fired handler",_staticWeapon); - _staticWeapon addEventHandler ["Fired", LINKFUNC(ai_handleFired)]; - _staticWeapon addEventHandler ["GetIn", LINKFUNC(ai_handleGetIn)]; // handle AI getting inside weapon with no ammo +params ["_vehicle"]; +if (!alive _vehicle) exitWith { WARNING_1("%1 not alive",_vehicle); }; +if (!simulationEnabled _vehicle) exitWith { + [{simulationEnabled _this}, FUNC(initVehicle), _vehicle] call CBA_fnc_waitUntilAndExecute; }; -TRACE_2("",local _staticWeapon,_staticWeapon turretLocal [0]); -if (_configEnabled && {_staticWeapon turretLocal [0]}) then { // if turret is local to us, then handle mags/weapon +private _typeOf = typeOf _vehicle; +private _configOf = configOf _vehicle; +private _configEnabled = (getNumber (_configOf >> QUOTE(ADDON) >> "enabled")) == 1; +private _assemblyConfig = _configEnabled && {(getText (_configOf >> QUOTE(ADDON) >> "disassembleWeapon")) != ""}; +TRACE_4("initVehicle",_vehicle,_typeOf,_configEnabled,_assemblyConfig); + +if (_configEnabled && {GVAR(ammoHandling) == 2}) then { + TRACE_1("adding AI fired handler",_vehicle); + _vehicle addEventHandler ["Fired", LINKFUNC(ai_handleFired)]; + _vehicle addEventHandler ["GetIn", LINKFUNC(ai_handleGetIn)]; // handle AI getting inside weapon with no ammo +}; + +TRACE_2("",local _vehicle,_vehicle turretLocal [0]); +if (_configEnabled && {_vehicle turretLocal [0]}) then { // if turret is local to us, then handle mags/weapon [{ - params ["_staticWeapon"]; - if (!alive _staticWeapon) exitWith { TRACE_1("dead/deleted",_staticWeapon); }; + params ["_vehicle"]; + if (!alive _vehicle) exitWith { TRACE_1("dead/deleted",_vehicle); }; // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] - private _assemblyModeIndex = _staticWeapon getVariable [QGVAR(assemblyMode), 3]; + private _assemblyModeIndex = _vehicle getVariable [QGVAR(assemblyMode), 3]; private _emptyWeapon = _assemblyModeIndex isEqualTo 2; private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select _assemblyModeIndex; - TRACE_2("turretLocal",_staticWeapon,_assemblyMode); - [_staticWeapon, [0], _assemblyMode, _emptyWeapon] call FUNC(proxyWeapon); - [_staticWeapon, _assemblyMode, _emptyWeapon] call FUNC(staticWeaponInit_unloadExtraMags); - }, [_staticWeapon]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly + TRACE_2("turretLocal",_vehicle,_assemblyMode); + [_vehicle, [0], _assemblyMode, _emptyWeapon] call FUNC(proxyWeapon); + [_vehicle, _assemblyMode, _emptyWeapon] call FUNC(staticWeaponInit_unloadExtraMags); + }, [_vehicle]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly }; if (_assemblyConfig) then { [{ - params ["_staticWeapon"]; - if (!alive _staticWeapon) exitWith { TRACE_1("dead/deleted",_staticWeapon); }; - private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 3]); - TRACE_2("assemblyConfig present",_staticWeapon,_assemblyMode); + params ["_vehicle"]; + if (!alive _vehicle) exitWith { TRACE_1("dead/deleted",_vehicle); }; + private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_vehicle getVariable [QGVAR(assemblyMode), 3]); + TRACE_2("assemblyConfig present",_vehicle,_assemblyMode); if (_assemblyMode) then { // Disable vanilla assembly if assemblyMode enabled - [_staticWeapon, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + [_vehicle, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); }; - }, [_staticWeapon]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly + }, [_vehicle]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly }; // Add interactions for players @@ -76,7 +80,7 @@ if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then { }; private _childenCode = { BEGIN_COUNTER(getActions); // can remove for final release - private _ret = (call FUNC(reload_actionsLoad)) + (call FUNC(reload_actionsUnload)); + private _ret = (call FUNC(getLoadActions)) + (call FUNC(getUnloadActions)); END_COUNTER(getActions); _ret }; diff --git a/addons/csw/functions/fnc_proxyWeapon.sqf b/addons/csw/functions/fnc_proxyWeapon.sqf index 40ab4b1e4c..fedd1d412b 100644 --- a/addons/csw/functions/fnc_proxyWeapon.sqf +++ b/addons/csw/functions/fnc_proxyWeapon.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: tcvm, PabstMirror - * Handles the use of proxy weapons to fix engine-reload times + * Handles the use of proxy weapons to bypass engine reload times * * Arguments: - * 0: Weapon + * 0: Vehicle * 1: Turret * 2: Proxy weapon needed * 2: Weapon should be emptied @@ -13,34 +13,34 @@ * None * * Example: - * [weapon, [0], true, false] call ace_csw_fnc_proxyWeapon + * [cursorObject, [0], true, false] call ace_csw_fnc_proxyWeapon * * Public: No */ -params ["_staticWeapon", "_turret", "_needed", "_emptyWeapon"]; -TRACE_4("proxyWeapon",_staticWeapon,_turret,_needed,_emptyWeapon); +params ["_vehicle", "_turret", "_needed", "_emptyWeapon"]; +TRACE_4("proxyWeapon",_vehicle,_turret,_needed,_emptyWeapon); -if (_staticWeapon getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _staticWeapon); }; +if (_vehicle getVariable [format [QGVAR(proxyHandled_%1), _turret], false]) exitWith { TRACE_1("already handled",typeOf _vehicle); }; -private _proxyWeapon = getText (configOf _staticWeapon >> "ace_csw" >> "proxyWeapon"); +private _proxyWeapon = getText (configOf _vehicle >> QUOTE(ADDON) >> "proxyWeapon"); -TRACE_2("",typeOf _staticWeapon,_proxyWeapon); +TRACE_2("",typeOf _vehicle,_proxyWeapon); if (_proxyWeapon == "") exitWith {}; -private _currentWeapon = (_staticWeapon weaponsTurret [0]) param [0, "#none"]; +private _currentWeapon = (_vehicle weaponsTurret [0]) param [0, "#none"]; if ((missionNamespace getVariable [_proxyWeapon, objNull]) isEqualType {}) then { // check if string is a function TRACE_1("Calling proxyWeapon function",_proxyWeapon); // This function may replace magazines or do other things to the static weapon - _proxyWeapon = [_staticWeapon, _turret, _currentWeapon, _needed, _emptyWeapon] call (missionNamespace getVariable _proxyWeapon); + _proxyWeapon = [_vehicle, _turret, _currentWeapon, _needed, _emptyWeapon] call (missionNamespace getVariable _proxyWeapon); _needed = _proxyWeapon != ""; }; if (!_needed) exitWith { TRACE_2("not needed",_needed,_proxyWeapon); }; // Rearm compatibility, prevent reloading entire static and breaking CSW -_staticWeapon setVariable [QEGVAR(rearm,scriptedLoadout), true, true]; +_vehicle setVariable [QEGVAR(rearm,scriptedLoadout), true, true]; TRACE_2("swapping to proxy weapon",_currentWeapon,_proxyWeapon); -_staticWeapon removeWeaponTurret [_currentWeapon, _turret]; -_staticWeapon addWeaponTurret [_proxyWeapon, _turret]; -_staticWeapon setVariable [format [QGVAR(proxyHandled_%1), _turret], true, true]; +_vehicle removeWeaponTurret [_currentWeapon, _turret]; +_vehicle addWeaponTurret [_proxyWeapon, _turret]; +_vehicle setVariable [format [QGVAR(proxyHandled_%1), _turret], true, true]; diff --git a/addons/csw/functions/fnc_reload_actionsUnload.sqf b/addons/csw/functions/fnc_reload_actionsUnload.sqf deleted file mode 100644 index 5ef40ace70..0000000000 --- a/addons/csw/functions/fnc_reload_actionsUnload.sqf +++ /dev/null @@ -1,75 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: PabstMirror - * Gets sub actions for what the player can unload from the static weapon - * - * Arguments: - * 0: Target - * 1: Player - * - * Return Value: - * Actions - * - * Example: - * [cursorObject, player] call ace_csw_fnc_reload_actionsUnload - * - * Public: No - */ - -params ["_vehicle", "_player"]; - -private _statement = { - params ["_target", "_player", "_params"]; - _params params ["_vehMag", "_turretPath", "_carryMag"]; - TRACE_5("starting unload",_target,_turretPath,_player,_carryMag,_vehMag); - - private _timeToUnload = 1; - if (!isNull(configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime")) then { - _timeToUnload = getNumber(configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime"); - }; - - [ - TIME_PROGRESSBAR(_timeToUnload), - [_target, _turretPath, _player, _carryMag, _vehMag], - { - (_this select 0) params ["_target", "_turretPath", "", "_carryMag", "_vehMag"]; - TRACE_5("unload progressBar finish",_target,_turretPath,_carryMag,_vehMag,_player); - [QGVAR(removeTurretMag), [_target, _turretPath, _carryMag, _vehMag, _player]] call CBA_fnc_globalEvent; - }, - {TRACE_1("unload progressBar fail",_this);}, - format [localize LSTRING(unloadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")], - {(_this select 0) call FUNC(reload_canUnloadMagazine)}, - ["isNotInside"] - ] call EFUNC(common,progressBar); -}; - -private _condition = { - params ["_target", "_player", "_params"]; - _params params ["_vehMag", "_turretPath", "_carryMag"]; - [_target, _turretPath, _player, _carryMag, _vehMag] call FUNC(reload_canUnloadMagazine) -}; - -private _actions = []; -private _handeledMagTypes = []; - -private _cfgMagazines = configFile >> "CfgMagazines"; - -// Go through magazines on static weapon and check if any are unloadable -{ - _x params ["_xMag", "_xTurret", "_xAmmo"]; - - if ((_xAmmo > 0) && {!(_xMag in _handeledMagTypes)}) then { - _handeledMagTypes pushBack _xMag; - private _carryMag = _xMag call FUNC(getCarryMagazine); - if (_carryMag == "") exitWith {}; - - private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName"); - private _text = format [LLSTRING(unloadX), _displayName]; - private _picture = getText (_cfgMagazines >> _carryMag >> "picture"); - private _action = [format ["unload_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, [_xMag, _xTurret, _carryMag]] call EFUNC(interact_menu,createAction); - _actions pushBack [_action, [], _vehicle]; - }; -} forEach (magazinesAllTurrets _vehicle); - -TRACE_1("unloadActions",count _actions); -_actions diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf index 74cd9f73b5..e5aa51d342 100644 --- a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author:tcvm, PabstMirror + * Author: tcvm, PabstMirror * Handles adding ammo to a turret * Called from a global event but only runs where turret is local * diff --git a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf index d718811d55..59d948ba27 100644 --- a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf +++ b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author:tcvm + * Author: tcvm * Handles removing ammo from a turret * Called from a global event but only runs where turret is local * diff --git a/addons/csw/stringtable.xml b/addons/csw/stringtable.xml index b6f8ecb47e..4aea2a24b4 100644 --- a/addons/csw/stringtable.xml +++ b/addons/csw/stringtable.xml @@ -179,7 +179,7 @@ Scorta di munizioni 탄약 보관 Magazyn amunicji - 弾薬の格納場所 + 弾薬保管位置 弹药存储 Хранилище боеприпасов Almacenamiento de munición @@ -192,7 +192,7 @@ Determina se ulteriori caricatori verranno stoccati sul suolo o in una cassa di munizioni. 여분의 탄약을 지면 또는 탄약 상자에 넣을 지 결정합니다. Decyduje, czy dodatkowe magazynki przechowywane są na ziemi, czy w skrzynce z amunicją. - 追加の弾倉を地面に配置するか、弾薬箱内に保管するかを設定します。 + 追加の弾倉を地面に直接配置するか、弾薬箱内に保管するかを設定します。 设置多余的弹夹是存放在地面上还是弹药箱内 Определяет будут ли дополнительные магазины лежать на земле или внутри хранилища Determina si los cargadores extra son almacenados en el suelo o en una caja de munición diff --git a/addons/disarming/functions/fnc_openDisarmDialog.sqf b/addons/disarming/functions/fnc_openDisarmDialog.sqf index a3762aec9f..27a7dbc521 100644 --- a/addons/disarming/functions/fnc_openDisarmDialog.sqf +++ b/addons/disarming/functions/fnc_openDisarmDialog.sqf @@ -74,7 +74,7 @@ GVAR(disarmTarget) = _target; private _rankPicture = _display displayCtrl 1203; //Show rank and name (just like BIS's inventory) - private _icon = format [DEFUALTPATH, toLower (rank _target)]; + private _icon = format [DEFUALTPATH, toLowerANSI (rank _target)]; if (_icon isEqualTo DEFUALTPATH) then {_icon = ""}; _rankPicture ctrlSetText _icon; _playerName ctrlSetText ([GVAR(disarmTarget), false, true] call EFUNC(common,getName)); diff --git a/addons/dogtags/stringtable.xml b/addons/dogtags/stringtable.xml index db3b0ee8fe..d19c61f505 100644 --- a/addons/dogtags/stringtable.xml +++ b/addons/dogtags/stringtable.xml @@ -54,7 +54,7 @@ Zabierz Взять Vezmi - 取る + 拾う Nehmen 회수 Prendre @@ -70,7 +70,7 @@ Zabrałeś nieśmiertelnik %1... Жетон снят с %1... Sebral jsem známku od %1... - %1 からドッグタグを取っています・・・ + %1 からドッグタグを回収しています・・・ Erkennungsmarke von %1 genommen... %1(으)로부터 군번줄을 회수했습니다... Plaque d'identification prise sur %1... @@ -86,7 +86,7 @@ Ktoś już zabrał ten nieśmiertelnik... Кто-то уже забрал жетон... Někdo jiný už vzal identifikační známku... - すでにドッグタグは取られています・・・ + 既に誰かがドッグタグを回収したようだ・・・ Jemand anderes hat bereits die Erkennungsmarke genommen... 누군가 이미 군번줄을 회수해갔습니다... Quelqu'un d'autre a déjà pris la plaque d'identification... @@ -102,7 +102,7 @@ Anzeige um Erkennungsmarke zu überprüfen 在畫面中顯示檢查兵籍牌 在画面中显示检查兵籍牌 - 確認中のドッグタグを画面上で表示します + 確認中のドッグタグを画面上に表示します Indicatore su schermo per il controllo delle piastrine Wyświetlacz ekranowy dla sprawdzania nieśmiertelników Экран для проверки жетонов diff --git a/addons/dragging/functions/fnc_startCarryLocal.sqf b/addons/dragging/functions/fnc_startCarryLocal.sqf index 15101e2950..2fc0af5e24 100644 --- a/addons/dragging/functions/fnc_startCarryLocal.sqf +++ b/addons/dragging/functions/fnc_startCarryLocal.sqf @@ -31,6 +31,9 @@ if !(_target getVariable [QGVAR(ignoreWeightCarry), false]) then { // Exit if object weight is over global var value if (_weight > GETMVAR(ACE_maxWeightCarry,1E11)) exitWith { + // Release claim on object + [objNull, _target, true] call EFUNC(common,claim); + [LLSTRING(UnableToDrag)] call EFUNC(common,displayTextStructured); }; diff --git a/addons/dragging/functions/fnc_startCarryPFH.sqf b/addons/dragging/functions/fnc_startCarryPFH.sqf index ca34275a2c..e8b864f260 100644 --- a/addons/dragging/functions/fnc_startCarryPFH.sqf +++ b/addons/dragging/functions/fnc_startCarryPFH.sqf @@ -55,8 +55,8 @@ if (_target isKindOf "CAManBase") then { TRACE_4("timeout",_unit,_target,_timeOut,CBA_missionTime); _idPFH call CBA_fnc_removePerFrameHandler; - private _draggedObject = _unit getVariable [QGVAR(draggedObject), objNull]; - [_unit, _draggedObject] call FUNC(dropObject_carry); + private _carriedObject = _unit getVariable [QGVAR(carriedObject), objNull]; + [_unit, _carriedObject] call FUNC(dropObject_carry); }; // Wait for the unit to stand up diff --git a/addons/dragging/functions/fnc_startDragLocal.sqf b/addons/dragging/functions/fnc_startDragLocal.sqf index b656c8ce5a..fe5f29fa61 100644 --- a/addons/dragging/functions/fnc_startDragLocal.sqf +++ b/addons/dragging/functions/fnc_startDragLocal.sqf @@ -31,6 +31,9 @@ if !(_target getVariable [QGVAR(ignoreWeightDrag), false]) then { // Exit if object weight is over global var value if (_weight > GETMVAR(ACE_maxWeightDrag,1E11)) exitWith { + // Release claim on object + [objNull, _target, true] call EFUNC(common,claim); + [LLSTRING(UnableToDrag)] call EFUNC(common,displayTextStructured); }; diff --git a/addons/dragging/stringtable.xml b/addons/dragging/stringtable.xml index 5c8a355be2..7cf53ba55c 100644 --- a/addons/dragging/stringtable.xml +++ b/addons/dragging/stringtable.xml @@ -166,6 +166,7 @@ 가벼운 개체 들고 달리기 허용 Autoriser la course avec des objets légers Permitir corrida com objetos leves + Позволяет работать с легкими объектами Allow the player to run when carrying lightweight objects. @@ -176,6 +177,7 @@ 가벼운 개체를 들고 다닐 때 플레이어가 뛸 수 있도록 허용합니다. Autorise le joueur à courir lorsqu'il porte un objet léger. Permite ao jogador correr enquanto carrega objetos leves. + Разрешите игроку бегать при переноске легких предметов. Skip Object Weight @@ -186,6 +188,7 @@ 개체 무게 무시 Ignorer le poids de l'objet Ignorar Peso do Objeto + Игнорировать вес объекта Determines whether object's weight is added onto weight calculations. @@ -196,6 +199,7 @@ 무게 계산에 개체의 무게를 추가할 지 여부를 결정합니다. Défini si le poids d'un objet est ajouté aux calculs du poids. Determina se o peso do objeto é adicionado aos cálculos de peso. + Определяет, добавляется ли вес объекта при расчете веса. Max Weight Coefficient @@ -205,6 +209,7 @@ Coeficiente Máximo de Peso Maximaler Gewichtskoeffizient 最大重量係数 + Максимальный коэффициент веса Modifies weight limit calculations. Set to 0 to ignore. @@ -214,6 +219,7 @@ Modifica os cálculos do limite de peso. Defina como 0 para ignorar. Ändert die Berechnung der Gewichtsbegrenzung. Zum Ignorieren auf 0 setzen. 重量制限の計算を変更します。 無視するには 0 に設定します。 + Изменяет расчеты предельного веса. Установите значение 0 для игнорирования. diff --git a/addons/dragon/functions/fnc_canPickupTripod.sqf b/addons/dragon/functions/fnc_canPickupTripod.sqf index 3d556385e5..a103277972 100644 --- a/addons/dragon/functions/fnc_canPickupTripod.sqf +++ b/addons/dragon/functions/fnc_canPickupTripod.sqf @@ -21,5 +21,4 @@ params ["_target", "_unit"]; && {!alive (gunner _target)} && {!(_target getVariable [QGVAR(fired), false])} && {!(_target getVariable [QGVAR(sightAttached), ((typeOf _target) == QGVAR(staticAssembled))])} -&& EFUNC(csw,assemble_canPickupTripod) - +&& EFUNC(csw,canPickupTripod) diff --git a/addons/explosives/XEH_PREP.hpp b/addons/explosives/XEH_PREP.hpp index 319bd2fec2..444b9db2ea 100644 --- a/addons/explosives/XEH_PREP.hpp +++ b/addons/explosives/XEH_PREP.hpp @@ -10,6 +10,7 @@ PREP(cancelPlacement); PREP(canDefuse); PREP(canDetonate); PREP(connectExplosive); +PREP(cycleActiveTrigger); PREP(defuseExplosive); PREP(detonateExplosive); PREP(detonateExplosiveAll); diff --git a/addons/explosives/XEH_postInit.sqf b/addons/explosives/XEH_postInit.sqf index 40b3bb6959..6c32bb0563 100644 --- a/addons/explosives/XEH_postInit.sqf +++ b/addons/explosives/XEH_postInit.sqf @@ -57,6 +57,8 @@ if (isServer) then { if (!hasInterface) exitWith {}; +#include "initKeybinds.inc.sqf" + GVAR(PlacedCount) = 0; GVAR(Setup) = objNull; GVAR(pfeh_running) = false; diff --git a/addons/explosives/XEH_preInit.sqf b/addons/explosives/XEH_preInit.sqf index a6b4e97ed3..e39270f0bb 100644 --- a/addons/explosives/XEH_preInit.sqf +++ b/addons/explosives/XEH_preInit.sqf @@ -10,6 +10,8 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" +GVAR(activeTrigger) = ""; + GVAR(detonationHandlers) = []; GVAR(excludedMines) = []; diff --git a/addons/explosives/functions/fnc_addDetonateActions.sqf b/addons/explosives/functions/fnc_addDetonateActions.sqf index c353f973c3..ea4b87128a 100644 --- a/addons/explosives/functions/fnc_addDetonateActions.sqf +++ b/addons/explosives/functions/fnc_addDetonateActions.sqf @@ -49,18 +49,43 @@ private _explosivesList = []; }; }; } forEach _result; -if (_detonator != "ACE_DeadManSwitch") then { - // Add action to detonate all explosives tied to the detonator - if (count _explosivesList > 0) then { - _children pushBack [ + +// If the detonator is not active, is a clacker and has assigned explosives, generate an interaction to make it the active detonator for use with the "trigger all" keybind +if ( + _detonator != GVAR(activeTrigger) && + {_detonator != "Cellphone"} && + { + _explosivesList isNotEqualTo [] || + {_detonator == "ACE_DeadManSwitch" && {_unit getVariable [QGVAR(deadmanInvExplosive), ""] != ""}} + } +) then { + _children pushBack [ [ - "Explosive_All", - localize LSTRING(DetonateAll), - getText(ConfigFile >> "CfgWeapons" >> _detonator >> "picture"), - {(_this select 2) call FUNC(detonateExplosiveAll);}, + QGVAR(setActiveTrigger), + LLSTRING(SetActiveTrigger), + "", + {GVAR(activeTrigger) = (_this select 2) select 0;}, {true}, {}, - [_unit,_range,_explosivesList, _detonator] + [_detonator] + ] call EFUNC(interact_menu,createAction), + [], + _unit + ]; +}; + +if (_detonator != "ACE_DeadManSwitch") then { + // Add action to detonate all explosives tied to the detonator + if (count _explosivesList > 1) then { + _children pushBack [ + [ + "Explosive_All", + LLSTRING(DetonateAll), + getText (configFile >> "CfgWeapons" >> _detonator >> "picture"), + {(_this select 2) call FUNC(detonateExplosiveAll);}, + {true}, + {}, + [_unit, _range, _explosivesList, _detonator] ] call EFUNC(interact_menu,createAction), [], _unit @@ -69,15 +94,15 @@ if (_detonator != "ACE_DeadManSwitch") then { } else { //Add action to detonate all explosives (including the inventory explosive): _children pushBack [ - [ - "Explosive_All_Deadman", - localize LSTRING(DetonateAll), - getText(ConfigFile >> "CfgWeapons" >> _detonator >> "picture"), - {[_player] call FUNC(onIncapacitated)}, - {true} - ] call EFUNC(interact_menu,createAction), - [], - _unit + [ + "Explosive_All_Deadman", + LLSTRING(DetonateAll), + getText (configFile >> "CfgWeapons" >> _detonator >> "picture"), + {[_player] call FUNC(onIncapacitated)}, + {true} + ] call EFUNC(interact_menu,createAction), + [], + _unit ]; //Adds actions for the explosives you can connect to the deadman switch. @@ -89,7 +114,7 @@ if (_detonator != "ACE_DeadManSwitch") then { _connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""]; if (_connectedInventoryExplosive != "") then { - //Add the disconect action + //Add the disconnect action private _magConfig = configFile >> "CfgMagazines" >> _connectedInventoryExplosive; private _name = if ((getText (_magConfig >> "displayNameShort")) != "") then { getText (_magConfig >> "displayNameShort") @@ -99,17 +124,20 @@ if (_detonator != "ACE_DeadManSwitch") then { private _picture = getText (_magConfig >> "picture"); _children pushBack [ - ([ - "Deadman_disconnect", - format ["%1 %2", localize "str_disp_disconnect", _name], - _picture, - { - params ["_player"]; - TRACE_1("clear",_player); - _player setVariable [QGVAR(deadmanInvExplosive), "", true]; - }, - {true} - ] call EFUNC(interact_menu,createAction)), [], _unit]; + ([ + "Deadman_disconnect", + format ["%1 %2", localize "str_disp_disconnect", _name], + _picture, + { + params ["_player"]; + TRACE_1("clear",_player); + _player setVariable [QGVAR(deadmanInvExplosive), "", true]; + }, + {true} + ] call EFUNC(interact_menu,createAction)), + [], + _unit + ]; } else { //Add all magazines that would work with the deadman switch diff --git a/addons/explosives/functions/fnc_cycleActiveTrigger.sqf b/addons/explosives/functions/fnc_cycleActiveTrigger.sqf new file mode 100644 index 0000000000..e5226c6165 --- /dev/null +++ b/addons/explosives/functions/fnc_cycleActiveTrigger.sqf @@ -0,0 +1,53 @@ +#include "..\script_component.hpp" +/* + * Author: mrschick + * Cycles the "Active Trigger" of a unit and shows a CBA Hint that displays the new Active Trigger. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * [ACE_player] call ace_explosives_fnc_cycleActiveTrigger; + * + * Public: No + */ + +params ["_unit"]; +TRACE_1("params",_unit); + +private _detonators = _unit call FUNC(getDetonators); + +// Remove ACE_Cellphone from list, as it should never be the active trigger due to having its own keybind +_detonators deleteAt (_detonators findIf {_x == "ACE_Cellphone"}); + +// Reset Active Trigger if none available +if (_detonators isEqualTo []) exitWith { + GVAR(activeTrigger) = ""; +}; + +private _activeTrigger = GVAR(activeTrigger); +private _index = _detonators findIf {_x == _activeTrigger}; +private _count = count _detonators; + +if (_activeTrigger != "" && {_index != -1} && {_count > 1}) then { + // If active trigger is set and among current detonators, switch to the next one + if (_index < _count - 1) then { + _index = _index + 1; + } else { + _index = 0; + }; + _activeTrigger = _detonators select _index; +} else { + // Assign first detonator in list as the active one + _activeTrigger = _detonators select 0; +}; + +GVAR(activeTrigger) = _activeTrigger; +private _triggerConfig = configFile >> "CfgWeapons" >> _activeTrigger; +private _triggerName = getText (_triggerConfig >> "displayName"); +private _triggerIcon = getText (_triggerConfig >> "picture"); + +[format ["%1: %2", LLSTRING(ActiveTrigger), _triggerName], _triggerIcon] call EFUNC(common,displayTextPicture); diff --git a/addons/explosives/functions/fnc_selectTrigger.sqf b/addons/explosives/functions/fnc_selectTrigger.sqf index ef9b686d25..7c7d5e58d4 100644 --- a/addons/explosives/functions/fnc_selectTrigger.sqf +++ b/addons/explosives/functions/fnc_selectTrigger.sqf @@ -22,6 +22,15 @@ TRACE_3("params",_explosive,_magazine,_trigger); private _config = ConfigFile >> "ACE_Triggers" >> _trigger; +// Make selected trigger the active one (for keybind) if it's the first to be connected +private _activeTrigger = GVAR(activeTrigger); +if ( + _activeTrigger == "" && + {(["Command", "MK16_Transmitter", "DeadManSwitch"] findIf {_x == _trigger}) != -1} +) then { + GVAR(activeTrigger) = getArray (_config >> "requires") select 0; +}; + // If the onSetup function returns true, it is handled elsewhere if (isText(_config >> "onSetup") && {[_explosive,_magazine] call compile getText (_config >> "onSetup")}) exitWith { TRACE_2("onSetup returned true",_explosive,_trigger); diff --git a/addons/explosives/initKeybinds.inc.sqf b/addons/explosives/initKeybinds.inc.sqf new file mode 100644 index 0000000000..c01d39795c --- /dev/null +++ b/addons/explosives/initKeybinds.inc.sqf @@ -0,0 +1,50 @@ +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +["ACE3 Equipment", QGVAR(openCellphone), LLSTRING(cellphone_displayName), { + if ( + !([ACE_player, "ACE_Cellphone"] call EFUNC(common,hasItem)) || + !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) + ) exitWith {}; + + closeDialog 0; + createDialog "Rsc_ACE_PhoneInterface"; + + true +}] call CBA_fnc_addKeybind; // Unbound + +["ACE3 Equipment", QGVAR(detonateActiveClacker), LLSTRING(DetonateAllOnActive), { + // Prevent use of keybind while surrendering or captive + if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {}; + + private _detonator = GVAR(activeTrigger); + if (_detonator == "" || !(_detonator in ([ACE_player] call FUNC(getDetonators)))) exitWith {}; + + // When using a Dead Man's Switch, skip all other logic and just call fnc_onIncapacitated, since it already handles everything that is required to detonate all connected explosives + if (_detonator == "ACE_DeadManSwitch") exitWith { + [ACE_player] call FUNC(onIncapacitated); + }; + + private _range = getNumber (configFile >> "CfgWeapons" >> _detonator >> QGVAR(Range)); + + private _explosivesList = []; + { + if (!isNull (_x select 0)) then { + private _required = getArray (configFile >> "ACE_Triggers" >> _x select 4 >> "requires"); + if (_detonator in _required) then { + _explosivesList pushBack _x; + }; + }; + } forEach ([ACE_player] call FUNC(getPlacedExplosives)); + + [ACE_player, _range, _explosivesList, _detonator] call FUNC(detonateExplosiveAll); + + true +}] call CBA_fnc_addKeybind; // Unbound + +["ACE3 Equipment", QGVAR(cycleActiveClacker), LLSTRING(CycleActiveTrigger), { + if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {}; + + [ACE_player] call FUNC(cycleActiveTrigger); + + true +}] call CBA_fnc_addKeybind; // Unbound diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index 86c3183fe3..96b6292952 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -46,7 +46,7 @@ Robbantás Detonar Подрыв - 点火 + 起爆 폭파 引爆 引爆 @@ -62,12 +62,40 @@ Detona Tutti Tout détoner Detonar Tudo - すべて点火 + 全て起爆 모두 폭파 引爆全部 引爆全部 Hepsini Patlat + + Detonate All on Active Clacker + Alle auf Standardzünder zünden + Detona Tutti sul Detonatore Attivo + Подрыв всех на активном детонаторе + 選択した点火装置を全て起爆 + + + Set Active Clacker + Als Standardzünder wählen + Imposta Detonatore Attivo + Установить активный детонатор + この点火装置を選択 + + + Cycle Active Clacker + Standardzünder wechseln + Cambia Detonatore Attivo + Цикл активного детонатора + 点火装置を切り替え + + + Active Clacker + Standardzünder + Detonatore Attivo + Активный детонатор + 選択中の点火装置 + Explosive code: %1 Sprengstoffcode: %1 diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml index ef613c633e..b68da23d28 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -324,6 +324,7 @@ FRIES 로프 자동 장착 Equipement automatique FRIES Auto-equipar FRIES + Авто-подготовка канатов Automatically add FRIES to helicopters that support them. @@ -334,6 +335,7 @@ 로프를 지원하는 헬기에 자동으로 FRIES 로프를 추가합니다. Ajoute automatiquement des FRIES aux hélicoptères qui les supportent. Adiciona automaticamente FRIES a helicópteros que os suportam. + Автоматически добавляйте канаты в вертолеты, которые их поддерживают. diff --git a/addons/fcs/functions/fnc_calculateSolution.sqf b/addons/fcs/functions/fnc_calculateSolution.sqf index 5800068e4b..b89122f65d 100644 --- a/addons/fcs/functions/fnc_calculateSolution.sqf +++ b/addons/fcs/functions/fnc_calculateSolution.sqf @@ -48,10 +48,10 @@ private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurret } count _muzzles; // Fix the `in` operator being case sensitive and BI fucking up the spelling of their own classnames - private _weaponMagazinesCheck = _weaponMagazines apply {toLower _x}; + private _weaponMagazinesCheck = _weaponMagazines apply {toLowerANSI _x}; // Another BIS fix: ShotBullet simulation uses weapon initSpeed, others ignore it - if (toLower _magazine in _weaponMagazinesCheck && {_bulletSimulation == "shotBullet"}) exitWith { + if (toLowerANSI _magazine in _weaponMagazinesCheck && {_bulletSimulation == "shotBullet"}) exitWith { private _initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed"); if (_initSpeedCoef < 0) then { diff --git a/addons/field_rations/XEH_preStart.sqf b/addons/field_rations/XEH_preStart.sqf index 88109cf9ee..ebb22b6ee8 100644 --- a/addons/field_rations/XEH_preStart.sqf +++ b/addons/field_rations/XEH_preStart.sqf @@ -15,7 +15,7 @@ private _waterSourceOffsets = [ // Fill water source arrays from CfgVehicles { private _split = (getText (_x >> "model")) splitString "\"; - private _string = toLower (_split param [((count _split) - 1), ""]); + private _string = toLowerANSI (_split param [((count _split) - 1), ""]); // Append extension if necessary if ((_string select [count _string - 4]) != ".p3d") then { diff --git a/addons/fieldmanual/stringtable.xml b/addons/fieldmanual/stringtable.xml index ae71211c6a..647a5bad43 100644 --- a/addons/fieldmanual/stringtable.xml +++ b/addons/fieldmanual/stringtable.xml @@ -26,6 +26,7 @@ Fame Hunger 空腹 + Голод %3Hunger%4 increases linearly with soldier's movement speed. Restore by eating food.<br/><br/>%3Usage:%4<br/>%2Pick up food.<br/>%2Use [%3%12%4] and select %3Survival%4.<br/>%2Choose an item to consume. @@ -35,6 +36,7 @@ %3Hunger%4 steigt linear mit der Bewegungsgeschwindigkeit des Soldaten. Regeneriert sich, indem Nahrung zu sich genommen wird.<br/><br/>%3Verwende:%4<br/>%2Nahrung einsammeln.<br/>%2Verwende [%3%12%4] und wählen %3Überleben%4.<br />%2Wähle einen Gegenstand zum Verzehr aus. %3Fame%4 aumenta linearmente con la velocità di movimento del soldato. Si rigenera consumando cibo.<br/><br/>%3Usa:%4<br/>%2Raccogli cibo.<br/>%2Usa [%3%12%4] e scegli %3sopravvivenza%4.<br />%2Scegli un articolo da mangiare. %3空腹度%4は兵士の移動速度に比例して増加します。食べ物を食べることで回復します。<br/><br/>%3使用方法:%4<br/>%2食べ物を持つ。<br/>%2[%3%12%4] を使って%3サバイバル%4を選択。<br/>%2食べたいものを選ぶ。 + %3Голод%4 линейно увеличивается со скоростью передвижения солдата. Восстанавливайтесь, употребляя пищу.<br/><br/>%3 Использование:%4<br/>%2Возьмите еду.<br/>%2Используйте [%3%12%4] и выберите %3Выживание% 4.<br/>%2Выберите продукт для потребления. Thirst @@ -44,6 +46,7 @@ Sete Durst 渇き + Жажда %3Thirst%4 increases linearly with soldier's movement speed. Restore by drinking liquids.<br/><br/>%3Usage:%4<br/>%2Pick up a drink.<br/>%2Use [%3%12%4] and select %3Survival%4.<br/>%2Choose an item to consume. @@ -53,6 +56,7 @@ %3Durst%4 steigt linear mit der Bewegungsgeschwindigkeit des Soldaten. Regeneriert sich durch das Trinken von Flüssigkeiten.<br/><br/>%3Verwende:%4<br/>%2Holen ein Getränk.<br/>%2Verwende [%3%12%4] und wähle %3Überleben%4.< br/>%2Wähle einen Gegenstand zum Verzehr aus. %3Sete%4 aumenta linearmente con la velocità di movimento del soldato. Si rigenera bevendo liquidi.<br/><br/>%3Usa:%4<br/>%2Raccogli bevanda.<br/>%2Usa [%3%12%4] e scegli %3sopravvivenza%4.<br />%2Scegli un articolo da bere. %3喉の渇き%4は兵士の移動速度に比例して増加します。飲み物を飲むことで回復します。<br/><br/>%3使用方法:%4<br/>%2飲み物を持つ。<br/>%2[%3%12%4] を使って%3サバイバル%4を選択。<br/>%2飲みたいものを選ぶ。 + %3Жажда%4 линейно увеличивается со скоростью передвижения солдата. Восстанавливайтесь, употребляя напитки.<br/><br/>%3 Использование:%4<br/>%2Возьмите напиток.<br/>%2Используйте [%3%12%4] и выберите %3Выживание% 4.<br/>%2Выберите напиток для потребления. Medical Treatment @@ -62,6 +66,7 @@ Medizinische Behandlung Cure Mediche 治療 + Медицинское лечение Decrease Heart Rate @@ -71,6 +76,7 @@ Verringere Herzfrequenz Rallenta ritmo cardiaco 心拍数を下げる + Уменьшить частоту сердечных сокращений %3Adenosine%4 is used to decrease heart rate.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Inject %3Adenosine%4. @@ -80,6 +86,7 @@ %3Adenosin%4 wird verwendet, um die Herzfrequenz zu senken.<br/><br/>%3Verwende:%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus.<br/>%2Injiziere %3Adenosin%4. %3Adenosina%4 è usata per rallentare il ritmo cardiaco.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto.<br/>%2Inject %3Adenosina%4. %3アデノシン%4は心拍数を下げるのに使われます。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2そして%3アデノシン%4を注射します。 + %3Аденозин%4 используется для снижения частоты сердечных сокращений.<br/><br/>%3Применение:%4<br/>%2Используйте [%3%13%4] или [%3%14%4] и выберите конечность.<br/>%2Введите %3Аденозин%4. Bandages @@ -89,6 +96,7 @@ Bandagen Bende 包帯 + Бинты Close Wounds @@ -98,6 +106,7 @@ Wunden schließen Chiudi ferite 傷口をふさぐ + Закрыть раны %3Bandages%4 stop bleeding and close wounds. Depending on your settings, bandages may reopen if surgery is not performed.<br/><br/>%2%3Field Dressing:%4<br/>%11<t color='#D9D900'>Average</t> In All Categories<br/>%2%3Packing Bandage:%4<br/>%11<t color='#D9D900'>Average</t> Treatment<br/>%11<t color='#E60000'>Higher</t> Reopen Chance<br/>%11<t color='#00CC00'>Longer</t> Reopen Delay<br/>%2%3Elastic Bandage:%4<br/>%11<t color='#00CC00'>Higher</t> Treatment<br/>%11<t color='#E60000'>Higher</t> Reopen Chance<br/>%11<t color='#E60000'>Shorter</t> Reopen Delay<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Lower</t> Treatment<br/>%11<t color='#00CC00'>Lower</t> Reopen Chance<br/>%11<t color='#00CC00'>Longer</t> Reopening Delay<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select a injured body part.<br/>%2Bandage body part by selecting desired %3Bandage%4 type. @@ -125,6 +134,7 @@ Blutvolumen wiederherstellen Ristorano Volume di Sangue 血液量を回復する + Внутривенные жидкости %3IV fluids%4 restore lost blood volume. Blood, Plasma, and Saline are functionally the same.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Restore blood volume by selecting desired %3IV Fluid%4 type. @@ -143,6 +153,7 @@ Herzfrequenz erhöhen | Wache schneller auf Aumenta ritmo cardiaco | Accelera rinvenimento 心拍数を上げる | はやく起こす + Увеличьте частоту сердечных сокращений | просыпайтесь быстрее %3Epinephrine%4 increases a patient's pulse as well as potentially decreasing the time between consciousnesss checks (effectively reducing the time needed for the patient to wake up).<br/><br/>%3Usage%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an appendage.<br/>%2Inject %3Epinephrine%4. @@ -161,6 +172,7 @@ Wie neu wiederherstellen Cura completa 生まれたてのように回復する + Лечение тела The %3Personal Aid Kit%4 is an item that allows a soldier to be fully healed. Independent of %3ACE Settings%4, it requires that the patient is in %3Stable Condition%4 before use.<br/><br/>%3Stable Condition%4 qualifies as:<br/>%2Unit is %3Alive%4.<br/>%2Unit is %3Conscious%4.<br/>%2Unit has no active %3Bleeding%4.<br/>%2Heart Rate >= 40.<br/>%2Systolic BP >= 60.<br/>%2Diastolic BP >= 50.<br/><br/>%3Usage:%4<br/>%2Move to appropriate location depending on %3ACE Settings%4.<br/>%2Use [%3%13%4] or [%3%14%4] and select %3Advanced Treatments%4<br/>%2Select %3Use Personal Aid Kit%4. @@ -179,6 +191,7 @@ Brüche richten Risolvi frattura 骨折を治す + Исправлять переломы A %3Splint%4 is used to fix fractures. The %3Splint%4 is consumed when used.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an affected appendage.<br/>%2Select %3Apply Splint%4. @@ -196,6 +209,7 @@ Prevenir Reabertura de Feridas Impedisce la riapertura di ferite 傷口が開くのを防ぐ + Предотвратить повторное открытие ран A %3Surgical Kit%4 is used to prevent wounds from reopening after being bandaged. Depending on settings, it can also clear trauma and may require additional %3Sutures%4 to close wounds. Sutures are consumable, much like bandages, and are not a replacement for the Surgical Kit.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select %3Advanced Treatment%4.<br/>%2Select %3Use Surgical Kit%4. @@ -212,6 +226,7 @@ Parar o Sangramento Ferma emorragia 出血を止める + Остановить кровотечение A %3Tourniquet%4 stops bleeding temporarily so that a wound(s) can be bandaged. Can only be used on limbs.<br/><br/>%3Usage:%4<br/>%2Use [%3%13%4] or [%3%14%4] and select an affected appendage.<br/>%2Select %3Apply Tourniquet%4. @@ -354,6 +369,7 @@ 내비게이션입니다 Naviga 測位 + Навигация The %3DAGR%4 is a simpler version of the %3MicroDAGR GPS%4. It has similar features but lacks the topographic and satellite imaging functions of the %3MicroDAGR GPS%4.<br/><br/>%3Usage:%4<br/>%2Equip a %3DAGR%4.<br/>%2Use [%3%12%4] and select %3Configure%4 or %3Toggle%4.<br/><br/>The following menus are available when configuring your %3DAGR:%4<br/>%11%2Data View: WIP<br/>%11%2GoTo WP: Select a waypoint to track.<br/>%11%2WP List: Add/Edit/Remove waypoints.<br/>%11%2Connect To: Connect %3DAGR%4 to the %3Vector 21 Rangefinder%4.<br/>%11%2Options @@ -368,6 +384,7 @@ '폭발'적인 복수입니다 Vendetta Esplosiva 爆発的な復讐 + Взрывная месть The %3Dead Man's Switch%4 is a device that allows a soldier to detonate an %3Explosive%4 when the soldier dies.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Explosives%4.<br/>%2Select %3Dead Man's Switch%4 and connect the desired %3Explosive%4.<br/>%2Repeat the process and disconnect to reverse. @@ -389,6 +406,7 @@ 폭발물을 해체합니다 Disinnesca Esplosivi 爆発物の解除 + Обезвреживание взрывчатки Protect Your Hearing @@ -396,6 +414,7 @@ 청력을 보호합니다 Proteggi il tuo Udito 聴覚の保護 + Защитите свой слух %3Ear Plugs%4 help prevent hearing damage from repeat loud noises near a soldier. Insert %3Ear Plugs%4 to lower volume of a soldier's environment and prevent %3Combat Deafness%4.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Insert %3Ear Plugs%4. @@ -410,6 +429,7 @@ 엄폐하십시오 Mettiti in Copertura 遮蔽を造り出す + Добраться до укрытия The %3Entrenching Tool%4 allows soldiers to dig trenches to help defend their position. The soldier must be on soil in order to dig a trench.<br/><br/>%3Usage:%4<br/>%2Equip an %3Entrenching Tool%4.<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select the type of trench you wish to build. @@ -424,6 +444,7 @@ Torce 손전등 フラッシュライト + Фонари Illuminate Your Map @@ -431,6 +452,7 @@ Illumina la tua Mappa 지도를 밝혀줍니다 地図に光あれ + Осветите свою карту %3Flashlights%4 give you the ability to read your map, even in dark environments. However, when using %3Flashlights%4, you will have a slight glow around you.<br/><br/>%3Usage:%4<br/>%2On the map screen, use [%3%12%4] and select %3Flashlights%4.<br/>%2Select the %3Flashlight%4 you want to use and select %3On%4.<br/><br/>%3Available Flashlight Items%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTE:%4<br/>Flashlight states are persistent. @@ -445,6 +467,7 @@ Osserva dal Cielo 하늘에서 관측합니다 空から戦場を見てみよう + Наблюдайте с Небес The %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 is designed to be fired from a grenade launcher. After being fired in the air, the built-in parachute will be deployed and the IR CMOS camera will activate, providing a video stream until it touches the ground or is shot down.<br/><br/>%3Usage:%4<br/>%2Equip a %3HuntIR Monitor%4 and compatible ammunition.<br/>%2Fire the %3HuntIR Round%4 as high as possible over the area you want to observe.<br/>%2Open the %3HuntIR Monitor%4.<br/>%2Use [%3%12%4], select %3Equipment%4.<br/>%2Select %3Activate HuntIR Monitor%4. @@ -459,6 +482,7 @@ Traccia la tua squadra con discrezione 은신하여 팀을 찾아냅니다 自分の部隊を追う + Следите за своей командой незаметно The %3IR Strobe%4 is a throwable that emits an IR light pulse intermittently. The %3IR Strobe%4 can also be attached to a soldier, making it useful for tracking teammates under night vision devices.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Attach%4 and select the %3IR Strobe%4. @@ -473,6 +497,7 @@ Stazione Meteo Tascabile 휴대용 기상 관측 장비입니다 携帯気象予報所 + Карманная метеостанция The %3Kestrel 4500 Pocket Weather Tracker%4 is a mini weather station useful for collecting the the following weather data:<br/>%2Heading and wind direction<br/>%2Crosswind and headwind<br/>%2Altitude and barometric pressure<br/>%2Wet bulb temperature<br/>%2Humidity and dewpoint<br/>%2Density altitude<br/>%2Wind chill and temperature<br/>%2Time and date<br/>%2Minimum, maximum, and average values<br/><br/>%3Usage:%4<br/>%2Equip a %3Kestrel%4.<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Open%4. @@ -487,6 +512,7 @@ Triangola la tua posizione 위치를 삼각측량합니다 三角測量で位置を特定 + Передавайте свое местоположение The %3Map Tools%4 are a set of tools that allows a soldier to measure distances and angles. Useful for land, and calculating firing solutions for artillery.<br/><br/>%3Usage:%4<br/>%2Open %3Map%4.<br/>%2Use [%3%12%4] and select %3Map Tools%4.<br/>%2 The Tool can be moved by dragging with [%3Left-Click%4] while holding [%3ALT%4]. @@ -501,6 +527,7 @@ DAGR Avanzato 고급형 DAGR입니다 より高度なDAGR + Продвинутый DAGR The %3MicroDAGR GPS%4 is an advanced version of the %3DAGR%4. It provides position, navigation, and timing (PNT) data to include:<br/>%2Compass and heading<br/>%2Date and hour synced to the mission<br/>%2Elevation (relative to sea level)<br/>%2Current speed<br/>%2GPS with topographic and satellite view<br/>%2Creating, naming, and deleting waypoints<br/>%2Friendly identification (Requires ACE BLUFOR Tracker Setting)<br/>Connection to the Vector-21 Rangefinder for data import (waypoint creation and grid reference of ranged targets)<br/><br/>%3Usage:%4<br/>%2For usage instructions, please visit the dedicated %3MicroDAGR%4 wiki. @@ -515,6 +542,7 @@ Tavole di Tiro 사거리표 射表 + Таблицы диапазонов Get A Firing Solution @@ -522,6 +550,7 @@ Per una soluzione di tiro 사격 솔루션을 제공합니다 撃ち方の解を得る + Получите расчёт %3Range Tables%4 allow for a soldier to estimate accurate shot placement on direct or indirect targets (depending on asset). The %3Range Table%4 will automatically fill depending on the soldiers selected weapon/vehicle.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select the desired %3Range Table%4. @@ -536,6 +565,7 @@ Corde 로프 ロープ + Канаты Tow With Ease @@ -543,6 +573,7 @@ Rimorchia con facilità 쉽게 견인을 할 수 있습니다 楽々けん引 + Буксируйте с легкостью %3Ropes%4 have multiple uses including %3Towing%4 vehicles and %3Fast Roping%4 from helicopters.<br/><br/>%3Towing:%4<br/>%2Approach a vehicle.<br/>%2Use [%3%13%4] and select %3Towing%4.<br/>%2Select rope length.<br/>%2Select attachment point on towing vehicle.<br/>%2Select attachment on towed vehicle.<br/><br/>%3Available Rope Lengths:%4<br/>%2 3.2 meters<br/>%2 6.2 meters<br/>%2 12.2 meters<br/>%2 15.2 meters<br/>%2 18.3 meters<br/>%2 27.4 meters<br/>%2 36.6 meters @@ -557,6 +588,7 @@ Espandi le tue Fortificazioni 당신의 요새를 확장합니다 要塞を拡張する + Расширить свои укрепления %3Sandbags%4 are sacks made of sturdy material, filled with sand, used for a variety of purposes such as creating barriers or providing stability in construction projects. Useful in expanding larger placed fortifications.<br/><br/>%3Usage:%4<br/>%2Equip a %3Sandbag (Empty)%4.<br/>%2Use [%3%12%4] and select %3Deploy Sandbag%4.<br/>%2Follow on-screen instructions for placement. @@ -571,6 +603,7 @@ Raffredda l'Arma 총기의 온도를 낮춥니다 銃の熱を冷ます + Понизьте температуру оружия %3Spare Barrels%4 allow a soldier to reduce their weapon's heat significantly. After a short delay, the weapon's barrel will be swapped and its heat reduced. A soldier may also check the temperature of any barrels within their inventory. Not all weapons support swapping barrels.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3Swap Barrel%4.<br/>%2Resume operation after barrel swap is complete. @@ -585,6 +618,7 @@ Bomboletta Spray 스프레이 페인트 ペイントスプレー + Аэрозольная краска Tag Your Territory @@ -592,6 +626,7 @@ Marca il tuo territorio 당신의 영역을 지정합니다 自分のテリトリーをマーキング + Пометьте свою территорию %3Spray Paint%4 is used to tag surfaces with various symbols.<br/><br/>%3Usage:%4<br/>%2Move close to a surface (wall, vehicle, ground, etc).<br/>%2Use [%3%12%4] and select %3Tag%4.<br/>%2Choose a symbol.<br/><br/>%3Available Colors:%4<br/>%2Black<br/>%2Blue<br/>%2Green<br/>%2Red @@ -606,6 +641,7 @@ Stabilizzati Ovunque 어느 곳에나 지지대를 배치할 수 있습니다 どこでも支持器 + Опора может быть установлена в любом месте The %3SSWT Kit%4 is a deployable tripod that allows a soldier to brace their aim when deployed. Use it when you need an elevated shooting position and there are no other objects around.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2Select %3SSWT Kit%4 and follow the on screen prompts to place. @@ -620,6 +656,7 @@ Tieni gli occhi nel cielo 하늘에서 계속 내려다봅니다 空の目を維持する + Не Отрывай Глаз От Неба %3UAV Batteries%4 are used to recharge a UAV's energy storage. Especially useful for small UAVs.<br/><br/>%3Usage:%4<br/>%2Equip a %3UAV Battery%4<br/>%2Approach a %3UAV%4 with its %3Engine Off%4.<br/>%2Use [%3%13%4] and select %3Recharge%4. @@ -634,6 +671,7 @@ Fai un'entrata 진입로를 만듭니다 堂々入場する + Создание собственного входа %3Wirecutters%4 are a tool that allows a soldier to bypass wired fencing. Useful for creating backdoor entrances into secure areas.<br/><br/>%3Usage:%4<br/>%2Move close to a fence.<br/>%2Use [%3%12%4] and select %3Cut Fence%4. @@ -664,6 +702,7 @@ ACE3 ACE3 ACE 3 + ACE3 Build Fortifications @@ -671,6 +710,7 @@ Costruisci Fortificazioni 요새를 건설합니다 要塞を構築する + Стройте укрепления The %3Fortify Tool%4 allows soldiers to build fortifications provided by their mission creator.<br/><br/>%3Usage:%4<br/>%2Pick up a %3Fortify Tool%4.<br/>%2Use [%3%12%4] and select %3Fortify%4.<br/>%2Select an available fortification and follow the on screen prompts for placement. @@ -685,6 +725,7 @@ Effrazione 침입용 도구입니다 破壊して乗り込む + Взлом и проникновение %3Lockpicks%4 are used to gain access to locked vehicles.<br/><br/>%3Usage:%4<br/>%2Equip a %3Lockpick%4.<br/>%2Approach a %3Locked%4 vehicle.<br/>Use [%3%13%4] and select %3Lockpick Vehicle%4.<br/><br/><t underline='1'>%3Note:%4</t> Lockpicks and keys are only available via scripting or ACE Vehicle Key modules. @@ -699,6 +740,7 @@ Chiavi dei Veicoli 차량 열쇠 車両キー + Взлом и проникновение Lock/Unlock Vehicles @@ -706,6 +748,7 @@ Blocco/Sblocco di Veicoli 차량을 잠그거나 해제합니다 車両のロック/ロック解除 + Взлом и проникновение %3Vehicle Keys%4 are used to lock/unlock your vehicles. Vehicle keys can exist for the whole side, or keys can be created for a particular vehicle itself.<br/><br/>%3Usage:%4<br/>%2Equip a %3Vehicle Key%4.<br/>%2Approach the vehicle that the key belongs to.<br/>Use [%3%13%4] and select %3Lock/Unlock Vehicle%4.<br/><br/><t underline='1'>%3Note:%4</t> Lockpicks and keys are only available via scripting or ACE Vehicle Key modules. diff --git a/addons/fire/XEH_postInit.sqf b/addons/fire/XEH_postInit.sqf index 9637354803..9becb56b71 100644 --- a/addons/fire/XEH_postInit.sqf +++ b/addons/fire/XEH_postInit.sqf @@ -5,13 +5,13 @@ [QGVAR(burnObjectEffects), LINKFUNC(burnObjectEffects)] call CBA_fnc_addEventHandler; [QGVAR(burnSimulation), LINKFUNC(burnSimulation)] call CBA_fnc_addEventHandler; -// Only play sound if enabled in settings [QGVAR(playScream), { - if (!GVAR(enableScreams)) exitWith {}; - params ["_scream", "_source"]; - _source say3D _scream; + // Only play sound if enabled in settings and enabled for the unit + if (GVAR(enableScreams) && {_source getVariable [QGVAR(enableScreams), true]}) then { + _source say3D _scream; + }; }] call CBA_fnc_addEventHandler; if (!isServer) exitWith {}; diff --git a/addons/fortify/functions/fnc_deployConfirm.sqf b/addons/fortify/functions/fnc_deployConfirm.sqf index 37e0d4fb9d..b0105a7919 100644 --- a/addons/fortify/functions/fnc_deployConfirm.sqf +++ b/addons/fortify/functions/fnc_deployConfirm.sqf @@ -38,7 +38,7 @@ private _perframeCheck = { _args params ["_unit", "_side", "_typeOf", "_posASL", "_vectorDir", "_vectorUp", "_cost"]; // Animation loop (required for longer constructions) - if (animationState _unit isNotEqualTo "AinvPknlMstpSnonWnonDnon_medic4") then { + if (_totalTime != 0 && {animationState _unit != "AinvPknlMstpSnonWnonDnon_medic4"}) then { // Perform animation [_unit, "AinvPknlMstpSnonWnonDnon_medic4"] call EFUNC(common,doAnimation); }; @@ -55,4 +55,3 @@ private _perframeCheck = { LLSTRING(progressBarTitle), _perframeCheck ] call EFUNC(common,progressBar); - diff --git a/addons/fortify/functions/fnc_handleChatCommand.sqf b/addons/fortify/functions/fnc_handleChatCommand.sqf index 46bdc3cb0b..1422558de8 100644 --- a/addons/fortify/functions/fnc_handleChatCommand.sqf +++ b/addons/fortify/functions/fnc_handleChatCommand.sqf @@ -20,7 +20,7 @@ TRACE_1("handleChatCommand",_args); _args = _args splitString " "; if (_args isEqualTo []) exitWith {ERROR("Bad command");}; -private _command = toLower (_args select 0); +private _command = toLowerANSI (_args select 0); _args deleteAt 0; switch (_command) do { diff --git a/addons/fortify/functions/fnc_parseSide.sqf b/addons/fortify/functions/fnc_parseSide.sqf index 3e9ca5d78d..6af2fac4b4 100644 --- a/addons/fortify/functions/fnc_parseSide.sqf +++ b/addons/fortify/functions/fnc_parseSide.sqf @@ -22,7 +22,7 @@ TRACE_1("parseSide",_side); if (_side isEqualType sideUnknown) exitWith {_side}; -private _char = toLower (_side select [0, 1]); +private _char = toLowerANSI (_side select [0, 1]); private _return = switch (_char) do { case ("b"); diff --git a/addons/fortify/functions/fnc_registerObjects.sqf b/addons/fortify/functions/fnc_registerObjects.sqf index b8e7abd171..7fea4996a4 100644 --- a/addons/fortify/functions/fnc_registerObjects.sqf +++ b/addons/fortify/functions/fnc_registerObjects.sqf @@ -28,7 +28,7 @@ TRACE_3("registerObjects",_side,_budget,_objects); if (_side isEqualTo sideUnknown) exitWith {ERROR_1("Bad Side %1",_this);}; -_objects select { +_objects = _objects select { private _isValid = _x params [["_xClassname", "", [""]], ["_xCost", 0, [0]]]; private _category = toLower (_x param [2, "", [""]]); if (_category != "") then { _x set [2, _category]; }; diff --git a/addons/frag/functions/fnc_dev_debugAmmo.sqf b/addons/frag/functions/fnc_dev_debugAmmo.sqf index ec52b4b39f..4484edbdc4 100644 --- a/addons/frag/functions/fnc_dev_debugAmmo.sqf +++ b/addons/frag/functions/fnc_dev_debugAmmo.sqf @@ -28,7 +28,7 @@ private _allMagsConfigs = configProperties [configFile >> "CfgMagazines", "isCla private _processedCfgAmmos = []; { - private _ammo = toLower getText (_x >> "ammo"); + private _ammo = toLowerANSI getText (_x >> "ammo"); if (_ammo != "" && {!(_ammo in _processedCfgAmmos)}) then { _processedCfgAmmos pushBack _ammo; diff --git a/addons/frag/functions/fnc_pfhRound.sqf b/addons/frag/functions/fnc_pfhRound.sqf index bd5a229f0e..ce734a08e3 100644 --- a/addons/frag/functions/fnc_pfhRound.sqf +++ b/addons/frag/functions/fnc_pfhRound.sqf @@ -26,7 +26,7 @@ if (!alive _round) exitWith { if (_skip == 0) then { if ((_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}) || {_force == 1}) then { // shotbullet, shotShell don't seem to explode when touching water, so don't create frags - if ((surfaceIsWater _lastPos) && {(toLower getText (configFile >> "CfgAmmo" >> _shellType >> "simulation")) in ["shotbullet", "shotshell"]}) exitWith {}; + if ((surfaceIsWater _lastPos) && {(toLowerANSI getText (configFile >> "CfgAmmo" >> _shellType >> "simulation")) in ["shotbullet", "shotshell"]}) exitWith {}; private _fuseDist = getNumber(configFile >> "CfgAmmo" >> _shellType >> "fuseDistance"); private _isArmed = _firedPos vectorDistance _lastPos >= _fuseDist; // rounds explode at exactly fuseDistance, so check inclusive TRACE_2("",_fuseDist,_isArmed); diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 7addcd4c38..2bd76c2928 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -136,7 +136,7 @@ Esta definição controla a quantidade máxima de projéteis que o sistema de fragmentação e estilhaçamento irá acompanhar em qualquer momento. Se mais projéteis são disparados, eles não serão rastreados. Diminua essa configuração se você não quiser que o FPS caia em cenários com alta contagem de projéteis (> 200 projéteis no ar ao mesmo tempo) Ce paramètre contrôle le nombre maximum de projectiles et d'éclats résultant de la fragmentation, que le système peut suivre à chaque instant.\nSi plus de projectiles sont générés, ils ne seront pas pris en compte. Baissez ce réglage si vous ne voulez pas de chute de FPS en cas de nombre important de projectiles (>200 éclats en même temps). Ez a beállítás szabályozza a repeszeződés és pattogzás által kilőtt objektumok követett számát. Ha több ez a szám, ezek az objektumok nem lesznek követve. Csökkentsd ezt a beállítást, ha nem akarsz lassulásokat magas-törmelékmennyiségű helyzetekben (200+ repesz a levegőben egyszerre) - Эта настройка контролирует максимальное количество снарядов, которок отслеживает система осколков и обломков в каждый момент времени. Снаряды, выстреленные сверх этого числа, отслеживаться не будут. Уменьшите это значение, если вы не хотите падения FPS при большом количестве снарядов в одной перестрелке (> 200 одновременно летящих снарядов) + Эта настройка контролирует максимальное количество снарядов, которок отслеживает система осколков и обломков в каждый момент времени. /nСнаряды, выстреленные сверх этого числа, отслеживаться не будут. Уменьшите это значение, если вы не хотите падения FPS при большом количестве снарядов в одной перестрелке (> 200 одновременно летящих снарядов) Questo parametro controlla il numero massimo di proiettili che la frammentazione e il sistema di spalling tracciano in ogni momento. Se vengono sparati ulteriori proiettili, non verranno tracciati. Abbassa questo parametro se non vuoi cali di FPS in scenari con molti proiettili (>200 proiettili in aria contemporaneamente) この設定では、断片化および剥離システムが常に追跡する飛翔体の最大量を制御します。 さらに多くの飛翔体が発射された場合、それらは追跡されません。 弾数が多いシナリオでFPSを低下させたくない場合は、この設定を下げてください。 (一度に200発以上が空中に発射されます) 이 설정은 탄환파편 및 파편 시스템으로 인해 생긴 발사체의 수를 결정합니다. 만약 더 많은 발사체가 나올 경우 정해진 수 이외에는 추적하지 않습니다. 이 설정을 낮춤으로써 파편이 많은 시나리오를 실행할때 더욱 원활히 진행할 수 있습니다 (한 번에 200개 이하) diff --git a/addons/goggles/stringtable.xml b/addons/goggles/stringtable.xml index 5fc06612d0..f02b95bf5c 100644 --- a/addons/goggles/stringtable.xml +++ b/addons/goggles/stringtable.xml @@ -101,7 +101,7 @@ Effects - эффекты + Эффекты エフェクト Efekty Effekte diff --git a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf index bba3cffd4d..e39a7730ce 100644 --- a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf +++ b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf @@ -63,6 +63,7 @@ _affected = _affected - [ACE_player]; if (_flashReactionDebounce < CBA_missionTime) then { // Not used interally but could be useful for other mods _unit setVariable [QGVAR(flashStrength), _strength, true]; + [QGVAR(flashbangedAI), [_unit, _strength, _grenadePosASL]] call CBA_fnc_localEvent; { _unit setSkill [_x, (_unit skill _x) / 50]; } forEach SUBSKILLS; @@ -144,11 +145,11 @@ if (hasInterface && {!isNull ACE_player} && {alive ACE_player}) then { //PARTIALRECOVERY - start decreasing effect over time [{ - params ["_strength"]; + params ["_strength", "_blend"]; - GVAR(flashbangPPEffectCC) ppEffectAdjust [1,1,0,[1,1,1,0],[0,0,0,1],[0,0,0,0]]; + GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, 0, _blend, [0,0,0,1], [0,0,0,0]]; GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength); - }, [_strength], 7 * _strength] call CBA_fnc_waitAndExecute; + }, [_strength, _blend], 7 * _strength] call CBA_fnc_waitAndExecute; //FULLRECOVERY - end effect [{ @@ -162,5 +163,7 @@ if (hasInterface && {!isNull ACE_player} && {alive ACE_player}) then { private _maxFlinch = linearConversion [0.2, 1, _strength, 0, 95, true]; private _flinch = (_minFlinch + random (_maxFlinch - _minFlinch)) * selectRandom [-1, 1]; ACE_player setDir (getDir ACE_player + _flinch); + + [QGVAR(flashbangedPlayer), [_strength, _grenadePosASL]] call CBA_fnc_localEvent; }; true diff --git a/addons/gunbag/XEH_preInit.sqf b/addons/gunbag/XEH_preInit.sqf index 2bb35513a2..3149314f87 100644 --- a/addons/gunbag/XEH_preInit.sqf +++ b/addons/gunbag/XEH_preInit.sqf @@ -26,17 +26,41 @@ PREP_RECOMPILE_END; }, _this] call CBA_fnc_execNextFrame; }] call CBA_fnc_addClassEventHandler; +[QEGVAR(arsenal,loadoutVerified), { + params ["_loadout", "_extendedInfo", "", "", "_missingExtendedInfo"]; + private _gunbagInfo = _extendedInfo getOrDefault [QGVAR(gunbagWeapon), []]; + if (_gunbagInfo isEqualTo []) exitWith {}; + + private _weapon = (_gunbagInfo select 0) call EFUNC(arsenal,baseWeapon); + if !(_weapon in EGVAR(arsenal,virtualItemsFlat)) exitWith { + _missingExtendedInfo pushBack [QGVAR(gunbagWeapon), _weapon]; + _extendedInfo deleteAt QGVAR(gunbagWeapon); + }; + private _missingItems = []; + private _attachments = _gunbagInfo select 1; + { + if (_x != "" && {!(_x call EFUNC(arsenal,baseWeapon) in EGVAR(arsenal,virtualItemsFlat))}) then { + _missingItems pushBack _x; + _attachments set [_forEachIndex, ""]; + }; + } forEach _attachments; + private _magazines = _gunbagInfo select 2; + { + private _class = _x param [0, ""]; + if (_class != "" && {!(_class in EGVAR(arsenal,virtualItemsFlat))}) then { + _missingItems pushBack _class; + _magazines set [_forEachIndex, ["", 0]]; + }; + } forEach _magazines; + if (_missingItems isNotEqualTo []) then { + _missingExtendedInfo pushBack [QGVAR(gunbagWeapon), _missingItems]; + }; +}] call CBA_fnc_addEventHandler; + ["CBA_loadoutSet", { params ["_unit", "_loadout", "_extendedInfo"]; private _gunbagWeapon = _extendedInfo getOrDefault [QGVAR(gunbagWeapon), []]; if (_gunbagWeapon isNotEqualTo []) then { - if (!isNil QEGVAR(arsenal,virtualItemsFlatAll)) then { - private _weapon = (_gunbagWeapon select 0) call EFUNC(arsenal,baseWeapon); - if !(_weapon in EGVAR(arsenal,virtualItemsFlatAll)) then { - INFO_1("removing [%1] from loadout",_gunbagWeapon); - _gunbagWeapon = []; - }; - }; (backpackContainer _unit) setVariable [QGVAR(gunbagWeapon), _gunbagWeapon, true]; }; }] call CBA_fnc_addEventHandler; diff --git a/addons/gunbag/functions/fnc_isMachineGun.sqf b/addons/gunbag/functions/fnc_isMachineGun.sqf index f07866a4aa..e6e4e5c96c 100644 --- a/addons/gunbag/functions/fnc_isMachineGun.sqf +++ b/addons/gunbag/functions/fnc_isMachineGun.sqf @@ -22,7 +22,7 @@ private _config = _weapon call CBA_fnc_getItemConfig; // definition of a machine gun by BIS_fnc_itemType private _cursor = getText (_config >> "cursor"); -if (toLower _cursor in ["", "emptycursor"]) then { +if (toLowerANSI _cursor in ["", "emptycursor"]) then { _cursor = getText (_config >> "cursorAim"); }; diff --git a/addons/hearing/XEH_postInit.sqf b/addons/hearing/XEH_postInit.sqf index d8b21f214a..f8f5c2938f 100644 --- a/addons/hearing/XEH_postInit.sqf +++ b/addons/hearing/XEH_postInit.sqf @@ -2,6 +2,8 @@ if (!hasInterface) exitWith {}; +#include "initKeybinds.inc.sqf" + GVAR(cacheAmmoLoudness) = call CBA_fnc_createNamespace; GVAR(deafnessDV) = 0; @@ -21,6 +23,8 @@ GVAR(lastPlayerVehicle) = objNull; // Spawn volume updating process [LINKFUNC(updateVolume), 1, [false]] call CBA_fnc_addPerFrameHandler; + [QGVAR(updateVolume), LINKFUNC(updateVolume)] call CBA_fnc_addEventHandler; + // Update veh attunation when player veh changes ["vehicle", { params ["_player", "_vehicle"]; diff --git a/addons/hearing/XEH_preInit.sqf b/addons/hearing/XEH_preInit.sqf index 2ab07c31e6..7a6195ec46 100644 --- a/addons/hearing/XEH_preInit.sqf +++ b/addons/hearing/XEH_preInit.sqf @@ -12,7 +12,8 @@ PREP_RECOMPILE_END; params ["_unit", "_loadout", "_extendedInfo"]; if (_extendedInfo getOrDefault ["ace_earplugs", false]) then { _unit setVariable ["ACE_hasEarPlugsIn", true, true]; - [[true]] remoteExec [QFUNC(updateVolume), _unit]; + + [QGVAR(updateVolume), [[true]], _unit] call CBA_fnc_targetEvent; }; }] call CBA_fnc_addEventHandler; diff --git a/addons/hearing/functions/fnc_addEarPlugs.sqf b/addons/hearing/functions/fnc_addEarPlugs.sqf index f467352410..c541d78618 100644 --- a/addons/hearing/functions/fnc_addEarPlugs.sqf +++ b/addons/hearing/functions/fnc_addEarPlugs.sqf @@ -15,14 +15,14 @@ * Public: No */ -params ["_unit"]; -TRACE_2("params",_unit,typeOf _unit); - // only run this after the settings are initialized if !(EGVAR(common,settingsInitFinished)) exitWith { EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(addEarPlugs), _this]; }; +params ["_unit"]; +TRACE_2("params",_unit,typeOf _unit); + // Exit if hearing is disabled OR autoAdd is disabled OR soldier has earplugs already in (persistence scenarios) if (!GVAR(enableCombatDeafness) || {!GVAR(autoAddEarplugsToUnits)} || {[_unit] call FUNC(hasEarPlugsIn)}) exitWith {}; @@ -38,16 +38,20 @@ if ((primaryWeapon _unit) == "") exitWith {}; (primaryWeaponMagazine _unit) params [["_magazine", ""]]; if (_magazine == "") exitWith {}; -private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); -private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -private _count = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); +private _cfgMagazine = configFile >> "CfgMagazines" >> _magazine; -private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_caliber"); +private _initSpeed = getNumber (_cfgMagazine >> "initSpeed"); +private _ammo = getText (_cfgMagazine >> "ammo"); +private _count = getNumber (_cfgMagazine >> "count"); + +private _cfgAmmo = configFile >> "CfgAmmo"; + +private _caliber = getNumber (_cfgAmmo >> _ammo >> "ACE_caliber"); _caliber = call { - if (_ammo isKindOf ["ShellBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; - if (_ammo isKindOf ["RocketBase", (configFile >> "CfgAmmo")]) exitWith { 200 }; - if (_ammo isKindOf ["MissileBase", (configFile >> "CfgAmmo")]) exitWith { 600 }; - if (_ammo isKindOf ["SubmunitionBase", (configFile >> "CfgAmmo")]) exitWith { 80 }; + if (_ammo isKindOf ["ShellBase", _cfgAmmo]) exitWith { 80 }; + if (_ammo isKindOf ["RocketBase", _cfgAmmo]) exitWith { 200 }; + if (_ammo isKindOf ["MissileBase", _cfgAmmo]) exitWith { 600 }; + if (_ammo isKindOf ["SubmunitionBase", _cfgAmmo]) exitWith { 80 }; [_caliber, 6.5] select (_caliber <= 0); }; private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; diff --git a/addons/hearing/initKeybinds.inc.sqf b/addons/hearing/initKeybinds.inc.sqf new file mode 100644 index 0000000000..22cf132add --- /dev/null +++ b/addons/hearing/initKeybinds.inc.sqf @@ -0,0 +1,15 @@ +["ACE3 Equipment", QGVAR(putOrRemoveEarplugs), LLSTRING(PutOrRemoveEarplugs), { + // Conditions: specific + if !([ACE_player, objNull, ["isNotSwimming", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + + if (GVAR(EnableCombatDeafness) && {!([ACE_player] call FUNC(hasEarPlugsIn))} && {[ACE_player, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith { + [ACE_player, true] call FUNC(putInEarPlugs); + true + }; + if (GVAR(EnableCombatDeafness) && {[ACE_player] call FUNC(hasEarPlugsIn)}) exitWith { + [ACE_player, true] call FUNC(removeEarPlugs); + true + }; + + false +}] call CBA_fnc_addKeybind; // UNBOUND diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index 7c40f3f702..4f4afb48ae 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -363,5 +363,11 @@ Volumen durante la inconsciencia. 기절 시 볼륨입니다. + + Put/take out earplugs + 耳栓を着け外す + Вставить/вынуть беруши + Metti/Togli tappi + diff --git a/addons/interaction/XEH_preStart.sqf b/addons/interaction/XEH_preStart.sqf index 799e9e5986..331b5c6d36 100644 --- a/addons/interaction/XEH_preStart.sqf +++ b/addons/interaction/XEH_preStart.sqf @@ -11,7 +11,7 @@ private _replaceTerrainClasses = QUOTE( private _cacheReplaceTerrainModels = createHashMap; { - private _model = toLower getText (_x >> "model"); + private _model = toLowerANSI getText (_x >> "model"); if (_model select [0, 1] == "\") then { _model = _model select [1]; }; diff --git a/addons/interaction/dev/initReplaceTerrainCursorObject.sqf b/addons/interaction/dev/initReplaceTerrainCursorObject.sqf index ee5ddcad49..a1708be423 100644 --- a/addons/interaction/dev/initReplaceTerrainCursorObject.sqf +++ b/addons/interaction/dev/initReplaceTerrainCursorObject.sqf @@ -17,7 +17,7 @@ DFUNC(replaceTerrainModelsAdd) = { if (_class isEqualTo "") then { private _configClasses = QUOTE(getNumber (_x >> 'scope') == 2 && {!(configName _x isKindOf 'AllVehicles')}) configClasses (configFile >> "CfgVehicles"); { - private _xmodel = toLower getText (_x >> "model"); + private _xmodel = toLowerANSI getText (_x >> "model"); if (_xmodel select [0, 1] == "\") then { _xmodel = _xmodel select [1]; }; diff --git a/addons/interaction/functions/fnc_getDoor.sqf b/addons/interaction/functions/fnc_getDoor.sqf index 02daf57a83..5f251d2589 100644 --- a/addons/interaction/functions/fnc_getDoor.sqf +++ b/addons/interaction/functions/fnc_getDoor.sqf @@ -33,7 +33,7 @@ if (typeOf _house == "") exitWith {[objNull, ""]}; _intersections = [_house, "GEOM"] intersect [_position0, _position1]; -private _door = toLower (_intersections select 0 select 0); +private _door = toLowerANSI (_intersections select 0 select 0); if (isNil "_door") exitWith {[_house, ""]}; diff --git a/addons/interaction/functions/fnc_getDoorAnimations.sqf b/addons/interaction/functions/fnc_getDoorAnimations.sqf index 2d5c81dc2d..b91c5eac6c 100644 --- a/addons/interaction/functions/fnc_getDoorAnimations.sqf +++ b/addons/interaction/functions/fnc_getDoorAnimations.sqf @@ -26,8 +26,8 @@ private _lockedVariable = []; private _numberStrings = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]; { - private _animName = toLower _x; - private _index = _animName find toLower _door; + private _animName = toLowerANSI _x; + private _index = _animName find toLowerANSI _door; if (_index != -1 && {!(_animName select [_index + count _door, 1] in _numberStrings)}) then { if (((_animName find "disabled") != -1) || ((_animName find "locked") != -1)) then { diff --git a/addons/interaction/functions/fnc_getGlassDoor.sqf b/addons/interaction/functions/fnc_getGlassDoor.sqf index ffa6bfec44..2aea74f82d 100644 --- a/addons/interaction/functions/fnc_getGlassDoor.sqf +++ b/addons/interaction/functions/fnc_getGlassDoor.sqf @@ -26,7 +26,7 @@ private _glassDoor = _door splitString "_"; private _glassPos = (_house selectionPosition [(_glassDoor select 0) + "_" + (_glassDoor select 1) + "_effects", "Memory"]); // Calculate all animation names so we know what is there { - private _animName = toLower _x; + private _animName = toLowerANSI _x; if (((_animName find "door") != -1) && ((_animName find "locked") == -1) && ((_animName find "disabled") == -1) && ((_animName find "handle") == -1)) then { private _splitStr = _animName splitString "_"; _doorParts pushBack ((_splitStr select 0) + "_" + (_splitStr select 1) + "_trigger"); @@ -64,4 +64,3 @@ private _lowestDistance = 0; if ((isNil "_door") || ((_door find "glass") != -1)) exitWith {}; _door - diff --git a/addons/interaction/functions/fnc_showMouseHint.sqf b/addons/interaction/functions/fnc_showMouseHint.sqf index 73567fa522..9adc15f493 100644 --- a/addons/interaction/functions/fnc_showMouseHint.sqf +++ b/addons/interaction/functions/fnc_showMouseHint.sqf @@ -71,7 +71,7 @@ if (_textMMB == "") then { // Only create extra key if both name and text are valid if (_keyName != "" && {_keyText != ""}) then { // Localize Ctrl, Shift, or Alt keys - switch (toLower _keyName) do { + switch (toLowerANSI _keyName) do { case "ctrl"; case "control": {_keyName = format ["<%1>", toUpper localize "STR_dik_control"]}; case "shift": {_keyName = format ["<%1>", toUpper localize "STR_dik_shift"]}; diff --git a/addons/inventory/XEH_preStart.sqf b/addons/inventory/XEH_preStart.sqf index faa0e1691e..a9a634ab5a 100644 --- a/addons/inventory/XEH_preStart.sqf +++ b/addons/inventory/XEH_preStart.sqf @@ -21,10 +21,6 @@ uiNamespace setVariable [QGVAR(backpackKeyCache), compileFinal createHashMapFrom if (_picture select [0, 1] == "\") then { _picture = _picture select [1]; }; - if (count _picture > 0 && !(_picture regexMatch ".*?\.paa")) then { // handle missing file extension - if (!fileExists (_picture + ".paa")) exitWith {}; - _picture = _picture + ".paa"; - }; // Handle missing file extension, as inventory returns path with extension if (count _picture > 0 && !(_picture regexMatch ".*?\.paa")) then { @@ -33,7 +29,7 @@ uiNamespace setVariable [QGVAR(backpackKeyCache), compileFinal createHashMapFrom }; // Listboxes store pictures as lowercase - [format ["%1:%2", _displayName, toLower _picture], _x] + [format ["%1:%2", _displayName, toLowerANSI _picture], _x] })]; // Generate list of grenades diff --git a/addons/irlight/stringtable.xml b/addons/irlight/stringtable.xml index ac874759a4..ab70abdebd 100644 --- a/addons/irlight/stringtable.xml +++ b/addons/irlight/stringtable.xml @@ -10,6 +10,7 @@ DBAL-A3 (rouge) DBAL-A3 (vermelho) DBAL-A3 (赤) + DBAL-A3 (красный) DBAL-A3 (green) @@ -20,6 +21,7 @@ DBAL-A3 (vert) DBAL-A3 (verde) DBAL-A3 (緑) + DBAL-A3 (зеленый) <t color='#9cf953'>Use: </t>Turn Laser ON/OFF<br>Double click to switch mode @@ -30,6 +32,7 @@ <t color='#9cf953'>Utilisation: </t>Allumer/Eteindre le laser<br>Double clic pour changer de mode <t color='#9cf953'>Uso: </t>Ligar/Desligar Laser<br>Duplo clique para mudar o modo <t color='#9cf953'>使用方法: </t>レーザーのオン/オフ切り替え<br>ダブルクリックでモード切り替え + <t color='#9cf953'>Использование: </t>Включение / выключение лазера <br>Двойной щелчок для переключения режима Dual Beam Aiming Laser @@ -40,6 +43,7 @@ Viseur laser à double faisceau Laser de Pontaria de Duplo Feixe 複合ビーム照準レーザー + Двухлучевой прицельный лазер Visible Laser @@ -50,6 +54,7 @@ Laser visible Laser Visível 可視光レーザー + Видимый лазер IR Laser @@ -60,6 +65,7 @@ Laser IR Laser IR IRレーザー + ИК-лазер IR Illuminator @@ -70,6 +76,7 @@ Illuminateur IR Iluminador IR IRイルミネーター + ИК-осветитель IR Laser and Illuminator @@ -80,6 +87,7 @@ Illuminateur et laser IR Laser e Iluminador IR IRレーザーとイルミネーター + ИК-лазер и осветитель Wide Beam @@ -90,6 +98,7 @@ Faisceau large Feixe Largo 広角ビーム + Широкий луч Medium Beam @@ -100,6 +109,7 @@ Faisceau moyen Feixe Médio 標準ビーム + Средний луч Narrow Beam @@ -110,6 +120,7 @@ Faisceau étroit Feixe Estreito 狭角ビーム + Узкий луч <t color='#9cf953'>Use: </t>Turn Light ON/OFF<br>Double click to switch mode @@ -120,6 +131,7 @@ <t color='#9cf953'>Utilisation: </t>Allumer/Eteindre la lumière<br>Double clic pour changer de mode <t color='#9cf953'>Uso: </t>Ligar/Desligar Iluminador<br>Duplo clique para mudar o modo <t color='#9cf953'>使用方法: </t>ライトのオン/オフ<br>ダブルクリックでモード切り替え + <t color='#9cf953'>Использование: </t>Включение / выключение освещения <br>Двойной щелчок для переключения режима Special Purpose IR LED Illuminator @@ -130,6 +142,7 @@ Illuminateur LED IR à usage spécial Iluminador LED IR de Uso Especial 特殊用途のIR LEDイルミネーター + ИК-светодиодный осветитель специального назначения Illuminator / Laser Momentary Switch @@ -140,6 +153,7 @@ Commutateur temporaire illuminateur/laser Interruptor Momentâneo Iluminador/Laser イルミネーター/レーザーモーメンタリースイッチ + Мгновенный переключатель осветителя/лазера diff --git a/addons/killtracker/CfgEventHandlers.hpp b/addons/killtracker/CfgEventHandlers.hpp index 9cc1b0427b..4300a157b9 100644 --- a/addons/killtracker/CfgEventHandlers.hpp +++ b/addons/killtracker/CfgEventHandlers.hpp @@ -1,3 +1,9 @@ +class Extended_PreInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); + }; +}; + class Extended_PostInit_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); diff --git a/addons/killtracker/XEH_postInit.sqf b/addons/killtracker/XEH_postInit.sqf index 9cef418ece..c5adc26692 100644 --- a/addons/killtracker/XEH_postInit.sqf +++ b/addons/killtracker/XEH_postInit.sqf @@ -136,7 +136,9 @@ GVAR(killCount) = 0; _unitName = format ["*AI* - %1", getText ((configOf _unit) >> "displayName")]; }; }; - TRACE_3("send kill event",_killer,_unitName,_killInfo); - [QGVAR(kill), [_unitName, _killInfo], _killer] call CBA_fnc_targetEvent; + if (_unitIsPlayer || GVAR(trackAI)) then { + TRACE_3("send kill event",_killer,_unitName,_killInfo); + [QGVAR(kill), [_unitName, _killInfo], _killer] call CBA_fnc_targetEvent; + }; }; }] call CBA_fnc_addEventHandler; diff --git a/addons/killtracker/XEH_preInit.sqf b/addons/killtracker/XEH_preInit.sqf new file mode 100644 index 0000000000..7c7b764686 --- /dev/null +++ b/addons/killtracker/XEH_preInit.sqf @@ -0,0 +1,7 @@ +#include "script_component.hpp" + +ADDON = false; + +#include "initSettings.inc.sqf" + +ADDON = true; diff --git a/addons/killtracker/initSettings.inc.sqf b/addons/killtracker/initSettings.inc.sqf new file mode 100644 index 0000000000..ebe1e55ccb --- /dev/null +++ b/addons/killtracker/initSettings.inc.sqf @@ -0,0 +1,8 @@ +[ + QGVAR(trackAI), + "CHECKBOX", + [LSTRING(TrackAI_DisplayName), LSTRING(TrackAI_Description)], + LSTRING(Category), + true, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/killtracker/stringtable.xml b/addons/killtracker/stringtable.xml index 4aa7308924..a44b42e1bc 100644 --- a/addons/killtracker/stringtable.xml +++ b/addons/killtracker/stringtable.xml @@ -1,9 +1,16 @@ + + ACE Kill Tracker + ACE Tracciatore di Uccisioni + ACE Kill Tracker + ACE Отслеживание убийств + ACE キルトラッカー + ACE Killed Events - ACE キルトラッカー + ACE キルイベント ACE Abgeschossene Ereignisse ACE Eventi di Morte ACE Licznik Zabójstw @@ -86,5 +93,19 @@ 同士討ち Dost Atışı + + Track AI units killed by player + Traccia IA uccise da giocatori + Sledovat AI zabité hráči + Отслеживание юнитов ИИ, убитых игроком + プレイヤーに殺害されたAIユニットを追跡 + + + Defines if killed AIs will be shown in the kill tracker during mission debriefing. + Determina se IA uccise verranno visualizzate nel tracciatore durante il debriefing della missione. + Udává zdali se zabité AI budou ukazovat v kill trackeru v průběhu debriefingu po misi. + Определяет, будут ли убитые ИИ отображаться в трекере убийств во время дебрифинга миссии. + ミッションデブリーフィングのキルトラッカーに殺害されたAIが表示されるかどうかを定義します。 + diff --git a/addons/laser/XEH_PREP.hpp b/addons/laser/XEH_PREP.hpp index 9b9be64752..2d26ff81f2 100644 --- a/addons/laser/XEH_PREP.hpp +++ b/addons/laser/XEH_PREP.hpp @@ -3,6 +3,7 @@ PREP(addLaserTarget); PREP(addMapHandler); PREP(dev_drawVisibleLaserTargets); PREP(findLaserSource); +PREP(getLaserCode); PREP(handleLaserTargetCreation); PREP(keyLaserCodeChange); PREP(laserOff); @@ -13,6 +14,7 @@ PREP(onLaserDesignatorDraw); PREP(rotateVectLine); PREP(rotateVectLineGetMap); PREP(seekerFindLaserSpot); +PREP(setLaserCode); PREP(shootCone); PREP(shootRay); PREP(showVehicleHud); diff --git a/addons/laser/functions/fnc_getLaserCode.sqf b/addons/laser/functions/fnc_getLaserCode.sqf new file mode 100644 index 0000000000..0a0fce363f --- /dev/null +++ b/addons/laser/functions/fnc_getLaserCode.sqf @@ -0,0 +1,24 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Gets the laser code of a laser source. + * + * Argument: + * 0: Laser source + * + * Return Value: + * Laser code + * + * Example: + * player call ace_laser_fnc_getLaserCode; + * + * Public: Yes + */ + +params [["_laserSource", objNull, [objNull]]]; + +if (isNull _laserSource) exitWith { + -1 +}; + +_laserSource getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE] diff --git a/addons/laser/functions/fnc_setLaserCode.sqf b/addons/laser/functions/fnc_setLaserCode.sqf new file mode 100644 index 0000000000..23f7e5c82f --- /dev/null +++ b/addons/laser/functions/fnc_setLaserCode.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Sets the laser code on a laser source. + * + * Argument: + * 0: Laser source + * 1: Laser code + * + * Return Value: + * None + * + * Example: + * [player, 1111] call ace_laser_fnc_setLaserCode; + * + * Public: Yes + */ + +params [["_laserSource", objNull, [objNull]], ["_laserCode", ACE_DEFAULT_LASER_CODE, [0]]]; + +_laserSource setVariable [QGVAR(code), _laserCode, true]; diff --git a/addons/laser/stringtable.xml b/addons/laser/stringtable.xml index 7c07582725..f0977c84f7 100644 --- a/addons/laser/stringtable.xml +++ b/addons/laser/stringtable.xml @@ -128,6 +128,7 @@ 레이저 스팟 추적기: 켬 Traqueur laser : activé Rastreador a Laser: Ligado + Лазерный точечный трекер: Включен Laser Spot Tracker: Off @@ -138,6 +139,7 @@ 레이저 스팟 추적기: 끔 Traqueur laser : désactivé Rastreador a Laser: Desligado + Лазерный точечный трекер: выключен Draw Laser on Map diff --git a/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf b/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf index 3698f4a22f..9a8bde077b 100644 --- a/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_destroyFence.sqf @@ -17,7 +17,7 @@ params ["_fence"]; -private _fenceModel = toLower ((getModelInfo _fence)#0); +private _fenceModel = toLowerANSI ((getModelInfo _fence)#0); // If fence cannot be replaced with destroyed model, just knock it over if !(_fenceModel in GVAR(replacements)) exitWith { diff --git a/addons/main/stringtable.xml b/addons/main/stringtable.xml index 902c0d97c2..b676359f74 100644 --- a/addons/main/stringtable.xml +++ b/addons/main/stringtable.xml @@ -6,7 +6,7 @@ ACE Logistik ACE Logistyka Logísticas ACE - ACE: логистика + ACE: Логистика ACE Logistika ACE Logística ACE Logistica diff --git a/addons/map/XEH_postInitClient.sqf b/addons/map/XEH_postInitClient.sqf index 49b8239e0a..72637e3092 100644 --- a/addons/map/XEH_postInitClient.sqf +++ b/addons/map/XEH_postInitClient.sqf @@ -93,7 +93,7 @@ GVAR(vehicleLightColor) = [1,1,1,0]; // Handle vehicles with toggleable interior lights: private _vehicleLightCondition = getText (_cfg >> QGVAR(vehicleLightCondition)); if (_vehicleLightCondition == "") then { - private _userAction = toLower getText (_cfg >> "UserActions" >> "ToggleLight" >> "statement"); + private _userAction = toLowerANSI getText (_cfg >> "UserActions" >> "ToggleLight" >> "statement"); if ( false // isClass (_cfg >> "compartmentsLights") || {_userAction find "cabinlights_hide" > 0} diff --git a/addons/maptools/stringtable.xml b/addons/maptools/stringtable.xml index fc719473b8..9d23c4ffff 100644 --- a/addons/maptools/stringtable.xml +++ b/addons/maptools/stringtable.xml @@ -39,11 +39,15 @@ Plotting Board 플로팅 보드 標定盤 + Tavola di calcolo + Графическая доска The Plotting Board is a map tool designed for use in the directing of short range indirect fires. 플로팅 보드는 단거리 간접 사격을 지시하는 데 사용하도록 설계된 독도용 도구입니다. 標定盤(プロッティング・ボード)は、短距離の間接射撃の指示に使用するために設計されたマップツールです。 + La tavola di calcolo è uno strumento utilizzato per dirigere fuoco di artiglieria a corto raggio. + Графическая доска - это картографический инструмент, предназначенный для использования при ведении непрямого огня с малой дистанции. Map Tools @@ -266,71 +270,99 @@ Allow Plotting Board Drawing channels 標定盤への書き込みを許可するチャンネル 플로팅 보드 그리기 채널 허용 + Canali ammessi su tavola di calcolo + Разрешить создание каналов на миллиметровой доске. Channels in which plotting board drawing is enabled. どのチャンネルで標定盤の書き込みを有効化するか。 플로팅 보드 그리기가 활성화된 채널입니다. + Canali in cui si può disegnare sulla tavola di calcolo. + Каналы, в которых включено рисование на миллиметровой доске. Allow Direct Comms Only (Polylines Only) 直接チャンネルのみ許可 (線のみ) 직접교신만 허용 (선 긋기만) + Comunicazioni Dirette (solo linee) + Разрешать только прямую связь (только полилинии) Allow Direct/Group Comms (Polylines and Group Markers) 直接/グループチャンネルを許可 (線とグループマーカー) 직접교신/그룹무전망 허용 (선 긋기와 그룹 마커) + Comunicazioni dirette/gruppo (linee e marker) + Разрешить прямую/групповую связь (полилинии и групповые маркеры) Plotting Board 標定盤 플로팅 보드 + Tavola di calcolo + Миллиметровая доска Plotting Board Acrylic 標定盤の アクリル板 플로팅 보드 (아크릴) + Acrilico tavola di calcolo + Миллиметровая доска акрилловая Plotting Board Ruler 標定盤の 定規 플로팅 보드 (자) + Righello tavola di calcolo + Линейка для миллиметровой доски To Plotting Board 標定盤に 플로팅 보드에 + Su tavola di calcolo + К миллиметровой доске. To Plotting Board Acrylic 標定盤の アクリル板に 플로팅 보드 (아크릴)에 + Su acrilico tavola di calcolo + К миллиметровой доске акрилловой To Plotting Board Ruler 標定盤の 定規に 플로팅 보드 (자)에 + Su righello tavola di calcolo + К линейке миллиметровой доски. Wipe all markers off Plotting Board 標定盤の 全マーカーを 拭き消す 플로팅 보드에 있는 모든 마커 지우기 + Cancella tutti i disegni dalla tavola + Сотрите все маркеры с миллиметровой доски. Show Plotting Board 標定盤を 表示 플로팅 보드 보이기 + Mostra tavola di calcolo + Показать миллиметровую доску. Hide Plotting Board 標定盤を 隠す 플로팅 보드 숨기기 + Nascondi tavola di calcolo + Скрыть миллиметровую доску. Toggle Plotting Board Ruler 標定盤の 定規を 表示切替 플로팅 보드 (자) 토글 + Mostra/Nascondi Righello + Переключить линейку миллиметровой доски. Align @@ -378,11 +410,15 @@ Up 上に 위로 + Su + Вверх To Maptool マップツールに 독도용 도구로 + Su strumento cartografico + К инструментам карты diff --git a/addons/markers/stringtable.xml b/addons/markers/stringtable.xml index 285dd007e8..a0c0be17f7 100644 --- a/addons/markers/stringtable.xml +++ b/addons/markers/stringtable.xml @@ -247,6 +247,7 @@ Zona horaria Strefa czasowa Zeitzone + Fuso orario 时区 시간대 @@ -258,6 +259,7 @@ Cambie la zona horaria para la marca de tiempo Zmień strefę czasową dla znaczników czasu Ändern Sie die Zeitzone für den Zeitstempel + Modifica il fuso orario per la marca temporale 更改时间戳的时区 타임스탬프의 시간대를 변경하십시오 @@ -269,6 +271,7 @@ Hora del juego Czas gry Ingame-Zeit + Ora del gioco 游戏内时间 게임 시간 @@ -280,6 +283,7 @@ Hora del sistema Czas systemowy Systemzeit + Ora del sistema 系统时间 시스템 시간 @@ -291,6 +295,7 @@ Hora UTC Czas UTC UTC-Zeit + Tempo-UTC UTC时间 UTC 시간 @@ -302,6 +307,7 @@ Desplazamiento UTC Przesunięcie UTC UTC-Verschiebung + Deviazione-UTC UTC偏移量 UTC 오프셋 @@ -313,17 +319,19 @@ Cambiar el desplazamiento horario para la marca de tiempo UTC Zmień przesunięcie czasu dla sygnatury czasowej UTC Ändere die Zeitverschiebung für den UTC-Zeitstempel + Modifica la deviazione della marca temporale UTC. 更改UTC时间戳的时间偏移量 UTC 타임 스탬프의 시간 오프셋을 변경하십시오 UTC Minutes Offset - UTC Минутное Смещение + UTC Минутное смещение Décalage des minutes UTC UTC分オフセット Desplazamiento de minutos UTC Przesunięcie minut UTC UTC-Minutenversatz + Deviazione Minuti UTC UTC分钟偏移量 UTC 분 오프셋 @@ -335,6 +343,7 @@ Cambiar el desplazamiento de minutos para la marca de tiempo UTC Zmień przesunięcie minut dla sygnatury czasowej UTC Ändere den Minutenversatz für den UTC-Zeitstempel + Modifica la deviazione dei minuti della marca temporale UTC. 更改UTC时间戳的分钟偏移量 UTC 타임 스탬프의 분 오프셋을 변경하십시오 @@ -407,17 +416,21 @@ "MM" - Milliseconds (from 0 to 59) "MM" - Millisecondes (de 0 à 59) "MS" - Milisekunden (von 0 bis 59) + "MS" - Millisecondi (da 0 a 59) "MS" - Milissegundos (de 0 a 59) "MS" - 밀리초 (0부터 59까지) "MM" - ミリ秒 (0から59) + "ММ" - миллисекунды (от 0 до 59) "mmm" - Milliseconds (from 0 to 999) "mmm" - Millisecondes (de 0 à 999) "mmm" - Milisekunden (von 0 bis 999) + "mmm" - Millisecondi (da 0 a 999) "mmm" - Milissegundos (de 0 a 999) "mmm" - 밀리초 (0부터 999까지) "mmm" - ミリ秒 (0から599) + "ммм" - миллисекунды (от 0 до 999) Timestamp Hour Format diff --git a/addons/maverick/config.cpp b/addons/maverick/config.cpp index 6d5837f87d..d25878d004 100644 --- a/addons/maverick/config.cpp +++ b/addons/maverick/config.cpp @@ -9,10 +9,6 @@ class CfgPatches { authors[] = {"xrufix"}; url = ECSTRING(main,URL); VERSION_CONFIG; - ammo[] = { - QGVAR(L), - "ace_kh25ml" - }; magazines[] = { QGVAR(L_magazine_x1), QGVAR(L_pylonmissile_x1), diff --git a/addons/medical/functions/fnc_addDamageToUnit.sqf b/addons/medical/functions/fnc_addDamageToUnit.sqf index 3d82cbe77a..e490399c4b 100644 --- a/addons/medical/functions/fnc_addDamageToUnit.sqf +++ b/addons/medical/functions/fnc_addDamageToUnit.sqf @@ -34,7 +34,7 @@ params [ ]; TRACE_7("addDamageToUnit",_unit,_damageToAdd,_bodyPart,_typeOfDamage,_instigator,_damageSelectionArray,_overrideInvuln); -_bodyPart = toLower _bodyPart; +_bodyPart = toLowerANSI _bodyPart; private _bodyPartIndex = ALL_BODY_PARTS find _bodyPart; if (_bodyPartIndex < 0) then { _bodyPartIndex = ALL_SELECTIONS find _bodyPart; }; // 2nd attempt with selection names ("hand_l", "hand_r", "leg_l", "leg_r") if (_bodyPartIndex < 0) exitWith {ERROR_1("addDamageToUnit - bad selection %1",_this); false}; diff --git a/addons/medical_ai/stringtable.xml b/addons/medical_ai/stringtable.xml index 61cebf9fb5..7f5680dc3f 100644 --- a/addons/medical_ai/stringtable.xml +++ b/addons/medical_ai/stringtable.xml @@ -57,6 +57,7 @@ Items requis Exigir Itens アイテムを要求 + Требуемые предметы AI will only perform medical treatment if they have the necessary items in their inventory. @@ -67,6 +68,7 @@ Les IA n'effectueront un traitement médical que si elles ont le matériel nécessaire dans leur inventaire. A IA só irá realizar tratamento médico se tiver os itens necessários em seu inventário. AIのインベントリに必要なアイテムがある場合にのみ治療を実行します。 + Искусственный интеллект будет оказывать медицинскую помощь только в том случае, если в его инвентаре есть необходимые предметы. Auto Convert Items for AI @@ -77,6 +79,7 @@ Conversione automatica di risorse mediche per IA Conversão automática de itens para IA AIのアイテムを自動変換 + Автоматическое преобразование элементов для ИИ diff --git a/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf b/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf index 5df29c7702..fb82f383b6 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerBase.sqf @@ -41,7 +41,7 @@ private _bodyPartVisParams = [_unit, false, false, false, false]; // params arra // process wounds separately for each body part hit { // forEach _allDamages _x params ["_damage", "_bodyPart"]; - _bodyPart = toLower _bodyPart; + _bodyPart = toLowerANSI _bodyPart; // silently ignore structural damage if (_bodyPart == "#structural") then {continue}; diff --git a/addons/medical_damage/stringtable.xml b/addons/medical_damage/stringtable.xml index 63d10dcd35..f21cb1901f 100644 --- a/addons/medical_damage/stringtable.xml +++ b/addons/medical_damage/stringtable.xml @@ -20,7 +20,7 @@ Sets the amount of damage a player can receive before going unconscious (and dying if "Sum of Trauma" is enabled). プレイヤーが気絶するまでに受けられるダメージ量を設定します。\n("外傷の合計"が有効な場合は死亡するまでに受けられるダメージ量) Définit la quantité de dégâts qu'un joueur peut subir avant de perdre connaissance (ou mourir, si l'option "Somme des traumatismes" est sélectionnée). - Устанавливает количество урона, которое может получить игрок, прежде чем потеряет сознание. + Устанавливает количество урона, которое может получить игрок, прежде чем потеряет сознание (и умирает, если включена функция "Сумма травм"). Define a quantidade de dano que um jogador pode receber antes de ficar inconsciente. 設定玩家在無意識前能承受多少傷害。 设置玩家在昏迷前可以承受的伤害量(如果启用了“创伤总和”,则会死亡)。 @@ -51,7 +51,7 @@ Sets the amount of damage an AI unit can receive before going unconscious (or dying when "Sum of Trauma" is enabled). AIが気絶するまでに受けられるダメージ量を設定します。\n("外傷の合計"が有効な場合は死亡するまでに受けられるダメージ量) Définit la quantité de dégâts qu'une unité IA peut subir avant de perdre connaissance (ou mourir, si l'option "Somme des traumatismes" est sélectionnée). - Устанавливает количество урона, которое может получить ИИ, прежде чем потеряет сознание. + Устанавливает количество урона, которое может получить ИИ, прежде чем потеряет сознание (или умирает, когда включена функция "Сумма травм").. Define a quantidade de dano que uma IA pode receber antes de ficar inconsciente. 設定AI在無意識之前能承受多少傷害 设置 AI 在昏迷前可以承受的伤害量(如果启用了“创伤总和”,则会死亡)。 diff --git a/addons/medical_engine/XEH_postInit.sqf b/addons/medical_engine/XEH_postInit.sqf index 2514c62254..5557807629 100644 --- a/addons/medical_engine/XEH_postInit.sqf +++ b/addons/medical_engine/XEH_postInit.sqf @@ -86,6 +86,12 @@ if (!isNull objectParent _unit && {local objectParent _unit}) exitWith { [_unit] call FUNC(lockUnconsciousSeat); }; + + // Prevent second ragdoll of uncon units when they're killed + if (IS_UNCONSCIOUS(_unit) && !isAwake _unit) then { + _unit enableSimulation false; + [{_this enableSimulation true}, _unit, 2] call CBA_fnc_waitAndExecute; + }; }] call CBA_fnc_addEventHandler; ["CAManBase", "deleted", { diff --git a/addons/medical_engine/XEH_preInit.sqf b/addons/medical_engine/XEH_preInit.sqf index dab2e7efe3..a7221ce1c1 100644 --- a/addons/medical_engine/XEH_preInit.sqf +++ b/addons/medical_engine/XEH_preInit.sqf @@ -19,6 +19,7 @@ if (isNil QUOTE(BLOOD_LOSS_KNOCK_OUT_THRESHOLD)) then {BLOOD_LOSS_KNOCK_OUT_THRE if (isNil QUOTE(PAIN_FADE_TIME)) then {PAIN_FADE_TIME = PAIN_FADE_TIME_DEFAULT}; if (isNil QUOTE(LIMPING_DAMAGE_THRESHOLD)) then {LIMPING_DAMAGE_THRESHOLD = LIMPING_DAMAGE_THRESHOLD_DEFAULT}; if (isNil QUOTE(FRACTURE_DAMAGE_THRESHOLD)) then {FRACTURE_DAMAGE_THRESHOLD = FRACTURE_DAMAGE_THRESHOLD_DEFAULT}; +if (isNil QUOTE(CARIDAC_OUTPUT_MIN)) then {CARIDAC_OUTPUT_MIN = CARIDAC_OUTPUT_MIN_DEFAULT}; // Derive the alternate fatal damage coefficents if (isNil QUOTE(FATAL_SUM_DAMAGE_WEIBULL_K) || isNil QUOTE(FATAL_SUM_DAMAGE_WEIBULL_L)) then { private _x1 = 0.5; diff --git a/addons/medical_engine/functions/fnc_damageBodyPart.sqf b/addons/medical_engine/functions/fnc_damageBodyPart.sqf index c25d83c46c..f69bce2cae 100644 --- a/addons/medical_engine/functions/fnc_damageBodyPart.sqf +++ b/addons/medical_engine/functions/fnc_damageBodyPart.sqf @@ -28,7 +28,7 @@ TRACE_3("damageBodyPart",_unit,_selection,_damage); _damage = [0, DAMAGED_MIN_THRESHOLD] select _damage; -switch (toLower _selection) do { +switch (toLowerANSI _selection) do { case ("head"): { _unit setHitPointDamage ["HitHead", _damage]; }; diff --git a/addons/medical_engine/script_macros_medical.hpp b/addons/medical_engine/script_macros_medical.hpp index 56c1eec401..f789caec9e 100644 --- a/addons/medical_engine/script_macros_medical.hpp +++ b/addons/medical_engine/script_macros_medical.hpp @@ -42,6 +42,7 @@ #define GET_ARRAY(config,default) (if (isArray (config)) then {getArray (config)} else {default}) #define DEFAULT_HEART_RATE 80 +#define DEFAULT_SPO2 97 #define DEFAULT_PERIPH_RES 100 // --- blood @@ -52,7 +53,8 @@ #define BLOOD_VOLUME_CLASS_2_HEMORRHAGE 5.100 // lost more than 15% blood, Class II Hemorrhage #define BLOOD_VOLUME_CLASS_3_HEMORRHAGE 4.200 // lost more than 30% blood, Class III Hemorrhage #define BLOOD_VOLUME_CLASS_4_HEMORRHAGE 3.600 // lost more than 40% blood, Class IV Hemorrhage -#define BLOOD_VOLUME_FATAL 3.0 // Lost more than 50% blood, Unrecoverable +// Lost more than 50% blood, Unrecoverable +#define BLOOD_VOLUME_FATAL 3.0 // Minimum blood volume, in liters, for a patient to have the chance to wake up #define MINIMUM_BLOOD_FOR_STABLE_VITALS EGVAR(medical,const_stableVitalsBloodThreshold) @@ -106,6 +108,10 @@ #define FRACTURE_DAMAGE_THRESHOLD EGVAR(medical,const_fractureDamageThreshold) #define FRACTURE_DAMAGE_THRESHOLD_DEFAULT 0.50 +// Minimum cardiac output +#define CARIDAC_OUTPUT_MIN EGVAR(medical,const_minCardiacOutput) +#define CARIDAC_OUTPUT_MIN_DEFAULT 0.05 + // Minimum body part damage required for blood effect on uniform #define VISUAL_BODY_DAMAGE_THRESHOLD 0.35 @@ -153,6 +159,8 @@ #define VAR_WOUND_BLEEDING QEGVAR(medical,woundBleeding) #define VAR_CRDC_ARRST QEGVAR(medical,inCardiacArrest) #define VAR_HEART_RATE QEGVAR(medical,heartRate) +#define VAR_SPO2 QEGVAR(medical,spo2) +#define VAR_OXYGEN_DEMAND QEGVAR(medical,oxygenDemand) #define VAR_PAIN QEGVAR(medical,pain) #define VAR_PAIN_SUPP QEGVAR(medical,painSuppress) #define VAR_PERIPH_RES QEGVAR(medical,peripheralResistance) @@ -175,6 +183,7 @@ #define GET_BLOOD_VOLUME(unit) (unit getVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME]) #define GET_WOUND_BLEEDING(unit) (unit getVariable [VAR_WOUND_BLEEDING, 0]) #define GET_HEART_RATE(unit) (unit getVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE]) +#define GET_SPO2(unit) (unit getVariable [VAR_SPO2, DEFAULT_SPO2]) #define GET_HEMORRHAGE(unit) (unit getVariable [VAR_HEMORRHAGE, 0]) #define GET_PAIN(unit) (unit getVariable [VAR_PAIN, 0]) #define GET_PAIN_SUPPRESS(unit) (unit getVariable [VAR_PAIN_SUPP, 0]) diff --git a/addons/medical_engine/stringtable.xml b/addons/medical_engine/stringtable.xml index 9a4179a38c..3aa0831a28 100644 --- a/addons/medical_engine/stringtable.xml +++ b/addons/medical_engine/stringtable.xml @@ -36,6 +36,7 @@ Fattore di Trapasso Armatura Efeito de Penetração de Blindagem 装甲貫通効果 + Эффект сквозного прохождения брони Controls effect of armor 'passThrough' on final damage. Makes high armor values, like ones used in GL rigs, less effective.\nUse 0% for pre 3.16.0 armor behavior.\nOnly touch this if you know what you're doing! @@ -46,6 +47,7 @@ Determina l'effetto di danni sul corpo che 'trapassano' l'armatura. Rende alti valori di protezione, come quelli su corpetti GL, meno efficaci.\nUtilizza 0% per il comportamento prima di v3.16.0.\nModifica questo valore solo se sai cosa stai facendo! Controla o efeito de penetração (passThrough) da blindagem no dano final. Torna valores de blindagem altos, como os usados em coletes GL, menos eficazes.\nUse 0% para o comportamento de blindagem anterior à versão 3.16.0.\nSó mexa nisso se souber o que está fazendo! ボディアーマーの'passThrough'値が最終的な身体ダメージに与える影響を調整します。擲弾兵リグで使用されるような高い装甲値では効果が低くなります。\n3.16.0以前の挙動にするには0%にしてください。\nこれが何かわからない場合は変更しないことをお勧めします。 + Контролирует эффект `passThrough` при нанесении конечного урона. Делает высокие значения брони, подобные тем, которые используются в GL rigs, менее эффективными.\nИспользуйте 0% для поведения брони до версии 3.16.0.n\Прикасайтесь к этому, только если знаете, что делаете! diff --git a/addons/medical_gui/XEH_postInit.sqf b/addons/medical_gui/XEH_postInit.sqf index f2777f6fd4..5ff49d2167 100644 --- a/addons/medical_gui/XEH_postInit.sqf +++ b/addons/medical_gui/XEH_postInit.sqf @@ -102,7 +102,7 @@ GVAR(selfInteractionActions) = []; params ["_unit", "_allDamages", ""]; if !(GVAR(peekMedicalOnHit) && {_unit == ACE_player}) exitWith {}; - private _bodypart = toLower (_allDamages select 0 select 1); + private _bodypart = toLowerANSI (_allDamages select 0 select 1); private _bodypartIndex = ALL_BODY_PARTS find _bodypart; [ACE_player, _bodypartIndex] call FUNC(displayPatientInformation); diff --git a/addons/medical_gui/functions/fnc_addTreatmentActions.sqf b/addons/medical_gui/functions/fnc_addTreatmentActions.sqf index 3df89894d2..b27801766b 100644 --- a/addons/medical_gui/functions/fnc_addTreatmentActions.sqf +++ b/addons/medical_gui/functions/fnc_addTreatmentActions.sqf @@ -36,14 +36,14 @@ private _fnc_condition = { private _displayName = getText (_x >> "displayName"); private _icon = getText (_x >> "icon"); - private _allowedBodyParts = getArray (_x >> "allowedSelections") apply {toLower _x}; + private _allowedBodyParts = getArray (_x >> "allowedSelections") apply {toLowerANSI _x}; if (_allowedBodyParts isEqualTo ["all"]) then { - _allowedBodyParts = ALL_BODY_PARTS apply {toLower _x}; + _allowedBodyParts = ALL_BODY_PARTS apply {toLowerANSI _x}; }; { private _bodyPart = _x; - private _actionPath = _actionPaths select (ALL_BODY_PARTS find toLower _bodyPart); + private _actionPath = _actionPaths select (ALL_BODY_PARTS find toLowerANSI _bodyPart); private _action = [ _actionName, diff --git a/addons/medical_gui/functions/fnc_countTreatmentItems.sqf b/addons/medical_gui/functions/fnc_countTreatmentItems.sqf index 6e8394c82f..ac7c4857e6 100644 --- a/addons/medical_gui/functions/fnc_countTreatmentItems.sqf +++ b/addons/medical_gui/functions/fnc_countTreatmentItems.sqf @@ -42,12 +42,27 @@ private _vehicle = [_patientVehicle, _medicVehicle] select (!isNull _medicVehicl if (!isNull _vehicle) then { _vehicleCount = 0; - (getItemCargo _vehicle) params ["_itemTypes", "_itemCounts"]; + private _magazineItems = []; + private _itemItems = []; { - private _item = _x; - private _index = _itemTypes find _item; - _vehicleCount = _vehicleCount + (_itemCounts param [_index, 0]); + if (isClass (configFile >> "CfgMagazines" >> _x)) then { + _magazineItems pushBack _x; + } else { + _itemItems pushBack _x; + }; } forEach _items; + if (_magazineItems isNotEqualTo []) then { + (getMagazineCargo _vehicle) params ["_itemTypes", "_itemCounts"]; + { + _vehicleCount = _vehicleCount + (_itemCounts param [_itemTypes find _x, 0]); + } forEach _magazineItems; + }; + if (_itemItems isNotEqualTo []) then { + (getItemCargo _vehicle) params ["_itemTypes", "_itemCounts"]; + { + _vehicleCount = _vehicleCount + (_itemCounts param [_itemTypes find _x, 0]); + } forEach _itemItems; + }; }; [_medicCount, _patientCount, _vehicleCount] diff --git a/addons/medical_gui/functions/fnc_updateBodyImage.sqf b/addons/medical_gui/functions/fnc_updateBodyImage.sqf index 4d22b68a2d..b8ee8ee240 100644 --- a/addons/medical_gui/functions/fnc_updateBodyImage.sqf +++ b/addons/medical_gui/functions/fnc_updateBodyImage.sqf @@ -105,3 +105,5 @@ private _bodyPartBloodLoss = [0, 0, 0, 0, 0, 0]; [IDC_BODY_LEGLEFT, IDC_BODY_LEGLEFT_S, IDC_BODY_LEGLEFT_T, IDC_BODY_LEGLEFT_B], [IDC_BODY_LEGRIGHT, IDC_BODY_LEGRIGHT_S, IDC_BODY_LEGRIGHT_T, IDC_BODY_LEGRIGHT_B] ]; + +[QGVAR(updateBodyImage), [_ctrlGroup, _target, _selectionN]] call CBA_fnc_localEvent; diff --git a/addons/medical_gui/functions/fnc_updateCategories.sqf b/addons/medical_gui/functions/fnc_updateCategories.sqf index c9917a8758..c2f1d2a11c 100644 --- a/addons/medical_gui/functions/fnc_updateCategories.sqf +++ b/addons/medical_gui/functions/fnc_updateCategories.sqf @@ -21,8 +21,9 @@ params ["_display"]; _x params ["_idc", "_category"]; private _ctrl = _display displayCtrl _idc; - private _enable = GVAR(actions) findIf {_category == _x select 1 && {call (_x select 2)}} > -1; - if (_category isEqualTo "triage") then {_enable = true}; + private _enable = if (_category == "triage") then { true } else { + GVAR(actions) findIf {_category == _x select 1 && {call (_x select 2)}} > -1 + }; _ctrl ctrlEnable _enable; private _selectedColor = [ diff --git a/addons/medical_gui/functions/fnc_updateInjuryList.sqf b/addons/medical_gui/functions/fnc_updateInjuryList.sqf index 328e80242a..3219eb025f 100644 --- a/addons/medical_gui/functions/fnc_updateInjuryList.sqf +++ b/addons/medical_gui/functions/fnc_updateInjuryList.sqf @@ -24,24 +24,31 @@ private _nonissueColor = [1, 1, 1, 0.33]; // Indicate if unit is bleeding at all if (IS_BLEEDING(_target)) then { - // Give a qualitative description of the rate of bleeding - private _cardiacOutput = [_target] call EFUNC(medical_status,getCardiacOutput); - private _bleedRate = GET_BLOOD_LOSS(_target); - private _bleedRateKO = BLOOD_LOSS_KNOCK_OUT_THRESHOLD * (_cardiacOutput max 0.05); - // Use nonzero minimum cardiac output to prevent all bleeding showing as massive during cardiac arrest - - switch (true) do { - case (_bleedRate < _bleedRateKO * BLEED_RATE_SLOW): { - _entries pushBack [localize LSTRING(Bleed_Rate1), [1, 1, 0, 1]]; + switch (GVAR(showBleeding)) do { + case 1: { + // Just show whether the unit is bleeding at all + _entries pushBack [localize LSTRING(Status_Bleeding), [1, 0, 0, 1]]; }; - case (_bleedRate < _bleedRateKO * BLEED_RATE_MODERATE): { - _entries pushBack [localize LSTRING(Bleed_Rate2), [1, 0.67, 0, 1]]; - }; - case (_bleedRate < _bleedRateKO * BLEED_RATE_SEVERE): { - _entries pushBack [localize LSTRING(Bleed_Rate3), [1, 0.33, 0, 1]]; - }; - default { - _entries pushBack [localize LSTRING(Bleed_Rate4), [1, 0, 0, 1]]; + case 2: { + // Give a qualitative description of the rate of bleeding + private _cardiacOutput = [_target] call EFUNC(medical_status,getCardiacOutput); + private _bleedRate = GET_BLOOD_LOSS(_target); + private _bleedRateKO = BLOOD_LOSS_KNOCK_OUT_THRESHOLD * (_cardiacOutput max 0.05); + // Use nonzero minimum cardiac output to prevent all bleeding showing as massive during cardiac arrest + switch (true) do { + case (_bleedRate < _bleedRateKO * BLEED_RATE_SLOW): { + _entries pushBack [localize LSTRING(Bleed_Rate1), [1, 1, 0, 1]]; + }; + case (_bleedRate < _bleedRateKO * BLEED_RATE_MODERATE): { + _entries pushBack [localize LSTRING(Bleed_Rate2), [1, 0.67, 0, 1]]; + }; + case (_bleedRate < _bleedRateKO * BLEED_RATE_SEVERE): { + _entries pushBack [localize LSTRING(Bleed_Rate3), [1, 0.33, 0, 1]]; + }; + default { + _entries pushBack [localize LSTRING(Bleed_Rate4), [1, 0, 0, 1]]; + }; + }; }; }; } else { @@ -70,13 +77,35 @@ if (GVAR(showBloodlossEntry)) then { }; // Show receiving IV volume remaining private _totalIvVolume = 0; +private _saline = 0; +private _blood = 0; +private _plasma = 0; { - _x params ["_volumeRemaining"]; + _x params ["_volumeRemaining", "_type"]; + switch (_type) do { + case "Saline": { + _saline = _saline + _volumeRemaining; + }; + case "Blood": { + _blood = _blood + _volumeRemaining; + }; + case "Plasma": { + _plasma = _plasma + _volumeRemaining; + }; + }; _totalIvVolume = _totalIvVolume + _volumeRemaining; } forEach (_target getVariable [QEGVAR(medical,ivBags), []]); -if (_totalIvVolume >= 1) then { - _entries pushBack [format [localize ELSTRING(medical_treatment,receivingIvVolume), floor _totalIvVolume], [1, 1, 1, 1]]; +if (_totalIvVolume > 0) then { + if (_saline > 0) then { + _entries pushBack [format [localize ELSTRING(medical_treatment,receivingSalineIvVolume), floor _saline], [1, 1, 1, 1]]; + }; + if (_blood > 0) then { + _entries pushBack [format [localize ELSTRING(medical_treatment,receivingBloodIvVolume), floor _blood], [1, 1, 1, 1]]; + }; + if (_plasma > 0) then { + _entries pushBack [format [localize ELSTRING(medical_treatment,receivingPlasmaIvVolume), floor _plasma], [1, 1, 1, 1]]; + }; } else { _entries pushBack [localize ELSTRING(medical_treatment,Status_NoIv), _nonissueColor]; }; @@ -116,6 +145,8 @@ if (_selectionN == -1) exitWith { _ctrl lbSetCurSel -1; }; +[QGVAR(updateInjuryListGeneral), [_ctrl, _target, _selectionN, _entries]] call CBA_fnc_localEvent; + _entries pushBack ["", [1, 1, 1, 1]]; // Add selected body part name @@ -184,6 +215,8 @@ switch (GET_FRACTURES(_target) select _selectionN) do { }; }; +[QGVAR(updateInjuryListPart), [_ctrl, _target, _selectionN, _entries, _bodyPartName]] call CBA_fnc_localEvent; + // Add entries for open, bandaged, and stitched wounds private _woundEntries = []; @@ -216,6 +249,8 @@ private _fnc_processWounds = { [GET_BANDAGED_WOUNDS(_target), "[B] %1", [0.88, 0.7, 0.65, 1]] call _fnc_processWounds; [GET_STITCHED_WOUNDS(_target), "[S] %1", [0.7, 0.7, 0.7, 1]] call _fnc_processWounds; +[QGVAR(updateInjuryListWounds), [_ctrl, _target, _selectionN, _woundEntries, _bodyPartName]] call CBA_fnc_localEvent; + // Handle no wound entries if (_woundEntries isEqualTo []) then { _entries pushBack [localize ELSTRING(medical_treatment,NoInjuriesBodypart), _nonissueColor]; diff --git a/addons/medical_gui/functions/fnc_updateLogList.sqf b/addons/medical_gui/functions/fnc_updateLogList.sqf index d2bb75b63f..51240705f9 100644 --- a/addons/medical_gui/functions/fnc_updateLogList.sqf +++ b/addons/medical_gui/functions/fnc_updateLogList.sqf @@ -23,6 +23,8 @@ lbClear _ctrl; { _x params ["_message", "_timeStamp", "_arguments"]; + private _unlocalizedMessage = _message; + // Localize message and arguments if (isLocalized _message) then { _message = localize _message; @@ -33,5 +35,7 @@ lbClear _ctrl; // Format message with arguments _message = format ([_message] + _arguments); - _ctrl lbAdd format ["%1 %2", _timeStamp, _message]; + private _row = _ctrl lbAdd format ["%1 %2", _timeStamp, _message]; + + [QGVAR(logListAppended), [_ctrl, _row, _message, _unlocalizedMessage, _timeStamp, _arguments]] call CBA_fnc_localEvent; } forEach _logs; diff --git a/addons/medical_gui/initSettings.inc.sqf b/addons/medical_gui/initSettings.inc.sqf index a0418ca74e..dfcbe48925 100644 --- a/addons/medical_gui/initSettings.inc.sqf +++ b/addons/medical_gui/initSettings.inc.sqf @@ -127,6 +127,15 @@ private _categoryColors = [ELSTRING(medical,Interface_Category), format ["| %1 | true // isGlobal ] call CBA_fnc_addSetting; +[ + QGVAR(showBleeding), + "LIST", + [LSTRING(showBleeding_DisplayName), LSTRING(showBleeding_Description)], + [ELSTRING(medical,Interface_Category), LSTRING(SubCategory)], + [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(ShowBleeding_Rate)], 2], + true // isGlobal +] call CBA_fnc_addSetting; + [ QGVAR(bodyPartOutlineColor), "COLOR", diff --git a/addons/medical_gui/stringtable.xml b/addons/medical_gui/stringtable.xml index 438b160bb2..db0bce9d2a 100644 --- a/addons/medical_gui/stringtable.xml +++ b/addons/medical_gui/stringtable.xml @@ -217,7 +217,7 @@ Mostra livello di Triage nel Menù d'Interazione インタラクションにトリアージ レベルを表示 Mostrar nivel de triado en menú de interacción - Показывать группу триажа в меню взаимодействий + Показать уровень триажа в меню взаимодействия Pokaż poziom Triażu w menu interakcji Zeige Triage-Einstufung im Interaktionsmenü 在交互式菜单中显示分诊级别 @@ -292,6 +292,7 @@ Sbircia Info Mediche Medizinische Info anzeigen 医療情報一時表示 + Просмотр медицинской информации Medical Peek Duration @@ -301,6 +302,7 @@ Durata di sbirciamento di info mediche Dauer zum Anzeigen der medizinischen Info 医療情報一時表示の表示時間 + Продолжительность медицинского осмотра How long the medical info peek remains open after releasing the key. @@ -310,6 +312,7 @@ Wie lange die medizinische Info-Anzeige nach dem Loslassen der Taste geöffnet bleibt. Durata di visualizzazione delle Info Mediche dopo aver rilasciato il tasto. 医療情報一時表示キーを放してからどれだけ長く情報表示するか。 + Как долго окно просмотра медицинской информации остается открытым после отпускания клавиши. Load Patient @@ -562,6 +565,7 @@ Wechseln zu selbst Passa a te stesso 自分に切り替え + Переключиться на себя Switch to target @@ -571,6 +575,7 @@ Wechseln zu Ziel Passa al paziente 相手に切り替え + Переключиться на цель Head @@ -996,6 +1001,7 @@ Keine Blutung Nessuna emorragia 出血はしていない + Кровотечения нет Slow bleeding @@ -1005,6 +1011,7 @@ Langsame Blutung Debole emorragia 出血は穏やか + Медленное кровотечение Moderate bleeding @@ -1014,6 +1021,7 @@ Mäßige Blutung Emorraggia moderata 出血はそこそこ速い + Умеренное кровотечение Severe bleeding @@ -1023,6 +1031,7 @@ Schwere Blutung Forte emorragia 出血は激しい + Сильное кровотечение Massive bleeding @@ -1032,6 +1041,7 @@ Massive Blutung Gravissima emorragia 出血は酷く多い + Огромное кровотечение in Pain @@ -1105,6 +1115,7 @@ Kein Blutverlust Nessuna perdita di sangue 失血なし + Потери крови нет @@ -1346,6 +1357,30 @@ Mostrar la pérdida de sangre cualitativa en la lista de heridas. Afficher la quantité de sang perdue + + Show Bleeding State + Mostrar estado de sangrado + Blutungsstatus anzeigen + Mostra stato di sanguinamento + Mostrar estado de sangramento + 出血状態の表示 + + + Display if the patient is bleeding, optionally with rate + Mostrar si el paciente está sangrando, opcionalmente con tasa + Zeigt an, dass der Patient blutet, optional mit Rate + Mostra se il paziente sta sanguinando, opzionalmente con rateo + Mostrar se o paciente está sangrando, opcionalmente com taxa + 患者が出血しているかどうかを表示します。オプションで出血速度も表示します + + + Show Bleeding Rate + Mostrar tasa de sangrado + Blutungsrate anzeigen + Mostra rateo di sanguinamento + Mostrar taxa de sangramento + 出血速度の表示 + Peek Medical Info on Hit Podgląd Informacji Medycznych po Zranieniu @@ -1355,6 +1390,7 @@ Mostra info mediche se colpito Zeige medizinische Info beim Treffer an 被弾時の医療情報一時表示 + Показать медицинскую информацию о попадании Temporarily show medical info when injured. @@ -1365,6 +1401,7 @@ Mostra temporaneamente le info mediche quando si viene feriti. Bei Verletzungen vorübergehend medizinische Info anzeigen. 被弾時に医療情報を一時的に表示します。 + Временно показывать медицинскую информацию при травме. Medical Peek Duration on Hit @@ -1375,6 +1412,7 @@ Durata di info mediche quando colpito Dauer der Anzeige bei einem Treffer. 被弾時の医療情報一時表示の表示時間 + Продолжительность медицинского осмотра при попадании How long the medical info peek remains open after being injured. @@ -1385,6 +1423,7 @@ Quanto tempo verranno visualizzate le info mediche quando si viene feriti. Wie lange die medizinische Info nach einer Verletzung angezeigt wird. 被弾時の医療情報の一時表示をどれだけ長く表示するか。 + Как долго окно просмотра медицинской информации остается открытым после получения травмы. Show Trauma Sustained @@ -1396,6 +1435,7 @@ 외상 지속 표시 显示遭受的创伤 Afficher les traumatismes subis + Показать полученную травму Show trauma sustained in the injury list. @@ -1407,6 +1447,7 @@ 부상 목록에 발생한 외상을 표시합니다. 在伤情表上显示创伤 Afficher les traumatismes subis dans la liste des blessures. + Показать полученную травму в списке травм. Body Part Outline Color @@ -1417,6 +1458,7 @@ Colore del contorno di parti del corpo Umrissfarbe des Körperteils 身体部位の輪郭表示の色 + Цвет контура части тела Color of outline around selected body part. @@ -1427,6 +1469,7 @@ Colore del contorno della parte del corpo selezionata. Farbe des Umrisses um das ausgewählten Körperteil. 選択した身体部位の輪郭表示の色。 + Цвет контура вокруг выбранной части тела. Minor Trauma @@ -1438,6 +1481,7 @@ 약한 외상 轻微创伤 Traumatisme mineur + Незначительная травма Major Trauma @@ -1449,6 +1493,7 @@ 중간 외상 中度创伤 Traumatisme majeur + Серьезная травма Severe Trauma @@ -1460,6 +1505,7 @@ 강한 외상 重度创伤 Traumatisme grave + Тяжелая травма Chronic Trauma @@ -1471,6 +1517,7 @@ 심각한 외상 慢性创伤 Traumatisme chronique + Хроническая травма L @@ -1481,6 +1528,7 @@ Sx L + Лево R @@ -1491,6 +1539,7 @@ Dx R + Право in your inventory @@ -1501,6 +1550,7 @@ Nel proprio inventario im Inventar 個あなたが保有 + в вашем инвентаре in patient's inventory @@ -1511,6 +1561,7 @@ Nell'inventario del paziente im Inventar des Patienten 個患者が保有 + в инвентаре пациента in vehicle's inventory @@ -1521,6 +1572,7 @@ im Inventar des Fahrzeuges Nell'inventario del veicolo 個車両内に保有 + в инвентаре транспорта No effect until tourniquet removed @@ -1530,6 +1582,7 @@ Keine Wirkung, bis das Tourniquet entfernt wurde Nessun effetto fino alla rimozione del laccio emostatico 止血帯を外すまで効果を発揮しません + Никакого эффекта до тех пор, пока жгут не будет снят Show Tourniquet Warning @@ -1539,6 +1592,7 @@ Tourniquet-Warnung anzeigen Mostra avviso di laccio emostatico 止血帯の警告を表示 + Показать предупреждение о наложении жгута Show a warning tooltip when a tourniquet will interfere with a medical action. @@ -1548,6 +1602,7 @@ Zeigt einen Hinweis an, wenn ein Tourniquet eine medizinische Maßnahme beeinträchtigt. Mostra un avviso se un laccio emostatico impedisce un trattamento medico. 止血帯が医療行為を妨げる場合には、警告ツールチップを表示します。 + Показать всплывающую подсказку с предупреждением, когда жгут помешает медицинскому вмешательству. diff --git a/addons/medical_status/functions/fnc_getBloodLoss.sqf b/addons/medical_status/functions/fnc_getBloodLoss.sqf index 8ff0fbff3b..d1adbb9864 100644 --- a/addons/medical_status/functions/fnc_getBloodLoss.sqf +++ b/addons/medical_status/functions/fnc_getBloodLoss.sqf @@ -23,4 +23,4 @@ if (_woundBleeding == 0) exitWith {0}; private _cardiacOutput = [_unit] call FUNC(getCardiacOutput); // even if heart stops blood will still flow slowly (gravity) -(_woundBleeding * (_cardiacOutput max 0.05) * EGVAR(medical,bleedingCoefficient)) +(_woundBleeding * (_cardiacOutput max CARIDAC_OUTPUT_MIN) * EGVAR(medical,bleedingCoefficient)) diff --git a/addons/medical_status/functions/fnc_initUnit.sqf b/addons/medical_status/functions/fnc_initUnit.sqf index 786f2be950..278163d90b 100644 --- a/addons/medical_status/functions/fnc_initUnit.sqf +++ b/addons/medical_status/functions/fnc_initUnit.sqf @@ -32,13 +32,15 @@ if (damage _unit > 0) then { if (_isRespawn) then { TRACE_1("reseting all vars on respawn",_isRespawn); // note: state is handled by ace_medical_statemachine_fnc_resetStateDefault - // - Blood and heart ---------------------------------------------------------- + // - Vitals ------------------------------------------------------------------ _unit setVariable [VAR_BLOOD_VOL, DEFAULT_BLOOD_VOLUME, true]; _unit setVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE, true]; _unit setVariable [VAR_BLOOD_PRESS, [80, 120], true]; _unit setVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES, true]; _unit setVariable [VAR_CRDC_ARRST, false, true]; _unit setVariable [VAR_HEMORRHAGE, 0, true]; + _unit setVariable [VAR_SPO2, DEFAULT_SPO2, true]; + _unit setVariable [VAR_OXYGEN_DEMAND, 0, true]; // - Pain --------------------------------------------------------------------- _unit setVariable [VAR_PAIN, 0, true]; diff --git a/addons/medical_status/functions/fnc_setUnconsciousState.sqf b/addons/medical_status/functions/fnc_setUnconsciousState.sqf index e3d34f3b5a..5981343c18 100644 --- a/addons/medical_status/functions/fnc_setUnconsciousState.sqf +++ b/addons/medical_status/functions/fnc_setUnconsciousState.sqf @@ -57,9 +57,19 @@ if (_active) then { // Do "Unlock controls" user action, co-pilot will then have to do the "Take Controls" actions _unit action ["UnlockVehicleControl", vehicle _unit]; }; + + // Disable AI talking (yes, this needs to be explicit) + if (!isPlayer _unit && {_unit checkAIFeature "RADIOPROTOCOL"}) then { + _unit disableAI "RADIOPROTOCOL"; + _unit setVariable [QGVAR(reenableRadioProtocol), true, true]; + }; } else { // Unit has woken up, no longer need to track this _unit setVariable [QEGVAR(medical,lastWakeUpCheck), nil]; + + if (_unit getVariable [QGVAR(reenableRadioProtocol), false]) then { + _unit enableAI "RADIOPROTOCOL"; + }; }; // This event doesn't correspond to unconscious in statemachine diff --git a/addons/medical_status/stringtable.xml b/addons/medical_status/stringtable.xml index f3f3d605d5..f6f51b5533 100644 --- a/addons/medical_status/stringtable.xml +++ b/addons/medical_status/stringtable.xml @@ -105,7 +105,7 @@ Controls how quickly fluid flows out of IV Bags. The IV Bag volume change is calculated as:\ntime interval (s) * iv change per second (4.1667 mL/s) * flow rate (this coefficient). Wie schnell der Effekt der Transfusion eintritt IV 輸液パックから輸液が流出する速度を制御します。 IV 輸液バッグの容量変化は次のように計算されます:\n時間間隔(秒) x 点滴速度毎秒(4.1667 mL/秒) x 流量(この係数) - Определяет, насколько быстро подействуют эффекты внутривенного переливания + Определяет, насколько быстро подействуют эффекты внутривенного переливания как:\nвременной интервал (s) * изменение внутривенного вливания в секунду (4,1667 мл/с) * скорость потока (этот коэффициент). Définit la vitesse à laquelle le liquide s'écoule des poches de perfusion.\nLa variation du volume de poche IV est calculée selon la formule suivante :\n intervalle de temps (s) * variation IV par seconde (4,1667 ml/s) * débit (ce coefficient). Controla o quão rápido fluidos são extraídos de bolsas de IV. A mudança no volume da bolsa d IV é calculado assim:\nIntervalo de tempo (s) * mudança de iv por segundo (4.1667 mL/s) * Velocidade de transferência (esse valor) 控制從點滴輸入人體的液體流量多快。點滴的體積更改是以\n時間間隔(單位秒)乘上點滴每秒速度(4.1667毫升/秒)乘上流量(該係數)。 @@ -125,6 +125,7 @@ 무기 떨어뜨릴 확률 Risque de perte d'arme 武器を落とす確率 + Шанс выпадения оружия Chance for a player to drop their weapon when going unconscious.\nHas no effect on AI. @@ -134,6 +135,7 @@ 플레이어가 기절할 때 무기를 떨어뜨릴 확률입니다.\nAI는 영향을 받지 않습니다. Pourcentage de chances pour un joueur de lâcher son arme lorsqu'il perd connaissance.\nAucun effet sur les IA. プレーヤーが意識を失ったときに武器を落とす可能性。\nAI には影響しません。 + Шанс для игрока выронить свое оружие, когда он теряет сознание.\nНе влияет на ИИ diff --git a/addons/medical_treatment/ACE_Medical_Treatment.hpp b/addons/medical_treatment/ACE_Medical_Treatment.hpp index d1ea741cb3..267a45dd44 100644 --- a/addons/medical_treatment/ACE_Medical_Treatment.hpp +++ b/addons/medical_treatment/ACE_Medical_Treatment.hpp @@ -565,8 +565,11 @@ class ADDON { timeInSystem = 120; // How long until the maximum effect is reached timeTillMaxEffect = 30; - // How many of this type of medication can be in the system before the patient overdoses? + // How many of this type of medication can be in the system before the patient can possibly overdose? maxDose = 4; + // The number of doses over maxDose where there is a chance to overdose. + // Example with maxDose = 4 and maxDoseDeviation = 2: Dose 4: Safe | Dose 5 and 6: Possible overdose | Dose 7: Guaranteed overdose + maxDoseDeviation = 2; // Function to execute upon overdose. Arguments passed to call back are 0: unit , 1: medicationClassName onOverDose = ""; // The viscosity of a fluid is a measure of its resistance to gradual deformation by shear stress or tensile stress. For liquids, it corresponds to the informal concept of "thickness". This value will increase/decrease the viscoty of the blood with the percentage given. Where 100 = max. Using the minus will decrease viscosity @@ -591,7 +594,7 @@ class ADDON { hrIncreaseHigh[] = {10, 40}; timeInSystem = 120; timeTillMaxEffect = 10; - maxDose = 10; + maxDose = 9; incompatibleMedication[] = {}; }; class Adenosine { @@ -601,7 +604,7 @@ class ADDON { hrIncreaseHigh[] = {-15, -35}; timeInSystem = 120; timeTillMaxEffect = 15; - maxDose = 6; + maxDose = 5; incompatibleMedication[] = {}; }; class PainKillers { @@ -611,7 +614,7 @@ class ADDON { hrIncreaseHigh[] = {-5, -17}; timeInSystem = 420; timeTillMaxEffect = 60; - maxDose = 6; + maxDose = 5; incompatibleMedication[] = {}; viscosityChange = 5; }; diff --git a/addons/medical_treatment/CfgMagazines.hpp b/addons/medical_treatment/CfgMagazines.hpp new file mode 100644 index 0000000000..c4daafab76 --- /dev/null +++ b/addons/medical_treatment/CfgMagazines.hpp @@ -0,0 +1,16 @@ +class CfgMagazines { + class CA_Magazine; + class ACE_painkillers: CA_Magazine { + scope = 2; + author = ECSTRING(common,ACETeam); + displayName = CSTRING(painkillers_Display); + model = "\A3\Structures_F_EPA\Items\Medical\PainKillers_F.p3d"; + picture = QPATHTOF(ui\painkillers_ca.paa); + descriptionShort = CSTRING(painkillers_Desc_Short); + descriptionUse = CSTRING(painkillers_Desc_Use); + ACE_isMedicalItem = 1; + ACE_asItem = 1; + count = 10; + mass = 1; + }; +}; diff --git a/addons/medical_treatment/CfgVehicles.hpp b/addons/medical_treatment/CfgVehicles.hpp index bcecdb155e..4f922eb199 100644 --- a/addons/medical_treatment/CfgVehicles.hpp +++ b/addons/medical_treatment/CfgVehicles.hpp @@ -290,8 +290,8 @@ class CfgVehicles { displayName = CSTRING(painkillers_Display); author = "Alganthe"; vehicleClass = "Items"; - class TransportItems { - MACRO_ADDITEM(ACE_painkillers,1); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_painkillers,1); }; }; @@ -313,9 +313,11 @@ class CfgVehicles { model = QPATHTOF(data\ace_medcrate.p3d); editorPreview = QPATHTOF(data\ACE_medicalSupplyCrate.jpg); author = ECSTRING(common,ACETeam); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_painkillers,25); + }; class TransportItems { MACRO_ADDITEM(ACE_fieldDressing,50); - MACRO_ADDITEM(ACE_painkillers,25); MACRO_ADDITEM(ACE_morphine,25); MACRO_ADDITEM(ACE_epinephrine,25); MACRO_ADDITEM(ACE_bloodIV,15); @@ -357,13 +359,15 @@ class CfgVehicles { }; class ACE_medicalSupplyCrate_advanced: ACE_medicalSupplyCrate { displayName = CSTRING(medicalSupplyCrate_advanced); + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_painkillers,15); + }; class TransportItems { MACRO_ADDITEM(ACE_fieldDressing,25); MACRO_ADDITEM(ACE_packingBandage,25); MACRO_ADDITEM(ACE_elasticBandage,25); MACRO_ADDITEM(ACE_tourniquet,15); MACRO_ADDITEM(ACE_splint,15); - MACRO_ADDITEM(ACE_painkillers,15); MACRO_ADDITEM(ACE_morphine,15); MACRO_ADDITEM(ACE_adenosine,15); MACRO_ADDITEM(ACE_epinephrine,15); diff --git a/addons/medical_treatment/CfgWeapons.hpp b/addons/medical_treatment/CfgWeapons.hpp index 31b98bd843..7b31e10bee 100644 --- a/addons/medical_treatment/CfgWeapons.hpp +++ b/addons/medical_treatment/CfgWeapons.hpp @@ -310,17 +310,4 @@ class CfgWeapons { hiddenSelectionsTextures[] = {QPATHTOF(data\bodybagItem_white_co.paa)}; GVAR(bodyBagObject) = "ACE_bodyBagObject_white"; }; - class ACE_painkillers: ACE_ItemCore { - scope = 2; - author = "Alganthe"; - displayName = CSTRING(painkillers_Display); - model = "\A3\Structures_F_EPA\Items\Medical\PainKillers_F.p3d"; - picture = QPATHTOF(ui\painkillers_ca.paa); - descriptionShort = CSTRING(painkillers_Desc_Short); - descriptionUse = CSTRING(painkillers_Desc_Use); - ACE_isMedicalItem = 1; - class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; - }; - }; }; diff --git a/addons/medical_treatment/config.cpp b/addons/medical_treatment/config.cpp index 75166a0f0c..3782645019 100644 --- a/addons/medical_treatment/config.cpp +++ b/addons/medical_treatment/config.cpp @@ -30,5 +30,6 @@ class CfgPatches { #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" #include "Cfg3DEN.hpp" +#include "CfgMagazines.hpp" #endif diff --git a/addons/medical_treatment/functions/fnc_bandage.sqf b/addons/medical_treatment/functions/fnc_bandage.sqf index a4fb2c7698..2152e81a3b 100644 --- a/addons/medical_treatment/functions/fnc_bandage.sqf +++ b/addons/medical_treatment/functions/fnc_bandage.sqf @@ -8,6 +8,9 @@ * 1: Patient * 2: Body Part * 3: Treatment + * 4: Item User + * 5: Used Item + * 6: Bandage effectiveness coefficient (default: 1) * * Return Value: * None @@ -18,8 +21,11 @@ * Public: No */ -params ["_medic", "_patient", "_bodyPart", "_classname"]; +_this set [6, _this param [6, 1]]; // set default Bandage effectiveness coefficient +[QGVAR(bandaged), _this] call CBA_fnc_localEvent; // Raise event with reference so mods can modify this + +params ["_medic", "_patient", "_bodyPart", "_classname", "", "", "_bandageEffectiveness"]; [_patient, "activity", LSTRING(Activity_bandagedPatient), [[_medic, false, true] call EFUNC(common,getName)]] call FUNC(addToLog); -[QGVAR(bandageLocal), [_patient, _bodyPart, _classname], _patient] call CBA_fnc_targetEvent; +[QGVAR(bandageLocal), [_patient, _bodyPart, _classname, _bandageEffectiveness], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_bandageLocal.sqf b/addons/medical_treatment/functions/fnc_bandageLocal.sqf index 0f695c4c61..4cecbb2f17 100644 --- a/addons/medical_treatment/functions/fnc_bandageLocal.sqf +++ b/addons/medical_treatment/functions/fnc_bandageLocal.sqf @@ -7,6 +7,7 @@ * 0: Patient * 1: Body Part * 2: Treatment + * 3: Bandage effectiveness coefficient (default: 1) * * Return Value: * None @@ -17,16 +18,16 @@ * Public: No */ -params ["_patient", "_bodyPart", "_bandage"]; -TRACE_3("bandageLocal",_patient,_bodyPart,_bandage); -_bodyPart = toLower _bodyPart; +params ["_patient", "_bodyPart", "_bandage", ["_bandageEffectiveness", 1]]; +TRACE_4("bandageLocal",_patient,_bodyPart,_bandage,_bandageEffectiveness); +_bodyPart = toLowerANSI _bodyPart; private _openWounds = GET_OPEN_WOUNDS(_patient); private _woundsOnPart = _openWounds getOrDefault [_bodyPart, []]; if (_woundsOnPart isEqualTo []) exitWith {}; // Figure out which injuries for this bodypart are the best choice to bandage -private _targetWounds = [_patient, _bandage, _bodyPart, GVAR(bandageEffectiveness)] call FUNC(findMostEffectiveWounds); +private _targetWounds = [_patient, _bandage, _bodyPart, _bandageEffectiveness * GVAR(bandageEffectiveness)] call FUNC(findMostEffectiveWounds); // Everything is patched up on this body part already if (count _targetWounds == 0) exitWith {}; diff --git a/addons/medical_treatment/functions/fnc_canBandage.sqf b/addons/medical_treatment/functions/fnc_canBandage.sqf index 18fb304d11..808f86b958 100644 --- a/addons/medical_treatment/functions/fnc_canBandage.sqf +++ b/addons/medical_treatment/functions/fnc_canBandage.sqf @@ -20,7 +20,7 @@ */ params ["_medic", "_patient", "_bodyPart", "_bandage"]; -_bodyPart = toLower _bodyPart; +_bodyPart = toLowerANSI _bodyPart; // If patient is swimming, don't allow bandage actions. if (_patient call EFUNC(common,isSwimming)) exitWith {false}; diff --git a/addons/medical_treatment/functions/fnc_canSplint.sqf b/addons/medical_treatment/functions/fnc_canSplint.sqf index f2fc6fa034..bc2b235bf8 100644 --- a/addons/medical_treatment/functions/fnc_canSplint.sqf +++ b/addons/medical_treatment/functions/fnc_canSplint.sqf @@ -19,6 +19,6 @@ params ["", "_patient", "_bodyPart"]; -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find toLowerANSI _bodyPart; (GET_FRACTURES(_patient) select _partIndex) == 1 diff --git a/addons/medical_treatment/functions/fnc_canTreat.sqf b/addons/medical_treatment/functions/fnc_canTreat.sqf index 995965dfe5..3b643afa2b 100644 --- a/addons/medical_treatment/functions/fnc_canTreat.sqf +++ b/addons/medical_treatment/functions/fnc_canTreat.sqf @@ -28,7 +28,7 @@ private _config = configFile >> QGVAR(actions) >> _classname; ) && { _patient isKindOf "CAManBase" } && { - private _selections = getArray (_config >> "allowedSelections") apply {toLower _x}; + private _selections = getArray (_config >> "allowedSelections") apply {toLowerANSI _x}; "all" in _selections || {_bodyPart in _selections} } && { GET_FUNCTION(_condition,_config >> "condition"); diff --git a/addons/medical_treatment/functions/fnc_createLitter.sqf b/addons/medical_treatment/functions/fnc_createLitter.sqf index 28269bb4ce..df9c2e7f4d 100644 --- a/addons/medical_treatment/functions/fnc_createLitter.sqf +++ b/addons/medical_treatment/functions/fnc_createLitter.sqf @@ -27,7 +27,7 @@ params ["_medic", "_patient", "_bodyPart", "_classname"]; if (vehicle _medic != _medic || {vehicle _patient != _patient}) exitWith {}; // Determine if treated body part is bleeding -private _index = ALL_BODY_PARTS find toLower _bodyPart; +private _index = ALL_BODY_PARTS find toLowerANSI _bodyPart; private _isBleeding = (GET_OPEN_WOUNDS(_patient) get _bodyPart) findIf { _x params ["", "_amountOf", "_bleeding"]; _amountOf * _bleeding > 0 diff --git a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf index e845e04304..dc95c44185 100644 --- a/addons/medical_treatment/functions/fnc_fullHealLocal.sqf +++ b/addons/medical_treatment/functions/fnc_fullHealLocal.sqf @@ -25,6 +25,9 @@ if ((["ace_fire"] call EFUNC(common,isModLoaded)) && {[_patient] call EFUNC(fire _patient setVariable [QEGVAR(fire,intensity), 0, true]; }; +// Allow mods to heal +[QGVAR(fullHealLocalMod), [_patient]] call CBA_fnc_localEvent; + private _state = GET_SM_STATE(_patient); TRACE_1("start",_state); @@ -63,6 +66,8 @@ _patient setVariable [VAR_FRACTURES, DEFAULT_FRACTURE_VALUES, true]; _patient setVariable [VAR_HEART_RATE, DEFAULT_HEART_RATE, true]; _patient setVariable [VAR_BLOOD_PRESS, [80, 120], true]; _patient setVariable [VAR_PERIPH_RES, DEFAULT_PERIPH_RES, true]; +_patient setVariable [VAR_SPO2, DEFAULT_SPO2, true]; +_patient setVariable [VAR_OXYGEN_DEMAND, 0, true]; // IVs _patient setVariable [QEGVAR(medical,ivBags), nil, true]; diff --git a/addons/medical_treatment/functions/fnc_getBandageTime.sqf b/addons/medical_treatment/functions/fnc_getBandageTime.sqf index ffe5c81f63..eb0a3bc5ae 100644 --- a/addons/medical_treatment/functions/fnc_getBandageTime.sqf +++ b/addons/medical_treatment/functions/fnc_getBandageTime.sqf @@ -20,7 +20,7 @@ params ["_medic", "_patient", "_bodyPart", "_bandage"]; -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find toLowerANSI _bodyPart; if (_partIndex < 0) exitWith { ERROR_1("invalid partIndex - %1",_this); 0 }; private _targetWounds = [_patient, _bandage, _bodyPart] call FUNC(findMostEffectiveWounds); diff --git a/addons/medical_treatment/functions/fnc_hasItem.sqf b/addons/medical_treatment/functions/fnc_hasItem.sqf index e84a79f142..e0ef4c8a4f 100644 --- a/addons/medical_treatment/functions/fnc_hasItem.sqf +++ b/addons/medical_treatment/functions/fnc_hasItem.sqf @@ -25,10 +25,11 @@ params ["_medic", "_patient", "_items"]; private _fnc_checkItems = { params ["_unit"]; - private _unitItems = _unit call EFUNC(common,uniqueItems); + private _unitItems = [_unit, 1] call EFUNC(common,uniqueItems); private _unitVehicle = objectParent _unit; if (!isNull _unitVehicle) then { _unitItems append (itemCargo _unitVehicle); + _unitItems append (magazineCargo _unitVehicle); }; _items findIf {_x in _unitItems} != -1 }; diff --git a/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf b/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf index 9ef1261238..56477eafee 100644 --- a/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf +++ b/addons/medical_treatment/functions/fnc_hasTourniquetAppliedTo.sqf @@ -18,6 +18,6 @@ params ["_unit", "_bodyPart"]; -private _index = ALL_BODY_PARTS find toLower _bodyPart; +private _index = ALL_BODY_PARTS find toLowerANSI _bodyPart; _index >= 0 && {HAS_TOURNIQUET_APPLIED_ON(_unit,_index)} diff --git a/addons/medical_treatment/functions/fnc_ivBagLocal.sqf b/addons/medical_treatment/functions/fnc_ivBagLocal.sqf index 64eabf844a..80f06fc11e 100644 --- a/addons/medical_treatment/functions/fnc_ivBagLocal.sqf +++ b/addons/medical_treatment/functions/fnc_ivBagLocal.sqf @@ -23,7 +23,7 @@ params ["_patient", "_bodyPart", "_classname"]; private _bloodVolume = GET_BLOOD_VOLUME(_patient); if (_bloodVolume >= DEFAULT_BLOOD_VOLUME) exitWith {}; -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find tolowerANSI _bodyPart; // Get attributes for the used IV private _defaultConfig = configFile >> QUOTE(ADDON) >> "IV"; diff --git a/addons/medical_treatment/functions/fnc_medication.sqf b/addons/medical_treatment/functions/fnc_medication.sqf index b69a63e994..dfd08d4de2 100644 --- a/addons/medical_treatment/functions/fnc_medication.sqf +++ b/addons/medical_treatment/functions/fnc_medication.sqf @@ -23,6 +23,7 @@ params ["_medic", "_patient", "_bodyPart", "_classname", "", "_usedItem"]; [_patient, _usedItem] call FUNC(addToTriageCard); -[_patient, "activity", LSTRING(Activity_usedItem), [[_medic, false, true] call EFUNC(common,getName), getText (configFile >> "CfgWeapons" >> _usedItem >> "displayName")]] call FUNC(addToLog); +private _cfg = ["CfgWeapons", "CfgMagazines"] select (isClass (configFile >> "CfgMagazines" >> _usedItem)); +[_patient, "activity", LSTRING(Activity_usedItem), [[_medic, false, true] call EFUNC(common,getName), getText (configFile >> _cfg >> _usedItem >> "displayName")]] call FUNC(addToLog); [QGVAR(medicationLocal), [_patient, _bodyPart, _classname], _patient] call CBA_fnc_targetEvent; diff --git a/addons/medical_treatment/functions/fnc_medicationLocal.sqf b/addons/medical_treatment/functions/fnc_medicationLocal.sqf index b5499e9bb4..31884dac20 100644 --- a/addons/medical_treatment/functions/fnc_medicationLocal.sqf +++ b/addons/medical_treatment/functions/fnc_medicationLocal.sqf @@ -42,7 +42,7 @@ TRACE_1("Running treatmentMedicationLocal with Advanced configuration for",_pati // Handle tourniquet on body part blocking blood flow at injection site -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find tolowerANSI _bodyPart; if (HAS_TOURNIQUET_APPLIED_ON(_patient,_partIndex)) exitWith { TRACE_1("unit has tourniquets blocking blood flow on injection site",_tourniquets); @@ -59,6 +59,7 @@ private _painReduce = GET_NUMBER(_medicationConfig >> "painReduce",g private _timeInSystem = GET_NUMBER(_medicationConfig >> "timeInSystem",getNumber (_defaultConfig >> "timeInSystem")); private _timeTillMaxEffect = GET_NUMBER(_medicationConfig >> "timeTillMaxEffect",getNumber (_defaultConfig >> "timeTillMaxEffect")); private _maxDose = GET_NUMBER(_medicationConfig >> "maxDose",getNumber (_defaultConfig >> "maxDose")); +private _maxDoseDeviation = GET_NUMBER(_medicationConfig >> "maxDoseDeviation",getNumber (_defaultConfig >> "maxDoseDeviation")); private _viscosityChange = GET_NUMBER(_medicationConfig >> "viscosityChange",getNumber (_defaultConfig >> "viscosityChange")); private _hrIncreaseLow = GET_ARRAY(_medicationConfig >> "hrIncreaseLow",getArray (_defaultConfig >> "hrIncreaseLow")); private _hrIncreaseNormal = GET_ARRAY(_medicationConfig >> "hrIncreaseNormal",getArray (_defaultConfig >> "hrIncreaseNormal")); @@ -75,4 +76,4 @@ TRACE_3("adjustments",_heartRateChange,_painReduce,_viscosityChange); [_patient, _className, _timeTillMaxEffect, _timeInSystem, _heartRateChange, _painReduce, _viscosityChange] call EFUNC(medical_status,addMedicationAdjustment); // Check for medication compatiblity -[_patient, _className, _maxDose, _incompatibleMedication] call FUNC(onMedicationUsage); +[_patient, _className, _maxDose, _maxDoseDeviation, _incompatibleMedication] call FUNC(onMedicationUsage); diff --git a/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf b/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf index 6235358446..cd26d15424 100644 --- a/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf +++ b/addons/medical_treatment/functions/fnc_onMedicationUsage.sqf @@ -6,27 +6,33 @@ * Arguments: * 0: The patient * 1: Medication Treatment classname - * 2: Max dosage (0 to ignore) + * 2: Max dose (0 to ignore) + * 3: Max dose deviation * 3: Incompatable medication > * * Return Value: * None * * Example: - * [player, "morphine", 4, [["x", 1]]] call ace_medical_treatment_fnc_onMedicationUsage + * [player, "morphine", 4, 2, [["x", 1]]] call ace_medical_treatment_fnc_onMedicationUsage * * Public: No */ -params ["_target", "_className", "_maxDosage", "_incompatibleMedication"]; -TRACE_4("onMedicationUsage",_target,_className,_maxDosage,_incompatibleMedication); +params ["_target", "_className", "_maxDose", "_maxDoseDeviation", "_incompatibleMedication"]; +TRACE_5("onMedicationUsage",_target,_className,_maxDose,_maxDoseDeviation,_incompatibleMedication); private _overdosedMedications = []; // Check for overdose from current medication -if (_maxDosage > 0) then { +if (_maxDose > 0) then { private _currentDose = [_target, _className] call EFUNC(medical_status,getMedicationCount); - if (_currentDose >= floor (_maxDosage + round(random(2)))) then { + // Because both {floor random 0} and {floor random 1} return 0 + if (_maxDoseDeviation > 0) then { + _maxDoseDeviation = _maxDoseDeviation + 1; + }; + + if (_currentDose > _maxDose + (floor random _maxDoseDeviation)) then { TRACE_1("exceeded max dose",_currentDose); _overdosedMedications pushBackUnique _className; }; diff --git a/addons/medical_treatment/functions/fnc_splintLocal.sqf b/addons/medical_treatment/functions/fnc_splintLocal.sqf index f415d8296f..ee15a63bf0 100644 --- a/addons/medical_treatment/functions/fnc_splintLocal.sqf +++ b/addons/medical_treatment/functions/fnc_splintLocal.sqf @@ -20,7 +20,7 @@ params ["_medic", "_patient", "_bodyPart"]; TRACE_3("splintLocal",_medic,_patient,_bodyPart); -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find tolowerANSI _bodyPart; private _fractures = GET_FRACTURES(_patient); _fractures set [_partIndex, -1]; diff --git a/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf b/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf index 3fe5f4e55d..9a0480bcb0 100644 --- a/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf +++ b/addons/medical_treatment/functions/fnc_tourniquetLocal.sqf @@ -19,7 +19,7 @@ params ["_patient", "_bodyPart"]; TRACE_2("tourniquetLocal",_patient,_bodyPart); -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find tolowerANSI _bodyPart; private _tourniquets = GET_TOURNIQUETS(_patient); _tourniquets set [_partIndex, CBA_missionTime]; diff --git a/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf b/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf index 5c5cf93dc8..8a6be10bb4 100644 --- a/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf +++ b/addons/medical_treatment/functions/fnc_tourniquetRemove.sqf @@ -22,7 +22,7 @@ params ["_medic", "_patient", "_bodyPart"]; TRACE_3("tourniquetRemove",_medic,_patient,_bodyPart); // Remove tourniquet from body part, exit if no tourniquet applied -private _partIndex = ALL_BODY_PARTS find toLower _bodyPart; +private _partIndex = ALL_BODY_PARTS find tolowerANSI _bodyPart; private _tourniquets = GET_TOURNIQUETS(_patient); if (_tourniquets select _partIndex == 0) exitWith { diff --git a/addons/medical_treatment/functions/fnc_treatmentFailure.sqf b/addons/medical_treatment/functions/fnc_treatmentFailure.sqf index 64d18fa830..42323922a3 100644 --- a/addons/medical_treatment/functions/fnc_treatmentFailure.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentFailure.sqf @@ -23,7 +23,11 @@ _args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_us // Return used item to user (if used) if (!isNull _itemUser) then { - [_itemUser, _usedItem] call EFUNC(common,addToInventory); + if (isClass (configFile >> "CfgMagazines" >> _usedItem)) then { + [_itemUser, _usedItem, 1] call EFUNC(common,adjustMagazineAmmo); + } else { + [_itemUser, _usedItem] call EFUNC(common,addToInventory); + }; }; // Switch medic to end animation immediately diff --git a/addons/medical_treatment/functions/fnc_useItem.sqf b/addons/medical_treatment/functions/fnc_useItem.sqf index 1f1d7c8355..9bba3d1c90 100644 --- a/addons/medical_treatment/functions/fnc_useItem.sqf +++ b/addons/medical_treatment/functions/fnc_useItem.sqf @@ -29,18 +29,31 @@ scopeName "Main"; private _useOrder = [[_patient, _medic], [_medic, _patient], [_medic]] select GVAR(allowSharedEquipment); { - private _unit = _x; + private _unit = _x; private _unitVehicle = objectParent _unit; - private _unitItems = _x call EFUNC(common,uniqueItems); + private _unitItems = [_x, 0] call EFUNC(common,uniqueItems); + private _unitMagazines = [_x, 2] call EFUNC(common,uniqueItems); + private _vehicleItems = itemCargo _unitVehicle; // [] for objNull + private _vehicleMagazines = magazineCargo _unitVehicle; // same { - if (!isNull _unitVehicle && {_x in (itemCargo _unitVehicle)}) then { - _unitVehicle addItemCargoGlobal [_x, -1]; - [_unit, _x] breakOut "Main"; - }; - if (_x in _unitItems) then { - _unit removeItem _x; - [_unit, _x] breakOut "Main"; + switch (true) do { + case (_x in _vehicleItems): { + _unitVehicle addItemCargoGlobal [_x, -1]; + [_unit, _x] breakOut "Main"; + }; + case (_x in _vehicleMagazines): { + [_unitVehicle, _x] call EFUNC(common,adjustMagazineAmmo); + [_unit, _x] breakOut "Main"; + }; + case (_x in _unitItems): { + _unit removeItem _x; + [_unit, _x] breakOut "Main"; + }; + case (_x in _unitMagazines): { + [_unit, _x] call EFUNC(common,adjustMagazineAmmo); + [_unit, _x] breakOut "Main"; + }; }; } forEach _items; } forEach _useOrder; diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index 05bb62a646..c9925768d2 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -70,7 +70,7 @@ Activé & Diagnostic du décès/de l'arrêt cardiaque Włączone i pozwala zdiagnozować Śmierć/Zatrzymanie Akcji Serca 有効 & 死亡/心停止状態を診断可能 - Включено & Может диагностировать смерть/остановку сердца + Включено и может диагностировать смерть/остановку сердца Aktiviert & kann Tod/Herzstillstand diagnostizieren 已启用 & 可以诊断死亡/心搏骤停 활성화 및 사망/심정지 진찰가능 @@ -438,6 +438,7 @@ Zeit zum Graben von Gräbern Tempo di scavo tomba 墓掘りの所要時間 + Время рытья могилы Time, in seconds, required to dig a grave for a body. @@ -447,6 +448,7 @@ Zeit (in Sekunden), die benötigt wird, um ein Grab für einen Leichnam auszuheben. Tempo in secondi richiesto per seppellire un morto. 遺体の墓を掘るのに掛かる時間 (秒) を決定します。 + Время в секундах, необходимое для того, чтобы выкопать могилу для тела. Allow Epinephrine @@ -760,6 +762,7 @@ Co powinno zostać zużyte po zastosowaniu. 봉합키트를 1회성 소모품으로 설정할 지 여부를 결정합니다. Ce qui doit être consommé après l'utilisation. + Решите, следует ли использовать набор для наложения швов в качестве одноразового расходного материала. Self Stitching @@ -772,7 +775,7 @@ Samo-zašívání Zszywanie własnych ran Selbstnähen - Зашивание своей раны + Зашитие своей раны Auto cosido 봉합키트 자가 사용 @@ -878,6 +881,7 @@ Permitir cavar tumbas Autoriser le creusement de tombes 墓掘りを許可 + Разрешить рытье могил Enables digging graves to dispose of corpses. @@ -888,6 +892,7 @@ Habilita cavar tumbas para deshacerse de los cadáveres. Active la possibilité de creuser des tombes pour enterrer les cadavres. 墓を掘って死体を処理できるようになります。 + Позволяет рыть могилы для захоронения трупов. Only if dead @@ -898,6 +903,7 @@ Solo si está muerto Uniquement s'il est mort 死体のみ + Только если мертв Create Grave Markers @@ -908,6 +914,7 @@ 무덤 마커 생성 Créer des pierres tombales 墓標を作成 + Создайте надгробные знаки Enables the creation of grave markers when digging graves. @@ -918,6 +925,7 @@ 무덤을 파낼 때 무덤 마커를 표시할 수 있습니다. Active la création de pierres tombales lors de l'enterrement de cadavres. 墓を掘った際、墓標を作成できるようにします。 + Позволяет создавать надгробные знаки при рытье могил. Allow IV Transfusion @@ -949,7 +957,7 @@ Locations IV Transfusion - IV 輸液の場所制限 + IV輸液の可能な場所 Ubicación para transfusiones IV Lieux perfusions IV Места введения пакетов внутривенного переливания @@ -2435,6 +2443,7 @@ Szew 봉합술 Suture + Нить Surgical Suture for stitching injuries. @@ -2445,6 +2454,7 @@ Szew chirurgiczny do zszywania ran. 상처를 꿰메는 수술용 봉합술. Suture chirurgicale pour suturer les blessures. + Хирургическая нить для зашивания травм. Surgical Suture for stitching injuries. @@ -2455,6 +2465,7 @@ Szew chirurgiczny do zszywania ran. 상처를 꿰메는 수술용 봉합술. Suture chirurgicale pour suturer les blessures. + Хирургическая нить для зашивания травм. Bodybag @@ -3494,6 +3505,7 @@ Nessun dolore Kein Schmerz 痛みはない + Нет боли In mild pain @@ -3558,21 +3570,53 @@ 軍用止血帶 Turnike [CAT] - - Receiving IV [%1ml] - Erhalte IV [%1ml] - Recibiendo IV [%1ml] - Принимается переливание [%1 мл] - Otrzymywanie IV [pozostało %1ml] - Transfusion : [%1 ml] - Přijímání transfúze [%1ml] - Infúzióra kötve [%1ml] - Ricevendo EV [%1ml] - Recebendo IV [%1ml] - IV [%1ml] を投与中 - IV로 [%1ml] 수혈중 - 正在接受静脉注射 [%1毫升] - 接收靜脈注射液中 [%1毫升] + + Receiving Saline IV [%1ml] + Erhalte Saline IV [%1ml] + Recibiendo Salina IV [%1ml] + Принимается солевой раствор IV [%1 мл] + Otrzymywanie soli IV [%1ml] + Transfusion de sérum salé : [%1 ml] + Přijímání soli IV [%1ml] + Saline Infúzióra kötve [%1ml] + Ricevendo Salina EV [%1ml] + Recebendo Salina IV [%1ml] + 生理食塩水 IV [%1ml] を投与中 + 생리식염수 IV로 [%1ml] 수혈중 + 正在接受生理盐水静脉注射 [%1毫升] + 接收生理鹽水靜脈注射液中 [%1毫升] + + + Receiving Blood IV [%1ml] + Erhalte Blut IV [%1ml] + Recibiendo Sangre IV [%1ml] + Принимается кровь IV [%1 мл] + Otrzymywanie krwi IV [%1ml] + Transfusion de sang : [%1 ml] + Přijímání krve IV [%1ml] + Vér Infúzióra kötve [%1ml] + Ricevendo Sangue EV [%1ml] + Recebendo Sangue IV [%1ml] + 血液 IV [%1ml] を投与中 + 혈액 IV로 [%1ml] 수혈중 + 正在接受血液静脉注射 [%1毫升] + 接收血液靜脈注射液中 [%1毫升] + + + Receiving Plasma IV [%1ml] + Erhalte Plasma IV [%1ml] + Recibiendo Plasma IV [%1ml] + Принимается плазма IV [%1 мл] + Otrzymywanie plazmy IV [%1ml] + Transfusion de plasma : [%1 ml] + Přijímání plazmy IV [%1ml] + Plazma Infúzióra kötve [%1ml] + Ricevendo Plasma EV [%1ml] + Recebendo Plasma IV [%1ml] + プラズマ IV [%1ml] を投与中 + 혈장 IV로 [%1ml] 수혈중 + 正在接受血浆静脉注射 [%1毫升] + 接收血漿靜脈注射液中 [%1毫升] No IV @@ -3582,6 +3626,7 @@ Nessuna Flebo EV Kein IV IV なし + Нет капельницы Blood Pressure @@ -4558,6 +4603,7 @@ Vücudu siyah ceset torbasına yerleştir 遺体袋 (黒) に入れる 시체를 검은 시체가방에 놓기 + Положить тело в черный мешок для тела Place body in blue bodybag @@ -4570,6 +4616,7 @@ Vücudu mavi ceset torbasına yerleştir 遺体袋 (青) に入れる 시체를 파란 시체가방에 놓기 + Положить тело в синий мешок для тела Place body in white bodybag @@ -4582,6 +4629,7 @@ Vücudu beyaz ceset torbasına yerleştir 遺体袋 (白) に入れる 시체를 흰 시체가방에 놓기 + Положить тело в белый мешок для тела Placing body in bodybag... @@ -4608,6 +4656,7 @@ Grabe ein Grab für den Leichnam Scava tomba per cadavere 墓を掘る + Выкопать могилу для тела Digging grave for body... @@ -4617,6 +4666,7 @@ Grab für Leichnam ausheben ... Scavando tomba per cadavere... 墓を掘っています + Рытьё могилы для тела... %1 has bandaged patient @@ -4787,7 +4837,7 @@ Heal fully bandaged hitpoints Lecz w pełni zabandażowane hitpointy Curar miembros totalmente vendados - Исцелять полностью перебинтованные части тела + Исцелить полностью перебинтованные части тела Curar membros totalmente enfaixados Heal fully bandaged hitpoints Cura hitpoints completamente bendati @@ -4868,6 +4918,7 @@ Überprüfe Name auf dem Grabstein Controlla nome sulla lapide 墓石の名前を確認 + Проверьте имя на надгробии Bandage Rollover @@ -4877,6 +4928,7 @@ Pansement de plaies multiples Srotolamento Bendaggi 包帯の繰り越し + Перевязка множественных ран If enabled, bandages can close different types of wounds on the same body part.\nBandaging multiple injuries will scale bandaging time accordingly. @@ -4886,6 +4938,7 @@ Si activé, les bandages peuvent fermer plusieurs types de blessures sur la même partie du corps.\nPanser de multiples blessures modifiera la durée d'application en conséquence. Se attivo, un singolo bendaggio potrà chiudere più ferite sulla stessa parte del corpo.\nBendare più ferite di conseguenza richiederà più tempo. 有効にすると、体の同じ部分にある別の種類の傷を一つの包帯で閉じることができます。\n複数の傷に包帯を巻くと、それに応じて包帯時間が変動します。 + Если эта функция включена, бинты могут закрывать различные типы ран на одной и той же части тела.\nПри перевязке нескольких повреждений время перевязки будет увеличено соответствующим образом. Bandage Effectiveness Coefficient @@ -4895,6 +4948,7 @@ Coefficient d'efficacité des bandages Coefficiente di efficacia bendaggi 包帯有効性係数 + Коэффициент эффективности повязки Determines how effective bandages are at closing wounds. @@ -4904,6 +4958,7 @@ Défini l'efficacité des bandages à refermer des plaies. Determina quanto i bendaggi sono efficaci nel chiudere le ferite. 包帯が傷をふさぐのにどれだけ効果的かを決定します。 + Определяет, насколько эффективны бинты при закрытии ран. Medical Items @@ -4925,6 +4980,7 @@ Zeit-Koeffizient für Zeus Behandlungen Zeus治療時間係数 제우스 치료 시간 계수 + Коэффициент времени обработки Zeus Multiply all treatment times with this coefficient when in Zeus. @@ -4932,6 +4988,7 @@ Dauer von Behandlungen als Zeus wird mit diesem Koeffizienten multipliziert. Zeus操作中は、すべての治療時間にこの係数を掛けます。 제우스일 때 모든 치료 시간에 이 계수를 곱합니다. + Умножьте все время лечения на этот коэффициент, когда вы находитесь в Zeus. Painkillers @@ -4951,15 +5008,27 @@ Administer Painkillers + Somministra Antidolorifici + Испол-ть обезболивающие + 鎮痛剤を投与 Administering Painkillers... + Somministrando Antidolorifici... + Использование обезболивающего... + 鎮痛剤を投与しています・・・ Over-the-counter analgesic used to combat light to moderate pain experiences. + Antidolorifici senza prescrizione, usati per alleviare dolore leggero o moderato. + Безрецептурный анальгетик, используемый для борьбы с легкими и умеренными болевыми ощущениями. + 軽度から中程度の痛みに対処するために使用される市販の鎮痛薬。 Over-the-counter analgesic used to combat light to moderate pain experiences. + Antidolorifici senza prescrizione, usati per alleviare dolore leggero o moderato. + Безрецептурный анальгетик, используемый для борьбы с легкими и умеренными болевыми ощущениями. + 軽度から中程度の痛みに対処するために使用される市販の鎮痛薬。 diff --git a/addons/medical_vitals/CfgWeapons.hpp b/addons/medical_vitals/CfgWeapons.hpp new file mode 100644 index 0000000000..5c6e4c9fd8 --- /dev/null +++ b/addons/medical_vitals/CfgWeapons.hpp @@ -0,0 +1,10 @@ +class CfgWeapons { + class H_HelmetB; + class H_PilotHelmetFighter_B: H_HelmetB { + GVAR(oxygenSupply) = QUOTE(vehicle _this isKindOf 'Plane' || vehicle _this isKindOf 'Helicopter'); + }; + class Vest_Camo_Base; + class V_RebreatherB: Vest_Camo_Base { + GVAR(oxygenSupply) = QUOTE(eyePos _this select 2 < 0); // will only work for sea-level water + }; +}; diff --git a/addons/medical_vitals/XEH_PREP.hpp b/addons/medical_vitals/XEH_PREP.hpp index 8f8c427751..02f1cc5f89 100644 --- a/addons/medical_vitals/XEH_PREP.hpp +++ b/addons/medical_vitals/XEH_PREP.hpp @@ -1,4 +1,6 @@ PREP(handleUnitVitals); +PREP(scanConfig); PREP(updateHeartRate); +PREP(updateOxygen); PREP(updatePainSuppress); PREP(updatePeripheralResistance); diff --git a/addons/medical_vitals/XEH_preInit.sqf b/addons/medical_vitals/XEH_preInit.sqf index b47cf6628d..8cc49805e9 100644 --- a/addons/medical_vitals/XEH_preInit.sqf +++ b/addons/medical_vitals/XEH_preInit.sqf @@ -6,4 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; +#include "initSettings.inc.sqf" + +GVAR(oxygenSupplyConditionCache) = uiNamespace getVariable QGVAR(oxygenSupplyConditionCache); + ADDON = true; diff --git a/addons/medical_vitals/XEH_preStart.sqf b/addons/medical_vitals/XEH_preStart.sqf index 022888575e..78dd8ad0e3 100644 --- a/addons/medical_vitals/XEH_preStart.sqf +++ b/addons/medical_vitals/XEH_preStart.sqf @@ -1,3 +1,9 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +GVAR(oxygenSupplyConditionCache) = createHashMap; + +call FUNC(scanConfig); + +GVAR(oxygenSupplyConditionCache) = compileFinal GVAR(oxygenSupplyConditionCache); diff --git a/addons/medical_vitals/config.cpp b/addons/medical_vitals/config.cpp index d105aa3144..290c25bc9b 100644 --- a/addons/medical_vitals/config.cpp +++ b/addons/medical_vitals/config.cpp @@ -23,5 +23,6 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" +#include "CfgWeapons.hpp" #endif diff --git a/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf b/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf index 683cfd34b7..c284b00701 100644 --- a/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf +++ b/addons/medical_vitals/functions/fnc_handleUnitVitals.sqf @@ -31,6 +31,9 @@ if (_syncValues) then { _unit setVariable [QGVAR(lastMomentValuesSynced), CBA_missionTime]; }; +// Update SPO2 intake and usage since last update +[_unit, _deltaT, _syncValues] call FUNC(updateOxygen); + private _bloodVolume = GET_BLOOD_VOLUME(_unit) + ([_unit, _deltaT, _syncValues] call EFUNC(medical_status,getBloodVolumeChange)); _bloodVolume = 0 max _bloodVolume min DEFAULT_BLOOD_VOLUME; diff --git a/addons/medical_vitals/functions/fnc_scanConfig.sqf b/addons/medical_vitals/functions/fnc_scanConfig.sqf new file mode 100644 index 0000000000..377b235315 --- /dev/null +++ b/addons/medical_vitals/functions/fnc_scanConfig.sqf @@ -0,0 +1,23 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Cache a hashmap of all oxygen-providing items for SpO2 simulation + * + * Arguments: + * None + * + * Return Value: + * None + * + * Public: No +*/ + +private _filter = toString {getText (_x >> QGVAR(oxygenSupply)) != ""}; + +{ + private _cfgRoot = configFile >> _x; + { + private _condition = compile getText (_x >> QGVAR(oxygenSupply)); + GVAR(oxygenSupplyConditionCache) set [configName _x, _condition]; + } forEach (_filter configClasses _cfgRoot); +} forEach ["CfgWeapons", "CfgGoggles"]; diff --git a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf index 9ffc52d663..187a8ffe58 100644 --- a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf +++ b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf @@ -37,6 +37,7 @@ if IN_CRDC_ARRST(_unit) then { if (_bloodVolume > BLOOD_VOLUME_CLASS_4_HEMORRHAGE) then { GET_BLOOD_PRESSURE(_unit) params ["_bloodPressureL", "_bloodPressureH"]; private _meanBP = (2/3) * _bloodPressureH + (1/3) * _bloodPressureL; + private _spo2 = GET_SPO2(_unit); private _painLevel = GET_PAIN_PERCEIVED(_unit); private _targetBP = 107; @@ -51,8 +52,11 @@ if IN_CRDC_ARRST(_unit) then { if (_painLevel > 0.2) then { _targetHR = _targetHR max (80 + 50 * _painLevel); }; + // Increase HR to compensate for low blood oxygen + // Increase HR to compensate for higher oxygen demand (e.g. running, recovering from sprint) + private _oxygenDemand = _unit getVariable [VAR_OXYGEN_DEMAND, 0]; + _targetHR = _targetHR + ((97 - _spo2) * 2) + (_oxygenDemand * -1000); _targetHR = (_targetHR + _hrTargetAdjustment) max 0; - _hrChange = round(_targetHR - _heartRate) / 2; } else { _hrChange = -round(_heartRate / 10); diff --git a/addons/medical_vitals/functions/fnc_updateOxygen.sqf b/addons/medical_vitals/functions/fnc_updateOxygen.sqf new file mode 100644 index 0000000000..f2c0f68f71 --- /dev/null +++ b/addons/medical_vitals/functions/fnc_updateOxygen.sqf @@ -0,0 +1,75 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Update the oxygen levels + * + * Arguments: + * 0: The Unit + * 1: Time since last update + * 2: Sync value? + * + * ReturnValue: + * Current SPO2 + * + * Example: + * [player, 1, false] call ace_medical_vitals_fnc_updateOxygen + * + * Public: No + */ + +params ["_unit", "_deltaT", "_syncValue"]; + +if (!GVAR(simulateSpO2)) exitWith {}; // changing back to default is handled in initSettings.inc.sqf + +#define IDEAL_PPO2 0.255 + +private _current = GET_SPO2(_unit); +private _heartRate = GET_HEART_RATE(_unit); + +private _altitude = EGVAR(common,mapAltitude) + ((getPosASL _unit) select 2); +private _po2 = if (missionNamespace getVariable [QEGVAR(weather,enabled), false]) then { + private _temperature = _altitude call EFUNC(weather,calculateTemperatureAtHeight); + private _pressure = _altitude call EFUNC(weather,calculateBarometricPressure); + [_temperature, _pressure, EGVAR(weather,currentHumidity)] call EFUNC(weather,calculateOxygenDensity) +} else { + // Rough approximation of the partial pressure of oxygen in the air + 0.25725 * (_altitude / 1000 + 1) +}; + +private _oxygenSaturation = (IDEAL_PPO2 min _po2) / IDEAL_PPO2; + +// Check gear for oxygen supply +[goggles _unit, headgear _unit, vest _unit] findIf { + _x in GVAR(oxygenSupplyConditionCache) && + {ACE_player call (GVAR(oxygenSupplyConditionCache) get _x)} && + { // Will only run this if other conditions are met due to lazy eval + _oxygenSaturation = 1; + _po2 = IDEAL_PPO2; + true + } +}; + +// Base oxygen consumption rate +private _negativeChange = BASE_OXYGEN_USE; + +// Fatigue & exercise will demand more oxygen +// Assuming a trained male in midst of peak exercise will have a peak heart rate of ~180 BPM +// Ref: https://academic.oup.com/bjaed/article-pdf/4/6/185/894114/mkh050.pdf table 2, though we don't take stroke volume change into account +if (_unit == ACE_player && {missionNamespace getVariable [QEGVAR(advanced_fatigue,enabled), false]}) then { + _negativeChange = _negativeChange - ((1 - EGVAR(advanced_fatigue,aeReservePercentage)) * 0.1) - ((1 - EGVAR(advanced_fatigue,anReservePercentage)) * 0.05); +}; + +// Effectiveness of capturing oxygen +// increases slightly as po2 starts lowering +// but falls off quickly as po2 drops further +private _capture = 1 max ((_po2 / IDEAL_PPO2) ^ (-_po2 * 3)); +private _positiveChange = _heartRate * 0.00368 * _oxygenSaturation * _capture; + +private _breathingEffectiveness = 1; + +private _rateOfChange = _negativeChange + (_positiveChange * _breathingEffectiveness); + +private _spo2 = (_current + (_rateOfChange * _deltaT)) max 0 min 100; + +_unit setVariable [VAR_OXYGEN_DEMAND, _negativeChange - BASE_OXYGEN_USE]; +_unit setVariable [VAR_SPO2, _spo2, _syncValue]; diff --git a/addons/medical_vitals/initSettings.inc.sqf b/addons/medical_vitals/initSettings.inc.sqf new file mode 100644 index 0000000000..db762d2c52 --- /dev/null +++ b/addons/medical_vitals/initSettings.inc.sqf @@ -0,0 +1,15 @@ +[ + QGVAR(simulateSpO2), + "CHECKBOX", + [LSTRING(simulateSpO2_DisplayName), LSTRING(simulateSpO2_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory)], + true, + 1, + { + if (_this) exitWith {}; // skip if true + { + _x setVariable [VAR_OXYGEN_DEMAND, 0, true]; + _x setVariable [VAR_SPO2, DEFAULT_SPO2, true]; + } forEach (allUnits select {local _x}) + } // reset oxygen demand on setting change +] call CBA_fnc_addSetting; diff --git a/addons/medical_vitals/script_component.hpp b/addons/medical_vitals/script_component.hpp index 3bfb4bcc26..1064ebc52c 100644 --- a/addons/medical_vitals/script_component.hpp +++ b/addons/medical_vitals/script_component.hpp @@ -16,3 +16,5 @@ #include "\z\ace\addons\medical_engine\script_macros_medical.hpp" #include "\z\ace\addons\main\script_macros.hpp" + +#define BASE_OXYGEN_USE -0.25 diff --git a/addons/medical_vitals/stringtable.xml b/addons/medical_vitals/stringtable.xml new file mode 100644 index 0000000000..57a1e250dd --- /dev/null +++ b/addons/medical_vitals/stringtable.xml @@ -0,0 +1,24 @@ + + + + + Vitals + Vitais + Parametri Vitali + Жизненно-важные органы + バイタル + + + Enable SpO2 Simulation + Abilita simulazione SpO2 + Включить имитацию SpO2 + SpO2シミュレーションを有効化 + + + Enables oxygen saturation simulation, providing variable heart rate and oxygen demand based on physical activity and altitude. Required for Airway Management. + Abilita la simulazione della saturazione di ossigeno, alterando la frequenza cardiaca e consumo di ossigeno in funzione dell'attività fisica e l'altitudine. Richiesto per la gestione delle vie aeree. + Позволяет имитировать насыщение кислородом, обеспечивая переменную частоту сердечных сокращений и потребность в кислороде в зависимости от физической активности и высоты над уровнем моря. Требуется для управления дыхательными путями. + 酸素飽和度シミュレーションを有効にし、身体活動や標高に基づいて変動する心拍数と酸素要求量の機能を提供します。 気道管理に必要です。 + + + diff --git a/addons/mk6mortar/CfgMagazines.hpp b/addons/mk6mortar/CfgMagazines.hpp index 0d5c1d5703..e0626479c4 100644 --- a/addons/mk6mortar/CfgMagazines.hpp +++ b/addons/mk6mortar/CfgMagazines.hpp @@ -1,10 +1,11 @@ -class cfgMagazines { +class CfgMagazines { class 8Rnd_82mm_Mo_shells; class ACE_1Rnd_82mm_Mo_HE: 8Rnd_82mm_Mo_shells { count = 1; scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_HE_displayName); displayNameShort = ""; @@ -19,6 +20,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_Smoke_displayName); displayNameShort = ""; @@ -33,6 +35,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_Illum_displayName); displayNameShort = ""; @@ -47,6 +50,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_HE_Guided_displayName); displayNameShort = ""; @@ -61,6 +65,7 @@ class cfgMagazines { scope = 2; scopeCurator = 2; EGVAR(arsenal,hide) = -1; + type = 256; author = ECSTRING(common,ACETeam); displayName = CSTRING(magazine_HE_LaserGuided_displayName); displayNameShort = ""; diff --git a/addons/mk6mortar/XEH_postInit.sqf b/addons/mk6mortar/XEH_postInit.sqf index 9f24a12a3b..aa5f2774df 100644 --- a/addons/mk6mortar/XEH_postInit.sqf +++ b/addons/mk6mortar/XEH_postInit.sqf @@ -1,6 +1,7 @@ #include "script_component.hpp" if (hasInterface) then { + #include "initKeybinds.inc.sqf" ["ace_infoDisplayChanged", FUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler; }; diff --git a/addons/mk6mortar/initKeybinds.inc.sqf b/addons/mk6mortar/initKeybinds.inc.sqf new file mode 100644 index 0000000000..0e3a53c1d9 --- /dev/null +++ b/addons/mk6mortar/initKeybinds.inc.sqf @@ -0,0 +1,15 @@ +#include "\a3\ui_f\hpp\defineDIKCodes.inc" + +["ACE3 Equipment", QGVAR(rangetable_action), LLSTRING(rangetable_action), { + if ( + !([ACE_player, "ACE_RangeTable_82mm"] call EFUNC(common,hasItem)) || + !([ACE_player, objNull, ["notOnMap", "isNotInside", "isNotSitting"]] call EFUNC(common,canInteractWith)) + ) exitWith {false}; + + // Close previously opened dialogs + closeDialog 0; + + // Statement + [] call FUNC(rangeTableOpen); + true +}] call CBA_fnc_addKeybind; // Unbound diff --git a/addons/nightvision/ACE_Arsenal_Stats.hpp b/addons/nightvision/ACE_Arsenal_Stats.hpp index 0b42d136f6..e6d2a87c89 100644 --- a/addons/nightvision/ACE_Arsenal_Stats.hpp +++ b/addons/nightvision/ACE_Arsenal_Stats.hpp @@ -3,7 +3,7 @@ class EGVAR(arsenal,stats) { class GVAR(generation): statBase { scope = 2; priority = 1.6; - condition = QUOTE('nvg' in (getArray ((_this select 1) >> 'visionMode') apply {toLower _x})); + condition = QUOTE('nvg' in (getArray ((_this select 1) >> 'visionMode') apply {toLowerANSI _x})); displayName = CSTRING(NVGeneration); showText = 1; textStatement = QUOTE(call FUNC(statTextStatement_NVGeneration)); diff --git a/addons/nightvision/XEH_preInit.sqf b/addons/nightvision/XEH_preInit.sqf index 894773534a..8251bf8baf 100644 --- a/addons/nightvision/XEH_preInit.sqf +++ b/addons/nightvision/XEH_preInit.sqf @@ -8,4 +8,7 @@ PREP_RECOMPILE_END; #include "initSettings.inc.sqf" +// #9781 - register effects layer ASAP +QGVAR(display) cutText ["", "PLAIN"]; + ADDON = true; diff --git a/addons/nightvision/functions/fnc_setupDisplayEffects.sqf b/addons/nightvision/functions/fnc_setupDisplayEffects.sqf index bb7067689c..6e480c1ca6 100644 --- a/addons/nightvision/functions/fnc_setupDisplayEffects.sqf +++ b/addons/nightvision/functions/fnc_setupDisplayEffects.sqf @@ -48,10 +48,9 @@ if (GVAR(fogScaling) > 0) then { }; }; -// Note: Using BIS_fnc_rscLayer because of bug with string syntax - https://feedback.bistudio.com/T120768 -(QGVAR(display) call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; // Cleanup Old Display +QGVAR(display) cutText ["", "PLAIN"]; // Cleanup Old Display if (_activated) then { // Create New Display - (QGVAR(display) call BIS_fnc_rscLayer) cutRsc [QGVAR(title), "PLAIN", 0, false, false]; // draw under HUD + QGVAR(display) cutRsc [QGVAR(title), "PLAIN", 0, false, false]; // draw under HUD }; // Cleanup Old PP Effects diff --git a/addons/nightvision/stringtable.xml b/addons/nightvision/stringtable.xml index ef57732337..e1345ec44e 100644 --- a/addons/nightvision/stringtable.xml +++ b/addons/nightvision/stringtable.xml @@ -131,6 +131,7 @@ NS-Brille (3. Generation, Braun, WP) 야투경 (3세대, 갈색, 백색광) JVN (Gen3, marron, WP) + ПНВ (Gen3, Коричневый, БФ) Night Vision Goggles, White Phosphor @@ -140,6 +141,7 @@ Nachtsichtbrille, weißer Phosphor 백색광 야투경 Jumelles Vision Nocturne, Phosphore blanc + Очки ночного видения, белый фосфор NV Goggles (Gen3, Green) @@ -166,6 +168,7 @@ NS-Brille (3. Generation, Grün, WP) 야투경 (3세대, 녹색, 백색광) JVN (Gen3, vertes, WP) + ПНВ (Gen3, Зелёный, БФ) NV Goggles (Gen3, Black) @@ -192,6 +195,7 @@ NS-Brille (3. Generation, Schwarz, WP) 야투경 (3세대, 검정, 백색광) JVN (Gen3, noires, WP) + ПНВ (Gen3, Чёрный, БФ) NV Goggles (Gen4, Brown) @@ -213,6 +217,7 @@ NS-Brille (4. Generation, Braun, WP) 야투경 (4세대, 갈색, 백색광) JVN (Gen4, marron, WP) + ПНВ (Gen4, Коричневый, БФ) NV Goggles (Gen4, Black) @@ -234,6 +239,7 @@ NS-Brille (4. Generation, Schwarz, WP) 야투경 (4세대, 검정, 백색광) JVN (Gen4, noires, WP) + ПНВ (Gen4, Чёрный, БФ) NV Goggles (Gen4, Green) @@ -255,6 +261,7 @@ NS-Brille (4. Generation, Grün, WP) 야투경 (4세대, 녹색, 백색광) JVN (Gen4, vertes, WP) + ПНВ (Gen4, Зелёный, БФ) NV Goggles (Wide, Brown) @@ -276,6 +283,7 @@ NS-Brille (Weit, Braun, WP) 야투경 (넓음, 갈색, 백색광) JVN (Large, marron, WP) + ПНВ (Широкий, Коричневый, БФ) NV Goggles (Wide, Black) @@ -297,6 +305,7 @@ NS-Brille (Weit, Schwarz, WP) 야투경 (넓음, 검정, 백색광) JVN (Large, noires, WP) + ПНВ (Широкий, Чёрный, БФ) NV Goggles (Wide, Green) @@ -318,6 +327,7 @@ NS-Brille (Weit, Grün, WP) 야투경 (넓음, 녹색, 백색광) JVN (Large, vertes, WP) + ПНВ (Широкий, Зелёный, БФ) Brightness: %1 @@ -576,6 +586,7 @@ Nachtsicht-Generation 야투경 세대 Génération de jumelles de vision nocturne + Генерация ночного видения Gen %1 @@ -585,6 +596,7 @@ Gen %1 %1세대 Gen %1 + Генерация %1 diff --git a/addons/novehicleclanlogo/stringtable.xml b/addons/novehicleclanlogo/stringtable.xml index d3f01899a9..96d463f582 100644 --- a/addons/novehicleclanlogo/stringtable.xml +++ b/addons/novehicleclanlogo/stringtable.xml @@ -5,7 +5,7 @@ Remove clan logo from vehicles Usuń logo klanu z pojazdów 차량에서 클랜 로고 제거 - Убрать логотип кланов с техники + Убрать логотип отрядов с техники Suprimir logo del clan de los vehículos 乗り物から部隊ロゴを削除 Clan-Logo von Fahrzeugen entfernen @@ -16,7 +16,7 @@ Prevents clan logo from being displayed on vehicles controlled by players. Zapobiega wyświetlaniu logo klanu na pojazdach kontrolowanych przez graczy. 플레이어가 조종하는 차량에 클랜 로고가 표시되지 않도록 합니다. - Не отображать логотипы кланов на технике контроллируемой игроками. + Не отображать логотипы отрядов на технике контроллируемой игроками. Previene que se muestre el logo del clan en los vehículos controlados por jugadores. プレイヤーが操作する乗り物に部隊ロゴが表示されないようにする。 Verhindert, dass das Clan-Logo auf von Spielern kontrollierten Fahrzeugen angezeigt wird. diff --git a/addons/overheating/functions/fnc_calculateCooling.sqf b/addons/overheating/functions/fnc_calculateCooling.sqf index f01f3950e7..e7ac83f236 100644 --- a/addons/overheating/functions/fnc_calculateCooling.sqf +++ b/addons/overheating/functions/fnc_calculateCooling.sqf @@ -7,6 +7,7 @@ * 0: Initial temperature * 1: Barrel mass * 2: Time interval + * 3: Bolt type * * Return Value: * Final temperature @@ -17,7 +18,7 @@ * Public: No */ -params ["_temperature", "_barrelMass", "_totalTime"]; +params ["_temperature", "_barrelMass", "_totalTime", "_boltType"]; // The lowest temperature a weapon can reach is the ambient air temperature. private _ambientTemperature = ambientTemperature select 0; @@ -43,6 +44,9 @@ if (ACE_player call EFUNC(common,isSwimming)) then { _convectionRate = _convectionRate * ((linearConversion [0,1,rain,1,5,true] + (5 min (vectorMagnitude wind / 10))) / 2); }; +//Increase convection cooling for open bolt type guns +if (_boltType == 0) then {_convectionRate = _convectionRate * OPEN_BOLT_ADDITIONAL_CONVECTION}; + TRACE_4("cooling",_temperature,_totalTime,_barrelMass,_barrelSurface); private _time = 0; diff --git a/addons/overheating/functions/fnc_coolWeaponWithItem.sqf b/addons/overheating/functions/fnc_coolWeaponWithItem.sqf index bc21963fb6..e5e79aaf62 100644 --- a/addons/overheating/functions/fnc_coolWeaponWithItem.sqf +++ b/addons/overheating/functions/fnc_coolWeaponWithItem.sqf @@ -61,8 +61,8 @@ private _fnc_onSuccess = { }; // cool the weapon - private _barrelMass = ([_weapon] call FUNC(getWeaponData)) select 7; - _temperature = [_temperature, _barrelMass, _liquidAmount * 10] call FUNC(calculateCooling); + private _weaponData = [_weapon] call FUNC(getWeaponData); + _temperature = [_temperature, _weaponData select 7, _liquidAmount * 10, _weaponData select 6] call FUNC(calculateCooling); [_target, _tempVarName, _temperature, TEMP_TOLERANCE] call EFUNC(common,setApproximateVariablePublic); }; diff --git a/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf b/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf index acf3286c4a..67f22a3cc0 100644 --- a/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf +++ b/addons/overheating/functions/fnc_coolWeaponWithWaterSource.sqf @@ -59,8 +59,8 @@ private _fnc_condition = { }; //Cool the weapon down - private _barrelMass = ([_weapon] call FUNC(getWeaponData)) select 7; - _temperature = [_temperature, _barrelMass, 20] call FUNC(calculateCooling); + private _weaponData = [_weapon] call FUNC(getWeaponData); + _temperature = [_temperature, _weaponData select 7, 20, _weaponData select 6] call FUNC(calculateCooling); [_player, _tempVarName, _temperature, TEMP_TOLERANCE] call EFUNC(common,setApproximateVariablePublic); /* // to be added when licence compatible audio can be found or recorded diff --git a/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf b/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf index 64110b2c76..da87c5fdba 100644 --- a/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf +++ b/addons/overheating/functions/fnc_updateSpareBarrelsTemperaturesThread.sqf @@ -20,10 +20,10 @@ TRACE_1("updateSpareBarrelsTemperaturesThread1",GVAR(storedSpareBarrels)); _y params ["_initialTemp","_initialTime", "_barrelMass"]; // Calculate cooling - private _finalTemp = [_initialTemp, _barrelMass, CBA_missionTime - _initialTime] call FUNC(calculateCooling); + private _finalTemp = [_initialTemp, _barrelMass, CBA_missionTime - _initialTime, 0] call FUNC(calculateCooling); //the zero is to indicate an open bolt gun. Barrel is outside of a gun here, so always open. TRACE_4("updateSpareBarrelsTemperaturesThread2",_barrelMagazineID,_initialTemp,_finalTemp,_barrelMass); - if (_finalTemp < 5) then { - // The barrel is cool enough to keep calculating. Remove it from the hash + if (_finalTemp <= (ambientTemperature select 0)) then { + // The barrel is cool enough to finish calculating. Remove it from the hash GVAR(storedSpareBarrels) deleteAt _x; } else { // Store the new temp diff --git a/addons/overheating/functions/fnc_updateTemperature.sqf b/addons/overheating/functions/fnc_updateTemperature.sqf index 8d5ca5d412..db7f48be83 100644 --- a/addons/overheating/functions/fnc_updateTemperature.sqf +++ b/addons/overheating/functions/fnc_updateTemperature.sqf @@ -33,8 +33,9 @@ _trackedWeapons pushBackUnique _tempVarName; _unit setVariable [QGVAR(trackedWeapons), _trackedWeapons]; // Calculate cooling -private _barrelMass = ([_weapon] call FUNC(getWeaponData)) select 7; -_temperature = [_temperature, _barrelMass, CBA_missionTime - _lastTime] call FUNC(calculateCooling); +private _weaponData = [_weapon] call FUNC(getWeaponData); +private _barrelMass = _weaponData select 7; +_temperature = [_temperature, _barrelMass, CBA_missionTime - _lastTime, _weaponData select 6] call FUNC(calculateCooling); TRACE_1("cooledTo",_temperature); // Calculate heating diff --git a/addons/overheating/script_component.hpp b/addons/overheating/script_component.hpp index 0837733cd3..dd1b18806f 100644 --- a/addons/overheating/script_component.hpp +++ b/addons/overheating/script_component.hpp @@ -19,6 +19,7 @@ #define TEMP_TOLERANCE 50 #define METAL_MASS_RATIO 0.55 #define GUNPOWDER_IGNITION_TEMP 180 +#define OPEN_BOLT_ADDITIONAL_CONVECTION 1.1 #ifdef DEBUG_MODE_FULL #define TRACE_PROJECTILE_INFO(BULLET) _vdir = vectorNormalized velocity BULLET; _dir = (_vdir select 0) atan2 (_vdir select 1); _up = asin (_vdir select 2); _mv = vectorMagnitude velocity BULLET; TRACE_3("adjusted projectile",_dir,_up,_mv); diff --git a/addons/overheating/stringtable.xml b/addons/overheating/stringtable.xml index 4160a77ea8..ba662bf684 100644 --- a/addons/overheating/stringtable.xml +++ b/addons/overheating/stringtable.xml @@ -877,33 +877,45 @@ Bolt Type + Tipo di otturatore 遊底(ボルト)形式 노리쇠 방식 + Тип болта Open Bolt + Otturatore Aperto オープンボルト 오픈 볼트 + Открыть болт Closed Bolt + Otturatore Chiuso クローズドボルト 클로즈드 볼트 + Закрыть болт Barrel Type + Tipo di Canna 銃身形式 총열 방식 + Тип ствола Non-Removeable + Non-Rimovibile 取り外し不可 제거 불가 + Несъемный Quick Change + Cambio Rapido 即時交換可 신속 교체 + Быстросъемный diff --git a/addons/parachute/RscTitles.hpp b/addons/parachute/RscTitles.hpp index 9e0a169937..48cf11bee4 100644 --- a/addons/parachute/RscTitles.hpp +++ b/addons/parachute/RscTitles.hpp @@ -39,10 +39,10 @@ class RscTitles { }; class TimeText: RscText { idc = 1001; - text = "00:00"; - x = "0.206094 * safezoneW + safezoneX"; + text = "00:00:00"; + x = "0.202094 * safezoneW + safezoneX"; y = "0.819 * safezoneH + safezoneY"; - w = "0.0309375 * safezoneW"; + w = "0.0380375 * safezoneW"; h = "0.022 * safezoneH"; colorText[] = {0,0,0,1}; }; diff --git a/addons/parachute/functions/fnc_showAltimeter.sqf b/addons/parachute/functions/fnc_showAltimeter.sqf index d4533a7a6b..f86f785cc6 100644 --- a/addons/parachute/functions/fnc_showAltimeter.sqf +++ b/addons/parachute/functions/fnc_showAltimeter.sqf @@ -40,8 +40,10 @@ private _TimeText = _display displayCtrl 1001; _pfhID call CBA_fnc_removePerFrameHandler; }; - private _hour = floor daytime; - private _minute = floor ((daytime - _hour) * 60); + private _daytime = dayTime; + private _hour = floor _daytime; + private _minute = floor ((_daytime - _hour) * 60); + private _seconds = floor ((((_daytime - _hour) * 60) - _minute) * 60); private _curTime = CBA_missionTime; private _timeDiff = _curTime - _prevTime; @@ -52,7 +54,7 @@ private _TimeText = _display displayCtrl 1001; 0 }; - _TimeText ctrlSetText (format ["%1:%2", [_hour, 2] call CBA_fnc_formatNumber, [_minute, 2] call CBA_fnc_formatNumber]); + _TimeText ctrlSetText (format ["%1:%2:%3", [_hour, 2] call CBA_fnc_formatNumber, [_minute, 2] call CBA_fnc_formatNumber, [_seconds, 2] call CBA_fnc_formatNumber]); _HeightText ctrlSetText str floor _height; _DecendRate ctrlSetText str (_descentRate max 0); diff --git a/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf b/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf index e55d498809..c1318e3f74 100644 --- a/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf +++ b/addons/quickmount/functions/fnc_addFreeSeatsActions.sqf @@ -29,6 +29,7 @@ #define TO_COMPARTMENT_STRING(var) if !(var isEqualType "") then {var = format [ARR_2("Compartment%1",var)]} // if unit isn't moved to new seat in TAKEN_SEAT_TIMEOUT, we move him back to his seat +#pragma hemtt suppress pw3_padded_arg file #define WAIT_IN_OR_MOVE_BACK \ [ARR_5( \ {!isNull objectParent (_this select 0)}, \ @@ -158,7 +159,7 @@ private _cargoNumber = -1; }; } else { private ["_name", "_icon", "_statement", "_params"]; - switch (toLower _role) do { + switch (toLowerANSI _role) do { case "driver": { if ( lockedDriver _vehicle diff --git a/addons/quickmount/functions/fnc_getInNearest.sqf b/addons/quickmount/functions/fnc_getInNearest.sqf index c618681f7e..5e6c21eb36 100644 --- a/addons/quickmount/functions/fnc_getInNearest.sqf +++ b/addons/quickmount/functions/fnc_getInNearest.sqf @@ -69,7 +69,7 @@ if (!isNull _target && { _x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; if ((isNull _unit) || {!alive _unit}) then { - private _effectiveRole = toLower _role; + private _effectiveRole = toLowerANSI _role; if ((_effectiveRole in ["driver", "gunner"]) && {unitIsUAV _target}) exitWith {}; // Ignoring UAV Driver/Gunner if ((_effectiveRole == "driver") && {(getNumber (configOf _target >> "hasDriver")) == 0}) exitWith {}; // Ignoring Non Driver (static weapons) diff --git a/addons/rangecard/XEH_postInit.sqf b/addons/rangecard/XEH_postInit.sqf index 6adc4cf2a1..af4dfa923c 100644 --- a/addons/rangecard/XEH_postInit.sqf +++ b/addons/rangecard/XEH_postInit.sqf @@ -1,7 +1,5 @@ #include "script_component.hpp" -#include "initKeybinds.inc.sqf" - GVAR(RangeCardOpened) = false; GVAR(controls) = []; @@ -17,3 +15,7 @@ GVAR(boreHeightCopy) = 3.81; GVAR(ammoClassCopy) = "";//"ACE_762x51_Ball_M118LR"; GVAR(magazineClassCopy) = "";//"ACE_20Rnd_762x51_M118LR_Mag"; GVAR(weaponClassCopy) = "";//srifle_DMR_06_olive_F"; + +if (!hasInterface) exitWith {}; + +#include "initKeybinds.inc.sqf" diff --git a/addons/rearm/functions/fnc_addRearmActions.sqf b/addons/rearm/functions/fnc_addRearmActions.sqf index e71cab8f0c..200dd2f2b4 100644 --- a/addons/rearm/functions/fnc_addRearmActions.sqf +++ b/addons/rearm/functions/fnc_addRearmActions.sqf @@ -30,7 +30,9 @@ private _cswCarryMagazines = []; private _vehicleActions = []; { private _vehicle = _x; - + private _displayName = getText (configOf _vehicle >> "displayName"); + private _distanceStr = (ACE_player distance _vehicle) toFixed 1; + private _actionName = format ["%1 (%2m)", _displayName, _distanceStr]; // Array of magazines that can be rearmed in the vehicle private _needRearmMags = ([_vehicle] call FUNC(getNeedRearmMagazines)) apply {_x select 0}; @@ -57,7 +59,7 @@ private _vehicleActions = []; // [Level 0] adds a single action to rearm the entire vic private _action = [ _vehicle, - getText(configOf _vehicle >> "displayName"), + _actionName, _icon, {_this call FUNC(rearmEntireVehicle)}, {true}, @@ -84,7 +86,7 @@ private _vehicleActions = []; private _action = [ _vehicle, - getText(configOf _vehicle >> "displayName"), + _actionName, _icon, {}, {true}, diff --git a/addons/rearm/functions/fnc_initSupplyVehicle.sqf b/addons/rearm/functions/fnc_initSupplyVehicle.sqf index 7749f0b609..4ab04fcaf6 100644 --- a/addons/rearm/functions/fnc_initSupplyVehicle.sqf +++ b/addons/rearm/functions/fnc_initSupplyVehicle.sqf @@ -33,7 +33,7 @@ if (!alive _vehicle) exitWith {}; private _configSupply = getNumber (_configOf >> QGVAR(defaultSupply)); if (_configSupply == 0) then { - _configSupply = getNumber (_config >> "transportAmmo"); + _configSupply = getNumber (_configOf >> "transportAmmo"); }; private _isSupplyVehicle = _vehicle getVariable [QGVAR(isSupplyVehicle), false]; private _oldRearmConfig = isClass (_configOf >> "ACE_Actions" >> "ACE_MainActions" >> QGVAR(takeAmmo)); diff --git a/addons/recoil/functions/fnc_camshake.sqf b/addons/recoil/functions/fnc_camshake.sqf index e2a7e3a4a1..d68da81db7 100644 --- a/addons/recoil/functions/fnc_camshake.sqf +++ b/addons/recoil/functions/fnc_camshake.sqf @@ -24,7 +24,7 @@ TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_veh #define BASE_FREQ 13 #define RECOIL_COEF 40 -if (toLower _weapon in ["throw", "put"]) exitWith {}; +if (toLowerANSI _weapon in ["throw", "put"]) exitWith {}; private _powerMod = ([0, -0.1, -0.1, 0, -0.2] select (["STAND", "CROUCH", "PRONE", "UNDEFINED", ""] find stance _unit)) + ([0, -1, 0, -1] select (["INTERNAL", "EXTERNAL", "GUNNER", "GROUP"] find cameraView)); diff --git a/addons/refuel/functions/fnc_canTakeNozzle.sqf b/addons/refuel/functions/fnc_canTakeNozzle.sqf index a2dc39b815..f2fa4a6a9c 100644 --- a/addons/refuel/functions/fnc_canTakeNozzle.sqf +++ b/addons/refuel/functions/fnc_canTakeNozzle.sqf @@ -24,7 +24,7 @@ if (isNull _unit || {!alive _object} || {!isNull (_unit getVariable [QGVAR(nozzle), objNull])} || // Not already carrying a nozzle {(_object getVariable [QGVAR(jerryCan), false]) && {!isNull (_object getVariable [QGVAR(nozzle), objNull])}} || // Prevent jerry cans from being picked up if they have a nozzle connected - {typeOf _object == QGVAR(fuelNozzle) && {!isNull (attachedTo _object)}} || // Not carried by someone else + {!([_unit, _object, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith))} || // Not carried by someone else {([_unit, _object] call EFUNC(interaction,getInteractionDistance)) > REFUEL_ACTION_DISTANCE}) exitWith {false}; !(_object getVariable [QGVAR(isConnected), false]) && {!(_unit getVariable [QGVAR(isRefueling), false])} diff --git a/addons/refuel/functions/fnc_connectNozzleAction.sqf b/addons/refuel/functions/fnc_connectNozzleAction.sqf index ad658492fa..502e1dc3a4 100644 --- a/addons/refuel/functions/fnc_connectNozzleAction.sqf +++ b/addons/refuel/functions/fnc_connectNozzleAction.sqf @@ -116,6 +116,9 @@ private _attachPosModel = _sink worldToModel (ASLtoAGL _bestPosASL); // Reset fuel counter _source setVariable [QGVAR(fuelCounter), 0, true]; + // Let other players access nozzle + [objNull, _nozzle] call EFUNC(common,claim); + [_unit, _sink, _nozzle, _endPosTestOffset] call FUNC(refuel); private _canReceive = getNumber ((configOf _sink) >> QGVAR(canReceive)) == 1; diff --git a/addons/refuel/functions/fnc_dropNozzle.sqf b/addons/refuel/functions/fnc_dropNozzle.sqf index 5ca375dc29..ee37a869e1 100644 --- a/addons/refuel/functions/fnc_dropNozzle.sqf +++ b/addons/refuel/functions/fnc_dropNozzle.sqf @@ -24,6 +24,9 @@ TRACE_3("dropNozzle",_unit,_nozzle,_disconnectOnly); detach _nozzle; _nozzle setVariable [QGVAR(isRefueling), false, true]; +// Remove claim on nozzle +[objNull, _nozzle] call EFUNC(common,claim); + if (_disconnectOnly) exitWith {}; _nozzle setVelocity [0, 0, 0]; diff --git a/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf index d2f1e2aaa5..611fa85e90 100644 --- a/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf +++ b/addons/refuel/functions/fnc_startNozzleInHandsPFH.sqf @@ -35,11 +35,9 @@ TRACE_2("start",_unit,_nozzle); _args params ["_unit", "_nozzle"]; if !( - alive _unit + _unit call EFUNC(common,isAwake) && {"" isEqualTo currentWeapon _unit || {_unit call EFUNC(common,isSwimming)}} && {[_unit, objNull, [INTERACT_EXCEPTIONS, "notOnMap"]] call EFUNC(common,canInteractWith)} - && {"unconscious" isNotEqualTo toLower animationState _unit} - && {!(_unit getVariable ["ACE_isUnconscious", false])} ) exitWith { TRACE_3("stop dead/weapon/interact/uncon",_unit,alive _unit,currentWeapon _unit); DROP_NOZZLE diff --git a/addons/refuel/functions/fnc_takeNozzle.sqf b/addons/refuel/functions/fnc_takeNozzle.sqf index 8eb0a16f1f..cd8f8b4eb4 100644 --- a/addons/refuel/functions/fnc_takeNozzle.sqf +++ b/addons/refuel/functions/fnc_takeNozzle.sqf @@ -32,17 +32,23 @@ params [ private _source = _object; private _nozzle = _object; - if (typeOf _object isEqualTo QGVAR(fuelNozzle) || {_object getVariable [QGVAR(jerryCan), false]}) then { // func is called on muzzle either connected or on ground + if (typeOf _object isEqualTo QGVAR(fuelNozzle) || {_object getVariable [QGVAR(jerryCan), false]}) then { // func is called on nozzle either connected or on ground _source = _nozzle getVariable QGVAR(source); if (_nozzle getVariable [QGVAR(jerryCan), false]) then { _nozzle attachTo [_unit, [0,1,0], "pelvis"]; } else { _nozzle attachTo [_unit, [-0.02,0.05,-0.12], "righthandmiddle1"]; }; + + // Don't allow other players to take nozzle + [_unit, _nozzle] call EFUNC(common,claim); } else { // func is called on fuel truck _nozzle = QGVAR(fuelNozzle) createVehicle [0,0,0]; _nozzle attachTo [_unit, [-0.02,0.05,-0.12], "righthandmiddle1"]; + // Don't allow other players to take nozzle + [_unit, _nozzle] call EFUNC(common,claim); + private _ropeTarget = _source; if !(_source isKindOf "AllVehicles") then { private _helper = QGVAR(helper) createVehicle [0,0,0]; diff --git a/addons/refuel/stringtable.xml b/addons/refuel/stringtable.xml index 4752f83caf..dc61a2c168 100644 --- a/addons/refuel/stringtable.xml +++ b/addons/refuel/stringtable.xml @@ -58,6 +58,7 @@ Prędkość Tankowania Ładunku Frachtflussrate Vitesse de ravitaillement + Скорость заполнения груза How fast should a fuel source's tank be filled? @@ -68,6 +69,7 @@ Jak szybko zbiornik paliwa powinien być napełniany? Wie schnell sollte der Tank einer Kraftstoffquelle gefüllt werden? A quelle vitesse le réservoir de carburant doit-il être rempli ? + Как быстро должен заполняться бак источника топлива? Refuel @@ -318,6 +320,7 @@ 給油を始める (コンテナ) Rozpocznij tankowanie (zbiornik) Commencer le ravitaillement (container) + Начать заправку топливом (контейнер) Couldn't turn on fuel nozzle @@ -501,6 +504,7 @@ Raccogli contenitore di carburante 燃料キャニスターを持つ 연료통 집어들기 + Взять канистру с топливом Picking fuel canister up... @@ -508,6 +512,7 @@ Raccogliendo contenitore di carburante... 燃料キャニスターを持ち上げています・・・ 연료통 집어드는 중... + Поднимаю канистру с топливом... Connect fuel canister @@ -515,6 +520,7 @@ Collega contenitore di carburante 燃料キャニスターを接続する 연료통 꽂기 + Подсоединить канистру с топливом Connecting fuel canister... @@ -522,6 +528,7 @@ Collegando contenitore di carburante... 燃料キャニスターを接続しています・・・ 연료통 꽂는 중... + Подсоединение топливной канистры... Disconnect fuel canister @@ -529,6 +536,7 @@ Scollega contenitore di carburante 燃料キャニスターを外します 연료통 빼기 + Отсоединить канистру с топливом Refuel hose length diff --git a/addons/reload/CfgVehicles.hpp b/addons/reload/CfgVehicles.hpp index 22086ad867..5a05f03734 100644 --- a/addons/reload/CfgVehicles.hpp +++ b/addons/reload/CfgVehicles.hpp @@ -45,5 +45,48 @@ class CfgVehicles { }; }; }; + + class ACE_SelfActions { + class GVAR(reloadTurret) { + displayName = "$STR_controls_tooltips_RELOAD_MAGAZINE"; + condition = QUOTE(call FUNC(canSwapTurretMagazine)); + statement = QUOTE(call FUNC(swapTurretMagazine)); + icon = "\A3\ui_f\data\igui\cfg\simpletasks\types\rearm_ca.paa"; + }; + }; + }; + + class Tank: LandVehicle { + class ACE_SelfActions { + class GVAR(reloadTurret) { + displayName = "$STR_controls_tooltips_RELOAD_MAGAZINE"; + condition = QUOTE(call FUNC(canSwapTurretMagazine)); + statement = QUOTE(call FUNC(swapTurretMagazine)); + icon = "\A3\ui_f\data\igui\cfg\simpletasks\types\rearm_ca.paa"; + }; + }; + }; + + class Car: LandVehicle { + class ACE_SelfActions { + class GVAR(reloadTurret) { + displayName = "$STR_controls_tooltips_RELOAD_MAGAZINE"; + condition = QUOTE(call FUNC(canSwapTurretMagazine)); + statement = QUOTE(call FUNC(swapTurretMagazine)); + icon = "\A3\ui_f\data\igui\cfg\simpletasks\types\rearm_ca.paa"; + }; + }; + }; + + class Air; + class Helicopter: Air { + class ACE_SelfActions { + class GVAR(reloadTurret) { + displayName = "$STR_controls_tooltips_RELOAD_MAGAZINE"; + condition = QUOTE(call FUNC(canSwapTurretMagazine)); + statement = QUOTE(call FUNC(swapTurretMagazine)); + icon = "\A3\ui_f\data\igui\cfg\simpletasks\types\rearm_ca.paa"; + }; + }; }; }; diff --git a/addons/reload/CfgWeapons.hpp b/addons/reload/CfgWeapons.hpp new file mode 100644 index 0000000000..0d52ae8f5c --- /dev/null +++ b/addons/reload/CfgWeapons.hpp @@ -0,0 +1,16 @@ +class CfgWeapons { + class HMG_01; + class HMG_static: HMG_01 { + type = 1; // makes it possible to swap to the fullest magazine + }; + + class GMG_F; + class GMG_20mm: GMG_F { + type = 1; + }; + + class CannonCore; + class mortar_82mm: CannonCore { + type = 1; + }; +}; diff --git a/addons/reload/XEH_PREP.hpp b/addons/reload/XEH_PREP.hpp index 578bc2ce9f..1a62a9f5bd 100644 --- a/addons/reload/XEH_PREP.hpp +++ b/addons/reload/XEH_PREP.hpp @@ -1,7 +1,9 @@ PREP(canCheckAmmo); PREP(canCheckAmmoSelf); +PREP(canSwapTurretMagazine); PREP(getAmmoToLinkBelt); PREP(checkAmmo); PREP(displayAmmo); PREP(onTake); PREP(startLinkingBelt); +PREP(swapTurretMagazine); diff --git a/addons/reload/XEH_postInit.sqf b/addons/reload/XEH_postInit.sqf index 02dedd14c3..a219efed0a 100644 --- a/addons/reload/XEH_postInit.sqf +++ b/addons/reload/XEH_postInit.sqf @@ -53,3 +53,18 @@ if (!hasInterface) exitWith {}; #include "initKeybinds.inc.sqf" + +// Reload when default reload keybind is pressed +addUserActionEventHandler ["ReloadMagazine", "Activate", { + private _vehicle = objectParent ACE_player; + + // If on foot, skip + if (isNull _vehicle) exitWith {}; + + // weaponState is only updated after 3 frames, so wait to run checks in case we're doing an engine reload at the same time + [{ + if !(_this call FUNC(canSwapTurretMagazine)) exitWith {}; + + _this call FUNC(swapTurretMagazine); + }, [_vehicle, ACE_player], 3] call CBA_fnc_execAfterNFrames; +}]; diff --git a/addons/reload/config.cpp b/addons/reload/config.cpp index 1cd11c5b17..f4871f1354 100644 --- a/addons/reload/config.cpp +++ b/addons/reload/config.cpp @@ -14,10 +14,11 @@ class CfgPatches { }; }; -#include "ACE_Arsenal_Stats.hpp" -#include "CfgVehicles.hpp" -#include "CfgMagazines.hpp" -#include "CfgEventHandlers.hpp" #include "CfgActions.hpp" +#include "CfgEventHandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgVehicles.hpp" +#include "CfgWeapons.hpp" +#include "ACE_Arsenal_Stats.hpp" #include "ACE_Settings.hpp" #include "ACE_UI.hpp" diff --git a/addons/reload/functions/fnc_canSwapTurretMagazine.sqf b/addons/reload/functions/fnc_canSwapTurretMagazine.sqf new file mode 100644 index 0000000000..114a124776 --- /dev/null +++ b/addons/reload/functions/fnc_canSwapTurretMagazine.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, johnb43 + * Check if the player can reload their vehicle's magazine to one with more ammo. + * + * Arguments: + * 0: Vehicle + * 1: Player + * + * Return Value: + * Can swap turret magazine + * + * Example: + * [vehicle player, player] call ace_reload_fnc_canSwapTurretMagazine + * + * Public: No + */ + +params ["_vehicle", "_unit"]; +TRACE_2("canSwapTurretMagazine",_vehicle,_unit); + +private _turretPath = _vehicle unitTurret _unit; +if (_turretPath in [[-1], []]) exitWith {false}; // skip driver / cargo +if !(_vehicle turretLocal _turretPath) exitWith {false}; // just to be safe + +(weaponState [_vehicle, _turretPath]) params ["_weapon", "_muzzle", "", "_magazine", "_ammoCount", "_roundReloadPhase", "_magazineReloadPhase"]; +TRACE_5("",_weapon,_muzzle,_magazine,_ammoCount,typeOf _vehicle); + +if ((_weapon == "") || {_weapon != _muzzle}) exitWith {false}; // skip multi-muzzle (he/ap auto-cannons) +if (_magazine == "") exitWith {false}; +if (_roundReloadPhase + _magazineReloadPhase != 0) exitWith {false}; // can't reload while already reloading or while shooting +if (isText (configFile >> "CfgMagazines" >> _magazine >> "pylonWeapon")) exitWith {false}; +if (getNumber (configFile >> "CfgWeapons" >> _weapon >> "type") % 2 == 1) exitWith {false}; // engine support for magazine swapping + +private _maxAmmo = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); +if ((_ammoCount == 0) || {_ammoCount == _maxAmmo}) exitWith {false}; + +private _magAmmoCounts = []; + +// Get count of rounds in magazines +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + + if ((_xMag == _magazine) && {_xTurret isEqualTo _turretPath}) then { + _magAmmoCounts pushBack _xAmmo; + }; +} forEach (magazinesAllTurrets _vehicle); + +TRACE_1("",_magAmmoCounts); + +// Select maximum +(selectMax _magAmmoCounts) > _ammoCount diff --git a/addons/reload/functions/fnc_swapTurretMagazine.sqf b/addons/reload/functions/fnc_swapTurretMagazine.sqf new file mode 100644 index 0000000000..c4574398d1 --- /dev/null +++ b/addons/reload/functions/fnc_swapTurretMagazine.sqf @@ -0,0 +1,43 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror, johnb43 + * Reloads a vehicles turret to a new magazine. + * + * Arguments: + * 0: Vehicle + * 1: Player + * + * Return Value: + * None + * + * Example: + * [vehicle player, player] call ace_reload_fnc_swapTurretMagazine + * + * Public: No + */ + +params ["_vehicle", "_unit"]; +TRACE_2("swapTurretMagazine",_vehicle,_unit); + +private _turretPath = _vehicle unitTurret _unit; +(weaponState [_vehicle, _turretPath]) params ["_weapon", "_muzzle", "", "_magazine"]; +TRACE_3("",_weapon,_magazine,typeOf _vehicle); + +private _magazinesAllTurrets = []; + +// Get magazines that are of the correct type; Exclude empty mags +{ + _x params ["_xMag", "_xTurret", "_xAmmo"]; + + if ((_xMag == _magazine) && {_xTurret isEqualTo _turretPath} && {_xAmmo > 0}) then { + _magazinesAllTurrets pushBack _x; + }; +} forEach (magazinesAllTurrets _vehicle); + +// Get count of rounds in magazines, then select maximum +private _magAmmoCounts = _magazinesAllTurrets apply {_x select 2}; +private _mag = _magazinesAllTurrets select (_magAmmoCounts find (selectMax _magAmmoCounts)); + +TRACE_2("",_magAmmoCounts,_mag); + +_unit action ["loadMagazine", _vehicle, _unit, _mag select 4, _mag select 3, _weapon, _muzzle]; diff --git a/addons/reload/stringtable.xml b/addons/reload/stringtable.xml index f52c5107e7..e081834e29 100644 --- a/addons/reload/stringtable.xml +++ b/addons/reload/stringtable.xml @@ -137,6 +137,7 @@ ベルトがリンクされた Taśma została połączona 탄띠가 연결되었습니다 + Ремень был пристегнут Belt could not be linked @@ -146,6 +147,7 @@ ベルトはリンクされなかった Taśma nie mogła być połączona 탄띠를 연결할 수 없습니다 + Ремень не удалось пристегнуть diff --git a/addons/reloadlaunchers/stringtable.xml b/addons/reloadlaunchers/stringtable.xml index 5d3567e5ef..ac42ef4d99 100644 --- a/addons/reloadlaunchers/stringtable.xml +++ b/addons/reloadlaunchers/stringtable.xml @@ -9,6 +9,7 @@ Mostra avviso di ricarica da parte del coppio 동료의 장전에 대한 알림 표시 Affichage de notifications lors d'une rechargement par un ami + Отображает уведомления о загрузке помощника Displays notifications when an assistant loads a gunner's launcher. @@ -18,6 +19,7 @@ Mostra un avviso quando un assistente sta ricaricando il proprio lanciatore. 부사수가 사수의 발사기를 장전할 때 알림을 표시합니다. Affiche une notofication lorsqu'un assistant recharge l'arme du tireur. + Отображает уведомления, когда помощник загружает пусковую установку стрелка. Load launcher @@ -44,6 +46,7 @@ %1 がランチャーを装填しています %1 ładuje twoją wyrzutnię %1이(가) 당신의 발사기를 장전했습니다. + %1 загружает Вашу установку %1 stopped loading your launcher @@ -53,6 +56,7 @@ %1 がランチャーの装填を中断しました %1 przestał ładować twoją wyrzutnię %1이(가) 당신의 발사기 장전을 멈췄습니다. + %1 прекратил загружать Вашу установку Loading launcher... @@ -113,6 +117,7 @@ ランチャーを装填できませんでした Wyrzutnia nie mogła być załadowana 발사기를 장전할 수 없습니다. + Не удалось загрузить пусковую установку Buddy Loading @@ -122,6 +127,7 @@ Chargement par un ami Nachladen durch Kamerad バディローディング + Перезарядка помощником diff --git a/addons/repair/dev/draw_showRepairInfo.sqf b/addons/repair/dev/draw_showRepairInfo.sqf index f516e14ef9..20bf748e7f 100644 --- a/addons/repair/dev/draw_showRepairInfo.sqf +++ b/addons/repair/dev/draw_showRepairInfo.sqf @@ -20,7 +20,7 @@ addMissionEventHandler ["Draw3D", { private _hitpoint = _hitPoints select _forEachIndex; if ((_selection != "") && {_hitPoint != ""}) then { - if (((toLower _hitPoint) find "glass") != -1) exitWith {}; + if ("glass" in (toLowerANSI _hitPoint)) exitWith {}; private _info = ""; private _color = [1,0,0,1]; diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf index 1e0147d7e2..9dad1ecc31 100644 --- a/addons/repair/functions/fnc_addRepairActions.sqf +++ b/addons/repair/functions/fnc_addRepairActions.sqf @@ -52,7 +52,7 @@ private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehi { private _selection = _x; - private _hitpoint = toLower (_hitPoints select _forEachIndex); + private _hitpoint = toLowerANSI (_hitPoints select _forEachIndex); // Skip ignored selections if (_forEachIndex in _selectionsToIgnore) then { diff --git a/addons/repair/functions/fnc_getHitPointString.sqf b/addons/repair/functions/fnc_getHitPointString.sqf index 93a4c153b2..35270887ad 100644 --- a/addons/repair/functions/fnc_getHitPointString.sqf +++ b/addons/repair/functions/fnc_getHitPointString.sqf @@ -40,7 +40,7 @@ private _text = LSTRING(Hit); if ((_hitpoint select [0, 1]) == "#") then { _hitPoint = _hitPoint select [1] }; // Remove "Hit" from hitpoint name if one exists -private _toFind = if ((toLower _hitPoint) find "hit" == 0) then { +private _toFind = if ((toLowerANSI _hitPoint) find "hit" == 0) then { [_hitPoint, 3] call CBA_fnc_substr } else { _hitPoint diff --git a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf index b90e44e8e6..08ca639a20 100644 --- a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf +++ b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf @@ -35,7 +35,7 @@ private _processedSelections = []; { private _selection = _x; - private _hitpoint = toLower (_hitPoints select _forEachIndex); + private _hitpoint = toLowerANSI (_hitPoints select _forEachIndex); private _isWheelOrTrack = _selection in _wheelHitSelections || {_hitpoint in _wheelHitPoints} || {_hitpoint in TRACK_HITPOINTS}; if (_hitpoint isEqualTo "") then { // skip empty hitpoint diff --git a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf index 347c3878d7..5d655887c6 100644 --- a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf +++ b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf @@ -68,7 +68,7 @@ private _wheelHitPointSelections = []; { if (_x != "") then { //Filter out things that definitly aren't wheeels (#3759) - if ((toLower (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; + 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; diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index b537963e0f..9e6a692fef 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -172,7 +172,7 @@ if (vehicle _caller == _caller && {_callerAnim != ""}) then { } else { _caller setVariable [QGVAR(repairPrevAnimCaller), animationState _caller]; }; - _caller setVariable [QGVAR(repairCurrentAnimCaller), toLower _callerAnim]; + _caller setVariable [QGVAR(repairCurrentAnimCaller), toLowerANSI _callerAnim]; [_caller, _callerAnim] call EFUNC(common,doAnimation); }; }; diff --git a/addons/repair/functions/fnc_setHitPointDamage.sqf b/addons/repair/functions/fnc_setHitPointDamage.sqf index bfce0e3f5e..0a6051e084 100644 --- a/addons/repair/functions/fnc_setHitPointDamage.sqf +++ b/addons/repair/functions/fnc_setHitPointDamage.sqf @@ -44,7 +44,7 @@ private _hitPointDamageRepaired = 0; //positive for repairs : newSum = (oldSum - if ((!isNil {_vehicle getHit _selectionName}) && {_x != ""}) then { _realHitpointCount = _realHitpointCount + 1; - if ((((toLower _x) find "glass") == -1) && {(getText (configOf _vehicle >> "HitPoints" >> _x >> "depends")) in ["", "0"]}) then { + if (!("glass" in (toLowerANSI _x)) && {(getText (configOf _vehicle >> "HitPoints" >> _x >> "depends")) in ["", "0"]}) then { _hitPointDamageSumOld = _hitPointDamageSumOld + (_allHitPointDamages select _forEachIndex); if (_forEachIndex == _hitPointIndex) then { _hitPointDamageRepaired = (_allHitPointDamages select _forEachIndex) - _hitPointDamage; diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 10a5fa3a0b..4d2f84eea5 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -44,6 +44,7 @@ Ruota 바퀴 Roue + Колесо Change Wheel @@ -279,6 +280,7 @@ Coefficiente di riparazione completa 전체 수리 시간 계수 Coefficient du temps de réparation complète + Коэффициент времени полного ремонта Modifies how long it takes to perform a Full Repair.\nThe repair time is based on the amount of repairs needed for each part, including those normally inaccessible. @@ -288,6 +290,7 @@ Ändert, wie lange es dauert, eine vollständige Reparatur durchzuführen.\nDie Reparaturzeit basiert auf der Menge der erforderlichen Reparaturen für jedes Teil, einschließlich derjenigen, die normalerweise nicht zugänglich sind. 전체적인 수리를 수행하는 데 걸리는 시간을 수정합니다.\n수리 시간은 일반적으로 접근할 수 없는 부품을 포함하여 각 부품에 필요한 수리 시간을 기준으로 합니다. Modifie la durée que prend une réparation complète.\nLe temps de réparation est basé sur la quantité de réparations requises pour chaque partie, incluant celles qui sont normalement inaccessibles. + Изменяет время, необходимое для выполнения полного ремонта.\nВремя ремонта зависит от объема ремонтных работ, необходимых для каждой детали, включая те, которые обычно недоступны. Boost engineer training when in repair vehicles or facilities. Untrained becomes engineer, engineer becomes advanced engineer. @@ -311,7 +314,7 @@ Lugares de reparación completa Luoghi Riparazione Completa Endroits pour réparation complète - 完全修理できる場所 + 完全修理可能な場所 완전수리 구역 完整维修地点 完整維修地點 @@ -1283,6 +1286,7 @@ Zezwól na Łatanie Kół 바퀴 수리 허용 Autoriser le rafistolage des roues + Разрешить починить колесо Who can patch wheels? @@ -1292,6 +1296,7 @@ Kto może łatać koła? 누가 바퀴를 수리할 수 있습니까? Qui peut rafistoler les roues ? + Кто может починить колеса? Allow Repair @@ -1951,6 +1956,7 @@ Wymagania do Łatania Koła 바퀴 수리 아이템 필요 Exigences pour rafistoler une roue + Требования для починки колеса Items required to patch a wheel. @@ -1960,6 +1966,7 @@ Przedmioty wymagane do załatania koła 바퀴를 수리하기 위해 아이템이 필요합니다. Equipements requis pour rafistoler une roue. + Предметы, необходимые для починки колеса. Misc Repair Requirements @@ -2134,6 +2141,7 @@ Teilreparaturzeit 부품 수리 시간 Temps de réparation des pièces + Время ремонта детали Time in seconds to complete a repair. @@ -2143,6 +2151,7 @@ Zeit in Sekunden, um eine Reparatur abzuschließen. 수리를 완료하는 시간(초 단위) Durée en secondes pour terminer une réparation. + Время завершения ремонта в секундах. Wheel Change Time @@ -2152,6 +2161,7 @@ Radwechselzeit 바퀴 교체 시간 Temps de changement d'une roue + Время замены колеса Time in seconds to remove or change a wheel. @@ -2161,6 +2171,7 @@ Zeit in Sekunden, um ein Rad zu entfernen oder zu wechseln. 바퀴를 제거하거나 교체하는 데 걸리는 시간(초 단위) Durée en seconde pour enlever ou changer une roue. + Время в секундах на снятие или замену колеса. Patch Wheel @@ -2170,6 +2181,7 @@ Załataj Koło 바퀴 수리 Rafistoler la roue + Чинить колесо Patching Wheel... @@ -2179,6 +2191,7 @@ Łatanie Koła... 바퀴 수리 중... Rafistolage de la roue... + Починка колеса... Wheel Patch Time @@ -2188,6 +2201,7 @@ Zeit um Räder zu flicken 바퀴 수리 시간 Temps de rafistolage d'une roue + Время починки полеса Time it takes to patch a wheel by 5%. @@ -2197,6 +2211,7 @@ Zeit, die benötigt wird, um ein Rad um 5 % zu flicken. 바퀴를 5% 수리하는 데 걸리는 시간(초 단위) Durée pour rafistoler une roue de 5%. + Время, необходимое для починки колеса, сокращается на 5%. Patch Wheel Threshold @@ -2206,33 +2221,37 @@ Rad flicken Schwellenwert 바퀴 수리 한계점 Seuil de rafistolage d'une roue + Порог починки колеса - Maximum level to which a wheel can be patched. - タイヤを補修できる最大の度合い。 - Maksymalny poziom, do którego koło może zostać załatane. + Maximum damage to which a wheel can be patched.\n0% means all damage can be repaired. + タイヤをのダメージ補修できる最大の度合い。/n 0%は、すべてのダメージが修復可能であることを意味します。 + Maksymalny poziom, do którego koło może zostać załatane.\n0% oznacza że każde uszkodzenia mogą być naprawione. Livello di integrità massimo di una ruota rattoppata. - Maximales Level, bis zu dem ein Rad geflickt werden kann. + Maximales Level, bis zu dem ein Rad geflickt werden kann.\n0% bedeutet, dass das Rad vollständig repariert werden kann. 바퀴를 수리할 수 있는 최대 레벨입니다. - Niveau maximum de rafistolage d'une roue. + Niveau maximum de dégâts jusqu'à laquelle une roue peut être réparée.\n0% signifie que la roue peut être reparée entièrement. + Максимальный уровень, до которого колесо может быть починено. Wheel Patch Location - タイヤ補修場所 + タイヤ補修可能な場所 Miejsce Łatania Koła Luoghi rattoppamento ruote Räder Flick Ort 바퀴 수리 장소 Lieu de rafistolage des roues + Место починки колеса Where the wheel can be patched. - タイヤを補修できる場所。 + タイヤを補修することが出来る場所。 Gdzie można załatać koło. In quali luoghi è possibile rattoppare una ruota? Wo das Rad geflickt werden kann. 바퀴를 수리할 수 있는 곳입니다. Lieu où les roues peuvent être rafistolées. + Где колесо можно починить. On the ground @@ -2242,6 +2261,7 @@ Na ziemi 지면 위 Sur le terrain + На земле On a vehicle @@ -2251,6 +2271,7 @@ Na pojeździe 차량 Sur un véhicule + На транспорте diff --git a/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf b/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf index 30c4dfd59c..257e5864f6 100644 --- a/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/safemode/functions/fnc_playChangeFiremodeSound.sqf @@ -34,7 +34,7 @@ if (_filename == "") exitWith { }; // add file extension .wss as default -if !(toLower (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { +if !(toLowerANSI (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { _filename = format ["%1.wss", _filename]; }; diff --git a/addons/smallarms/CfgWeapons.hpp b/addons/smallarms/CfgWeapons.hpp index 1e4be69369..7b569d4292 100644 --- a/addons/smallarms/CfgWeapons.hpp +++ b/addons/smallarms/CfgWeapons.hpp @@ -191,6 +191,9 @@ class CfgWeapons { class LMG_03_F: LMG_03_Base_F { magazineReloadTime = 0; // Fix for reloading every time weapon is equipped }; + class LMG_03_Vehicle_F: LMG_03_F { + magazineReloadTime = 5.8; // Should be same as LMG_03_Base_F + }; // Sniper and anti-materiel rifles ///////////////////////////////// diff --git a/addons/spectator/functions/fnc_compat_spectatorBI.sqf b/addons/spectator/functions/fnc_compat_spectatorBI.sqf index 3d982830a0..9bf39ec256 100644 --- a/addons/spectator/functions/fnc_compat_spectatorBI.sqf +++ b/addons/spectator/functions/fnc_compat_spectatorBI.sqf @@ -18,7 +18,7 @@ */ private _respawn = getMissionConfigValue ["respawn",0]; -if (_respawn isEqualType "") then { _respawn = ["","bird","","","group","side"] find (toLower _respawn); }; +if (_respawn isEqualType "") then { _respawn = ["","bird","","","group","side"] find (toLowerANSI _respawn); }; if !(_respawn in [1,4,5]) exitWith {}; // Remember to check for side specific templates diff --git a/addons/tagging/XEH_preStart.sqf b/addons/tagging/XEH_preStart.sqf index 9303bdb135..e1ac396c48 100644 --- a/addons/tagging/XEH_preStart.sqf +++ b/addons/tagging/XEH_preStart.sqf @@ -12,7 +12,7 @@ private _vehicleClasses = "(configName _x) isKindOf 'Static'" configClasses (con private _model = getText (_x >> "model"); if (_model != "") then { private _array = _model splitString "\"; - _cacheStaticModels pushBackUnique toLower (_array select ((count _array) - 1)); + _cacheStaticModels pushBackUnique toLowerANSI (_array select -1); }; } forEach _vehicleClasses; @@ -24,7 +24,7 @@ private _cfgBase = configFile >> "CfgNonAIVehicles"; private _model = getText (_x >> "model"); if (_model != "") then { private _array = _model splitString "\"; - _cacheStaticModels pushBackUnique toLower (_array select ((count _array) - 1)); + _cacheStaticModels pushBackUnique toLowerANSI (_array select -1); }; } forEach (_nonaivehicleClasses select {(configName _x) isKindOf ["Bridge_base_F", _cfgBase]}); diff --git a/addons/tagging/stringtable.xml b/addons/tagging/stringtable.xml index 34445fab21..4d32fac6d6 100644 --- a/addons/tagging/stringtable.xml +++ b/addons/tagging/stringtable.xml @@ -383,6 +383,7 @@ Marcatore identificativo sui veicoli 차량 ID 마킹 Marquage ID des véhicules + Идентификационная маркировка транспортного средства Replaces clan tag with stenciled text @@ -392,6 +393,7 @@ Sostituisce l'icona del clan con testo in stampatello 클랜 태그를 스텐실 텍스트로 바꿉니다. Remplace le tag du clan par un texte au pochoir + Заменяет тег клана трафаретным текстом diff --git a/addons/towing/functions/fnc_isSuitableSimulation.sqf b/addons/towing/functions/fnc_isSuitableSimulation.sqf index 6df9c3d40e..a4131e6a91 100644 --- a/addons/towing/functions/fnc_isSuitableSimulation.sqf +++ b/addons/towing/functions/fnc_isSuitableSimulation.sqf @@ -22,4 +22,4 @@ private _simulationType = getText ((configOf _target) >> "simulation"); // TRACE_1("sim type",_simulationType); // Biki lies, you can both tow and tow as either TankX or CarX -(toLower _simulationType) in ["tankx", "carx", "shipx"] +(toLowerANSI _simulationType) in ["tankx", "carx", "shipx"] diff --git a/addons/towing/functions/fnc_towStateMachinePFH.sqf b/addons/towing/functions/fnc_towStateMachinePFH.sqf index c3b7e19720..50afdeb153 100644 --- a/addons/towing/functions/fnc_towStateMachinePFH.sqf +++ b/addons/towing/functions/fnc_towStateMachinePFH.sqf @@ -51,7 +51,7 @@ private _exitCondition = !( || {getPosASLW _unit select 2 < -1.5} // walking-to-swimming animation in wetsuit lasts for 3 seconds } && { [_unit, objNull, [INTERACTION_EXCEPTIONS]] call EFUNC(common,canInteractWith) } && - { "unconscious" isNotEqualTo toLower animationState _unit } && + { "unconscious" isNotEqualTo toLowerANSI animationState _unit } && { !(_unit getVariable ["ACE_isUnconscious", false]) } && { ACE_player == _unit } ); diff --git a/addons/ui/XEH_clientInit.sqf b/addons/ui/XEH_clientInit.sqf index 66aa0b3650..8f6a3b8ada 100644 --- a/addons/ui/XEH_clientInit.sqf +++ b/addons/ui/XEH_clientInit.sqf @@ -40,7 +40,7 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; if (_name in ELEMENTS_BASIC) then { [true] call FUNC(setElements); } else { - private _nameNoPrefix = toLower (_name select [7]); + private _nameNoPrefix = toLowerANSI (_name select [7]); private _cachedElement = GVAR(configCache) getVariable _nameNoPrefix; if (!isNil "_cachedElement") then { [_nameNoPrefix, _value, true] call FUNC(setAdvancedElement); diff --git a/addons/ui/functions/fnc_compileConfigUI.sqf b/addons/ui/functions/fnc_compileConfigUI.sqf index 17eaa27308..ef6ec1026a 100644 --- a/addons/ui/functions/fnc_compileConfigUI.sqf +++ b/addons/ui/functions/fnc_compileConfigUI.sqf @@ -17,7 +17,7 @@ { private _failure = false; - private _class = toLower (configName _x); + private _class = toLowerANSI (configName _x); private _idd = getNumber (_x >> "idd"); diff --git a/addons/ui/functions/fnc_setElementVisibility.sqf b/addons/ui/functions/fnc_setElementVisibility.sqf index 89b8684af7..f7f8dccd0c 100644 --- a/addons/ui/functions/fnc_setElementVisibility.sqf +++ b/addons/ui/functions/fnc_setElementVisibility.sqf @@ -29,7 +29,7 @@ if (_source == "" || {_element == ""}) exitWith { WARNING("Source or Element may not be empty strings!"); }; -_element = toLower _element; +_element = toLowerANSI _element; // Verify element is bound private _cachedElement = GVAR(configCache) getVariable _element; diff --git a/addons/vehicle_damage/functions/fnc_addEventHandler.sqf b/addons/vehicle_damage/functions/fnc_addEventHandler.sqf index 3697ff2cf9..a7e59c75a1 100644 --- a/addons/vehicle_damage/functions/fnc_addEventHandler.sqf +++ b/addons/vehicle_damage/functions/fnc_addEventHandler.sqf @@ -35,7 +35,7 @@ private _slatHitpoints = [_vehicleConfig >> QGVAR(slatHitpoints), "ARRAY", []] c { _x params ["_hitpoints", "_type"]; { - [_hitpointHash, toLower _x, [_type, _hitpointsConfig >> _x, _x]] call CBA_fnc_hashSet; + [_hitpointHash, toLowerANSI _x, [_type, _hitpointsConfig >> _x, toLowerANSI _x]] call CBA_fnc_hashSet; } forEach _hitpoints; } forEach ALL_HITPOINTS; @@ -45,7 +45,7 @@ _vehicle setVariable [QGVAR(hitpointHash), _hitpointHash]; private _iterateThroughConfig = { params ["_vehicle", "_config", "_iterateThroughConfig", "_hitpointAliases"]; TRACE_1("checking config",_config); - private _configName = configName _config; + private _configName = toLowerANSI configName _config; private _isGun = ([_config >> "isGun", "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1; private _isTurret = ([_config >> "isTurret", "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1; private _isEra = _configName in _eraHitpoints; @@ -53,18 +53,18 @@ private _iterateThroughConfig = { private _isMisc = false; // prevent incompatibilites with old mods - if ((toLower _configName) isEqualTo "hitturret") then { + if (_configName isEqualTo "hitturret") then { _isTurret = true; }; - if ((toLower _configName) isEqualTo "hitgun") then { + if (_configName isEqualTo "hitgun") then { _isGun = true; }; private _hash = _vehicle getVariable QGVAR(hitpointHash); { _x params ["_hitType", "_hitPoints"]; - if ((toLower _configName) in _hitPoints) then { - [_hash, toLower _configName, [_hitType, _config, _configName]] call CBA_fnc_hashSet; + if (_configName in _hitPoints) then { + [_hash, _configName, [_hitType, _config, _configName]] call CBA_fnc_hashSet; _isMisc = true; }; } forEach _hitpointAliases; @@ -72,16 +72,16 @@ private _iterateThroughConfig = { if (_isGun || _isTurret || _isEra || _isSlat || _isMisc) then { TRACE_6("found gun/turret/era/slat/misc",_isGun,_isTurret,_isEra,_isSlat,_isMisc,_hash); if (_isGun) then { - [_hash, toLower _configName, ["gun", _config, _configName]] call CBA_fnc_hashSet; + [_hash, _configName, ["gun", _config, _configName]] call CBA_fnc_hashSet; }; if (_isTurret) then { - [_hash, toLower _configName, ["turret", _config, _configName]] call CBA_fnc_hashSet; + [_hash, _configName, ["turret", _config, _configName]] call CBA_fnc_hashSet; }; if (_isEra) then { - [_hash, toLower _configName, ["era", _config, _configName]] call CBA_fnc_hashSet; + [_hash, _configName, ["era", _config, _configName]] call CBA_fnc_hashSet; }; if (_isSlat) then { - [_hash, toLower _configName, ["slat", _config, _configName]] call CBA_fnc_hashSet; + [_hash, _configName, ["slat", _config, _configName]] call CBA_fnc_hashSet; }; _vehicle setVariable [QGVAR(hitpointHash), _hash]; } else { diff --git a/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf b/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf index 813e97a766..4e847c2d36 100644 --- a/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf +++ b/addons/vehicle_damage/functions/fnc_calculatePenetrationInfo.sqf @@ -83,7 +83,7 @@ _projectileData params ["_projectileType", "_projectileConfig"]; private _enabled = ([_hitpointConfig >> QGVAR(enabled), "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1; #define MATERIAL_ARRAY ([[0, 0, 0, 0, 0, 0], "steel", [7850, 500, 1.104, 9874, 0.3598, -0.2342], "tungsten", [19300, 0, 0.994, 134.5, -0.148], "depleted_uranium", [18600, 0, 0.825, 90, -0.0849]]) private _rodMaterialStr = [_projectileConfig >> QGVAR(material), "STRING", "tungsten"] call CBA_fnc_getConfigEntry; -private _rodMaterialParams = MATERIAL_ARRAY select (1 + MATERIAL_ARRAY find toLower _rodMaterial); +private _rodMaterialParams = MATERIAL_ARRAY select (1 + MATERIAL_ARRAY find toLowerANSI _rodMaterial); if !(_enabled) exitWith { [false, 0, 0, 0, 0] }; if (_rodMaterialParams isEqualTo [0, 0, 0, 0, 0, 0]) exitWith { [] }; diff --git a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf index a6e7335542..7cf6337796 100644 --- a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf +++ b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf @@ -40,7 +40,7 @@ if (!_alreadyCookingOff && { _chanceOfFire >= random 1 }) exitWith { private _detonateAfterCookoff = (_fireDetonateChance / 4) > random 1; private _source = ""; - if (toLower _hitPart isEqualTo "engine") then { + if (_hitPart == "engine") then { _source = ["hit_engine_point", "HitPoints"]; }; diff --git a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf index 01f098efb0..e18d8a3814 100644 --- a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf @@ -34,7 +34,7 @@ if !(alive _vehicle) exitWith { true }; -_hitPoint = toLower _hitPoint; +_hitPoint = toLowerANSI _hitPoint; private _hitpointHash = _vehicle getVariable [QGVAR(hitpointHash), []]; private _type = if (_hitpointHash isEqualTo []) then { "exit" diff --git a/addons/viewports/functions/fnc_eachFrame.sqf b/addons/viewports/functions/fnc_eachFrame.sqf index 6bb452baad..068a5edcf5 100644 --- a/addons/viewports/functions/fnc_eachFrame.sqf +++ b/addons/viewports/functions/fnc_eachFrame.sqf @@ -36,7 +36,7 @@ if (cba_events_control) then { _shownIndex = -1; }; - ([_player] call FUNC(getSeatInfo)) params ["_role", "", "", "_comparment"]; + ([_player] call FUNC(getSeatInfo)) params ["_role", "", "", "_compartment"]; private _newIndexAngle = 45; // Controls the max angle private _eyesPosASL = AGLtoASL (positionCameraToWorld [0, 0, 0]); @@ -52,8 +52,8 @@ if (cba_events_control) then { #endif if ( (_viewAngle < _newIndexAngle) - && {(_compartments isEqualTo []) || {(toLower _comparment) in _compartments}} - && {(_roles isEqualTo []) || {(toLower _role) in _roles}} + && {(_compartments isEqualTo []) || {(toLowerANSI _compartment) in _compartments}} + && {(_roles isEqualTo []) || {(toLowerANSI _role) in _roles}} && {(vectorMagnitude _viewDiff) < _maxDistance} ) then { _newIndex = _forEachIndex; diff --git a/addons/viewports/functions/fnc_getViewports.sqf b/addons/viewports/functions/fnc_getViewports.sqf index 32f97e18f6..744b973151 100644 --- a/addons/viewports/functions/fnc_getViewports.sqf +++ b/addons/viewports/functions/fnc_getViewports.sqf @@ -61,9 +61,9 @@ if (isNil "_viewports") then { _maxDistance = 0.8; }; // compartments [ARRAY] - Optional - private _compartments = (getArray (_x >> "compartments")) apply {toLower _x}; + private _compartments = (getArray (_x >> "compartments")) apply {toLowerANSI _x}; // roles [ARRAY] - Optional - private _roles = (getArray (_x >> "roles")) apply {toLower _x}; + private _roles = (getArray (_x >> "roles")) apply {toLowerANSI _x}; [_name, _type, _camLocation, _camAttach, _screenLocation, _maxDistance, _compartments, _roles] }; diff --git a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf index 2be2d740ea..fc55b54b5f 100644 --- a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf @@ -30,7 +30,7 @@ _sound params ["_filename", ["_volume", 1], ["_soundPitch", 1], ["_distance", 0] if (_filename == "") exitWith {}; // add file extension .wss as default -if !(toLower (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { +if !(toLowerANSI (_filename select [count _filename - 4]) in [".wav", ".ogg", ".wss"]) then { _filename = format ["%1.wss", _filename]; }; diff --git a/addons/weather/XEH_PREP.hpp b/addons/weather/XEH_PREP.hpp index 5f17905849..220a18ef3c 100644 --- a/addons/weather/XEH_PREP.hpp +++ b/addons/weather/XEH_PREP.hpp @@ -1,9 +1,9 @@ - PREP(calculateAirDensity); PREP(calculateBarometricPressure); PREP(calculateDensityAltitude); PREP(calculateDewPoint); PREP(calculateHeatIndex); +PREP(calculateOxygenDensity); PREP(calculateRoughnessLength); PREP(calculateSpeedOfSound); PREP(calculateTemperatureAtHeight); diff --git a/addons/weather/functions/fnc_calculateOxygenDensity.sqf b/addons/weather/functions/fnc_calculateOxygenDensity.sqf new file mode 100644 index 0000000000..542b4b2f10 --- /dev/null +++ b/addons/weather/functions/fnc_calculateOxygenDensity.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Calculates the oxygen density + * + * Arguments: + * 0: Temperature - °C + * 1: Pressure - hPa + * 2: Relative humidity - value between 0.0 and 1.0 + * + * Return Value: + * Density of oxygen - kg * m^(-3) + * + * Example: + * [0, 1020] call ace_weather_fnc_calculateOxygenDensity + * + * Public: No + */ + +(_this call FUNC(calculateAirDensity)) * 0.21 diff --git a/addons/weather/functions/fnc_getMapData.sqf b/addons/weather/functions/fnc_getMapData.sqf index d80573c286..c1cae6e2f8 100644 --- a/addons/weather/functions/fnc_getMapData.sqf +++ b/addons/weather/functions/fnc_getMapData.sqf @@ -15,7 +15,7 @@ * Public: No */ -private _worldName = toLower worldName; +private _worldName = toLowerANSI worldName; TRACE_1("getting map data",_worldName); // Set default values diff --git a/addons/yardage450/XEH_postInit.sqf b/addons/yardage450/XEH_postInit.sqf index 2959360f7d..1f3cb1a1cf 100644 --- a/addons/yardage450/XEH_postInit.sqf +++ b/addons/yardage450/XEH_postInit.sqf @@ -1,5 +1,7 @@ #include "script_component.hpp" +if (!hasInterface) exitWith {}; + #include "initKeybinds.inc.sqf" GVAR(active) = false; diff --git a/addons/zeus/functions/fnc_bi_moduleProjectile.sqf b/addons/zeus/functions/fnc_bi_moduleProjectile.sqf index 135ed538cd..ba30a2eaf4 100644 --- a/addons/zeus/functions/fnc_bi_moduleProjectile.sqf +++ b/addons/zeus/functions/fnc_bi_moduleProjectile.sqf @@ -42,7 +42,7 @@ if (_activated) then { _posAmmo = +_pos; _posAmmo set [2,0]; _dir = direction _logic; - _simulation = tolower gettext (configfile >> "cfgammo" >> _ammo >> "simulation"); + _simulation = toLowerANSI gettext (configfile >> "cfgammo" >> _ammo >> "simulation"); _altitude = 0; _velocity = []; _attach = false; diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index 6f163b46be..bb78c86c1a 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -1320,6 +1320,7 @@ Scarica dal carico 貨物室から降ろす 화물 내리기 + Выгрузить из отсека Toggle NVGs @@ -1964,6 +1965,7 @@ Il Menù Medico è disabilitato 医療メニューは無効になっています 의료 메뉴가 비활성화되었습니다 + Медицинское меню отключено Lay Trenchline @@ -1973,6 +1975,7 @@ Grabenlinie legen Piazza Trincea 塹壕溝線を敷設 + Проложить траншею +SHIFT to force (Can only lay N/S or E/W) @@ -1982,6 +1985,7 @@ +SHIFT zum Erzwingen (Kann nur nach N/S oder E/W legen) +SHIFT per forzare (Può piazzare solo N/S o E/O +SHIFTキー で強制的に敷設 (北/南または東/西方向にのみ配置可能) + +SHIFT на принудительное (может укладываться только на Север/Юг или Восток/Запад) diff --git a/docs/img/wiki/feature/atragmx1.webp b/docs/img/wiki/feature/atragmx1.webp deleted file mode 100644 index 809f44a6c0..0000000000 Binary files a/docs/img/wiki/feature/atragmx1.webp and /dev/null differ diff --git a/docs/img/wiki/feature/atragmx1ab.webp b/docs/img/wiki/feature/atragmx1ab.webp new file mode 100644 index 0000000000..7a71559f24 Binary files /dev/null and b/docs/img/wiki/feature/atragmx1ab.webp differ diff --git a/docs/img/wiki/feature/atragmx1db.webp b/docs/img/wiki/feature/atragmx1db.webp new file mode 100644 index 0000000000..0bf6bc71f7 Binary files /dev/null and b/docs/img/wiki/feature/atragmx1db.webp differ diff --git a/docs/team.md b/docs/team.md index f8fe165bf9..d5d9d03bfa 100644 --- a/docs/team.md +++ b/docs/team.md @@ -11,6 +11,8 @@ This page lists all current maintainers for the ACE3 projects with their areas o This lists all the maintainers responsible for project management and the overall direction of the ACE3 project. +- [BaerMitUmlaut](https://github.com/BaerMitUmlaut){:target="_blank"} + - Scripting, Config - [bux](https://github.com/bux){:target="_blank"} - Scripting, Testing - [Felix Wiegand](https://github.com/koffeinflummi){:target="_blank"} @@ -23,13 +25,13 @@ This lists all the maintainers responsible for project management and the overal - Coding, Modeling, Performance, SME - [PabstMirror](https://github.com/PabstMirror){:target="_blank"} - Scripting, Config +- [veteran29](https://github.com/veteran29){:target="_blank"} + - Scripting, Config - [ViperMaul](https://github.com/vipermaul){:target="_blank"} - Project management ## Core Maintainers -- [BaerMitUmlaut](https://github.com/BaerMitUmlaut){:target="_blank"} - - Scripting, Config - [commy2](https://github.com/commy2){:target="_blank"} - Scripting, Config - [esteldunedain](https://github.com/esteldunedain){:target="_blank"} @@ -58,18 +60,19 @@ This lists all the maintainers responsible for project management and the overal - gundy - Janus - [johnb43](https://github.com/johnb432){:target="_blank"} +- [Kex](https://github.com/kexanone){:target="_blank"} - [Kieran](https://github.com/kieran-s){:target="_blank"} - [mharis001](https://github.com/mharis001){:target="_blank"} - [tcvm](https://github.com/TheCandianVendingMachine){:target="_blank"} - [TheMagnetar](https://github.com/TheMagnetar){:target="_blank"} - Scripting - tpM -- [veteran29](https://github.com/veteran29){:target="_blank"} ## Moderators - [drofseh](https://github.com/Drofseh){:target="_blank"} - [MikeMF](https://github.com/Mike-MF){:target="_blank"} +- [MiszczuZPolski](https://github.com/MiszczuZPolski){:target="_blank"} ## Contributors diff --git a/docs/wiki/feature/atragmx.md b/docs/wiki/feature/atragmx.md index 2f778f222a..7a3b54d64e 100644 --- a/docs/wiki/feature/atragmx.md +++ b/docs/wiki/feature/atragmx.md @@ -22,7 +22,7 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r ## 2. Requirement -- [Advanced Ballistics module enabled]({{ site.baseurl }}/wiki/feature/advanced-ballistics.html) +- [Advanced Ballistics enabled]({{ site.baseurl }}/wiki/feature/advanced-ballistics.html) ## 3. Usage @@ -31,9 +31,9 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r #### 3.1.1 Interaction Menu -- Open the self interaction menu Ctrl + ⊞ Win -- Select `Equipment` -- Select `Open AtragMx` +- Open the self interaction menu Ctrl + ⊞ Win. +- Select `Equipment`. +- Select `Open AtragMx`. #### 3.1.2 Custom key @@ -43,43 +43,66 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r **Start of the mission:** -- Open the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) and check the cartridge, the zeroed distance, the rifle twist, the muzzle velocity at 15°C and the bore height. +- Open the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) and check the ammunition: bullet diameter, bullet weight, rifle twist, muzzle velocity at 15°C, zeroed distance and bore height. -Range card +Range card -- Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=15) -- `Open Gun` the 7.62x51mm M80 in the `GunList`. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=25) -- Select `E` (English unit) at the top right. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=10) -- Open the `Gun` column, check and update the `Bore`, the `Rifle Twist` and `Done`. +- Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`. +- `Open Gun` the 7.62x51mm M80 in the `GunList`. +- Select `E` (English unit) at the top right. +- Open the `Gun` column, check and update the `Bore (inches)`, `Bullet Weight (grains)`, `Bullet Diam (inches)`, `Rifle Twist (in/trn)` and `Done`. - Select `M` (Metric unit) at the top right. -- Open the `Gun` column, check and update the `Muzzle Velocity`, the `Zero Range` and `Done`. -- *The Muzzle Velocity Table will be automatically updated.* [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=22) -- *(Must be edited manually for specific cartridges according with the range card)* +- Open the `Gun` column, check and update the `Muzzle Velocity (m/s)`, the `Zero Range (meters)` and `Done`. +- *Muzzle Velocities (`Options` / `Muz Vel table`) may need a manual update according to the range card.* +- *AtragMx is configured with `C1 coefficient` according to vanilla weapons and its ammunitions in `GunList`.* +- *More information about C1: [Example with `Add New Gun` in `GunList`](#35-example-with-add-new-gun-in-gunlist).* +- Check `Elev` = 0 with `ZR` = `TR` *(if not, open `Gun` column and `Done`)*. - Optionally, `Save Gun` and `Done` in the `GunList`. - + **In position:** -- Update the `Atmsphr` column with the [Kestrel 4500]({{ site.baseurl }}/wiki/feature/kestrel4500.html) and `Done`. +- Update the `Atmsphr` column and `Done`. Requirement: [Kestrel 4500]({{ site.baseurl }}/wiki/feature/kestrel4500.html). - *Check the new `Muzzle Velocity` in the `Gun` column.* -- Update the `Target` column (the [wind arrow]({{ site.baseurl }}/wiki/feature/weather.html) will also help). [[1]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=16) [[2]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=30) [[3]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=32) [[4]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=33) -- *The latitude for all common maps can be found in the [ACE3 Github]({{ site.ace.githubUrl }}/blob/master/addons/common/functions/fnc_getMapData.sqf).* -- Apply the vertical and horizontal elevations on the [scope]({{ site.baseurl }}/wiki/feature/scopes.html). -- Control the breath and press. - +- Update the `Target` column and `Done`. Requirement: [Wind arrow]({{ site.baseurl }}/wiki/feature/weather.html), [Protractor]({{ site.baseurl }}/wiki/feature/advanced-ballistics#22-protractor), [Map Tools]({{ site.baseurl }}/wiki/feature/maptools.html). For advanced tools: [ACE3 Equipment]({{ site.baseurl }}/wiki/feature.html). + - `Latitude`: *[ACE3 Github]({{ site.ace.githubUrl }}/blob/master/addons/common/functions/fnc_getMapData.sqf) or Eden Editor's Extended Debug Console: Watch:* `ace_common_maplatitude`. + - `Dir of Fire (deg from N)`: *The value is therefore given as the direction of the barrel axis from true north.* [Horus manual p.14] + - `Wind speed (m/s)`: *Two wind speed values (low and high) may be entered on the target screen,[...] Lead/Wind2 button on the screen.* [Horus manual p.32] + - Wind takes into account geographic location, season, time of day, obstacles, altitude and surface roughness: [Wind Profile](https://wind-data.ch/tools/profile.php?lng=en). + - `Wind Direction (clock)`: *Wind Direction is expressed in clock points.[...], wind is always described in terms of where it is coming from.* [Horus manual p.16] + - `Inclination Angle`: *The degrees field is marked with a “d” and the cosine field with a “c”.* [Horus manual p.33] + - `Target Speed`: *Target Speed Assist* [Horus manual p.21] + - `Target Range (meters)`: *Parameter Limits minimum and maximum values: 25 - 3700 meters.* [Horus manual p.17] +- Apply vertical (Page Up and Down keys as default) and horizontal (Left Ctrl + Page Up and Down keys as default) elevations to the [scope]({{ site.baseurl }}/wiki/feature/scopes.html). +- Hold Breath (Left Shift as default) and Fire (Prim. Mouse. Btn. as default). + ### 3.3 Example with Truing tool -- Open the `Truing Drop` in the `Options` menu. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=23) -- Add the actual `Target Range` in the `SUPER` column and `Calc`. -- Add the same `Target Range` in the `SUB` column and `Calc`. -- Apply the actual scope elevation in the `Drop` field and `Calc`. -- `Accept` the new `C1`, `Gun` column and `Elev` are updated. -- *The Drag Coefficient Table will be automatically updated.* [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=22) -- Optionally, `Save Gun` and `Done` in the `GunList`. - +> This process is called “Truing Drop”, or simply “Truing”. It involves taking 2 or 3 real flight data points (finding bullet drop at 2 or 3 places along its flight) and feeding it into the calculation parameters. [Horus manual p.23] + +> The Truing Drop function is opened from ATrag’s main screen by selecting “Options” [...], then selecting “Truing Drop” from the menu that appears. [Horus manual p.23] + +> With C1, you can also insert the new BC into the C1 table (with the target range value), or you can replace the C1 table with the following values: +> 1. first entry: Zero Range, original C1. +> 2. second entry: range at 75% of distance between transonic start and subsonic start, with original C1. +> 3. third entry: range 200 (y/m) beyond subsonic start, with new calculated C1. [Horus manual p.24] + +- Basic example with ammunition 7.62x51mm G7 ballistic coefficient. + - Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`. + - `Open Gun` a custom profile in the `GunList`. + - *More information about custom profile: [Example with `Add New Gun` in `GunList`](#35-example-with-add-new-gun-in-gunlist).* + - Check `Elev` = 0 with `ZR` = `TR` *(if not, open `Gun` column and `Done`)*. + - Open the `Truing Drop` in the `Options` menu. + - Add the actual `Target Range` in the `SUPER` column and `Calc`. + - Add the same `Target Range` in the `SUB` column and `Calc`. + - Apply the actual scope elevation in the `Drop` field and `Calc`. + - `Accept` the new `C1`, `Gun` column and `Elev` are updated. + - *C1 Ballistic Coefficient vs. Distance Interpolation Table (`Options` / `Drag Coef Table`) will be updated.* + - Optionally, `Save Gun` and `Done` in the `GunList`. + Calculation - -- If a new `Target Range` is applied in the `Target` column, the ballistic coefficient `C1` and the elevation `Elev` will be automatically recalculated. - + +- If a new `Target Range` is applied in the `Target` column, the ballistic coefficient `C1` and the elevation `Elev` will be recalculated. + Interpolation Extrapolation @@ -87,23 +110,26 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r ### 3.4 Example with overwritten zero distance - The `Default zero distance` can be overwritten with the [Scopes Options]({{ site.baseurl }}/wiki/feature/scopes.html), the [Scopes Framework]({{ site.baseurl }}/wiki/framework/scopes-framework.html) or the [CBA Settings System](https://github.com/CBATeam/CBA_A3/wiki/CBA-Settings-System). -- In this case, the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) will be automatically updated, NOT the AtragMx. -- Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=15) +- In this case, the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) will be updated, **NOT the AtragMx**. +- Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`. - Open the `Gun` column, check and update the `Zero Range` and `Done`. - +- Check `Elev` = 0 with `ZR` = `TR` *(if not, open `Gun` column and `Done`)*. +- Optionally, `Save Gun` and `Done` in the `GunList`. + Zero distance 300m ### 3.5 Example with `Add New Gun` in `GunList` -- Open the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) and check the bullet diameter, the bullet weight, the **(bullet Class Name)** and the muzzle velocities. -- Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=15) -- Select `Add New Gun` in the `GunList`. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=25) +- Open the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) and check the ammunition: **bullet Class Name**, bullet diameter, bullet weight, rifle twist, muzzle velocities, zeroed distance and bore height. +- Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`. +- Select `Add New Gun` in the `GunList`. - Add a `New Gun Name` and `Open Gun`. -- Select `E` (English unit) at the top right. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=10) -- Open the `Gun` column, check and update the `Bullet Weight (grains)`, the `Bullet Diam (inches)` and `Done`. +- Select `E` (English unit) at the top right. +- Open the `Gun` column, check and update the `Bore (inches)`, `Bullet Weight (grains)`, `Bullet Diam (inches)`, `Rifle Twist (in/trn)` and `Done`. - Select `M` (Metric unit) at the top right. -- Open the `Muz Vel Table` in the `Options` menu or click on `MV` in the `Gun` column. -- Edit manually the `Muzzle Velocity Table` according with the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) and `Done`. [[Manual]](https://horusvision.com/download/manual_Horus_ATrag-v385.pdf#page=22) +- Open the `Gun` column, check and update the `Zero Range (meters)` and `Done`. +- Open the `Muz Vel Table` in the `Options` menu or click on `MV` in the `Gun` column. +- Edit manually the `Muzzle Velocity Table` according to the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) and `Done`. - The `C1 coefficient` of the bullet can be found with the Eden Editor `Config Viewer`: > configfile >> "CfgAmmo" >> "**bullet Class Name**" >> "ACE_ballisticCoefficients" @@ -112,26 +138,92 @@ Horus ATragMX software considers atmospheric conditions, gun data, ammunition, r - *The AtragMx accepts only **G1 ballistic coefficient**.* - *G7 ballistic coefficient can be converted, for example, with the online [JBM Ballistics Calculators](http://www.jbmballistics.com/cgi-bin/jbmgf-5.1.cgi)*. +- Check `Elev` = 0 with `ZR` = `TR` *(if not, open `Gun` column and `Done`)*. - Optionally, `Save Gun` and `Done` in the `GunList`. +> Note: The ballistic coefficient can be calculated by using the [360 Degree Training Course mission](#5-resources) as a chronograph at different distances and [JBM Ballistics Calculators](http://www.jbmballistics.com/cgi-bin/jbmbcv-5.1.cgi) for example, an another ballistic software at your own convenience, or the [AtragMx Truing Tool](#33-example-with-truing-tool). -> Note: The ballistic coefficient can be calculated by using the [360 Degree Training Course mission](https://forums.bistudio.com/forums/topic/171228-sp-360-degree-training-course/) as a chronograph at different distances and [JBM Ballistics Calculators](http://www.jbmballistics.com/cgi-bin/jbmbcv-5.1.cgi) for example, an another ballistic software at your own convenience, or the [AtragMx Truing Tool](#33-example-with-truing-tool). - -> Example direct conversion with .408 Cheytac 305 grains G7 BC 0.279 at 2000 meters 15°C: +> Example direct conversion with .408 Cheytac 305 grains, G7 BC 0.279 at 2000 meters, ICAO conditions (15°C, 1013.25hPa, 0%): Conversion G7/G1 BC -### 3.6 Adding ATragMX Presets +### 3.6 Connecting AtragMx with Vector 21 and DAGR -- [ATragMX Framework]({{ site.baseurl }}/wiki/framework/atragmx.html) +- Requirement: [Vector]({{ site.baseurl }}/wiki/feature/vector.html) and [DAGR]({{ site.baseurl }}/wiki/feature/dagr.html). +- Open the self interaction menu Ctrl + ⊞ Win. +- Select `Equipment`. +- Select `Configure DAGR` and `CONNECT TO` (DOWN and HELP/SEL) `Vector 21`(HELP/SEL). +- Equip and use the Vector (B key as default). +- Check target's [slope distance and azimuth]({{ site.baseurl }}/wiki/feature/vector#23-slope-distance-and-azimuth) (hold both R and Tab keys as default). +- Open the [AtragMx properly configured before](#32-example-with-m14-and-default-762mm-20rnd-mag) according to current rifle and ammunition. +- Open the `Target` column: `Dir of Fire (deg from N)`, `Inclination Angle` and `Target Range (meters)` updated with Vector's values. -### 3.7 Reseting the AtragMx `GunList` +### 3.7 Adding AtragMx Presets -- Open the Eden Editor and the Extended Debug Console (Ctrl+D). -- Execute `call ace_atragmx_fnc_clear_user_data` (LOCAL EXEC). +- [AtragMx Framework]({{ site.baseurl }}/wiki/framework/atragmx.html) + +> Scope Base Angle value: +> - Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`. +> - `Open Gun` the custom profile (with an arbitrary scope base angle) in the `GunList`. +> - Check `Elev` value with `ZR` = `TR`. +> - Open the `Gun` column and `Done`. +> - Execute `copyToClipboard Str(ace_atragmx_workingMemory select 3);` [LOCAL EXEC] with the Eden Editor's Extended Debug Console. +> - Paste new value to the `preset`. +> - After new test, check `Elev` = 0 with `ZR` = `TR`. + +### 3.7 Reseting AtragMx `GunList` + +- Open the Eden Editor's Extended Debug Console. +- Execute `call ace_atragmx_fnc_clear_user_data` or `call ace_atragmx_fnc_initGunList` [LOCAL EXEC], (`RESTART` eventually needed). - The original ACE3 `GunList` will be restored (all `Add New Gun` entries deleted). +### 3.8 Example with AtragMx and default ballistic (M14, 7.62mm 20Rnd Mag) + +> Note: ACE3 has two external ballistics, the vanilla default ballistic (enabled as default) and the [Advanced Ballistics]({{ site.baseurl }}/wiki/feature/advanced-ballistics.html) (must be enabled). The ACE3 default ballistic doesn't take atmospheric conditions (except wind), powder temperature, rifle twist and Earth effects into account. The AtragMx will need for `Gun` column: `Bore`, `C1 Coefficient`, `Muzzle Velocity` and `Zero Range`. With `Target` column, `Latitude` and `Dir of Fire` are useless. `Atmsphr` column must not be updated. + +**Start of the mission:** + +- Open the [Range Card]({{ site.baseurl }}/wiki/feature/rangecard.html) and check the ammunition: **bullet Class Name**, muzzle velocity, zeroed distance and bore height. + +Range card + +- Open the AtragMx and the `Atmsphr` column, select `Default` and `Done`. +- Select `E` (English unit) at the top right. +- Open the `Gun` column, check and update the `Bore (inches)` and `Done`. +- Select `M` (Metric unit) at the top right. +- Open the `Gun` column, check and update the `Muzzle Velocity (m/s)`, the `Zero Range (meters)` and `Done`. +- `C1 coefficient` of the bullet = `airFriction x -1000`. +- `airFriction` can be found with the Eden Editor `Config Viewer`: + +> configfile >> "CfgAmmo" >> "**bullet Class Name**" >> "airFriction" + +- *AtragMx is configured with `C1 coefficient` according to vanilla weapons and its ammunitions in `GunList`.* +- *Spin drift and Earth effects not taken into account, `Options` / `Show Coriolis` can be disabled.* +- Check `Elev` = 0 with `ZR` = `TR` *(if not, open `Gun` column and `Done`)*. +- Optionally, `Save Gun` and `Done` in the `GunList`. + +**In position:** + +- **Do not update the `Atmsphr` column.** Default ballistic doesn't take into account temperature, pressure and humidity. +- Update the `Target` column and `Done`. Requirement: [Wind arrow]({{ site.baseurl }}/wiki/feature/weather.html), [Protractor]({{ site.baseurl }}/wiki/feature/advanced-ballistics#22-protractor), [Map Tools]({{ site.baseurl }}/wiki/feature/maptools.html). For advanced tools: [ACE3 Equipment]({{ site.baseurl }}/wiki/feature.html). + - `Wind speed (m/s)`: *Two wind speed values (low and high) may be entered on the target screen,[...] Lead/Wind2 button on the screen.* [Horus manual p.32] + - Wind takes into account geographic location, season, time of day and obstacles. + - `Wind Direction (clock)`: *Wind Direction is expressed in clock points.[...], wind is always described in terms of where it is coming from.* [Horus manual p.16] + - `Inclination Angle`: *The degrees field is marked with a “d” and the cosine field with a “c”.* [Horus manual p.33] + - `Target Speed`: *Target Speed Assist* [Horus manual p.21] + - `Target Range (meters)`: *Parameter Limits minimum and maximum values: 25 - 3700 meters.* [Horus manual p.17] +- Apply vertical (Page Up and Down keys as default) and horizontal (Left Ctrl + Page Up and Down keys as default) elevations to the [scope]({{ site.baseurl }}/wiki/feature/scopes.html). +- Hold Breath (Left Shift as default) and Fire (Prim. Mouse. Btn. as default). + ## 4. Official References -- [Official Manual]({{ site.ace.githubUrl }}/blob/master/extras/manual_Horus_ATrag-v385.pdf) +- [Horus AtragMx Manual]({{ site.ace.githubUrl }}/blob/master/extras/manual_Horus_ATrag-v385.pdf) + + +## 5. Resources + +Missions by Ruthberg, author of Advanced Ballistics and its tools: + +- Arma3 Missions folder: [360 Degree Training Course v1.3]({{ site.ace.githubUrl }}/blob/master/extras/ruthberg_missions/360_Degree_Training_Course-Missions.zip), *[Features](https://forums.bistudio.com/forums/topic/171228-sp-360-degree-training-course/)* +- Eden Editor mission: [360 Degree Training Course Framework]({{ site.ace.githubUrl }}/blob/master/extras/ruthberg_missions/360_Degree_Training_Course-Framework.zip) diff --git a/docs/wiki/feature/explosives.md b/docs/wiki/feature/explosives.md index ec20c0f62f..ec14c4466a 100644 --- a/docs/wiki/feature/explosives.md +++ b/docs/wiki/feature/explosives.md @@ -35,6 +35,7 @@ Enables attaching explosives to vehicles. - Interact with the explosive ⊞ Win (ACE3 default key bind `Interact Key`). - Choose the arming method. - For clackers use Self Interaction `Explosives` → `Detonate` and choose the corresponding Firing Device. +- Alternatively, use Ctrl+Alt+C (ACE3 default key bind `Detonate All on Active Clacker`) to detonate all explosives tied to the `Active Detonator`, which can be changed via the `Set Active Detonator` interaction on the desired Clacker / Dead Man Switch. ### 2.3 Defusing explosives - A `Defusal Kit` is required. diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index 95c7e82211..273a70836f 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -136,8 +136,9 @@ Examples: ACE Arsenal uses 2 existing config entries to sort and display items. -- `baseWeapon`: Class name that is used to display an item in the arsenal. This property can be applied to any weapon or weapon attachment in `CfgWeapons`. +- `baseWeapon`: Class name that is used to display an item in the arsenal, used for weapon/attachment variants that are not normally shown to the player (AI variants, PIP optics, and so on). This property can be applied to any weapon or weapon attachment in `CfgWeapons`. Items using CBA or RHS' Scripted Optics systems, or CBA Switchable Attachments do not need this property explictly set, and will automatically use their player-accessible class. - `ACE_isUnique`: Classes in `CfgMagazines` with this property set to `1` will be treated and shown by the Arsenal as Misc. Items. Used for items with attached data that needs to be kept track of, such as Notepads or Spare Barrels. +- `ACE_asItem`: Classes in `CfgMagazines` with this property set to `1` will be treated and shown by the Arsenal as Items. Used for magazines that are not meant to be used in a weapon, such as Painkillers. ### 3.2 New config entries @@ -159,7 +160,7 @@ ACE Medical Treatment and ACE Field Rations also add their own sub-categories, i - `ACE_isMedicalItem`: Items with this property set to `1` will be sorted to the ACE Medical Tab. - `ACE_isFieldRationItem`: Items with this property set to `1` will be sorted to the ACE Field Rations Tab. -Only Misc. Items will be checked for these properties. Magazines must have ACE_isUnique property. +Only Misc. Items will be checked for these properties. Magazines must have `ACE_isUnique` or `ACE_asItem` property. ## 4. Default loadouts @@ -402,6 +403,8 @@ For actions involving frame delays or timers, a second call of the `ace_arsenal_ Since CBA frame functions are deactivated during preInit as of Oct 24th 2023, the refresh function is executed immediatelly after the action code is executed. Take note of this information and the comment below if you'd like your actions to be usable in 3DEN. +By default actions are updated whenever the arsenal is refreshed (`ace_arsenal_fnc_refresh`) and whenever item info (the bottom right GUI element that shows item name and author) is updated. If any action with the `updateOnCargoChanged` property is added, then actions will also be updated on container inventory changes. + ### 7.1 Adding actions via config ```cpp @@ -410,6 +413,7 @@ class ace_arsenal_actions { displayName = "My Actions"; condition = QUOTE(true); scopeEditor = 2; // Only actions with scopeEditor = 2 are shown in 3DEN. Actions working with variables should take object variables being reset between editor view and mission start into account. + updateOnCargoChanged = 1; // See comment above. tabs[] = {0,5}; class text { // A simple text label @@ -417,6 +421,7 @@ class ace_arsenal_actions { }; class statement { // Statement output as text + // Return can be string or array of strings: for array each entry is automatically displayed on a separate line textStatement = QUOTE([_this select 0] call tag_fnc_myTextStatement); }; class button { @@ -441,6 +446,7 @@ The focused unit object is passed to the condition and statement functions. 3 | Actions | Array of arrays | Required 4 | Condition | Code | Optional (default: `{true}`) 5 | Scope editor | Number | Optional (default: `2`) +6 | Update on cargo change | Boolean | Optional (default: `false`) Return Value: - Array of action IDs @@ -506,6 +512,7 @@ All are local. | ace_arsenal_loadoutsDisplayClosed | None | 3.12.3 | | ace_arsenal_loadoutsTabChanged | loadouts screen display (DISPLAY), tab control (CONTROL) | 3.12.3 | | ace_arsenal_loadoutsListFilled | loadouts screen display (DISPLAY), tab control (CONTROL) | 3.12.3 | +| ace_arsenal_loadoutVerified | loadout data (ARRAY), loadout CBA extended data (HASHMAP), null items (ARRAY), unavailable items (ARRAY), unavailable extended data (ARRAY) | 3.17.0 | | ace_arsenal_weaponItemChanged | weapon classname (STRING), item classname (STRING), item index (NUMBER, 0-5: muzzle, side, optic, bipod, magazine, underbarrel) | 3.16.0 | ## 9. Custom sub item categories diff --git a/docs/wiki/framework/events-framework.md b/docs/wiki/framework/events-framework.md index c29f271719..d8d8674218 100644 --- a/docs/wiki/framework/events-framework.md +++ b/docs/wiki/framework/events-framework.md @@ -42,6 +42,7 @@ The vehicle events will also have the following local variables available `_gunn |`ace_treatmentSucceded` | [_caller, _target, _selectionName, _className, _itemUser, _usedItem] | Local | Listen | Treatment action is completed (local on the _caller) |`ace_treatmentFailed` | [_caller, _target, _selectionName, _className, _itemUser, _usedItem] | Local | Listen | Treatment action has been interrupted (local on the _caller) |`ace_medical_handleUnitVitals` | [_unit, _deltaT] | Local | Listen | Vitals update ran for unit, _deltaT is the time elapsed since the previous vitals update (local to _unit) +|`ace_medical_treatment_bandaged` | [_medic, _patient, _bodyPart, _className, _bandageEffectiveness] | Local | Listen | _medic has bandaged _patient, the array can be modified to change treatment parameters (local to _medic) ### 2.3 Interaction Menu (`ace_interact_menu`) MenuType: 0 = Interaction, 1 = Self Interaction @@ -129,6 +130,22 @@ MenuType: 0 = Interaction, 1 = Self Interaction | `ace_trenches_placed` | [_unit, _trench] | Global | Listen | After trench object is placed by unit. | `ace_trenches_finished` | [_unit, _trench] | Global | Listen | After trench object is fully dug up by unit (100% progress). +### 2.13 Medical GUI (`ace_medical_gui`) + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_medical_gui_updateBodyImage` | [_ctrlGroup, _target, _selectionN] | Local | Listen | Allows mods to update any modifications they have made to the body image +| `ace_medical_gui_updateInjuryListGeneral` | [_ctrl, _target, _selectionN, _entries] | Local | Listen | Allows mods to update the general injury list by pushing to the _entries array +| `ace_medical_gui_updateInjuryListPart` | [_ctrl, _target, _selectionN, _entries, _bodyPartName] | Local | Listen | Allows mods to update the part injury list by pushing to the _entries array +| `ace_medical_gui_updateInjuryListWounds` | [_ctrl, _target, _selectionN, _woundEntries, _bodyPartName] | Local | Listen | Allows mods to update the wounds injury list by pushing to the _woundEntries array +| `ace_medical_gui_logListAppended` | [_ctrl, _row, _message, _unlocalizedMessage, _timeStamp, _arguments] | Local | Listen | After an entry is appended to the log list + +### 2.14 Medical Treatment (`ace_medical_treatment`) + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_medical_treatment_fullHealLocalMod` | [_patient] | Local | Listen | Called before a local unit is fully healed, mods can listen and apply their own healing logic + ## 3. Usage Also Reference [CBA Events System](https://github.com/CBATeam/CBA_A3/wiki/Custom-Events-System){:target="_blank"} documentation. diff --git a/docs/wiki/framework/fire-framework.md b/docs/wiki/framework/fire-framework.md index eec9baf3e5..74b79a7a4f 100644 --- a/docs/wiki/framework/fire-framework.md +++ b/docs/wiki/framework/fire-framework.md @@ -37,3 +37,11 @@ Use `CBA_fnc_serverEvent` to use the following features. Events are defined only | Arguments | Type | Optional (default value) ---| --------- | ---- | ------------------------ 0 | Fire source ID | Array/Boolean/Code/Config/Group/Namespace/NaN/Number/Object/Side/String | Required + +## 2. Variables + +Screams can be disabled for an individual unit by setting the `ace_fire_enableScreams` variable on the unit, which can be synced across machines. + +```sqf +_unit setVariable ["ace_fire_enableScreams", false, _isGlobal]; +``` diff --git a/docs/wiki/framework/fortify-framework.md b/docs/wiki/framework/fortify-framework.md index 3f6619a746..14d48532b5 100644 --- a/docs/wiki/framework/fortify-framework.md +++ b/docs/wiki/framework/fortify-framework.md @@ -116,8 +116,8 @@ The Fortify budget can be updated for any side using the function. Event Name | Passed Parameter(s) | Locality | Description ---------- | ----------- | ------------------- | -------- -`acex_fortify_objectPlaced` | [player, side, objectPlaced] | Global | Foritfy object placed -`acex_fortify_objectDeleted` | [player, side, objectDeleted] | Global | Foritfy object deleted +`acex_fortify_objectPlaced` | [player, side, objectPlaced] | Global | Fortify object placed +`acex_fortify_objectDeleted` | [player, side, objectDeleted] | Global | Fortify object deleted `acex_fortify_onDeployStart` | [player, object, cost] | Local | Player starts placing object -`ace_fortify_deployFinished` | [player, side, configName, posASL, vectorDir, vectorUp] | Local | Player successfully finishes building object -`ace_fortify_deployCanceled` | [player, side, configName, posASL, vectorDir, vectorUp] | Local | Player cancels building object +`ace_fortify_deployFinished` | [[player, side, configName, posASL, vectorDir, vectorUp, cost], elapsedTime, totalTime, errorCode] | Local | Player successfully finishes building object +`ace_fortify_deployCanceled` | [[player, side, configName, posASL, vectorDir, vectorUp, cost], elapsedTime, totalTime, errorCode] | Local | Player cancels building object diff --git a/docs/wiki/framework/grenades-framework.md b/docs/wiki/framework/grenades-framework.md index a0b0ceeea7..b8f61872ff 100644 --- a/docs/wiki/framework/grenades-framework.md +++ b/docs/wiki/framework/grenades-framework.md @@ -68,3 +68,13 @@ The average amount of time in seconds, after `explosionTime` has passed, between ### 2.4 ace_grenades_flashbangIntervalMaxDeviation The amount of randomness in the fuse time. + +## 3. Events + +### 3.1 Listenable + +Event Name | Description | Passed Parameter(s) | Locality +---------- | ----------- | ------------------- | -------- +`ace_flashbangExploded` | A flashbang exploded | `[_grenadePosASL]` | Global +`ace_grenades_flashbangedAI` | A local AI was affected by a flashbang | `[_unit, _strength, _grenadePosASL]` | Local +`ace_grenades_flashbangedPlayer` | The local player was affected by a flashbang | `[_strength, _grenadePosASL]` | Local diff --git a/docs/wiki/framework/laser-framework.md b/docs/wiki/framework/laser-framework.md new file mode 100644 index 0000000000..1a7bbf7d6b --- /dev/null +++ b/docs/wiki/framework/laser-framework.md @@ -0,0 +1,34 @@ +--- +layout: wiki +title: Laser +description: Explains the functions available for laser designators. +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 16 + patch: 4 +--- + +## 1. Scripting + +### 1.1. Get object's laser code + +`ace_laser_fnc_getLaserCode` + +| | Arguments | Type | Optional (default value) +---| --------- | ---- | ------------------------ +0 | Unit/Vehicle | Object | Required +**R** | Laser code | Number | Return value + +### 1.2. Set object's laser code + +`ace_laser_fnc_setLaserCode` + +| | Arguments | Type | Optional (default value) +---| --------- | ---- | ------------------------ +0 | Unit/Vehicle | Object | Required +1 | Laser code | Number | Required +**R** | None | None | Return value diff --git a/extras/ruthberg_missions/360_Degree_Training_Course-Framework.zip b/extras/ruthberg_missions/360_Degree_Training_Course-Framework.zip new file mode 100644 index 0000000000..5886421544 Binary files /dev/null and b/extras/ruthberg_missions/360_Degree_Training_Course-Framework.zip differ diff --git a/extras/ruthberg_missions/360_Degree_Training_Course-Missions.zip b/extras/ruthberg_missions/360_Degree_Training_Course-Missions.zip new file mode 100644 index 0000000000..1d745d815b Binary files /dev/null and b/extras/ruthberg_missions/360_Degree_Training_Course-Missions.zip differ diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_AT15.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_AT15.p3d new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V1.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V1.p3d new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V2.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V2.p3d new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V3.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V3.p3d new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V4.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V4.p3d new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_Satchel.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_Satchel.p3d new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_TM46.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_TM46.p3d new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/AGS/data/ui/ags_static_ca.paa b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/AGS/data/ui/ags_static_ca.paa new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/DShKM/data/ui/icomap_DShKM_ca.paa b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/DShKM/data/ui/icomap_DShKM_ca.paa new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/KORD/data/ui/icomap_kord_ca.paa b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/KORD/data/ui/icomap_kord_ca.paa new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/M2/data/ui/icomap_M2_ca.paa b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/M2/data/ui/icomap_M2_ca.paa new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/M252/data/ui/icomap_mortar_m251_ca.paa b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/M252/data/ui/icomap_mortar_m251_ca.paa new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/Mk19/data/ui/icomap_mk19_stat_ca.paa b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/Mk19/data/ui/icomap_mk19_stat_ca.paa new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/Podnos/data/ui/podnos_2b14_ca.paa b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/Podnos/data/ui/podnos_2b14_ca.paa new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/SPG9/data/ui/icon_spg9_ca.paa b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/SPG9/data/ui/icon_spg9_ca.paa new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/TOW/data/ui/icomap_tow_static_ca.paa b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/TOW/data/ui/icomap_tow_static_ca.paa new file mode 100644 index 0000000000..e69de29bb2