diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index c71190ce39..08c14747e5 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -23,14 +23,14 @@ All good? Then proceed and fill out the items below. **Mods (complete and add to the following information):** - **Arma 3:** `x.xx` [e.g. 1.00 stable, rc, dev] - **CBA:** `3.x.x` [e.g. 3.0.0 stable, commit hash] -- **ACE3:** `3.x.x` [eg. 3.0.0 stable, commit hash] +- **ACE3:** `3.x.x` [e.g. 3.0.0 stable, commit hash] **Description:** A clear and concise description of what the bug is. **Steps to reproduce:** -_Follow [https://ace3.acemod.org/img/wiki/user/issue_flowchart.webp](this flowchart)!_ +_Follow [this flowchart](https://ace3.acemod.org/img/wiki/user/issue_flowchart.webp)!_ 1. _Go to ..._ 2. _Click ..._ diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml index e6b87a25ee..778d34fd9f 100644 --- a/.github/release-drafter.yml +++ b/.github/release-drafter.yml @@ -5,14 +5,16 @@ branches: name-template: 'Version $NEXT_PATCH_VERSION' tag-template: 'v$NEXT_PATCH_VERSION' +sort-by: title # sort alphabetically +sort-direction: ascending + categories: - title: '**ADDED:**' labels: - - 'kind/feature request' - - 'kind/added feature' + - 'kind/feature' - title: '**FIXED:**' labels: - - 'kind/bug fix' + - 'kind/bug-fix' - title: '**IMPROVED:**' labels: - 'kind/enhancement' @@ -20,13 +22,16 @@ categories: - title: '**CHANGED:**' labels: - 'kind/cleanup' - - 'area/compatibility' + - 'kind/change' + - title: '**SETTINGS:**' + labels: + - 'kind/setting' - title: '**TRANSLATIONS:**' labels: - - 'area/translations' + - 'kind/translation' exclude-labels: - - 'ignore changelog' + - 'ignore-changelog' - 'dependencies' change-template: '- $TITLE (#$NUMBER)' @@ -39,5 +44,5 @@ template: | replacers: # Category titles - - search: '/\#\# (\*\*(ADDED|FIXED|IMPROVED|CHANGED|TRANSLATIONS):\*\*)/g' + - search: '/\#\# (\*\*(ADDED|FIXED|IMPROVED|CHANGED|SETTINGS|TRANSLATIONS):\*\*)/g' replace: '$1' 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 4d3c6703c9..71e36eb12b 100644 --- a/.github/workflows/pboproject.yml +++ b/.github/workflows/pboproject.yml @@ -25,7 +25,7 @@ jobs: Invoke-WebRequest "$env:RHSUSF_URL" -OutFile rhsusf.zip $files = @("arma3.zip", "rhsafrf.zip", "rhsgref.zip", "rhssaf.zip", "rhsusf.zip") ForEach ($file in $files) { - Extract-7Zip -Path $file -DestinationPath . + Expand-7ZipArchive -Path $file -DestinationPath . Remove-Item $file } env: @@ -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/.hemtt/project.toml b/.hemtt/project.toml index 59a26f40b0..f5ed361e3e 100644 --- a/.hemtt/project.toml +++ b/.hemtt/project.toml @@ -18,22 +18,17 @@ include = [ [version] git_hash = 0 +# Unused in HEMTT v1.11 or higher, kept for backwards compatibility [asc] enabled = true exclude = [ - "/initsettings.sqf", - "/initkeybinds.sqf", - "/xeh_prep.sqf", + ".inc.sqf", "/dev/", - "medical_ai/statemachine.sqf", "common/functions/fnc_dummy.sqf", "zeus/functions/fnc_zeusAttributes.sqf", ] -[hemtt.config] -preset = "Hemtt" - -[hemtt.launch] +[hemtt.launch.default] workshop = [ "450814997", # CBA_A3 ] diff --git a/AUTHORS.txt b/AUTHORS.txt index bcc4a5d40e..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 @@ -126,6 +127,7 @@ Keithen Kllrt KokaKolaA3 Krzyciu +LAxemann legman Legolasindar "Viper" licht-im-Norden87 @@ -190,3 +192,4 @@ YetheSamartaka xrufix Zakant zGuba +Zman6258 diff --git a/README.md b/README.md index b461bfe520..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 9ff22efe95..9d0dd0ee4b 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.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 {}; @@ -19,11 +19,11 @@ if (!hasInterface) exitWith {}; [] call FUNC(initializeTerrainExtension); // Register fire event handler - ["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; // Register Perframe Handler - [FUNC(handleFirePFH), GVAR(simulationInterval)] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(handleFirePFH), GVAR(simulationInterval)] call CBA_fnc_addPerFrameHandler; //Add warnings for missing compat PBOs (only if AB is on) { diff --git a/addons/advanced_ballistics/XEH_preInit.sqf b/addons/advanced_ballistics/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/advanced_ballistics/XEH_preInit.sqf +++ b/addons/advanced_ballistics/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/advanced_ballistics/functions/fnc_handleFired.sqf b/addons/advanced_ballistics/functions/fnc_handleFired.sqf index a167d027f3..ff2fe85ae4 100644 --- a/addons/advanced_ballistics/functions/fnc_handleFired.sqf +++ b/addons/advanced_ballistics/functions/fnc_handleFired.sqf @@ -17,9 +17,9 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -if (!(_ammo isKindOf "BulletBase")) exitWith {}; +if !(_ammo isKindOf "BulletBase") exitWith {}; if (!alive _projectile) exitWith {}; if (underwater _unit) exitWith {}; diff --git a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf index 6af9efca24..89e89b9f7e 100644 --- a/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf +++ b/addons/advanced_ballistics/functions/fnc_initializeTerrainExtension.sqf @@ -22,7 +22,7 @@ private _initStartTime = diag_tickTime; private _mapSize = worldSize; if (("ace_advanced_ballistics" callExtension format["init:%1:%2", worldName, _mapSize]) == "Terrain already initialized") exitWith { - INFO_1("Terrain already initialized [world: %1]", worldName); + INFO_1("Terrain already initialized [world: %1]",worldName); #ifdef DEBUG_MODE_FULL systemChat "AdvancedBallistics: Terrain already initialized"; #endif @@ -33,14 +33,14 @@ private _gridCells = _mapGrids * _mapGrids; GVAR(currentGrid) = 0; -INFO_2("Starting Terrain Extension [cells: %1] [world: %2]", _gridCells, worldName); +INFO_2("Starting Terrain Extension [cells: %1] [world: %2]",_gridCells,worldName); [{ params ["_args","_idPFH"]; _args params ["_mapGrids", "_gridCells", "_initStartTime"]; if (GVAR(currentGrid) >= _gridCells) exitWith { - INFO_2("Finished terrain initialization in %1 seconds [world: %2]", (diag_tickTime - _initStartTime) toFixed 2, worldName); + INFO_2("Finished terrain initialization in %1 seconds [world: %2]",(diag_tickTime - _initStartTime) toFixed 2,worldName); #ifdef DEBUG_MODE_FULL systemChat format["AdvancedBallistics: Finished terrain initialization in %1 seconds", (diag_tickTime - _initStartTime) toFixed 2]; #endif @@ -53,7 +53,7 @@ INFO_2("Starting Terrain Extension [cells: %1] [world: %2]", _gridCells, worldNa private _gridCenter = [_x + 25, _y + 25]; private _gridHeight = round(getTerrainHeightASL _gridCenter); private _gridNumObjects = count (_gridCenter nearObjects ["Building", 50]); - private _gridSurfaceIsWater = if (surfaceIsWater _gridCenter) then {1} else {0}; + private _gridSurfaceIsWater = parseNumber (surfaceIsWater _gridCenter); "ace_advanced_ballistics" callExtension format["set:%1:%2:%3", _gridHeight, _gridNumObjects, _gridSurfaceIsWater]; GVAR(currentGrid) = GVAR(currentGrid) + 1; if (GVAR(currentGrid) >= _gridCells) exitWith {}; diff --git a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf index 103ce3d1cd..5190786924 100644 --- a/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readAmmoDataFromConfig.sqf @@ -40,10 +40,13 @@ if (_transonicStabilityCoef == 0) then { _transonicStabilityCoef = 0.5; }; private _dragModel = getNumber(_ammoConfig >> "ACE_dragModel"); -if (!(_dragModel in [1, 2, 5, 6, 7, 8])) then { +if !(_dragModel in [1, 2, 5, 6, 7, 8]) then { _dragModel = 1; }; private _ballisticCoefficients = getArray(_ammoConfig >> "ACE_ballisticCoefficients"); +if (_ballisticCoefficients isEqualTo []) then { + _ballisticCoefficients = [0.5]; +}; private _velocityBoundaries = getArray(_ammoConfig >> "ACE_velocityBoundaries"); private _atmosphereModel = getText(_ammoConfig >> "ACE_standardAtmosphere"); if (_atmosphereModel isEqualTo "") then { @@ -66,7 +69,7 @@ if ((_typicalSpeed > 0) && {_typicalSpeed < 360}) then { if (_inheritedBarrelConfig || _inheritedTempConfig) then { private _parentConfig = inheritsFrom _ammoConfig; private _parentSpeed = getNumber (_parentConfig >> "typicalSpeed"); - WARNING_4("Subsonic Ammo %1 (%2 m/s) missing `ACE_muzzleVelocities` or `ACE_ammoTempMuzzleVelocityShifts` configs, attempting to use parent %3 (%4m/s)",_this,_typicalSpeed,configName _parentConfig, _parentSpeed); + WARNING_4("Subsonic Ammo %1 (%2 m/s) missing `ACE_muzzleVelocities` or `ACE_ammoTempMuzzleVelocityShifts` configs, attempting to use parent %3 (%4m/s)",_this,_typicalSpeed,configName _parentConfig,_parentSpeed); if (_parentSpeed <= 0) exitWith {//Handle weird or null parent _muzzleVelocityTable = []; _ammoTempMuzzleVelocityShifts = []; diff --git a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf index bf0e23f97c..c79aeaf2ea 100644 --- a/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf +++ b/addons/advanced_ballistics/functions/fnc_readWeaponDataFromConfig.sqf @@ -21,7 +21,7 @@ private _weaponConfig = (configFile >> "CfgWeapons" >> _this); private _barrelTwist = 0 max getNumber(_weaponConfig >> "ACE_barrelTwist"); -private _twistDirection = [0, 1] select (_barrelTwist != 0); +private _twistDirection = parseNumber (_barrelTwist != 0); if (isNumber (_weaponConfig >> "ACE_twistDirection")) then { _twistDirection = getNumber (_weaponConfig >> "ACE_twistDirection"); if !(_twistDirection in [-1, 0, 1]) then { diff --git a/addons/advanced_ballistics/initKeybinds.sqf b/addons/advanced_ballistics/initKeybinds.inc.sqf similarity index 100% rename from addons/advanced_ballistics/initKeybinds.sqf rename to addons/advanced_ballistics/initKeybinds.inc.sqf diff --git a/addons/advanced_ballistics/initSettings.sqf b/addons/advanced_ballistics/initSettings.inc.sqf similarity index 100% rename from addons/advanced_ballistics/initSettings.sqf rename to addons/advanced_ballistics/initSettings.inc.sqf diff --git a/addons/advanced_ballistics/stringtable.xml b/addons/advanced_ballistics/stringtable.xml index eb9d865c79..b077f53b6a 100644 --- a/addons/advanced_ballistics/stringtable.xml +++ b/addons/advanced_ballistics/stringtable.xml @@ -4,7 +4,7 @@ Show Wind Info Pokaż inf. o wietrze - Mostra indicazioni del vento + Mostra indicazioni vento Показать информацию о ветре Afficher les infos sur le vent Mostrar información del viento @@ -46,7 +46,7 @@ Fejlett ballisztika Продвинутая баллистика Balistica Avanzata - アドバンスド バリスティックス + アドバンスド弾道計算 고급 탄도학 先進彈道系統 进阶弹道系统 @@ -63,7 +63,7 @@ Fejlett ballisztika Продвинутая баллистика Balistica Avanzata - アドバンスド バリスティックスを有効化 + アドバンスド弾道計算を有効化 고급 탄도학 先進彈道系統 进阶弹道系统 @@ -80,7 +80,7 @@ Engedélyezi a fejlett ballisztikát Включает продвинутую баллистику Abilita Balistica Avanzata - アドバンスド バリスティックスを有効化します。 + アドバンスド弾道計算は高度な弾道計算処理を有効化します。 고급 탄도학을 적용합니다 啟用先進彈道系統 启用进阶弹道系统 @@ -106,8 +106,8 @@ Simulates slight variations in muzzle velocity between each shot Simula variaciones ligeras de velocidad entre cada disparo Simuliert leichte Variationen der Mündungsgeschwindigkeit zwischen jedem Schuss. - 発射毎の銃口初速の変動をシミュレートします。 - Simula lievi variazioni della velocità della volata tra un colpo e l'altro + 各発射毎の銃口初速のわずかな変動をシミュレートします。 + Simula piccole variazioni della velocità alla volata tra ogni colpo. 각 사격 사이에 총구속도 변화를 시뮬레이션 합니다. 模擬每發子彈的槍口初速都略有不同 模拟每发子弹的枪口初速都略有不同 @@ -128,8 +128,8 @@ Activer la simulation de la température Lőszer-hő szimuláció engedélyezése Симуляция температуры для боеприпасов - Abilita simulazione della temperatura delle munizioni - 弾薬温度のシミュレーションを有効化 + Abilita simulazione temperatura munizioni + 弾薬温度シミュレーションを有効化 탄약 온도 구현 적용 啟用彈藥溫度模擬系統 启用弹药温度模拟系统 @@ -145,7 +145,7 @@ La vitesse initiale varie en fonction de la température des munitions. A kezdősebesség a lőszer hőmérsékletétől függően változó Начальная скорость пули зависит от температуры - La velocità dello sparo varia a seconda della temperatura delle munizioni + La velocità alla volata varia a seconda della temperatura delle munizioni. 弾薬の温度により銃口初速を変動させます。 탄약 온도에 비례해 총구 속도가 달라집니다 子彈初速將隨彈藥溫度而有所變化 @@ -162,8 +162,8 @@ Activer la simulation de la longueur de canon Csőhossz-szimuláció engedélyezése Симуляция длины ствола - Abilita simulazione della lunghezza della canna - 銃身長のシミュレーションを有効化 + Abilita simulazione lunghezza canna + 銃身長シミュレーションを有効化 총열 길이 구현 적용 啟用槍管長度模擬系統 启用枪管长度模拟系统 @@ -179,7 +179,7 @@ La vitesse initiale varie en fonction de la longueur du canon. A kezdősebesség a cső hosszától függően változó Начальная скорость пули зависит от длины ствола - La velocità di sparo varia a seconda della lunghezza della canna + La velocità alla volata varia a seconda della lunghezza della canna. 銃身長により銃口初速を変動させます。 총구 속도가 총열에 비례해 달라집니다 子彈初速將隨槍管長度而有所變化 @@ -196,7 +196,7 @@ Activer l'effet de balle traçante Nyomkövető-effekt engedélyezése Следы пуль - Abilita effetto dei Proiettili Traccianti + Abilita effetto di traccia proiettile 弾丸の軌跡エフェクトを有効化 예광탄 효과 적용 啟用曳光彈效果 @@ -213,7 +213,7 @@ Active un effet de balle traçante pour les munitions de gros calibre (seulement visible en utilisant une optique à fort grossissement). Engedélyezi a nagy kaliberű lövedékek nyomának vizuális követését (csak nagy teljesítményű optikán keresztül látható) Включает эффект следов пуль для больших калибров (видны только через мощную оптику) - Abilita effetto dei proiettili traccianti di alto calibro (visibile solo attraverso ottiche ad alto potenziale) + Abilita effetto di traccia lasciata da proiettili di alto calibro (visibile solo attraverso ottiche ad alto ingrandimento) 大口径弾の軌跡エフェクトを有効化します。 (高性能光学機器を介してのみ見ることができます) 대구경 탄환에 예광탄 효과를 적용합니다(오직 고성능 조준경 사용시에만 보입니다) 啟用曳光彈效果給大口徑子彈 (只有透過高倍率光學瞄鏡才能看到) @@ -230,7 +230,7 @@ Intervalle de simulation Szimuláció intervalluma Интервал симуляции - Intervallo Simulazione + Intervallo di Simulazione シミュレーション間隔 구현 간격 模擬間隔 @@ -246,7 +246,7 @@ Définit l'intervalle entre chacune des étapes de calcul. Meghatározza a számítási lépések közötti időintervallumot Определяет временной интервал между вычислениями - Definisce l'intervallo tra ogni step di calcolo + Definisce l'intervallo tra ogni passo del calcolo 各シミュレーション毎の間隔を定義します。 각 계산 단위의 간격을 정의합니다 定義每個模擬計算之間的時間間隔 @@ -263,7 +263,7 @@ Szimuláció hatóköre Радиус симуляции Raggio Simulazione - シミュレーションの範囲 + シミュレーションの半径 구현 범위 模擬半徑 模拟半径 @@ -279,8 +279,8 @@ Définit le rayon autour du joueur (en mètres), dans lequel la balistique avancée est appliquée aux projectiles. Meghatározza a játékos körüli hatókört (méterben), ahol a lövedékek fejlett ballisztikát használnak Определяет радиус вокруг игрока (в метрах), в котором продвинутая баллистика применяется к снарядам - Definisce il raggio attorno al giocatore (in metri) per cui la Balistica Avanzata è applicata ai proiettili - アドバンスド バリスティックスの適用半径範囲 (プレイヤー中心、メートル単位) を定義します。 + Definisce il raggio attorno al giocatore (in metri) entro il quale la Balistica Avanzata è applicata ai proiettili + アドバンスド弾道計算の適用半径範囲 (プレイヤー中心、メートル単位) を定義します。 플레이어 주위의 발사체를 고급 탄도학으로 정의하는 범위를 정합니다(미터) 以玩家的半徑距離(公尺)定義先進彈道系統啟用範圍 定义玩家周围的半径(米),在这个半径内,进阶弹道系统会被启用 @@ -296,8 +296,8 @@ Ez a modul engedélyezi a fejlett ballisztikai szimulációt - a lövedékek röppályáját befolyásolni fogja a levegő hőmérséklete, légnyomás, páratartalom, gravitáció, a lövedék fajtája, valamint a fegyver, amiből kilőtték a lövedéket. Этот модуль включает симуляцию продвинутой баллистики - при этом на траекторию полета снаряда влияют различные параметры, такие как температура воздуха, атмосферное давление, влажность, гравитация, тип боеприпаса и оружия, из которого произвели выстрел. Este módulo permite la simulación balística avanzada - es decir, la trayectoria de los proyectiles está influenciada por variables como la temperatura del aire, la presión atmosférica, la humedad, la gravedad, el tipo de municiones y el arma desde el que fue disparada. - Questo modulo abilita la simulazione della Balistica Avanzata - cioè la traiettoria dei proiettili è influenzata da variabili come la temperatura dell'aria, pressione atmosferica, umidità, gravità, il tipo di munizione e l'arma da cui è sparata - アドバンスド バリスティックスのシミュレーションを有効化します。 弾道は気温・気圧・湿度・重力・弾薬の種類・発射する武器などの変化による影響を受けるようになります。 + Questo modulo abilita la simulazione della Balistica Avanzata - essa comporta che la traiettoria dei proiettili è influenzata da variabili come la temperatura dell'aria, pressione atmosferica, umidità, gravità, il tipo di munizione e l'arma da cui è sparata. + アドバンスド弾道計算のシミュレーションを有効化します。 弾道は気温・気圧・湿度・重力・弾薬の種類・発射する武器などの変化による影響を受けるようになります。 이 모듈은 고급 탄도학을 적용시킵니다 - 이는 발사체의 궤적이 기온, 대기압, 습도, 중력, 탄환의 종류와 어느 무기에서 발사되는지에 따라 영향을 받습니다. 該模塊實現先進的彈道仿真 - 這意味著子彈的軌跡是由空氣溫度、大氣壓力、濕度、重力、彈藥類型以及射擊的武器所影響 该模块实现增强的弹道模拟—子弹的轨迹由空气温度、大气压力、湿度、重力、弹药类型和射击的武器等变量所影响 diff --git a/addons/advanced_fatigue/XEH_PREP.hpp b/addons/advanced_fatigue/XEH_PREP.hpp index 4ee00e3ce4..22bb99617a 100644 --- a/addons/advanced_fatigue/XEH_PREP.hpp +++ b/addons/advanced_fatigue/XEH_PREP.hpp @@ -9,3 +9,4 @@ PREP(handleStaminaBar); PREP(mainLoop); PREP(moduleSettings); PREP(removeDutyFactor); +PREP(renderDebugLines); diff --git a/addons/advanced_fatigue/XEH_postInit.sqf b/addons/advanced_fatigue/XEH_postInit.sqf index d447c3f651..519d218b8c 100644 --- a/addons/advanced_fatigue/XEH_postInit.sqf +++ b/addons/advanced_fatigue/XEH_postInit.sqf @@ -2,34 +2,9 @@ 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); +#ifdef DEBUG_MODE_FULL +call FUNC(renderDebugLines); +#endif // recheck weapon inertia after weapon swap, change of attachments or switching unit ["weapon", {[ACE_player] call FUNC(getWeaponInertia)}, true] call CBA_fnc_addPlayerEventHandler; @@ -39,6 +14,21 @@ 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); + // - Post process effect ------------------------------------------------------ GVAR(ppeBlackout) = ppEffectCreate ["ColorCorrections", 4220]; GVAR(ppeBlackout) ppEffectEnable true; @@ -47,28 +37,26 @@ if (!hasInterface) exitWith {}; GVAR(ppeBlackout) ppEffectCommit 0.4; // - GVAR updating and initialization ----------------------------------------- - ["unit", LINKFUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler; + ["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; ["visibleMap", { params ["", "_visibleMap"]; // command visibleMap is updated one frame later - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlShow ((!_visibleMap) && {(vehicle ACE_player) == ACE_player}); + (uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]) ctrlShow (!_visibleMap && isNull objectParent ACE_player); }, true] call CBA_fnc_addPlayerEventHandler; ["vehicle", { - private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; - _staminaBarContainer ctrlShow ((!visibleMap) && {(vehicle ACE_player) == ACE_player}); + (uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]) ctrlShow (!visibleMap && isNull objectParent ACE_player); }, true] call CBA_fnc_addPlayerEventHandler; // - Duty factors ------------------------------------------------------------- - if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [QEGVAR(medical,pain), { // 0->1.0, 0.5->1.05, 1->1.1 - linearConversion [0, 1, (_this getVariable [QEGVAR(medical,pain), 0]), 1, 1.1, true]; + linearConversion [0, 1, _this getVariable [QEGVAR(medical,pain), 0], 1, 1.1, true]; }] call FUNC(addDutyFactor); [QEGVAR(medical,bloodVolume), { // 6->1.0, 5->1.167, 4->1.33 - linearConversion [6, 0, (_this getVariable [QEGVAR(medical,bloodVolume), 6]), 1, 2, true]; + linearConversion [6, 0, _this getVariable [QEGVAR(medical,bloodVolume), 6], 1, 2, true]; }] call FUNC(addDutyFactor); }; - if (["ACE_Dragging"] call EFUNC(common,isModLoaded)) then { + if (["ace_dragging"] call EFUNC(common,isModLoaded)) then { [QEGVAR(dragging,isCarrying), { [1, 3] select (_this getVariable [QEGVAR(dragging,isCarrying), false]); }] call FUNC(addDutyFactor); @@ -76,7 +64,7 @@ if (!hasInterface) exitWith {}; // Weather has an off switch, Dragging & Medical don't. if (missionNamespace getVariable [QEGVAR(weather,enabled), false]) then { [QEGVAR(weather,temperature), { // 35->1, 45->2 - linearConversion [35, 45, (missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25]), 1, 2, true]; + linearConversion [35, 45, missionNamespace getVariable [QEGVAR(weather,currentTemperature), 25], 1, 2, true]; }] call FUNC(addDutyFactor); }; diff --git a/addons/advanced_fatigue/XEH_preInit.sqf b/addons/advanced_fatigue/XEH_preInit.sqf index edbd421f8d..643b7b0be0 100644 --- a/addons/advanced_fatigue/XEH_preInit.sqf +++ b/addons/advanced_fatigue/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(staminaBarWidth) = 10 * (((safezoneW / safezoneH) min 1.2) / 40); GVAR(dutyList) = createHashMap; diff --git a/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf b/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf index e992816e9b..50e052d5f8 100644 --- a/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf +++ b/addons/advanced_fatigue/functions/fnc_getAnimDuty.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: BaerMitUmlaut - * Calculates the duty of the current animation. + * Calculates the duty ('postureWeight') of the current animation. * * Arguments: * 0: Unit diff --git a/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf b/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf index cc07d9e004..36048cee04 100644 --- a/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf +++ b/addons/advanced_fatigue/functions/fnc_getMetabolicCosts.sqf @@ -1,54 +1,74 @@ #include "..\script_component.hpp" /* - * Author: BaerMitUmlaut - * Calculates the current metabolic costs for a unit. + * Author: BaerMitUmlaut, ulteq + * Calculates the current metabolic costs. * Calculation is done according to the Pandolf/Wojtowicz formulas. * * Arguments: - * 0: Unit - * 1: Speed + * 0: Duty of animation + * 1: Mass of unit + * 2: Terrain gradient + * 3: Terrain factor + * 4: Speed * * Return Value: * Metabolic cost * * Example: - * [player, 3.3] call ace_advanced_fatigue_fnc_getMetabolicCosts + * [1, 840, 20, 1, 4] call ace_advanced_fatigue_fnc_getMetabolicCosts * * Public: No */ -params ["_unit", "_velocity"]; -private _gearMass = ((_unit getVariable [QEGVAR(movement,totalLoad), loadAbs _unit]) / 22.046) * GVAR(loadFactor); - -private _terrainAngle = asin (1 - ((surfaceNormal getPosASL _unit) select 2)); -private _terrainGradient = (_terrainAngle / 45 min 1) * 5 * GVAR(terrainGradientFactor); -private _duty = GVAR(animDuty); - -{ - if (_x isEqualType 0) then { - _duty = _duty * _x; - } else { - _duty = _duty * (_unit call _x); - }; -} forEach (values GVAR(dutyList)); - -if (GVAR(isSwimming)) then { - _terrainGradient = 0; -}; +params ["_duty", "_gearMass", "_terrainGradient", "_terrainFactor", "_speed"]; // Metabolic cost for walking and running is different -if (_velocity > 2) then { +if (_speed > 2) then { // Running + #ifdef DEBUG_MODE_FULL + private _baseline = 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 0.9 * (_speed ^ 2); + private _graded = 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.9 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient); + private _terrainImpact = abs ((_graded / _baseline) - 1); + hintSilent format ["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n TerrainImpact: %5 \n Speed: %6 | CarriedLoad: %7 \n Duty: %8 | Work: %9", + _fwdAngle toFixed 1, + _sideAngle toFixed 1, + _terrainFactor toFixed 2, + _terrainGradient toFixed 1, + _terrainImpact toFixed 2, + _speed toFixed 2, + _gearMass toFixed 1, + _duty toFixed 2, + round (_graded * BIOMECH_EFFICIENCY * _duty) + ]; + #endif + ( - 2.10 * SIM_BODYMASS + 2.1 * SIM_BODYMASS + 4 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) - + (SIM_BODYMASS + _gearMass) * (0.9 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) - ) * 0.23 * _duty + + _terrainFactor * (SIM_BODYMASS + _gearMass) * (0.9 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient) + ) * BIOMECH_EFFICIENCY * _duty } else { // Walking + #ifdef DEBUG_MODE_FULL + private _baseline = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + (SIM_BODYMASS + _gearMass) * 1.15 * (_speed ^ 2); + private _graded = 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient); + private _terrainImpact = abs ((_graded / _baseline) - 1); + hintSilent format ["FwdAngle: %1 | SideAngle: %2 \n TerrainFactor: %3 | TerrainGradient: %4 \n TerrainImpact: %5 \n Speed: %6 | CarriedLoad: %7 \n Duty: %8 | Work: %9", + _fwdAngle toFixed 1, + _sideAngle toFixed 1, + _terrainFactor toFixed 2, + _terrainGradient toFixed 1, + _terrainImpact toFixed 2, + _speed toFixed 2, + _gearMass toFixed 1, + _duty toFixed 2, + round (_graded * BIOMECH_EFFICIENCY * _duty) + ]; + #endif + ( 1.05 * SIM_BODYMASS + 2 * (SIM_BODYMASS + _gearMass) * ((_gearMass / SIM_BODYMASS) ^ 2) - + (SIM_BODYMASS + _gearMass) * (1.15 * (_velocity ^ 2) + 0.66 * _velocity * _terrainGradient) - ) * 0.23 * _duty + + _terrainFactor * (SIM_BODYMASS + _gearMass) * (1.15 * (_speed ^ 2) + 0.66 * _speed * _terrainGradient) + ) * BIOMECH_EFFICIENCY * _duty }; diff --git a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf index 13c1fefc62..d948823354 100644 --- a/addons/advanced_fatigue/functions/fnc_handleEffects.sqf +++ b/addons/advanced_fatigue/functions/fnc_handleEffects.sqf @@ -1,44 +1,44 @@ #include "..\script_component.hpp" /* - * Author: BaerMitUmlaut + * Author: BaerMitUmlaut, ulteq * Handles any audible, visual and physical effects of fatigue. * * Arguments: * 0: Unit * 1: Fatigue - * 2: Speed - * 3: Overexhausted + * 2: Overexhausted + * 3: Forward Angle + * 4: Side Angle * * Return Value: * None * * Example: - * [_player, 0.5, 3.3, true] call ace_advanced_fatigue_fnc_handleEffects + * [_player, 0.5, 3.3, true, 0, 0] call ace_advanced_fatigue_fnc_handleEffects * * Public: No */ -params ["_unit", "_fatigue", "_speed", "_overexhausted"]; -#ifdef DEBUG_MODE_FULL - systemChat str _fatigue; - systemChat str vectorMagnitude velocity _unit; -#endif +params ["_unit", "_fatigue", "_overexhausted", "_fwdAngle", "_sideAngle"]; // - Audible effects ---------------------------------------------------------- GVAR(lastBreath) = GVAR(lastBreath) + 1; + if (_fatigue > 0.4 && {GVAR(lastBreath) > (_fatigue * -10 + 9)} && {!underwater _unit}) then { if (!isGameFocused) exitWith {}; + switch (true) do { case (_fatigue < 0.6): { - playSound (QGVAR(breathLow) + str(floor random 6)); + playSound (QGVAR(breathLow) + str (floor random 6)); }; case (_fatigue < 0.85): { - playSound (QGVAR(breathMid) + str(floor random 6)); + playSound (QGVAR(breathMid) + str (floor random 6)); }; default { - playSound (QGVAR(breathMax) + str(floor random 6)); + playSound (QGVAR(breathMax) + str (floor random 6)); }; }; + GVAR(lastBreath) = 0; }; @@ -62,31 +62,35 @@ if (GVAR(isSwimming)) exitWith { if (GVAR(setAnimExclusions) isEqualTo []) then { _unit setAnimSpeedCoef linearConversion [0.7, 0.9, _fatigue, 1, 0.5, true]; }; - if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then { + + if (isSprintAllowed _unit && _fatigue > 0.7) then { // small checks like these are faster without lazy eval [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { - if ((!isSprintAllowed _unit) && {_fatigue < 0.7}) then { + if (!isSprintAllowed _unit && _fatigue < 0.7) then { [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); }; }; }; -if ((getAnimSpeedCoef _unit) != 1) then { - if (GVAR(setAnimExclusions) isEqualTo []) then { - TRACE_1("reset",getAnimSpeedCoef _unit); - _unit setAnimSpeedCoef 1; - }; + +// If other components are setting setAnimSpeedCoef, do not change animSpeedCoef +if (getAnimSpeedCoef _unit != 1 && {GVAR(setAnimExclusions) isEqualTo []}) then { + TRACE_1("reset",getAnimSpeedCoef _unit); + _unit setAnimSpeedCoef 1; }; -if (_overexhausted) then { +if (!isForcedWalk _unit && _fatigue >= 1) then { // small checks like these are faster without lazy eval [_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { - if (isForcedWalk _unit && {_fatigue < 0.7}) then { + if (isForcedWalk _unit && _fatigue < 0.7) then { [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); + [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); } else { - if ((isSprintAllowed _unit) && {_fatigue > 0.7}) then { + // Forward angle is the slope of the terrain, side angle simulates the unevenness/roughness of the terrain + if (isSprintAllowed _unit && {_fatigue > 0.7 || abs _fwdAngle > 20 || abs _sideAngle > 20}) then { [_unit, "blockSprint", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); } else { - if ((!isSprintAllowed _unit) && {_fatigue < 0.6}) then { + if (!isSprintAllowed _unit && _fatigue < 0.6 && abs _fwdAngle < 20 && abs _sideAngle < 20) then { [_unit, "blockSprint", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); }; }; diff --git a/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf b/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf index a119b35862..82c9c90a56 100644 --- a/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf +++ b/addons/advanced_fatigue/functions/fnc_handlePlayerChanged.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Author: BaerMitUmlaut - * Handles switching units (once on init and afterwards via Zeus). + * Author: BaerMitUmlaut, ulteq + * Handles switching units (once on init and afterwards via Zeus). Also handles CBA setting change for performance factor. * * Arguments: * 0: New Unit @@ -15,20 +15,24 @@ * * Public: No */ + params ["_newUnit", "_oldUnit"]; + TRACE_2("unit changed",_newUnit,_oldUnit); -if !(isNull _oldUnit) then { +if (!isNull _oldUnit) then { + TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); + _oldUnit enableStamina true; _oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]]; _oldUnit setVariable [QGVAR(animHandler), nil]; - TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); _oldUnit setVariable [QGVAR(ae1Reserve), GVAR(ae1Reserve)]; _oldUnit setVariable [QGVAR(ae2Reserve), GVAR(ae2Reserve)]; _oldUnit setVariable [QGVAR(anReserve), GVAR(anReserve)]; _oldUnit setVariable [QGVAR(anFatigue), GVAR(anFatigue)]; _oldUnit setVariable [QGVAR(muscleDamage), GVAR(muscleDamage)]; + _oldUnit setVariable [QGVAR(respiratoryRate), GVAR(respiratoryRate)]; }; _newUnit enableStamina false; @@ -38,6 +42,7 @@ if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then { private _animHandler = _newUnit addEventHandler ["AnimChanged", { GVAR(animDuty) = _this call FUNC(getAnimDuty); }]; + TRACE_1("add new",_animHandler); _newUnit setVariable [QGVAR(animHandler), _animHandler]; }; @@ -47,18 +52,27 @@ GVAR(ae2Reserve) = _newUnit getVariable [QGVAR(ae2Reserve), AE2_MAXRESERVE] GVAR(anReserve) = _newUnit getVariable [QGVAR(anReserve), AN_MAXRESERVE]; GVAR(anFatigue) = _newUnit getVariable [QGVAR(anFatigue), 0]; GVAR(muscleDamage) = _newUnit getVariable [QGVAR(muscleDamage), 0]; +GVAR(respiratoryRate) = _newUnit getVariable [QGVAR(respiratoryRate), 0]; // Clean variables for respawning units { _newUnit setVariable [_x, nil]; -} forEach [QGVAR(ae1Reserve), QGVAR(ae2Reserve), QGVAR(anReserve), QGVAR(anFatigue), QGVAR(muscleDamage)]; +} forEach [QGVAR(ae1Reserve), QGVAR(ae2Reserve), QGVAR(anReserve), QGVAR(anFatigue), QGVAR(muscleDamage), QGVAR(respiratoryRate)]; GVAR(VO2Max) = 35 + 20 * (_newUnit getVariable [QGVAR(performanceFactor), GVAR(performanceFactor)]); -GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * 0.23 * JOULES_PER_ML_O2 / 60; +GVAR(VO2MaxPower) = GVAR(VO2Max) * SIM_BODYMASS * BIOMECH_EFFICIENCY * JOULES_PER_ML_O2 / 60; GVAR(peakPower) = VO2MAX_STRENGTH * GVAR(VO2MaxPower); -GVAR(ae1PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 13.3 * ANTPERCENT ^ 1.28 * 1.362; -GVAR(ae2PathwayPower) = GVAR(peakPower) / (13.3 + 16.7 + 113.3) * 16.7 * ANTPERCENT ^ 1.28 * 1.362; +GVAR(ae1PathwayPower) = GVAR(peakPower) / (AE1_ATP_RELEASE_RATE + AE2_ATP_RELEASE_RATE + AN_ATP_RELEASE_RATE) * AE1_ATP_RELEASE_RATE * ANTPERCENT ^ 1.28 * 1.362; +GVAR(ae2PathwayPower) = GVAR(peakPower) / (AE1_ATP_RELEASE_RATE + AE2_ATP_RELEASE_RATE + AN_ATP_RELEASE_RATE) * AE2_ATP_RELEASE_RATE * ANTPERCENT ^ 1.28 * 1.362; +GVAR(aePathwayPower) = GVAR(ae1PathwayPower) + GVAR(ae2PathwayPower); +GVAR(anPathwayPower) = GVAR(peakPower) - GVAR(aePathwayPower); + +GVAR(aeWattsPerATP) = GVAR(ae1PathwayPower) / AE1_ATP_RELEASE_RATE; +GVAR(anWattsPerATP) = GVAR(anPathwayPower) / AN_ATP_RELEASE_RATE; + +GVAR(respiratoryBufferDivisor) = (RESPIRATORY_BUFFER - 1) / RESPIRATORY_BUFFER; +GVAR(maxPowerFatigueRatio) = 0.057 / GVAR(peakPower); GVAR(ppeBlackoutLast) = 100; GVAR(lastBreath) = 0; diff --git a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf index 8903bab495..a07abae794 100644 --- a/addons/advanced_fatigue/functions/fnc_mainLoop.sqf +++ b/addons/advanced_fatigue/functions/fnc_mainLoop.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: BaerMitUmlaut + * Author: BaerMitUmlaut, ulteq * Main looping function that updates fatigue values. * * Arguments: @@ -17,67 +17,131 @@ // Dead people don't breathe, will also handle null (map intros) if (!alive ACE_player) exitWith { - [FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; + [LINKFUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; + private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; _staminaBarContainer ctrlSetFade 1; _staminaBarContainer ctrlCommit 1; }; +private _velocity = velocity ACE_player; +private _normal = surfaceNormal (getPosWorld ACE_player); +private _movementVector = vectorNormalized _velocity; +private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal); +private _fwdAngle = asin (_movementVector select 2); +private _sideAngle = asin (_sideVector select 2); + private _currentWork = REE; -private _currentSpeed = (vectorMagnitude (velocity ACE_player)) min 6; +private _currentSpeed = (vectorMagnitude _velocity) min 6; // fix #4481. Diving to the ground is recorded as PRONE stance with running speed velocity. Cap maximum speed to fix. if (GVAR(isProne)) then { _currentSpeed = _currentSpeed min 1.5; }; -if ((vehicle ACE_player == ACE_player) && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then { - _currentWork = [ACE_player, _currentSpeed] call FUNC(getMetabolicCosts); +// Get the current duty +private _duty = GVAR(animDuty); + +{ + if (_x isEqualType 0) then { + _duty = _duty * _x; + } else { + _duty = _duty * (ACE_player call _x); + }; +} forEach (values GVAR(dutyList)); + +private _terrainGradient = abs _fwdAngle; +private _terrainFactor = 1; +private _gearMass = 0 max (((ACE_player getVariable [QEGVAR(movement,totalLoad), loadAbs ACE_player]) / 22.046 - UNDERWEAR_WEIGHT) * GVAR(loadFactor)); + +if (isNull objectParent ACE_player && {_currentSpeed > 0.1} && {isTouchingGround ACE_player || {underwater ACE_player}}) then { + if (!GVAR(isSwimming)) then { + // If the unit is going downhill, it's much less demanding + if (_fwdAngle < 0) then { + _terrainGradient = 0.15 * _terrainGradient; + }; + + // Used to simulate the unevenness/roughness of the terrain + if ((getPosATL ACE_player) select 2 < 0.01) then { + private _sideGradient = abs (_sideAngle / 45) min 1; + + _terrainFactor = 1 + _sideGradient ^ 4; + }; + }; + + _currentWork = [_duty, _gearMass, _terrainGradient * GVAR(terrainGradientFactor), _terrainFactor, _currentSpeed] call FUNC(getMetabolicCosts); _currentWork = _currentWork max REE; }; +// Oxygen calculation +private _oxygen = if (GETEGVAR(medical,enabled,false) && {EGVAR(medical_vitals,simulateSpo2)}) then { // Defer to medical + (ACE_player getVariable [QEGVAR(medical,spo2), 97]) / 100 +} else { + 1 - 0.131 * GVAR(respiratoryRate) ^ 2 // Default AF oxygen saturation +}; // Calculate muscle damage increase -// Note: Muscle damage recovery is ignored as it takes multiple days -GVAR(muscleDamage) = (GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * 0.00004) min 1; -private _muscleIntegritySqrt = sqrt (1 - GVAR(muscleDamage)); +GVAR(muscleDamage) = GVAR(muscleDamage) + (_currentWork / GVAR(peakPower)) ^ 3.2 * MUSCLE_TEAR_RATE; + +// Calculate muscle damage recovery +GVAR(muscleDamage) = 0 max (GVAR(muscleDamage) - MUSCLE_RECOVERY * GVAR(recoveryFactor)) min 1; +private _muscleIntegrity = 1 - GVAR(muscleDamage); +private _muscleFactor = sqrt _muscleIntegrity; // Calculate available power -private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt; -private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * OXYGEN * _muscleIntegritySqrt; +private _ae1PathwayPowerFatigued = GVAR(ae1PathwayPower) * sqrt (GVAR(ae1Reserve) / AE1_MAXRESERVE) * _oxygen * _muscleFactor; +private _ae2PathwayPowerFatigued = GVAR(ae2PathwayPower) * sqrt (GVAR(ae2Reserve) / AE2_MAXRESERVE) * _oxygen * _muscleFactor; +private _aePathwayPowerFatigued = _ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued; +private _anPathwayPowerFatigued = GVAR(anPathwayPower) * sqrt (GVAR(anReserve) / AN_MAXRESERVE) * _oxygen * _muscleIntegrity; // Calculate how much power is consumed from each reserve private _ae1Power = _currentWork min _ae1PathwayPowerFatigued; -private _ae2Power = ((_currentWork - _ae1Power) max 0) min _ae2PathwayPowerFatigued; -private _anPower = (_currentWork - _ae1Power - _ae2Power) max 0; +private _ae2Power = (_currentWork - _ae1Power) min _ae2PathwayPowerFatigued; +private _anPower = 0 max (_currentWork - _ae1Power - _ae2Power); // Remove ATP from reserves for current work -GVAR(ae1Reserve) = GVAR(ae1Reserve) - _ae1Power / WATTSPERATP; -GVAR(ae2Reserve) = GVAR(ae2Reserve) - _ae2Power / WATTSPERATP; -GVAR(anReserve) = GVAR(anReserve) - _anPower / WATTSPERATP; -// Increase anearobic fatigue -GVAR(anFatigue) = GVAR(anFatigue) + _anPower * (0.057 / GVAR(peakPower)) * 1.1; +GVAR(ae1Reserve) = 0 max (GVAR(ae1Reserve) - _ae1Power / GVAR(aeWattsPerATP)); +GVAR(ae2Reserve) = 0 max (GVAR(ae2Reserve) - _ae2Power / GVAR(aeWattsPerATP)); +GVAR(anReserve) = 0 max (GVAR(anReserve) - _anPower / GVAR(anWattsPerATP)); + +// Acidosis accumulation +GVAR(anFatigue) = GVAR(anFatigue) + _anPower * GVAR(maxPowerFatigueRatio) * 1.1; // Aerobic ATP reserve recovery -GVAR(ae1Reserve) = ((GVAR(ae1Reserve) + OXYGEN * 6.60 * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower) * GVAR(recoveryFactor)) min AE1_MAXRESERVE) max 0; -GVAR(ae2Reserve) = ((GVAR(ae2Reserve) + OXYGEN * 5.83 * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower) * GVAR(recoveryFactor)) min AE2_MAXRESERVE) max 0; +GVAR(ae1Reserve) = (GVAR(ae1Reserve) + _oxygen * GVAR(recoveryFactor) * AE1_ATP_RECOVERY * (GVAR(ae1PathwayPower) - _ae1Power) / GVAR(ae1PathwayPower)) min AE1_MAXRESERVE; +GVAR(ae2Reserve) = (GVAR(ae2Reserve) + _oxygen * GVAR(recoveryFactor) * AE2_ATP_RECOVERY * (GVAR(ae2PathwayPower) - _ae2Power) / GVAR(ae2PathwayPower)) min AE2_MAXRESERVE; -// Anaerobic ATP reserver and fatigue recovery -GVAR(anReserve) = ((GVAR(anReserve) - + (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) / GVAR(VO2MaxPower) * 56.7 * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor) -) min AN_MAXRESERVE) max 0; +private _aeSurplus = _ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power; -GVAR(anFatigue) = ((GVAR(anFatigue) - - (_ae1PathwayPowerFatigued + _ae2PathwayPowerFatigued - _ae1Power - _ae2Power) * (0.057 / GVAR(peakPower)) * GVAR(anFatigue) ^ 2 * GVAR(recoveryFactor) -) min 1) max 0; +// Anaerobic ATP reserve recovery +GVAR(anReserve) = 0 max (GVAR(anReserve) + _aeSurplus / GVAR(VO2MaxPower) * AN_ATP_RECOVERY * GVAR(recoveryFactor) * (GVAR(anFatigue) max linearConversion [AN_MAXRESERVE, 0, GVAR(anReserve), 0, 0.75, true]) ^ 2) min AN_MAXRESERVE; // max linearConversion ensures that if GVAR(anFatigue) is very low, it will still regenerate reserves +// Acidosis recovery +GVAR(anFatigue) = 0 max (GVAR(anFatigue) - _aeSurplus * GVAR(maxPowerFatigueRatio) * GVAR(recoveryFactor) * GVAR(anFatigue) ^ 2) min 1; -private _aeReservePercentage = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2; -private _anReservePercentage = GVAR(anReserve) / AN_MAXRESERVE; -private _perceivedFatigue = 1 - (_anReservePercentage min _aeReservePercentage); +// Respiratory rate decrease +GVAR(respiratoryRate) = GVAR(respiratoryRate) * GVAR(respiratoryBufferDivisor); -[ACE_player, _perceivedFatigue, _currentSpeed, GVAR(anReserve) == 0] call FUNC(handleEffects); +// Respiratory rate increase +private _aePowerRatio = (GVAR(aePathwayPower) / _aePathwayPowerFatigued) min 2; +private _respiratorySampleDivisor = 1 / (RESPIRATORY_BUFFER * 4.72 * GVAR(VO2Max)); +GVAR(respiratoryRate) = (GVAR(respiratoryRate) + _currentWork * _respiratorySampleDivisor * _aePowerRatio) min 1; + +// Calculate a pseudo-perceived fatigue, which is used for effects +GVAR(aeReservePercentage) = (GVAR(ae1Reserve) / AE1_MAXRESERVE + GVAR(ae2Reserve) / AE2_MAXRESERVE) / 2; +GVAR(anReservePercentage) = GVAR(anReserve) / AN_MAXRESERVE; +private _perceivedFatigue = 1 - (GVAR(anReservePercentage) min GVAR(aeReservePercentage)); + +#ifdef DEBUG_MODE_FULL +systemChat format ["---- muscleDamage: %1 ----", GVAR(muscleDamage) toFixed 8]; +systemChat format ["---- ae2: %1 - an: %2 ----", (GVAR(ae2Reserve) / AE2_MAXRESERVE) toFixed 2, (GVAR(anReserve) / AN_MAXRESERVE) toFixed 2]; +systemChat format ["---- anFatigue: %1 - perceivedFatigue: %2 ----", GVAR(anFatigue) toFixed 2, _perceivedFatigue toFixed 2]; +systemChat format ["---- velocity %1 - respiratoryRate: %2 ----", (vectorMagnitude _velocity) toFixed 2, GVAR(respiratoryRate) toFixed 2]; +// systemChat format ["---- aePower: %1 ----", _aePathwayPowerFatigued toFixed 1]; +#endif + +[ACE_player, _perceivedFatigue, GVAR(anReserve) == 0, _fwdAngle, _sideAngle] call FUNC(handleEffects); if (GVAR(enableStaminaBar)) then { [GVAR(anReserve) / AN_MAXRESERVE] call FUNC(handleStaminaBar); }; -[FUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; +[LINKFUNC(mainLoop), [], 1] call CBA_fnc_waitAndExecute; diff --git a/addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf b/addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf new file mode 100644 index 0000000000..3826637b9e --- /dev/null +++ b/addons/advanced_fatigue/functions/fnc_renderDebugLines.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" +/* + * Author: ulteq + * Draw lines for debugging. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_advanced_fatigue_fnc_renderDebugLines + * + * Public: No + */ + +addMissionEventHandler ["Draw3D", { + private _normal = surfaceNormal (getPosWorld ACE_player); + private _beg = (getPosWorld ACE_player) vectorAdd (_normal vectorMultiply 0.5); + private _end = _beg vectorAdd (_normal vectorMultiply 2); + drawLine3D [ASLToATL _beg, ASLToATL _end, [0, 1, 0, 1]]; + + private _side = vectorNormalized (_normal vectorCrossProduct [0, 0, 1]); + private _end = _beg vectorAdd (_side vectorMultiply 2); + drawLine3D [ASLToATL _beg, ASLToATL _end, [0, 0, 1, 1]]; + + private _up = vectorNormalized (_normal vectorCrossProduct _side); + private _end = _beg vectorAdd (_up vectorMultiply 2); + drawLine3D [ASLToATL _beg, ASLToATL _end, [1, 0, 0, 1]]; + + private _movementVector = vectorNormalized (velocity ACE_player); + private _end = _beg vectorAdd (_movementVector vectorMultiply 2); + drawLine3D [ASLToATL _beg, ASLToATL _end, [1, 1, 0, 1]]; + + private _sideVector = vectorNormalized (_movementVector vectorCrossProduct _normal); + _sideVector set [2, 0]; + private _end = _beg vectorAdd (_sideVector vectorMultiply 2); + drawLine3D [ASLToATL _beg, ASLToATL _end, [0, 1, 1, 1]]; +}]; diff --git a/addons/advanced_fatigue/initSettings.sqf b/addons/advanced_fatigue/initSettings.inc.sqf similarity index 75% rename from addons/advanced_fatigue/initSettings.sqf rename to addons/advanced_fatigue/initSettings.inc.sqf index e2d797bf91..01eba8652d 100644 --- a/addons/advanced_fatigue/initSettings.sqf +++ b/addons/advanced_fatigue/initSettings.inc.sqf @@ -4,12 +4,14 @@ [LSTRING(Enabled), LSTRING(Enabled_Description)], LSTRING(DisplayName), true, - true, { + 1, + { if (!_this) then { private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; _staminaBarContainer ctrlSetFade 1; _staminaBarContainer ctrlCommit 0; }; + [QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged) }, true // Needs mission restart @@ -21,7 +23,8 @@ [LSTRING(EnableStaminaBar), LSTRING(EnableStaminaBar_Description)], LSTRING(DisplayName), true, - true, { + 1, + { if (!_this) then { private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; _staminaBarContainer ctrlSetFade 1; @@ -36,7 +39,8 @@ [LSTRING(FadeStaminaBar), LSTRING(FadeStaminaBar_Description)], LSTRING(DisplayName), true, - false, { + 0, + { if (!_this && GVAR(enabled) && GVAR(enableStaminaBar)) then { private _staminaBarContainer = uiNamespace getVariable [QGVAR(staminaBarContainer), controlNull]; _staminaBarContainer ctrlSetFade 0; @@ -50,8 +54,14 @@ "SLIDER", [LSTRING(PerformanceFactor), LSTRING(PerformanceFactor_Description)], LSTRING(DisplayName), - [0, 5, 1, 1], - true + [0, 10, 1, 2], + 1, + { + // Recalculate values if the setting is changed mid-mission + if (GVAR(enabled) && hasInterface && !isNull ACE_player) then { + [ACE_player, ACE_player] call FUNC(handlePlayerChanged); + }; + } ] call CBA_fnc_addSetting; [ @@ -59,8 +69,8 @@ "SLIDER", [LSTRING(RecoveryFactor), LSTRING(RecoveryFactor_Description)], LSTRING(DisplayName), - [0, 5, 1, 1], - true + [0, 10, 1, 2], + 1 ] call CBA_fnc_addSetting; [ @@ -68,8 +78,8 @@ "SLIDER", [LSTRING(LoadFactor), LSTRING(LoadFactor_Description)], LSTRING(DisplayName), - [0, 5, 1, 1], - true + [0, 5, 1, 2], + 1 ] call CBA_fnc_addSetting; [ @@ -77,33 +87,6 @@ "SLIDER", [LSTRING(TerrainGradientFactor), LSTRING(TerrainGradientFactor_Description)], LSTRING(DisplayName), - [0, 5, 1, 1], - true -] call CBA_fnc_addSetting; - -[ - QGVAR(swayFactor), - "SLIDER", - [LSTRING(SwayFactor), LSTRING(SwayFactor_Description)], - LSTRING(DisplayName), - [0, 5, 1, 1], - true -] call CBA_fnc_addSetting; - -[ - QGVAR(restedSwayFactor), - "SLIDER", - [LSTRING(RestedSwayFactor), LSTRING(RestedSwayFactor_Description)], - LSTRING(DisplayName), [0, 5, 1, 2], - true -] call CBA_fnc_addSetting; - -[ - QGVAR(deployedSwayFactor), - "SLIDER", - [LSTRING(DeployedSwayFactor), LSTRING(DeployedSwayFactor_Description)], - LSTRING(DisplayName), - [0, 5, 1, 2], - true + 1 ] call CBA_fnc_addSetting; diff --git a/addons/advanced_fatigue/script_component.hpp b/addons/advanced_fatigue/script_component.hpp index fcc8abd3c0..7e3255439f 100644 --- a/addons/advanced_fatigue/script_component.hpp +++ b/addons/advanced_fatigue/script_component.hpp @@ -16,14 +16,28 @@ #include "\z\ace\addons\main\script_macros.hpp" +#define UNDERWEAR_WEIGHT 3.5 + #define ANTPERCENT 0.8 #define SIM_BODYMASS 70 #define JOULES_PER_ML_O2 20.9 #define VO2MAX_STRENGTH 4.1 -#define REE 18.83 //((0.5617 * SIM_BODYMASS + 42.57) * 0.23) -#define OXYGEN 0.9 -#define WATTSPERATP 7 +#define BIOMECH_EFFICIENCY 0.23 +#define REE 18.83 // ((0.5617 * SIM_BODYMASS + 42.57) * BIOMECH_EFFICIENCY) -#define AE1_MAXRESERVE 4000000 -#define AE2_MAXRESERVE 84000 -#define AN_MAXRESERVE 2300 +#define RESPIRATORY_BUFFER 60 + +#define MUSCLE_TEAR_RATE 0.00004 +#define MUSCLE_RECOVERY 0.00000386 + +#define AE1_ATP_RELEASE_RATE 13.3 // mmol +#define AE2_ATP_RELEASE_RATE 16.7 // mmol +#define AN_ATP_RELEASE_RATE 113.3 // mmol + +#define AE1_ATP_RECOVERY 6.60 // mmol +#define AE2_ATP_RECOVERY 5.83 // mmol +#define AN_ATP_RECOVERY 56.70 // mmol + +#define AE1_MAXRESERVE 4000000 // mmol +#define AE2_MAXRESERVE 84000 // mmol +#define AN_MAXRESERVE 2300 // mmol diff --git a/addons/advanced_fatigue/stringtable.xml b/addons/advanced_fatigue/stringtable.xml index 3088ed2db1..5cd36ffce6 100644 --- a/addons/advanced_fatigue/stringtable.xml +++ b/addons/advanced_fatigue/stringtable.xml @@ -7,7 +7,7 @@ ACE Erweiterte Ausdauer ACE 進階疲勞 ACE 进阶体力 - ACE アドバンスド ファティーグ + ACE アドバンスド疲労 ACE Fatica Avanzata ACE 고급 피로도 ACE Fatigue avancée @@ -41,10 +41,10 @@ Wpływa na ogólną wydolność organizmu u wszystkich graczy bez ustawionego niestandardowego współczynnika. Więcej znaczy lepiej. 모든 성능이 임의로 설정된 값 없이 영향받습니다. 값이 클수록 더 나은 성능을 발휘합니다 Impacte la performance globale de tous les joueurs n'ayant pas de facteur personnalisé.\nPlus la valeur est élevée, plus le joueur est performant. - Influenza qualsiasi prestazione di tutti i giocatori smuniti di un fattore personalizzato. Maggiore significa migliore. + 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. @@ -56,10 +56,10 @@ Wpływa na ogólną wydolność tej jednostki. Więcej znaczy lepiej. 모든 성능이 이 단위로 영향을 받습니다. 값이 클수록 더 나은 성능을 발휘합니다 Impacte la performance globale de cette unité.\nPlus la valeur est élevée, plus l'unité est performante. - Influenza qualsiasi prestazione di questa unità. Maggiore significa migliore. + 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. @@ -87,7 +87,7 @@ Wpływa na czas regeneracji podczas postoju. Więcej znaczy szybciej. 얼마나 빨리 회복하는지를 바꿉니다. 값이 클수록 더 나은 성능을 발휘합니다 Modifie la vitesse à laquelle le joueur récupère lorsqu'il se repose.\nPlus la valeur est élevée, plus la récupération est rapide. - Determina in quanto tempo il giocatore recupera quando rilassato. Maggiore significa migliore. + Determina quanto velocemente il giocatore recupera le energie quando si ferma. Maggiore significa migliore. 決定玩家休息多久就能回復體力,值越高恢復越快 决定玩家休息多久就能恢复体力,值越高恢复越快 Изменяет скорость восстановления игрока во время отдыха. Чем выше, тем быстрее. @@ -102,7 +102,7 @@ Współczynnik masy ekwipunku 부담 요인 Facteur de charge - Fattore Caricamento + Fattore Carico 負重量 重量系数 Фактор нагрузки @@ -117,7 +117,7 @@ Zmniejsza lub zwiększa wpływ ciężaru ekwipunku na wydolność gracza. Zero oznacza kompletny brak wpływu na wydolność. 플레이어가 무게에 따라 얼마나 영향받는지를 증가시키거나 감소시킵니다. 0의 경우 플레이어가 장비 무게에 영향받지 않습니다. Augmente ou diminue l'influence du poids sur les performances du joueur.\nUne valeur nulle indique que le poids de l'équipement n'a aucun impact sur les performances. - Incrementa o decrementa quanto il peso influenza le prestazioni dei giocatori. Zero significa che il peso dell'equipaggiamento non ha alcuna influenza nelle prestazioni. + Determina quanto il peso trasportato influenza le prestazioni dei giocatori. Zero significa che il peso dell'equipaggiamento non influisce sulle prestazioni. 增加或降低玩家所能承受的負重量. 如設定值為0, 代表裝備的重量將不會影響到玩家的體力表現 增加或降低玩家所能承受的负重量。如设定值为0,代表装备的重量将不会影响到玩家的体力表现 Увеличивает или уменьшает вес, влияющий на производительность игроков. Ноль означает, что вес снаряжения не влияет на производительность @@ -147,76 +147,22 @@ Wpływa na to w jakim stopniu stromy teren wpływa na utratę wytrzymałości. Więcej oznacza szybszą utratę wytrzymałości. 경사도에 따라 얼마나 피로해지는지를 정합니다. 값이 클수록 더 많은 피로를 유발합니다. Définit à quel point un terrain escarpé réduit l'endurance du joueur.\nPlus la valeur est élevée, moins le joueur est endurant. - Stabilisce quanto la pendenza del terreno incrementa la perdita della stamina. Maggiore significa più stamina persa. + Determina quanto la pendenza del terreno incrementa la perdita della stamina. Maggiore significa più stamina persa. 設定陡峭的地形將會影響多少體力的流失,值越高代表體力流失越快 设定陡峭的地形将会影响多少体力的流失速度,值越高代表体力流失越快 Устанавливает, насколько крутая местность увеличивает потерю выносливости. Чем выше, тем быстрее теряется выносливость. Define o quanto que um terreno íngrime aumenta na perda de estamina. Quanto maior, maior a perda de estamina. Nastavuje, o kolik strmý terén zvyšuje ztrátu výdrže. Vyšší znamená vyšší ztrátu výdrže. - - Sway factor - Factor de balanceo de mira - Verwacklungsfaktor - 手ぶれ因数 - 抖动系数 - 抖動因素 - Facteur de tremblement - Fattore di oscillazione - Czynnik kołysania - Фактор колебания прицела - Fator de Balanço de Mira - Faktor kývání - 손떨림 정도 - - - Influences the amount of weapon sway. Higher means more sway. - Afecta al la estabilidad de la mira. Más alto significa más balanceo - Beeinflusst, wie ruhig man eine Waffe halten kann. Ein höherer Wert bedeutet weniger Stabilisierung. - 武器を持つ手のぶれ度合いを設定します。 値が高ければ高いほど、手ぶれが強くなります。 - 影响手持武器的晃动程度,数值越高,抖动的越厉害。 - 影響手持武器晃動程度,數值越高抖動越厲害 - Influe sur l'amplitude du tremblement de l'arme. Une valeur plus élevée signifie plus de tremblement. - Influenza l'ammontare di oscillazione dell'arma. Maggiore significa più oscillazione. - Wpływa na poziom kołysania broni. Większa ilość znaczy większe kołysanie. - Влияет на колебания прицела оружия. Чем выше - тем больше. - Influencia a quantidade de balanço da mira da arma. Quanto maior, mais balanço. - Ovlivňuje množství kývání zbraní. Vyšší znamená více kývání. - 손떨림의 정도를 정합니다. 높을 수록 많이 휘적입니다. - - - Rested sway factor - Facteur de balancement au repos - 휴식 시 손떨림 정도 - Verwacklungsfaktor, wenn aufgelegt - - - Influences the amount of weapon sway while weapon is rested. - Influence le degré de balancement de l'arme au repos. - 무기가 아무런 행동도 하지 않는 동안 무기가 흔들리는 정도를 정합니다. - Beeinflusst, wie ruhig man die Waffe hält, während sie aufgelegt ist. - - - Deployed sway factor - Facteur de balancement déployé - 거치 시 손떨림 정도 - Verwacklungsfaktor, wenn Zweibein aufgestellt ist. - - - Influences the amount of weapon sway while weapon is deployed. - Influence le degré de balancement de l'arme déployée. - 무기를 거치하는 동안 무기를 흔드는 정도를 정합니다. - Beeinflusst, wie ruhig man die Waffen hält, während das Zweibein aufgestellt ist. - Enabled Activada Aktiv - アドバンスド ファティーグを有効化 + 有効化 Włączone 활성화 Activé - Abilitato + Abilitata 啟用 启用 Включена @@ -227,14 +173,14 @@ Enables/disables Advanced Fatigue. Activa/desactiva la fatiga avanzada Aktiviert/deaktiviert Advanced Fatigue. - アドバンスド ファティーグを有効化します。 + アドバンスド疲労は高度な疲労管理システムを有効化します。 Włącza/wyłącza zaawansowaną wytrzymałość 고급 피로도 활성화/비활성화 Active/Désactive la fatigue avancée. - Abilita/disabilita la Fatica Avanzata. + Abilita/Disabilita la Fatica Avanzata. 啟用/關閉進階體力. 启用/关闭进阶体力。 - Включает / Отключает Продвинутую усталость + Включает/отключает Продвинутую усталость Ativa/Desativa Fadiga Avançada. Aktivuje / deaktivuje Pokročilou únavu. @@ -275,7 +221,7 @@ Blende Ausdauerleiste automatisch aus 體力條自動淡去 自动淡化体力条 - Dissolvenza automatica della barra della stamina + Nascondi in automatico la barra della stamina Automaticky schovat lištu výdrže Fondu automatique de la barre d'endurance 自動的にスタミナバーを非表示 diff --git a/addons/advanced_throwing/XEH_postInit.sqf b/addons/advanced_throwing/XEH_postInit.sqf index 96b0fbb09b..d91129b025 100644 --- a/addons/advanced_throwing/XEH_postInit.sqf +++ b/addons/advanced_throwing/XEH_postInit.sqf @@ -2,26 +2,18 @@ // Fired XEH GVAR(ammoEventHandlers) = createHashMap; -[QGVAR(throwFiredXEH), FUNC(throwFiredXEH)] call CBA_fnc_addEventHandler; +[QGVAR(throwFiredXEH), LINKFUNC(throwFiredXEH)] call CBA_fnc_addEventHandler; // Exit on HC if (!hasInterface) exitWith {}; -// Ammo/Magazines look-up hash for correctness of initSpeed -GVAR(ammoMagLookup) = call CBA_fnc_createNamespace; -{ - { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - if (_ammo != "") then { GVAR(ammoMagLookup) setVariable [_ammo, _x]; }; - } count (getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines")); - nil -} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); - +// Temporary Wind Info indication +GVAR(tempWindInfo) = false; // Add keybinds ["ACE3 Weapons", QGVAR(prepare), localize LSTRING(Prepare), { // Condition - if (!([ACE_player] call FUNC(canPrepare))) exitWith {false}; + if !([ACE_player] call FUNC(canPrepare)) exitWith {false}; if (EGVAR(common,isReloading)) exitWith {true}; // Statement diff --git a/addons/advanced_throwing/XEH_preInit.sqf b/addons/advanced_throwing/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/advanced_throwing/XEH_preInit.sqf +++ b/addons/advanced_throwing/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/advanced_throwing/XEH_preStart.sqf b/addons/advanced_throwing/XEH_preStart.sqf index 022888575e..efd2ca1f7e 100644 --- a/addons/advanced_throwing/XEH_preStart.sqf +++ b/addons/advanced_throwing/XEH_preStart.sqf @@ -1,3 +1,21 @@ #include "script_component.hpp" #include "XEH_PREP.hpp" + +// Ammo/Magazines look-up hash for correctness of initSpeed +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; + +private _ammoMagLookup = createHashMap; + +{ + { + private _ammo = getText (_cfgMagazines >> _x >> "ammo"); + if (_ammo != "") then { + _ammoMagLookup set [configName (_cfgAmmo >> _ammo), _x]; + }; + } forEach (getArray (_cfgThrow >> _x >> "magazines")); +} forEach (getArray (_cfgThrow >> "muzzles")); + +uiNamespace setVariable [QGVAR(ammoMagLookup), compileFinal _ammoMagLookup]; diff --git a/addons/advanced_throwing/functions/fnc_canThrow.sqf b/addons/advanced_throwing/functions/fnc_canThrow.sqf index 06cf166f88..8b2987eafa 100644 --- a/addons/advanced_throwing/functions/fnc_canThrow.sqf +++ b/addons/advanced_throwing/functions/fnc_canThrow.sqf @@ -19,7 +19,7 @@ params ["_unit"]; if !(_unit getVariable [QGVAR(inHand), false]) exitWith {false}; -if (vehicle _unit != _unit) exitWith { +if (!isNull objectParent _unit) exitWith { private _startPos = eyePos _unit; private _aimLinePos = AGLToASL (positionCameraToWorld [0, 0, 1]); private _intersections = lineIntersectsSurfaces [_startPos, _aimLinePos, _unit, objNull, false]; diff --git a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf index 5bc3f22b57..f85c33dbde 100644 --- a/addons/advanced_throwing/functions/fnc_drawThrowable.sqf +++ b/addons/advanced_throwing/functions/fnc_drawThrowable.sqf @@ -43,13 +43,10 @@ if ((!_primed) && {!((_throwableMag in (uniformItems ACE_player)) || {_throwable // Get correct throw power for primed grenade if (_primed) then { - private _ammoType = typeOf _activeThrowable; - _throwableMag = GVAR(ammoMagLookup) getVariable _ammoType; - if (isNil "_throwableMag") then { - // What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke) - // Just use HandGrenade as it has an average initSpeed value - _throwableMag = "HandGrenade"; - }; + // If ammo type is not found: + // What we're trying to throw must not be a normal throwable because it is not in our lookup hash (e.g. 40mm smoke) + // Just use HandGrenade as it has an average initSpeed value + _throwableMag = (uiNamespace getVariable QGVAR(ammoMagLookup)) getOrDefault [typeOf _activeThrowable, "HandGrenade"]; }; // Some throwables have different classname for magazine and ammo diff --git a/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf b/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf index 744a6d7aae..3b88564eae 100644 --- a/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf +++ b/addons/advanced_throwing/functions/fnc_exitThrowMode.sqf @@ -53,6 +53,12 @@ _unit setVariable [QGVAR(dropDistance), DROP_DISTANCE_DEFAULT]; // Remove controls hint (check if ever enabled is inside the function) call EFUNC(interaction,hideMouseHint); +// Hide wind info after throw, if it was temporarily enabled for the throw +if (GVAR(tempWindInfo)) then { + EGVAR(weather,WindInfo) = false; + GVAR(tempWindInfo) = false; +}; + // Remove throw action [_unit, "DefaultAction", _unit getVariable [QGVAR(throwAction), -1]] call EFUNC(common,removeActionEventHandler); 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/advanced_throwing/functions/fnc_prepare.sqf b/addons/advanced_throwing/functions/fnc_prepare.sqf index 070870879b..c158ad5150 100644 --- a/addons/advanced_throwing/functions/fnc_prepare.sqf +++ b/addons/advanced_throwing/functions/fnc_prepare.sqf @@ -21,7 +21,7 @@ TRACE_1("params",_unit); // Select next throwable if one already in hand if (_unit getVariable [QGVAR(inHand), false]) exitWith { TRACE_1("inHand",_unit); - if (!(_unit getVariable [QGVAR(primed), false])) then { + if !(_unit getVariable [QGVAR(primed), false]) then { TRACE_1("not primed",_unit); // Restore muzzle ammo (setAmmo 1 has no impact if no appliccable throwable in inventory) // selectNextGrenade relies on muzzles array (setAmmo 0 removes the muzzle from the array and current can't be found, cycles between 0 and 1 muzzles) @@ -35,6 +35,11 @@ if (isNull (_unit getVariable [QGVAR(activeThrowable), objNull]) && {(currentThr TRACE_1("no throwables",_unit); }; +// Temporarily enable wind info, to aid in throwing smoke grenades effectively +if (GVAR(enableTempWindInfo) && {!(missionNamespace getVariable [QEGVAR(weather,WindInfo), false])}) then { + [] call EFUNC(weather,displayWindInfo); + GVAR(tempWindInfo) = true; +}; _unit setVariable [QGVAR(inHand), true]; diff --git a/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf b/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf index 15cae41585..d45f2add93 100644 --- a/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf +++ b/addons/advanced_throwing/functions/fnc_renderPickUpInteraction.sqf @@ -44,8 +44,7 @@ _addedPickUpHelpers pushBack _pickUpHelper; _throwablesHelped pushBack _x; }; - nil - } count _nearThrowables; + } forEach _nearThrowables; _args set [0, getPosASL ACE_player]; _args set [3, _nearThrowables]; @@ -56,11 +55,10 @@ { // Only handling with attachTo works nicely _x attachTo [_x getVariable [QGVAR(throwable), objNull], [0, 0, 0]]; - nil - } count _addedPickUpHelpers; + } forEach _addedPickUpHelpers; } else { TRACE_1("Cleaning Pick Up Helpers",count _addedPickUpHelpers); - {deleteVehicle _x} count _addedPickUpHelpers; + {deleteVehicle _x} forEach _addedPickUpHelpers; [_idPFH] call CBA_fnc_removePerFrameHandler; }; }, 0, [(getPosASL ACE_player) vectorAdd [-100, 0, 0], [], [], []]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/advanced_throwing/functions/fnc_throw.sqf b/addons/advanced_throwing/functions/fnc_throw.sqf index 0380d3d896..d6b38a6a0c 100644 --- a/addons/advanced_throwing/functions/fnc_throw.sqf +++ b/addons/advanced_throwing/functions/fnc_throw.sqf @@ -20,7 +20,7 @@ TRACE_1("params",_unit); // Prime the throwable if it hasn't been cooking already // Next to proper simulation this also has to happen before delay for orientation of the throwable to be set -if (!(_unit getVariable [QGVAR(primed), false])) then { +if !(_unit getVariable [QGVAR(primed), false]) then { [_unit] call FUNC(prime); }; @@ -45,7 +45,7 @@ if (!(_unit getVariable [QGVAR(primed), false])) then { private _newVelocity = (_p1 vectorFromTo _p2) vectorMultiply _velocity; // Adjust for throwing from inside vehicles, where we have a vehicle-based velocity that can't be compensated for by a human - if (vehicle _unit != _unit) then { + if (!isNull objectParent _unit) then { _newVelocity = _newVelocity vectorAdd (velocity (vehicle _unit)); }; diff --git a/addons/advanced_throwing/initSettings.sqf b/addons/advanced_throwing/initSettings.inc.sqf similarity index 83% rename from addons/advanced_throwing/initSettings.sqf rename to addons/advanced_throwing/initSettings.inc.sqf index d4ebe14918..d8396637c5 100644 --- a/addons/advanced_throwing/initSettings.sqf +++ b/addons/advanced_throwing/initSettings.inc.sqf @@ -40,3 +40,11 @@ private _category = format ["ACE %1", localize LSTRING(Category)]; true, 1 ] call CBA_fnc_addSetting; + +[ + QGVAR(enableTempWindInfo), "CHECKBOX", + [LSTRING(EnableTempWindInfo_DisplayName), LSTRING(EnableTempWindInfo_Description)], + _category, + true, + 0 +] call CBA_fnc_addSetting; diff --git a/addons/advanced_throwing/stringtable.xml b/addons/advanced_throwing/stringtable.xml index 793c426dd3..fc9cf2705a 100644 --- a/addons/advanced_throwing/stringtable.xml +++ b/addons/advanced_throwing/stringtable.xml @@ -5,7 +5,7 @@ Advanced Throwing Lanzamiento Avanzado Улучшенный бросок гранат - アドバンスド スローイング + アドバンスド投擲 Zaawansowane rzucanie Erweitertes Wurfsystem 고급 투척 @@ -21,7 +21,7 @@ Allows changing advanced throwing behaviour. Permite modificar el comportamiento del lanzamiento avanzado Позволяет настраивать поведение улучшенного броска гранат. - アドバンスド スローイングの動作挙動を変更します。 + アドバンスド投擲は投擲の高度な動作挙動を変更可能にします。 Zezwala na zmianę zachowania zaawansowanego trybu rzucania. Erlaubt es, das Verhalten des erweiterten Wurfsystems zu ändern. 고급 투척 행위를 허가합니다 @@ -36,7 +36,7 @@ Enable Advanced Throwing Activar Lanzamiento Avanzado Вкл. улучшенный бросок - アドバンスド スローイングを有効化 + アドバンスド投擲を有効化 Aktywuj zaawansowane rzucanie Aktiviere erweitertes Wurfsystem 고급 투척 활성화 @@ -52,7 +52,7 @@ Enables advanced throwing system. Activa el Lanzamiento Avanzado Включает систему улучшенного броска. - アドバンスド スローイングを有効化します。 + アドバンスド投擲は高度な投擲システムを有効化します。 Aktywuje system zaawansowanego rzucania. Aktiviert das erweiterte Wurfsystem. 고급 투척을 활성화 합니다 @@ -68,7 +68,7 @@ Show Throw Arc Mostrar Arco de Lanzamiento Показать траекторию броска - 投てき軌道を表示 + 投擲軌道を表示 Pokaż trasę lotu Zeige Wurfbogen 투척 궤적 표시 @@ -84,7 +84,7 @@ Enables visualization of the throw arc (where throwable will fly). Activa la visualización del arco de lanzamiento (donde irá el objeto lanzado) Включает визуализацию траектории броска (как полетит граната). - 投てき軌道 (投てき物がどこに飛ぶか) の表示を有効化します。 + 投擲軌道 (投擲物がどこに飛ぶか) の表示を有効化します。 Wyświetla wizualizację trasy przelotu granatu. Aktiviert die Visualisierung des Wurfbogens (wohin das Objekt geworfen werden wird). 투척 궤도를 시각화 합니다(투척물이 어디로 갈지) @@ -99,12 +99,12 @@ Show Throwing Mouse Controls Mostrar controles de ratón de lanzamiento Показывать управление мышью - 投てきのマウス操作を表示 + 投擲のマウス操作を表示 Pokaż podpowiedzi sterowania myszą Zeige Maussteuerung beim Werfen 마우스 조작 표시 Afficher les contrôles à la souris du lancé - Mostra Comandi Mouse Lancio + Mostra Comandi Mouse di Lancio 顯示滑鼠投擲控制提示 显示鼠标投掷控制提示 Mostrar os controles de mouse para Arremesso @@ -114,7 +114,7 @@ Enables visual cues for mouse controls when throwable is prepared. Activa muestras visuales para los controles del ratón cuando el objeto lanzable está preparado Включает отображение подсказок по управлению мышью, когда граната подготовлена. - 投てき物を構える時、マウス操作の説明表示を有効化します。 + 投擲物を構える時、マウス操作の説明表示を有効化します。 Wyświetla podpowiedzi sterowania myszą kiedy obiekt miotany jest w ręku. Aktiviert visuelle Hinweise zur Maussteuerung, wenn ein Objekt zum Werfen vorbereitet wird. 투척물을 준비시 마우스 조작을 시각화해서 보여줍니다 @@ -129,12 +129,12 @@ Enable Throwables Pick Up Habilitar recoger objetos lanzados Вкл. подбор гранат - 投てき物の拾い上げを有効化 + 投擲物の拾い上げを有効化 Zezwól na podnoszenie obiektów miotanych Aktiviere Aufheben von Wurfobjekten 투척물 줍기 활성화 Permettre le ramassage d'objets lançables - Abilita Raccogli Oggetti + Abilita Raccolta Lanciabili 啟用可撿取地面投擲物 启用捡取地面投掷物 Permitir pegar arremessáveis @@ -144,12 +144,12 @@ Enables ability to pick up throwables from the ground. Activa la habilidad de coger objetos lanzados del suelo Включает возможность подбирать гранаты с земли. - 地面に落ちている投てき物を拾い上げる機能を有効化します。 + 地面に落ちている投擲物を拾う機能を有効化します。 Umożliwia podnoszenie obiektów miotanych z ziemi. Aktiviert die Möglichkeit, geworfene Objekte wieder vom Boden aufzuheben. 땅에 떨어진 투척물을 주울 수 있게 해줍니다. Active la possibilité de ramasser des objets lançables du sol. - Abilita la possibilità di raccogliere un oggetto lanciabile da terra. + Permette ai giocatori di raccogliere un oggetto lanciabile da terra. 啟用後, 可撿取地面上的投擲物 启用后,可捡取地面上的投掷物 Permite que objetos arremessados sejam pegos do chão. (ACE Menu de Interação) @@ -159,12 +159,12 @@ Enable Attached Throwables Pick Up Activar coger objetos lanzables que se enganchan Вкл. подбор прикрепленных гранат - 取り付けられた投てき物の拾い上げを有効化 + 装着済の投擲物の拾い上げを有効化 Zezwól na podnoszenie przyczepionych obiektów miotanych Aktiviere erneute Aufnahme befestigter Wurfobjekte 부착 투척물 줍기 활성화 Activer le ramassage d'objets lançables attachés - Abilita Raccogli Oggetti Lanciabili da altri Oggetti + Abilita Raccolta Lanciabili Attaccati 啟用可撿取附著投擲物 启用捡取附着投掷物 Permitir pegar arremessáveis fixados @@ -174,27 +174,47 @@ Enables ability to pick up throwables from attached objects. Activa la habilidad de lanzar objetos enganchados Включает возможность подбирать гранаты, прикрепленные к объектам. - 取り付けられた投てき物を拾い上げる機能を有効化します。 + オブジェクトに装着された投擲物を拾う機能を有効化します。 Umożliwia podnoszenie obiektów miotanych przyczepionych do innych obiektów. Aktiviert die Möglichkeit, befestigte Wurfobjekte erneut aufzunehmen. 부착된 투척물을 주울 수 있게 해줍니다. Active la possibilité de ramasser des objets lançables attachés à d'autres objets. - Abilita la possibilità di raccogliere gli oggetti lanciabili dagli altri oggetti. + Permette ai giocatori di raccogliere gli oggetti lanciabili da altri oggetti attaccati. 啟用後, 可撿取附著在物件上的投擲物 启用后,可捡取附着在物体上的投掷物 Permite que arremessáveis fixados em objetos sejam pegos. Zapíná schopnost zvednutí předmětů z objektů ke kterým jsou připnuté. + + Show Temporary Wind Info + Zeige temporäre Windinformationen + Mostra informazioni sul vento temporaneamente + 一時的に風の情報を表示 + 바람 정보 임시로 표시 + Afficher temporairement les informations sur le vent + Временно показать информацию о ветре + Mostrar información del viento temporalmente + + + Temporarily display Wind Info while throwing, to aid in placing smoke grenades effectively. + Zeige während des werfens Windinformationen an, um Rauchgranaten effektiver zu platzieren. + Mostra le informazioni sul vento durante il lancio di granate, facilitando il piazzamento ottimale di fumogeni. + 投擲行動中に風向きの情報を一時的に表示し、発煙手榴弾の煙幕を効果的に展開しやすくします。 + 연막탄을 효과적으로 배치하는 데 도움이 되도록 투척하는 동안 일시적으로 바람 정보를 표시합니다. + Affiche les informations sur le vent pendant le lancement pour placer les grenades fumigènes plus efficacement. + Временно отображайте информацию о ветре во время броска, чтобы помочь эффективно разместить дымовые шашки. + Mostrar información del viento temporalmente mientras se lanza, para ayudar a lanzar las granadas de humo de forma efectiva. + Prepare/Change Throwable Preparar/Cambiar objetos lanzables Подготовить/заменить гранату - 投てき物の準備/変更 + 投擲物の準備/変更 Przygotuj/zmień ob. miotany Wurfobjekt vorbereiten/wechseln 투척물 준비/변경 Préparer/Changer d'objet lançable - Prepara/Cambia Oggetto lanciabile + Prepara/Cambia Oggetto Lanciabile 準備/變更投擲物 准备/变更投掷物 Preparar/Mudar Arremessável @@ -204,12 +224,12 @@ Throwable Drop Mode (Hold) Modo soltar objeto lanzable (Mantener pulsado) Режим броска гранаты (удерживать) - 投てきモード (押している間) + 投擲モード (押している間) Tryb upuszczania ob. miotanego (przytrzymaj) Wurfobjekt Fallmodus (halten) 투척물 떨어뜨리기 모드(꾹눌러서) Mode de lancé de l'objet (Tenir) - Modalità Oggetto Gettabile (Mantenere) + Modalità Gettare (Tieni premuto) 投擲模式 (按住) 投掷模式(按住) Modo de Arremesso (Segurar) @@ -219,12 +239,12 @@ Throwable Drop Mode (Toggle) Modo soltar objeto lanzable (interruptor) Режим броска гранаты (переключить) - 投てきモード (切り替え) + 投擲モード (切り替え) Tryb upuszczania ob. miotanego (przełącz) Wurfobjekt Fallmodus (umschalten) 투척물 떨어뜨리기 모드(토글) Mode de lancé de l'objet (Basculer) - Modalità Oggetto lanciabile Gettabile (Interruttore) + Modalità Getta Oggetto (Cambia) 投擲模式 (切換) 投掷模式(切换) Modo de Arremesso (Alternar) @@ -234,12 +254,12 @@ Primed Preparado Подготовлена - 点火 + を点火した Odbezpieczony Scharf gemacht 뇌관 작동 amorcée - Armato + Innescato 引信開始燃燒 已开引信 Preparado @@ -254,7 +274,7 @@ Werfen 던지기 Lancer - Lanciare + Lancia 投擲 投掷 Arremessar @@ -270,7 +290,7 @@ (Scrollen) Modus wechseln (마우스 휠) 모드 변경 (Défilement) Changer de mode - (Scorrere) Cambio Modalità + (Scorri) Cambia Modalità (滾輪) 變更模式 (滚轮)变更模式 (Roda do Mouse) Alternar modo @@ -286,7 +306,7 @@ (Scrollen) Erweitern (마우스 휠) 연장 (Défilement) Étendre - (Scorrere) Estendere + (Scorri) Estendi (滾輪) 延長 (滚轮)延长 (Roda do Mouse) Estender @@ -302,7 +322,7 @@ (Klicken) Abkochen (클릭) 예열 (Clique) Dégoupiller - (Click) Arma + (Click) Innesca (點擊) 提早拉開引信 (点击)提早拉开引信 (Clique) Cozinhar @@ -313,7 +333,7 @@ Pick Up Coger Подобрать - 拾い上げる + 拾う Podnieś Aufheben 줍기 diff --git a/addons/ai/XEH_postInit.sqf b/addons/ai/XEH_postInit.sqf index fce5152e3d..7c4f79f8fb 100644 --- a/addons/ai/XEH_postInit.sqf +++ b/addons/ai/XEH_postInit.sqf @@ -16,7 +16,7 @@ } forEach _sections; }] call CBA_fnc_addEventHandler; -[QGVAR(unGarrison), FUNC(unGarrison)] call CBA_fnc_addEventHandler; +[QGVAR(unGarrison), LINKFUNC(unGarrison)] call CBA_fnc_addEventHandler; [QGVAR(doMove), { params ["_unitsArray"]; @@ -73,6 +73,6 @@ if (isServer) then { ["CAManBase", "init", { // wait for HMD to be assigned so `hmd _unit` works - [FUNC(assignNVG), _this, 1] call CBA_fnc_waitAndExecute; + [LINKFUNC(assignNVG), _this, 1] call CBA_fnc_waitAndExecute; }] call CBA_fnc_addClassEventHandler; }; diff --git a/addons/ai/XEH_preInit.sqf b/addons/ai/XEH_preInit.sqf index 5ec0849ff9..b8b036fb31 100644 --- a/addons/ai/XEH_preInit.sqf +++ b/addons/ai/XEH_preInit.sqf @@ -11,6 +11,6 @@ if (isServer) then { GVAR(assignNVGstate) = false; }; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/ai/functions/fnc_garrison.sqf b/addons/ai/functions/fnc_garrison.sqf index ead982d951..4b8f84fce6 100644 --- a/addons/ai/functions/fnc_garrison.sqf +++ b/addons/ai/functions/fnc_garrison.sqf @@ -7,8 +7,8 @@ * 0: The building(s) nearest this position are used * 1: Limit the building search to those type of building * 2: Units that will be garrisoned - * 3: Radius to fill building(s) (default: 50) - * 4: 0: even filling, 1: building by building, 2: random filling (default: 0) + * 3: Radius to fill building(s) (default: 50) + * 4: 0: even filling, 1: building by building, 2: random filling (default: 0) * 5: True to fill building(s) from top to bottom (default: false) (note: only works with filling mode 0 and 1) * 6: Teleport units (default: false) @@ -33,7 +33,7 @@ if (_startingPos isEqualTo [0,0,0]) exitWith { [LSTRING(GarrisonInvalidPosition)] call EFUNC(common,displayTextStructured); }; -if (count _unitsArray == 0 || {isNull (_unitsArray select 0)}) exitWith { +if (_unitsArray isEqualTo [] || {isNull (_unitsArray select 0)}) exitWith { TRACE_1("fnc_garrison: Units error",_unitsArray); [LSTRING(GarrisonNoUnits)] call EFUNC(common,displayTextStructured); }; @@ -43,7 +43,7 @@ if (_fillingRadius >= 50) then { _buildings = [_buildings] call CBA_fnc_shuffle; }; -if (count _buildings == 0) exitWith { +if (_buildings isEqualTo []) exitWith { TRACE_1("fnc_garrison: Building error",_buildings); [LSTRING(GarrisonNoBuilding)] call EFUNC(common,displayTextStructured); }; @@ -128,7 +128,7 @@ switch (_fillingType) do { } else { private _pos = _building select 0; private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); - LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits,{floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); @@ -177,7 +177,7 @@ switch (_fillingType) do { } else { private _pos = _building select 0; private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); - LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits,{floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); @@ -224,7 +224,7 @@ switch (_fillingType) do { } else { private _pos = selectRandom _building; private _nearestUnits = (_pos nearEntities ["CAManBase", 2]); - LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits, {floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); + LOG(format [ARR_3("fnc_garrison: Unit detection | %1 units nearby | %2 units within height",count _nearestUnits,{floor ((getPos _x) select 2) == floor (_pos select 2)} count _nearestUnits)]); if (count _nearestUnits > 0 && {[_nearestUnits, _pos] call _fnc_comparePos}) then { LOG(format [ARR_2("fnc_garrison: Unit present | removing position | %1 positions remaining for this building",count (_buildingsIndex select (_buildingsIndex find _building)) - 1)]); @@ -258,7 +258,7 @@ switch (_fillingType) do { }; }; -TRACE_1(format [ARR_2("fnc_garrison: while loop ended | %1 units ready to be treated by PFH",count _unitMoveList)], _teleport); +TRACE_1(format [ARR_2("fnc_garrison: while loop ended | %1 units ready to be treated by PFH",count _unitMoveList)],_teleport); // Update the unit list and remove duplicate positions and units private _garrison_unitMoveList = missionNameSpace getVariable [QGVAR(garrison_unitMoveList), []]; @@ -279,5 +279,5 @@ if (_teleport) then { [_unitMoveList] call FUNC(garrisonMove); }; -TRACE_1(format [ARR_3("fnc_garrison: End | %1 units left | %2 buildings left", count _unitsArray, count _buildingsIndex)], _unitsArray); +TRACE_1(format [ARR_3("fnc_garrison: End | %1 units left | %2 buildings left",count _unitsArray,count _buildingsIndex)],_unitsArray); _unitsArray diff --git a/addons/ai/functions/fnc_garrisonMove.sqf b/addons/ai/functions/fnc_garrisonMove.sqf index 588ebb2016..4d1c471a0e 100644 --- a/addons/ai/functions/fnc_garrisonMove.sqf +++ b/addons/ai/functions/fnc_garrisonMove.sqf @@ -81,13 +81,13 @@ if (isNil QGVAR(garrison_moveUnitPFH)) then { [QGVAR(enableAttack), [[_unit], true], _unit] call CBA_fnc_targetEvent; }; - LOG(format [ARR_2("garrisonMove PFH: unit in position | %1 units left", count _unitMoveList)]); + LOG(format [ARR_2("garrisonMove PFH: unit in position | %1 units left",count _unitMoveList)]); }; // Check if unit is alive or even existing if (!alive _unit || {_unit getVariable [QGVAR(garrisoned), false]}) then { _unitMoveList deleteAt (_unitMoveList find _x); - LOG(format [ARR_2("garrisonMove PFH: unit dead, deleted or garrisoned via TP | %1 units left", count _unitMoveList)]); + LOG(format [ARR_2("garrisonMove PFH: unit dead, deleted or garrisoned via TP | %1 units left",count _unitMoveList)]); } else { private _unitPos = getPos _unit; diff --git a/addons/ai/functions/fnc_unGarrison.sqf b/addons/ai/functions/fnc_unGarrison.sqf index ab0c525a24..09ebc3e63d 100644 --- a/addons/ai/functions/fnc_unGarrison.sqf +++ b/addons/ai/functions/fnc_unGarrison.sqf @@ -28,7 +28,7 @@ _units = _units select {local _x}; private _leader = leader _unit; - TRACE_3("fnc_ungarrison: unit and leader",_unit , _leader, (_leader == _unit)); + TRACE_3("fnc_ungarrison: unit and leader",_unit,_leader,(_leader == _unit)); _unit setVariable [QGVAR(garrisonned), false, true]; diff --git a/addons/ai/initSettings.sqf b/addons/ai/initSettings.inc.sqf similarity index 100% rename from addons/ai/initSettings.sqf rename to addons/ai/initSettings.inc.sqf diff --git a/addons/ai/stringtable.xml b/addons/ai/stringtable.xml index 0014330650..b9df8bb35a 100644 --- a/addons/ai/stringtable.xml +++ b/addons/ai/stringtable.xml @@ -6,7 +6,7 @@ AI IA IA - AI + IA SI ИИ KI @@ -85,15 +85,25 @@ Auto-Equip NVGs Automatyczne zakładanie NVG Automatisch NVGs ausrüsten + Equipaggia NVG in automatico 야투경 자동 창착 Equipement JVN automatique + Equipar NVGs automaticamente + 暗視装置の自動装備 + Автоматическое оснащение ПНВ + Auto equipar gafas de visión nocturna Equips NVG in inventory during night time and unequips it during day time.\nDoes not add NVGs to inventory! Zakłada NVG w nocy i zdejmuje je w ciągu dnia.\nNie dodaje NVG do ekwipunku! Rüstet NVG nachts aus dem Inventar aus und entfernt es tagsüber.\nFügt keine NVGs zum Inventar hinzu! + Equipaggia NVG dall'inventario durante la notte, e li mette nell'inventario durante il giorno.\nNon aggiunge NVG all'inventario se non sono presenti. 야간에는 야투경을 소지품에 장착하고 주간에는 장착을 해제합니다.\n주의! 소지품에 야투경을 추가하는 것이 아닙니다! 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Не добавляет ПНВ в инвентарь! + Equipa las gafas de visión nocturna en el inventario cuando es de noche, y las desequipa cuando es de día.\nNo añade las gafas al inventario! diff --git a/addons/aircraft/functions/fnc_canShowEject.sqf b/addons/aircraft/functions/fnc_canShowEject.sqf index 08c55eb781..9239c413a7 100644 --- a/addons/aircraft/functions/fnc_canShowEject.sqf +++ b/addons/aircraft/functions/fnc_canShowEject.sqf @@ -30,6 +30,6 @@ _vehicle == vehicle _unit if (_unit == _x select FULLCREW_UNIT) exitWith { _ejectVarName = format [QGVAR(ejectAction_%1_%2), _x select FULLCREW_ROLE, _x select FULLCREW_TURRETPATH]; }; - } count fullCrew _vehicle; + } forEach fullCrew _vehicle; _vehicle getVariable [_ejectVarName, false] } diff --git a/addons/aircraft/functions/fnc_droneAddActions.sqf b/addons/aircraft/functions/fnc_droneAddActions.sqf index 38ca53e4c6..895004f0e9 100644 --- a/addons/aircraft/functions/fnc_droneAddActions.sqf +++ b/addons/aircraft/functions/fnc_droneAddActions.sqf @@ -22,7 +22,7 @@ if (!alive _vehicle) exitWith {}; if (_vehicle getVariable [QGVAR(droneActionsAdded), false]) exitWith {}; _vehicle setVariable [QGVAR(droneActionsAdded), true]; -// move to location +// Move to location private _condition = { params ["_vehicle"]; (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} @@ -37,14 +37,63 @@ private _action = [QGVAR(droneSetWaypointMove), localize "$STR_AC_MOVE", "\a3\3DEN\Data\CfgWaypoints\Move_ca.paa", _statement, _condition] call EFUNC(interact_menu,createAction); [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); +// Follow unit/vehicle at turret location +_condition = { + params ["_vehicle"]; + private _target = cursorTarget; + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} && {!isNull _target} && {["CAManBase", "LandVehicle", "Ship"] findIf {_target isKindOf _x} != -1} +}; +_statement = { + params ["_vehicle"]; + private _group = group driver _vehicle; + private _pos = ([_vehicle, [0]] call FUNC(droneGetTurretTargetPos)) select 0; + [QGVAR(droneSetWaypoint), [_vehicle, _group, _pos, "FOLLOW", cursorTarget], _group] call CBA_fnc_targetEvent; + private _followDistance = _vehicle getVariable [QGVAR(wpFollowDistance), 0]; + [[LLSTRING(DroneFollowHint), _followDistance], 3] call EFUNC(common,displayTextStructured); +}; +_action = [QGVAR(droneSetWaypointFollow), localize "$STR_AC_FOLLOW", "\a3\3DEN\Data\CfgWaypoints\Follow_ca.paa", _statement, _condition] call EFUNC(interact_menu,createAction); +[_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); + +// Set drone follow distance +_condition = { + params ["_vehicle"]; + private _group = group driver _vehicle; + private _index = (currentWaypoint _group) min count waypoints _group; + private _waypoint = [_group, _index]; + (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} && {(waypointType _waypoint) == "HOLD"} +}; +_statement = { + params ["_vehicle", "", "_value"]; + _vehicle setVariable [QGVAR(wpFollowDistance), _value]; + [[LLSTRING(DroneFollowHint), _value], 3] call EFUNC(common,displayTextStructured); +}; +_action = [QGVAR(droneSetFollowDistance), LLSTRING(DroneFollowDistance), "", {}, _condition] call EFUNC(interact_menu,createAction); +private _base = [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); +private _followDistances = if (_vehicle isKindOf "Car_F") then { + [0, 25, 50, 100, 200] +} else { + [0, 100, 200, 300, 400, 500] +}; +{ + _action = [ + QGVAR(droneSetFollowDistance_) + str _x, + str _x, + "", + _statement, + {true}, + {}, + _x + ] call EFUNC(interact_menu,createAction); + [_vehicle, 1, _base, _action] call EFUNC(interact_menu,addActionToObject); +} forEach _followDistances; if (_vehicle isKindOf "Air") then { - // loiter at location + // Loiter at location _condition = { params ["_vehicle"]; (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} }; - _statement = { + _statement = { params ["_vehicle"]; private _group = group driver _vehicle; private _pos = ([_vehicle, [0]] call FUNC(droneGetTurretTargetPos)) select 0; @@ -55,7 +104,7 @@ if (_vehicle isKindOf "Air") then { [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); - // set height + // Set height _condition = { params ["_vehicle"]; (missionNamespace getVariable [QGVAR(droneWaypoints), true]) && {waypointsEnabledUAV _vehicle} && {(ACE_controlledUAV select 2) isEqualTo [0]} @@ -74,7 +123,7 @@ if (_vehicle isKindOf "Air") then { } forEach [20, 50, 200, 500, 2000]; - // set loiter radius + // Set loiter radius _condition = { params ["_vehicle"]; private _group = group driver _vehicle; @@ -97,7 +146,7 @@ if (_vehicle isKindOf "Air") then { } forEach [500, 750, 1000, 1250, 1500]; - // set loiter direction + // Set loiter direction _condition = { params ["_vehicle", "", "_args"]; private _group = group driver _vehicle; 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/aircraft/functions/fnc_droneSetWaypoint.sqf b/addons/aircraft/functions/fnc_droneSetWaypoint.sqf index 5c919564ce..953b99a357 100644 --- a/addons/aircraft/functions/fnc_droneSetWaypoint.sqf +++ b/addons/aircraft/functions/fnc_droneSetWaypoint.sqf @@ -8,6 +8,7 @@ * 1: Group * 2: Pos 2D * 3: Type + * 4: Target to follow (default: objNull) * * Return Value: * None @@ -18,7 +19,7 @@ * Public: No */ -params ["_vehicle", "_group", "_pos", "_type"]; +params ["_vehicle", "_group", "_pos", "_type", ["_target", objNull]]; TRACE_4("droneSetWaypoint",_vehicle,_group,_pos,_type); private _index = (currentWaypoint _group) min count waypoints _group; @@ -29,11 +30,39 @@ private _currentLoiterRadius = waypointLoiterRadius _waypoint; private _currentLoiterType = waypointLoiterType _waypoint; // Set pos to ATL -_pos set [2, if (_currentHeight >= 50) then { _currentHeight } else { 0 }]; +_pos set [ + 2, + [0, _currentHeight] select (_currentHeight >= 50) +]; -// [_group] call CBA_fnc_clearWaypoints; _waypoint = _group addWaypoint [_pos, 0]; -_waypoint setWaypointType _type; +// The Vanilla "FOLLOW"-type waypoint is not used directly, due to 2 main issues (as of v2.16): +// - It does not work at all for UGVs, which is a known issue https://feedback.bistudio.com/T126283; +// - No clear scripting way was found to mimic the UAV Terminal's "Follow Distance" functionality; +// Instead, the solution for both UAV and UGV following consists of a CBA PFH that moves a "HOLD"-type Waypoint every 3 seconds. +// Either on the target itself, or on the Drone's current position if the target is within the desired follow distance. +if (_type == "FOLLOW" && {["CAManBase", "LandVehicle", "Ship"] findIf {_target isKindOf _x} != -1}) then { + _waypoint setWaypointType "HOLD"; + [{ + params ["_args", "_handle"]; + _args params ["_vehicle", "_group", "_waypoint", "_target"]; + + if ( // Abort PFH if a new waypoint is created via UAV Terminal or ACE Interaction + _waypoint select 1 != currentWaypoint _group || + {!alive _vehicle} || {isNull _target} + ) exitWith { + deleteWaypoint _waypoint; + [_handle] call CBA_fnc_removePerFrameHandler; + }; + + private _followDistance = _vehicle getVariable [QGVAR(wpFollowDistance), 0]; + if ((_vehicle distance2D _target) < _followDistance) then { + _waypoint setWaypointPosition [getPosASL _vehicle, -1]; + } else { + _waypoint setWaypointPosition [getPosASL _target, -1]; + }; + }, 3, [_vehicle, _group, _waypoint, _target]] call CBA_fnc_addPerFrameHandler; +}; TRACE_3("",_currentHeight,_currentLoiterRadius,_currentLoiterType); if (_currentHeight > 1) then { _vehicle flyInHeight _currentHeight; }; diff --git a/addons/aircraft/stringtable.xml b/addons/aircraft/stringtable.xml index 6cd3700c73..041653fe2b 100644 --- a/addons/aircraft/stringtable.xml +++ b/addons/aircraft/stringtable.xml @@ -29,7 +29,7 @@ Открыть грузовой отсек Apri la rampa di carico Abrir porta de carga - カーゴ ドアを開く + 貨物室ドアを 開く 화물칸 개방 開啟貨艙門 开启货舱门 @@ -46,7 +46,7 @@ Закрыть грузовой отсек Chiudi la rampa di carico Fechar porta de carga - カーゴ ドアを閉じる + 貨物室ドアを 閉じる 화물칸 폐쇄 關閉貨艙門 关闭货舱门 @@ -61,16 +61,19 @@ 30mm Odłamkowo-Burzące - Zapalające 30mm Yüksek Patlayıcı 30mm Hochexplosiv/Brandladung - 30mm 焼夷りゅう弾 + 30mm Esplosivo/Incendiario + 30mm 焼夷榴弾 30mm Tříštivo-trhavá zápalná střela 30мм Осколочно-Фугасный Зажигательный 30mm 고폭소이탄 + 30mm Alto-Explosivo Incendiária 30mm HEI 30mm AEI 30毫米高爆燃燒 30mm 高爆燃烧 + 30mm HEI 30 mm HEI 30mm OB-Z 30mm HEI @@ -79,6 +82,7 @@ 30mm HEI 30мм ОФЗ 30mm HEI + 30mm AEI 30mm DU Armor Piercing @@ -86,13 +90,15 @@ 30毫米貧化鈾穿甲彈 30 mm 贫铀穿甲 30 mm UA Armor Piercing + 30mm AP Uranio Impoverito 30mm Zubożony Uran - Przebijające 30mm DU Zırh Delici 30mm abgereichertes panzerbrechendes Uraniumgeschoss - 30mm DU 徹甲弾 + 30mm 劣化ウラン徹甲弾 30mm Protipancéřová střela z ochuzeného Uranu 30мм ОУ Бронебойный Снаряд 30mm 열화우라늄 철갑탄 + 30mm DU Perfurante de Blindagem 30mm DU AP @@ -100,6 +106,7 @@ 30毫米貧鈾穿甲 30mm 贫铀穿甲 30 mm UA AP + 30mm AP-UI 30mm ZU-P 30mm DU AP 30mm DU-PB @@ -107,6 +114,7 @@ 30 mm DU AP 30мм ОУ БС 30mm DU AP + 30mm DU AP 30mm Combat Mix 4:1 DU:HEI @@ -114,13 +122,15 @@ 30毫米戰鬥混合彈4:1 穿甲:高爆 30mm 战斗混合 穿甲/高爆 4:1 30 mm Mix de Combat 4:1 UA:HEI + 30mm Misto 4:1 UI:HEI 30mm Mieszanka bojowa 4:1 ZU:OB-Z 30mm Combat Mix 4:1 DU:HEI 30mm Kampfmischung 4:1 DU:HEB - 30mm コンバット ミックス 4:1 DU:HEI + 30mm コンバット ミックス 4:1 劣化ウラン徹甲弾:焼夷榴弾 30mm Bojový Mix 4:1 DU:HEI 30мм Смешанное боепитание 4:1 ОУ:ОФЗ - 30mm 4:1 열화:고폭소이 + 30mm 열화우라늄:고폭소이 4:1 혼합 + 30mm Mix de Combate 4:1 DU:AEI 30mm CM 4:1 @@ -128,13 +138,14 @@ 30毫米 穿高混合 4:1 30mm 穿爆混合 4:1 30 mm MdC 4:1 + 30mm Misto 4:1 30mm MB 4:1 30mm CM 4:1 30mm KM 4:1 30mm CM 4:1 30mm BM 4:1 30мм СБ 4:1 - 30mm CM 4:1 + 30mm 4:1 혼합 30mm Combat Mix 5:1 DU:HEI @@ -142,13 +153,14 @@ 30毫米戰鬥混合彈5:1 穿甲:高爆 30 mm 战斗混合 穿甲/高爆 5:1 30 mm Mix de Combat 5:1 UA:HEI + 30mm Misto 5:1 UI:HEI 30mm Mieszanka bojowa 5:1 ZU:OB-Z 30mm Combat Mix 5:1 DU:HEI 30mm Kampfmischung 5:1 DU:HEB - 30mm コンバット ミックス 5:1 DU:HEI + 30mm コンバット ミックス 5:1 劣化ウラン徹甲弾:焼夷榴弾 30mm Bojový Mix 5:1 DU:HEI 30мм Смешанное боепитание 5:1 ОУ:ОФЗ - 30mm 5:1 열화:고폭소이 + 30mm 열화우라늄:고폭소이 5:1 혼합 30mm CM 5:1 @@ -156,13 +168,28 @@ 30毫米 穿高混合 5:1 30mm 穿爆混合 5:1 30 mm MdC 5:1 + 30mm Misto 5:1 30mm MB 5:1 30mm CM 5:1 30mm KM 5:1 30mm CM 5:1 30mm BM 5:1 30мм СБ 5:1 - 30mm CM 5:1 + 30mm 5:1 혼합 + + + Follow Distance + Distanza di seguimento + Folge-Entfernung + 따라가는 거리 + 追跡距離 + + + Following unit within %1m + Seguendo unità entro %1m + Folgt Einheit bis zu %1m + %1m 이내로 유닛을 따라갑니다 + %1m 間隔で 目標を追跡します 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 ee03bff9a9..7c7c677819 100644 --- a/addons/arsenal/XEH_postInit.sqf +++ b/addons/arsenal/XEH_postInit.sqf @@ -18,6 +18,16 @@ GVAR(lastSortDirectionRight) = DESCENDING; [QGVAR(removeDefaultLoadout), LINKFUNC(removeDefaultLoadout)] call CBA_fnc_addEventHandler; [QGVAR(renameDefaultLoadout), LINKFUNC(renameDefaultLoadout)] call CBA_fnc_addEventHandler; +[QGVAR(refresh), { + params ["_object"]; + + // If the arsenal is already open, refresh arsenal display + // Deliberate == check, fail on objNull + if (!isNil QGVAR(currentBox) && {GVAR(currentBox) == _object}) then { + [true, true] call FUNC(refresh); + }; +}] call CBA_fnc_addEventHandler; + [QGVAR(broadcastFace), { params ["_unit", "_face"]; _unit setFace _face; @@ -60,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]; @@ -71,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]]; }; }; @@ -98,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 @@ -137,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 34299c1871..10cc3989e9 100644 --- a/addons/arsenal/XEH_preInit.sqf +++ b/addons/arsenal/XEH_preInit.sqf @@ -9,60 +9,13 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // Arsenal events -[QGVAR(statsToggle), { - params ["_display", "_showStats"]; - - private _statsCtrlGroupCtrl = _display displayCtrl IDC_statsBox; - private _statsPreviousPageCtrl = _display displayCtrl IDC_statsPreviousPage; - private _statsNextPageCtrl = _display displayCtrl IDC_statsNextPage; - private _statsCurrentPageCtrl = _display displayCtrl IDC_statsCurrentPage; - - { - _x ctrlShow (GVAR(showStats) && {_showStats}); - } forEach [ - _statsCtrlGroupCtrl, - _statsPreviousPageCtrl, - _statsNextPageCtrl, - _statsCurrentPageCtrl - ]; -}] call CBA_fnc_addEventHandler; - -[QGVAR(statsChangePage), { - _this call FUNC(buttonStatsPage); -}] call CBA_fnc_addEventHandler; - -[QGVAR(displayStats), { - _this call FUNC(handleStats); -}] call CBA_fnc_addEventHandler; - -[QGVAR(actionsChangePage), { - _this call FUNC(buttonActionsPage); -}] call CBA_fnc_addEventHandler; - -[QGVAR(displayActions), { - _this call FUNC(handleActions); -}] call CBA_fnc_addEventHandler; - -[QGVAR(actionsToggle), { - params ["_display", "_showActions"]; - - private _actionsCtrlGroupCtrl = _display displayCtrl IDC_actionsBox; - private _actionsPreviousPageCtrl = _display displayCtrl IDC_actionsPreviousPage; - private _actionsNextPageCtrl = _display displayCtrl IDC_actionsNextPage; - private _actionsCurrentPageCtrl = _display displayCtrl IDC_actionsCurrentPage; - - { - _x ctrlShow (GVAR(showActions) && {_showActions}); - } forEach [ - _actionsCtrlGroupCtrl, - _actionsPreviousPageCtrl, - _actionsNextPageCtrl, - _actionsCurrentPageCtrl - ]; -}] call CBA_fnc_addEventHandler; +[QGVAR(statsChangePage), LINKFUNC(buttonStatsPage)] call CBA_fnc_addEventHandler; +[QGVAR(displayStats), LINKFUNC(handleStats)] call CBA_fnc_addEventHandler; +[QGVAR(actionsChangePage), LINKFUNC(buttonActionsPage)] call CBA_fnc_addEventHandler; +[QGVAR(displayActions), LINKFUNC(handleActions)] call CBA_fnc_addEventHandler; call FUNC(compileActions); call FUNC(compileSorts); @@ -83,8 +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 4606be5abe..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) @@ -38,13 +41,13 @@ call FUNC(compileActions); // Skip if not allowed in editor and in editor if (is3DEN && {_scopeEditor != 2}) exitWith { - TRACE_1("Skipping action because in editor", _rootClass); + TRACE_1("Skipping action because in editor",_rootClass); [] }; // Class can't contain ~, because it's used for formatting result if ("~" in _rootClass) exitWith { - TRACE_1("Classname can't contain '~'", _rootClass); + TRACE_1("Classname can't contain '~'",_rootClass); [] }; @@ -65,7 +68,7 @@ private _fnc_addToGroup = { // Don't allow two of the same class if (_group findIf {(_x select 0) == _class} != -1) then { - TRACE_1("An action with this ID already exists", _class); + TRACE_1("An action with this ID already exists",_class); continue; }; @@ -119,4 +122,8 @@ private _group = []; }; } forEach _tabs; +if (_updateOnCargoChange) then { + GVAR(updateActionsOnCargoChange) = true; +}; + _return diff --git a/addons/arsenal/functions/fnc_addDefaultLoadout.sqf b/addons/arsenal/functions/fnc_addDefaultLoadout.sqf index b9b8853f15..f54ff03eeb 100644 --- a/addons/arsenal/functions/fnc_addDefaultLoadout.sqf +++ b/addons/arsenal/functions/fnc_addDefaultLoadout.sqf @@ -20,8 +20,9 @@ params [["_name", "", [""]], ["_loadout", [], [[]]], ["_global", false, [false]]]; -if (_global) then { - [QGVAR(addDefaultLoadout), [_name, _loadout]] call CBA_fnc_remoteEvent; +if (_global) exitWith { + private _eventID = format [QGVAR(loadouts_%1), _name]; + [QGVAR(addDefaultLoadout), [_name, _loadout], _eventID] call CBA_fnc_globalEventJIP; }; private _extendedInfo = createHashMap; 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_addSort.sqf b/addons/arsenal/functions/fnc_addSort.sqf index 053f2ff52f..767660402f 100644 --- a/addons/arsenal/functions/fnc_addSort.sqf +++ b/addons/arsenal/functions/fnc_addSort.sqf @@ -72,7 +72,7 @@ private _fnc_addToTabs = { _currentTab pushBack _sort; _return pushBack _sortName; } else { - TRACE_1("A sort with this ID already exists", _sortName); + TRACE_1("A sort with this ID already exists",_sortName); }; } forEach _tabsToAddTo; }; diff --git a/addons/arsenal/functions/fnc_addStat.sqf b/addons/arsenal/functions/fnc_addStat.sqf index 98dfe45213..d618b96a93 100644 --- a/addons/arsenal/functions/fnc_addStat.sqf +++ b/addons/arsenal/functions/fnc_addStat.sqf @@ -77,7 +77,7 @@ private _fnc_addToTabs = { // Find if there is an entry with same ID if (_currentTab findIf {_x select 5 == _statName} != -1) then { - TRACE_1("A stat with this ID already exists", _statName); + TRACE_1("A stat with this ID already exists",_statName); } else { _stat = +_finalArray; _stat set [5, _statName]; @@ -109,11 +109,10 @@ private _tabToChange = []; { _x params ["_tab", "_tabSide"]; - _tabToChange = if (_tabSide == "R") then { + _tabToChange = [ + GVAR(statsListLeftPanel), GVAR(statsListRightPanel) - } else { - GVAR(statsListLeftPanel) - }; + ] select (_tabSide == "R"); _stats = _tabToChange select _tab; diff --git a/addons/arsenal/functions/fnc_addVirtualItems.sqf b/addons/arsenal/functions/fnc_addVirtualItems.sqf index c8b270ea6a..19859f619c 100644 --- a/addons/arsenal/functions/fnc_addVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_addVirtualItems.sqf @@ -125,6 +125,8 @@ if (_items isEqualType true) then { _object setVariable [QGVAR(virtualItems), _cargo, _global]; // If the arsenal is already open, refresh arsenal display -if (!isNil QGVAR(currentBox) && {GVAR(currentBox) isEqualTo _object}) then { - [true, true] call FUNC(refresh); +if (_global) then { + [QGVAR(refresh), _object] call CBA_fnc_globalEvent; +} else { + [QGVAR(refresh), _object] call CBA_fnc_localEvent; }; 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_attributeInit.sqf b/addons/arsenal/functions/fnc_attributeInit.sqf index 1e44dc579f..42e72056fc 100644 --- a/addons/arsenal/functions/fnc_attributeInit.sqf +++ b/addons/arsenal/functions/fnc_attributeInit.sqf @@ -24,14 +24,12 @@ if (_mode > 0) then { // Blacklist: add full arsenal and take items away [_object, true, true] call FUNC(initBox); - // Need to delay removal by 2 frames + // Wait until all items have been added, so that the blacklisted items can be removed [{ - [{ - params ["_object", "_items"]; - - [_object, _items, true] call FUNC(removeVirtualItems); - }, _this] call CBA_fnc_execNextFrame; - }, [_object, _items]] call CBA_fnc_execNextFrame; + !isNil {(_this select 0) getVariable QGVAR(virtualItems)} + }, { + [_this select 0, _this select 1, true] call FUNC(removeVirtualItems); + }, [_object, _items], 20] call CBA_fnc_waitUntilAndExecute; // 20s timeout in case of failure } else { // Exit on whitelist mode with no items if (_items isEqualTo []) exitWith {}; 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..968fd05d9b --- /dev/null +++ b/addons/arsenal/functions/fnc_baseAttachment.sqf @@ -0,0 +1,59 @@ +#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; + +// If the switch config entries are inherited, ignore +if ( + (inheritsFrom (_config >> "MRT_SwitchItemNextClass") isNotEqualTo _config) || + {inheritsFrom (_config >> "MRT_SwitchItemPrevClass") isNotEqualTo _config} +) exitWith { + _item // return +}; + +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_buttonActionsPage.sqf b/addons/arsenal/functions/fnc_buttonActionsPage.sqf index 17da357100..b3a46a68e3 100644 --- a/addons/arsenal/functions/fnc_buttonActionsPage.sqf +++ b/addons/arsenal/functions/fnc_buttonActionsPage.sqf @@ -2,12 +2,12 @@ #include "..\defines.hpp" /* * Author: Brett Mayson - * Handles the previous / next page buttons for actions + * Handles the previous / next page buttons for actions. * * Arguments: * 0: Arsenal display - * 1: Actions control - * 2: Previous or next (false = previous, true = next) + * 1: Actions page + * 2: Previous (false) or next (true) page * * Return Value: * None @@ -17,10 +17,11 @@ params ["_display", "_control", "_nextPage"]; -TRACE_1("control enabled", ctrlEnabled _control); +TRACE_1("control enabled",ctrlEnabled _control); if !(ctrlEnabled _control) exitWith {}; GVAR(currentActionPage) = GVAR(currentActionPage) + ([-1, 1] select _nextPage); GVAR(actionsInfo) params ["_panelControl", "_curSel", "_itemCfg"]; + [QGVAR(displayActions), [_display, _panelControl, _curSel, _itemCfg]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonCargo.sqf b/addons/arsenal/functions/fnc_buttonCargo.sqf index 48c5ee477e..d7713a2518 100644 --- a/addons/arsenal/functions/fnc_buttonCargo.sqf +++ b/addons/arsenal/functions/fnc_buttonCargo.sqf @@ -47,8 +47,8 @@ private _container = switch (GVAR(currentLeftPanel)) do { }; }; - /// Get all items from container (excluding container itself) - _containerItems = [GVAR(center), 0, 3, 0, 0, false] call EFUNC(common,uniqueUnitItems); + // Get all items from container + _containerItems = uniformItems GVAR(center); // Update currentItems GVAR(currentItems) set [IDX_CURR_UNIFORM_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_UNIFORM) param [1, []]]; @@ -75,8 +75,8 @@ private _container = switch (GVAR(currentLeftPanel)) do { }; }; - // Get all items from container (excluding container itself) - _containerItems = [GVAR(center), 0, 0, 3, 0, false] call EFUNC(common,uniqueUnitItems); + // Get all items from container + _containerItems = vestItems GVAR(center); // Update currentItems GVAR(currentItems) set [IDX_CURR_VEST_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_VEST) param [1, []]]; @@ -103,8 +103,8 @@ private _container = switch (GVAR(currentLeftPanel)) do { }; }; - // Get all items from container (excluding container itself) - _containerItems = [GVAR(center), 0, 0, 0, 3, false] call EFUNC(common,uniqueUnitItems); + // Get all items from container + _containerItems = backpackItems GVAR(center); // Update currentItems GVAR(currentItems) set [IDX_CURR_BACKPACK_ITEMS, ((getUnitLoadout GVAR(center)) select IDX_LOADOUT_BACKPACK) param [1, []]]; @@ -117,7 +117,7 @@ private _container = switch (GVAR(currentLeftPanel)) do { }; // Find out how many items of that type there are and update the number displayed -_ctrlList lnbSetText [[_lnbCurSel, 2], str (_containerItems getOrDefault [_item, 0])]; +_ctrlList lnbSetText [[_lnbCurSel, 2], str ({_item == _x} count _containerItems)]; [QGVAR(cargoChanged), [_display, _item, _addOrRemove, GVAR(shiftState)]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonHide.sqf b/addons/arsenal/functions/fnc_buttonHide.sqf index 6b6c84da93..d1bb5657b0 100644 --- a/addons/arsenal/functions/fnc_buttonHide.sqf +++ b/addons/arsenal/functions/fnc_buttonHide.sqf @@ -52,10 +52,20 @@ private _ctrl = controlNull; IDC_buttonCurrentMag2, IDC_iconBackgroundCurrentMag, IDC_iconBackgroundCurrentMag2, + IDC_statsBox, IDC_statsPreviousPage, IDC_statsNextPage, - IDC_statsCurrentPage + IDC_statsCurrentPage, + IDC_actionsBox, + IDC_actionsPreviousPage, + IDC_actionsNextPage, + IDC_actionsCurrentPage ]; -[QGVAR(statsToggle), [_display, _showToggle]] call CBA_fnc_localEvent; -[QGVAR(actionsToggle), [_display, _showToggle]] call CBA_fnc_localEvent; +if (!_showToggle) exitWith {}; + +// When showing the stats/actions again, update them to fit with currently selected item +GVAR(actionsInfo) params ["_control", "_curSel", "_itemCfg"]; + +[QGVAR(displayStats), [_display, _control, _curSel, _itemCfg]] call CBA_fnc_localEvent; +[QGVAR(displayActions), [_display, _control, _curSel, _itemCfg]] call CBA_fnc_localEvent; diff --git a/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf index 87191a99c2..d25fa485cf 100644 --- a/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf +++ b/addons/arsenal/functions/fnc_buttonLoadoutsRename.sqf @@ -43,11 +43,7 @@ private _loadoutIndex = _data findIf {(_x select 0) == _loadoutName}; (_data select _loadoutIndex) set [0, _editBoxContent]; if (GVAR(currentLoadoutsTab) == IDC_buttonDefaultLoadouts) then { - if (is3DEN) then { - set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; - } else { - [QGVAR(renameDefaultLoadout), [_loadoutName, _editBoxContent]] call CBA_fnc_remoteEvent; - }; + set3DENMissionAttributes [[QGVAR(DummyCategory), QGVAR(DefaultLoadoutsListAttribute), GVAR(defaultLoadoutsList)]]; }; private _currentLoadoutsTab = str GVAR(currentLoadoutsTab); diff --git a/addons/arsenal/functions/fnc_buttonStatsPage.sqf b/addons/arsenal/functions/fnc_buttonStatsPage.sqf index bef2631f8c..33eec398e9 100644 --- a/addons/arsenal/functions/fnc_buttonStatsPage.sqf +++ b/addons/arsenal/functions/fnc_buttonStatsPage.sqf @@ -17,11 +17,11 @@ params ["_display", "_control", "_nextPage"]; -TRACE_1("control enabled", ctrlEnabled _control); +TRACE_1("control enabled",ctrlEnabled _control); if !(ctrlEnabled _control) exitWith {}; -GVAR(currentStatPage) = [GVAR(currentStatPage) - 1, GVAR(currentStatPage) + 1] select _nextPage; +GVAR(currentStatPage) = GVAR(currentStatPage) + ([-1, 1] select _nextPage); -GVAR(statsInfo) params ["_isLeftPanel", "_panelControl", "_curSel", "_itemCfg"]; +GVAR(statsInfo) params ["", "_panelControl", "_curSel", "_itemCfg"]; [QGVAR(displayStats), [_display, _panelControl, _curSel, _itemCfg]] call CBA_fnc_localEvent; 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_compileStats.sqf b/addons/arsenal/functions/fnc_compileStats.sqf index ef8cba2f40..f19854793a 100644 --- a/addons/arsenal/functions/fnc_compileStats.sqf +++ b/addons/arsenal/functions/fnc_compileStats.sqf @@ -101,7 +101,7 @@ private _priority = 0; (_finalArray select 4) set [1, compile (getText (_x >> "textStatement"))]; }; - TRACE_3("stats array", _finalArray, _leftTabsList, _rightTabsList); + TRACE_3("stats array",_finalArray,_leftTabsList,_rightTabsList); if (_leftTabsList isNotEqualTo []) then { [_statsListLeftPanel, _leftTabsList, "L"] call _fnc_addToTabs; diff --git a/addons/arsenal/functions/fnc_fillLeftPanel.sqf b/addons/arsenal/functions/fnc_fillLeftPanel.sqf index effcc03d20..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]; - } 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 d01991f924..d8dc7e2403 100644 --- a/addons/arsenal/functions/fnc_fillRightPanel.sqf +++ b/addons/arsenal/functions/fnc_fillRightPanel.sqf @@ -44,12 +44,16 @@ private _cfgMagazines = configFile >> "CfgMagazines"; private _cfgWeapons = configFile >> "CfgWeapons"; private _rightPanelCache = uiNamespace getVariable QGVAR(rightPanelCache); -private _currentCargo = itemsWithMagazines GVAR(center); +private _currentCargo = []; // we only need this if we're filtering for favorites +if (GVAR(favoritesOnly)) then { + _currentCargo = itemsWithMagazines GVAR(center) + backpacks GVAR(center); + _currentCargo = _currentCargo arrayIntersect _currentCargo; +}; private _fnc_fillRightContainer = { - params ["_configCategory", "_className", "_hasItemInfo", ["_isUnique", false, [false]], ["_unknownOrigin", false, [false]]]; + 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 { @@ -64,7 +68,6 @@ private _fnc_fillRightContainer = { // "Misc. items" magazines (e.g. spare barrels, intel, photos) if (_className in (uiNamespace getVariable QGVAR(magazineMiscItems))) then { _configPath = _cfgMagazines >> _className; - _hasItemInfo = false; }; // If an item with unknown origin is in the arsenal list, try to find it @@ -75,37 +78,18 @@ private _fnc_fillRightContainer = { if (isNull _configPath) then { _configPath = _className call CBA_fnc_getObjectConfig; }; - - // Check if item is has item info - _itemInfo = isClass (_cfgWeapons >> configName _configPath); }; - // Get mass - private _mass = if (!_hasItemInfo) then { - getNumber (_configPath >> "mass") - } else { - private _mass = getNumber (_configPath >> "itemInfo" >> "mass"); - - if (_mass == 0) then { - _mass = getNumber (_configPath >> "WeaponSlotsInfo" >> "mass"); - }; - - _mass - }; - - _rightPanelCache set [_className, _mass]; // Needed because this provides more accurate weight for FUNC(updateRightPanel) - - [getText (_configPath >> "displayName"), getText (_configPath >> "picture"), _mass] - }, true]) params ["_displayName", "_picture", "_mass"]; + [getText (_configPath >> "displayName"), getText (_configPath >> "picture")] + }, true]) params ["_displayName", "_picture"]; private _lbAdd = _ctrlPanel lnbAddRow ["", _displayName, "0"]; _ctrlPanel lnbSetText [[_lbAdd, 1], _displayName]; _ctrlPanel lnbSetData [[_lbAdd, 0], _className]; _ctrlPanel lnbSetPicture [[_lbAdd, 0], _picture]; - _ctrlPanel lnbSetValue [[_lbAdd, 0], _mass]; - _ctrlPanel lnbSetValue [[_lbAdd, 2], [0, 1] select _isUnique]; + _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]; }; @@ -114,15 +98,9 @@ private _fnc_fillRightContainer = { private _ctrlPanel = _display displayCtrl IDC_rightTabContent; private _listnBox = _display displayCtrl IDC_rightTabContentListnBox; -// Reset right panel content -lbClear _ctrlPanel; -lbClear _listnBox; - -_ctrlPanel lbSetCurSel -1; -_listnBox lbSetCurSel -1; - // Retrieve compatible items -private _itemToCheck = ""; +private _isContainer = false; +private _selectedItem = ""; private _compatibleItems = []; private _compatibleMagsMuzzle = []; private _compatibleMagsAll = createHashMap; @@ -154,12 +132,12 @@ switch (GVAR(currentLeftPanel)) do { // Check if weapon attachement or magazine if (_index != -1) then { - _itemToCheck = (GVAR(currentItems) select _currentWeaponItemsIndex) select _index; + _selectedItem = (GVAR(currentItems) select _currentWeaponItemsIndex) select _index; // If weapon attachment, get base weapon; Get compatible items if (_index <= 3) then { _compatibleItems = compatibleItems _weapon; - _itemToCheck = _itemToCheck call FUNC(baseWeapon); + _selectedItem = _selectedItem call FUNC(baseWeapon); } else { // Get compatible magazines for primary & secondary muzzle (secondary muzzle is not guaranteed to exist) // Assumption: One weapon can have two muzzles maximum @@ -171,7 +149,15 @@ switch (GVAR(currentLeftPanel)) do { case IDC_buttonUniform; case IDC_buttonVest; case IDC_buttonBackpack: { - _ctrlPanel = _listnBox; + _isContainer = true; + + // Get the currently selected item in panel + private _selectedItemIndex = lnbCurSelRow _listnBox; + + // If something is selected, save it + if (_selectedItemIndex != -1) then { + _selectedItem = _listnBox lnbData [_selectedItemIndex, 0]; + }; // This is for the "compatible magazines" tab when a container is open if (_ctrlIDC == IDC_buttonMag) then { @@ -183,6 +169,17 @@ switch (GVAR(currentLeftPanel)) do { }; }; +// Reset right panel content +lbClear _ctrlPanel; +lnbClear _listnBox; + +_ctrlPanel lbSetCurSel -1; +_listnBox lnbSetCurSelRow -1; + +if (_isContainer) then { + _ctrlPanel = _listnBox; +}; + // Force a "refresh" animation of the panel if (_animate) then { _ctrlPanel ctrlSetFade 1; @@ -217,11 +214,11 @@ switch (_ctrlIDC) do { } forEach _compatibleItems; } else { { - ["CfgWeapons", _x, true] call _fnc_fillRightContainer; + ["CfgWeapons", _x] call _fnc_fillRightContainer; } forEach (keys ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get _index)); { - ["CfgWeapons", _x, true, true] call _fnc_fillRightContainer; + ["CfgWeapons", _x, true] call _fnc_fillRightContainer; } forEach (keys ((GVAR(virtualItems) get IDX_VIRT_UNIQUE_ATTACHMENTS) get _index)); }; }; @@ -240,44 +237,44 @@ switch (_ctrlIDC) do { case IDC_buttonMag: { { if (_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)) then { - ["CfgMagazines", _x, false] call _fnc_fillRightContainer; + ["CfgMagazines", _x] call _fnc_fillRightContainer; continue; }; if (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL)) then { - ["CfgMagazines", _x, false, true] call _fnc_fillRightContainer; + ["CfgMagazines", _x, true] call _fnc_fillRightContainer; }; } forEach (keys _compatibleMagsAll); }; // All magazines case IDC_buttonMagALL: { { - ["CfgMagazines", _x, false] call _fnc_fillRightContainer; + ["CfgMagazines", _x] call _fnc_fillRightContainer; } forEach (keys (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL)); { - ["CfgMagazines", _x, false, true] call _fnc_fillRightContainer; + ["CfgMagazines", _x, true] call _fnc_fillRightContainer; } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_VIRT_ITEMS_ALL)); }; // Grenades case IDC_buttonThrow: { { - ["CfgMagazines", _x, false] call _fnc_fillRightContainer; + ["CfgMagazines", _x] call _fnc_fillRightContainer; } forEach (keys (GVAR(virtualItems) get IDX_VIRT_GRENADES)); { - ["CfgMagazines", _x, false, true] call _fnc_fillRightContainer; + ["CfgMagazines", _x, true] call _fnc_fillRightContainer; } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GRENADES)); }; // Explosives case IDC_buttonPut: { { - ["CfgMagazines", _x, false] call _fnc_fillRightContainer; + ["CfgMagazines", _x] call _fnc_fillRightContainer; } forEach (keys (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES)); { - ["CfgMagazines", _x, false, true] call _fnc_fillRightContainer; + ["CfgMagazines", _x, true] call _fnc_fillRightContainer; } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_EXPLOSIVES)); }; // Misc. items @@ -296,33 +293,35 @@ switch (_ctrlIDC) do { // "Regular" misc. items { if !(_x in _items) then { - ["CfgWeapons", _x, true] call _fnc_fillRightContainer; + ["CfgWeapons", _x] call _fnc_fillRightContainer; }; } forEach (keys (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)); // Unique items { if !(_x in _items) then { - ["CfgWeapons", _x, true, true] call _fnc_fillRightContainer; + ["CfgWeapons", _x, true] call _fnc_fillRightContainer; }; } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS)); // Unique backpacks { if !(_x in _items) then { - ["CfgVehicles", _x, false, true] call _fnc_fillRightContainer; + ["CfgVehicles", _x, true] call _fnc_fillRightContainer; }; } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS)); // Unique goggles { if !(_x in _items) then { - ["CfgGlasses", _x, false, true] call _fnc_fillRightContainer; + // _y indicates if an item is truly unique or if it's a non-inventory item in a container (e.g. goggles in backpack) + ["CfgGlasses", _x, _y] call _fnc_fillRightContainer; }; - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES)); + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES); // Unknown items { if !(_x in _items) then { - ["CfgWeapons", _x, true, true, true] call _fnc_fillRightContainer; + // _y indicates if an item is truly unique or if it's a non-inventory item in a container (e.g. helmet in backpack) + ["CfgWeapons", _x, _y, true] call _fnc_fillRightContainer; }; - } forEach (keys (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS)); + } forEach (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS); // if an item is here but in virtual items, it's just in the wrong place }; // Custom buttons default { @@ -334,23 +333,23 @@ switch (_ctrlIDC) do { switch (true) do { // "Regular" misc. items case (_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)): { - ["CfgWeapons", _x, true] call _fnc_fillRightContainer; + ["CfgWeapons", _x] call _fnc_fillRightContainer; }; // Unique items case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_MISC_ITEMS)): { - ["CfgWeapons", _x, true, true] call _fnc_fillRightContainer; + ["CfgWeapons", _x, true] call _fnc_fillRightContainer; }; // Unique backpacks case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_BACKPACKS)): { - ["CfgVehicles", _x, false, true] call _fnc_fillRightContainer; + ["CfgVehicles", _x, true] call _fnc_fillRightContainer; }; // Unique goggles case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES)): { - ["CfgGlasses", _x, false, true] call _fnc_fillRightContainer; + ["CfgGlasses", _x, GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES get _x] call _fnc_fillRightContainer; }; // Unknown items case (_x in (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS)): { - ["CfgWeapons", _x, true, true, true] call _fnc_fillRightContainer; + ["CfgWeapons", _x, GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS get _x, true] call _fnc_fillRightContainer; }; }; } forEach _items; @@ -368,7 +367,7 @@ GVAR(currentRightPanel) = _ctrlIDC; [QGVAR(rightPanelFilled), [_display, GVAR(currentLeftPanel), _ctrlIDC]] call CBA_fnc_localEvent; // Add current items, change progress bar of container load and get relevant container -if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBackpack]) then { +if (_isContainer) then { private _containerItems = []; private _container = switch (GVAR(currentLeftPanel)) do { // Uniform @@ -376,8 +375,8 @@ if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBack // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadUniform GVAR(center)); - // Get all items from container (excluding container itself) - _containerItems = [GVAR(center), 0, 3, 0, 0, false] call EFUNC(common,uniqueUnitItems); + // Get all items from container + _containerItems = uniformItems GVAR(center); uniformContainer GVAR(center) }; @@ -386,8 +385,8 @@ if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBack // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadVest GVAR(center)); - // Get all items from container (excluding container itself) - _containerItems = [GVAR(center), 0, 0, 3, 0, false] call EFUNC(common,uniqueUnitItems); + // Get all items from container + _containerItems = vestItems GVAR(center); vestContainer GVAR(center) }; @@ -396,8 +395,8 @@ if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBack // Update load bar (_display displayCtrl IDC_loadIndicatorBar) progressSetPosition (loadBackpack GVAR(center)); - // Get all items from container (excluding container itself) - _containerItems = [GVAR(center), 0, 0, 0, 3, false] call EFUNC(common,uniqueUnitItems); + // Get all items from container + _containerItems = backpackItems GVAR(center); backpackContainer GVAR(center) }; @@ -405,7 +404,8 @@ if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBack // Find out how many items of a type there are and update the number displayed for "_lbIndex" from 0 to (lnbSize _ctrlPanel select 0) - 1 do { - _ctrlPanel lnbSetText [[_lbIndex, 2], str (_containerItems getOrDefault [_ctrlPanel lnbData [_lbIndex, 0], 0])]; + private _xItem = _ctrlPanel lnbData [_lbIndex, 0]; + _ctrlPanel lnbSetText [[_lbIndex, 2], str ({_xItem == _x} count _containerItems)]; }; // Refresh availibility of items based on space remaining in container @@ -415,17 +415,34 @@ if (GVAR(currentLeftPanel) in [IDC_buttonUniform, IDC_buttonVest, IDC_buttonBack // Sorting [_display, _control, _display displayCtrl IDC_sortRightTab, _display displayCtrl IDC_sortRightTabDirection] call FUNC(fillSort); -// Try to select previously selected item again, otherwise select first item ("Empty") -if (_itemToCheck != "") then { - private _index = 0; +if (_selectedItem != "") then { + if (_isContainer) then { + // Try to select previously selected item again, otherwise select nothing + private _index = -1; - for "_lbIndex" from 0 to (lbSize _ctrlPanel) - 1 do { - if ((_ctrlPanel lbData _lbIndex) == _itemToCheck) exitWith { - _index = _lbIndex; + for "_lbIndex" from 0 to (lnbSize _ctrlPanel select 0) - 1 do { + if ((_ctrlPanel lnbData [_lbIndex, 0]) == _selectedItem) exitWith { + _index = _lbIndex; + }; }; - }; - _ctrlPanel lbSetCurSel _index; + _ctrlPanel lnbSetCurSelRow _index; + } else { + // Try to select previously selected item again, otherwise select first item ("Empty") + private _index = 0; + + for "_lbIndex" from 0 to (lbSize _ctrlPanel) - 1 do { + if ((_ctrlPanel lbData _lbIndex) == _selectedItem) exitWith { + _index = _lbIndex; + }; + }; + + _ctrlPanel lbSetCurSel _index; + }; } else { - _ctrlPanel lbSetCurSel 0; + if (_isContainer) then { + _ctrlPanel lnbSetCurSelRow -1; // select nothing + } else { + _ctrlPanel lbSetCurSel 0; // select "Empty" + }; }; diff --git a/addons/arsenal/functions/fnc_handleActions.sqf b/addons/arsenal/functions/fnc_handleActions.sqf index 833a615cb5..03c25f77df 100644 --- a/addons/arsenal/functions/fnc_handleActions.sqf +++ b/addons/arsenal/functions/fnc_handleActions.sqf @@ -7,7 +7,7 @@ * Arguments: * 0: Arsenal display * 1: Current panel control - * 2: Current panel selection + * 2: Current panel selection * 3: Item config entry * * Return Value: @@ -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,36 +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 ctrlCommit 0; - }; - default { - _actionTextCtrl ctrlSetFade 1; - _actionTextCtrl ctrlCommit 0; - _actionButtonCtrl ctrlSetFade 1; - _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_handleSearchbar.sqf b/addons/arsenal/functions/fnc_handleSearchbar.sqf index d25a064867..d5ff2dc69a 100644 --- a/addons/arsenal/functions/fnc_handleSearchbar.sqf +++ b/addons/arsenal/functions/fnc_handleSearchbar.sqf @@ -49,7 +49,7 @@ if ((ctrlIDC _control) == IDC_rightSearchbar) then { // If something is selected, save it if (_selectedItemIndex != -1) then { - _selectedItem = _rightPanelCtrl lbText _selectedItemIndex; + _selectedItem = _rightPanelCtrl lbData _selectedItemIndex; }; private _currentDisplayName = ""; @@ -72,7 +72,7 @@ if ((ctrlIDC _control) == IDC_rightSearchbar) then { // Try to find previously selected item in panel for "_lbIndex" from 0 to (lbSize _rightPanelCtrl) - 1 do { - if ((_rightPanelCtrl lbText _lbIndex) == _selectedItem) exitWith { + if ((_rightPanelCtrl lbData _lbIndex) == _selectedItem) exitWith { _index = _lbIndex; }; }; @@ -89,7 +89,7 @@ if ((ctrlIDC _control) == IDC_rightSearchbar) then { // If something is selected, save it if (_selectedItemIndex != -1) then { - _selectedItem = _rightPanelCtrl lnbText [_selectedItemIndex, 1]; + _selectedItem = _rightPanelCtrl lnbData [_selectedItemIndex, 0]; }; private _currentDisplayName = ""; @@ -112,7 +112,7 @@ if ((ctrlIDC _control) == IDC_rightSearchbar) then { // Try to find previously selected item in panel for "_lbIndex" from 0 to (lnbSize _rightPanelCtrl select 0) - 1 do { - if ((_rightPanelCtrl lnbText [_lbIndex, 1]) == _selectedItem) exitWith { + if ((_rightPanelCtrl lnbData [_lbIndex, 0]) == _selectedItem) exitWith { _index = _lbIndex; }; }; @@ -145,7 +145,7 @@ if ((ctrlIDC _control) == IDC_rightSearchbar) then { // If something is selected, save it if (_selectedItemIndex != -1) then { - _selectedItem = _leftPanelCtrl lbText _selectedItemIndex; + _selectedItem = _leftPanelCtrl lbData _selectedItemIndex; }; private _currentDisplayName = ""; @@ -167,7 +167,7 @@ if ((ctrlIDC _control) == IDC_rightSearchbar) then { private _index = -1; for "_lbIndex" from 0 to (lbSize _leftPanelCtrl) - 1 do { - if ((_leftPanelCtrl lbText _lbIndex) == _selectedItem) exitWith { + if ((_leftPanelCtrl lbData _lbIndex) == _selectedItem) exitWith { _index = _lbIndex; }; }; diff --git a/addons/arsenal/functions/fnc_initBox.sqf b/addons/arsenal/functions/fnc_initBox.sqf index 446438d2b5..8651d25db8 100644 --- a/addons/arsenal/functions/fnc_initBox.sqf +++ b/addons/arsenal/functions/fnc_initBox.sqf @@ -51,7 +51,10 @@ if (_global && {isMultiplayer} && {isNil {_object getVariable QGVAR(initBoxJIP)} ] call EFUNC(interact_menu,createAction); [_object, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToObject); - [_object, _items, false] call FUNC(addVirtualItems); + // If items were set globally, do not add items locally + if (isNil {_object getVariable QGVAR(virtualItems)}) then { + [_object, _items, false] call FUNC(addVirtualItems); + }; [QGVAR(boxInitialized), [_object, _items]] call CBA_fnc_localEvent; }; diff --git a/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf b/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf index a0203ff5b9..a8938e8c48 100644 --- a/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf +++ b/addons/arsenal/functions/fnc_loadoutsChangeTab.sqf @@ -63,6 +63,7 @@ switch (ctrlIDC _control) do { _saveButtonCtrl ctrlSetTooltip LLSTRING(buttonSaveTooltip); }; + _renameButtonCtrl ctrlEnable is3DEN; // no renaming mid-mission _saveButtonCtrl ctrlEnable call FUNC(canEditDefaultLoadout); _saveButtonCtrl ctrlCommit 0; }; diff --git a/addons/arsenal/functions/fnc_onArsenalClose.sqf b/addons/arsenal/functions/fnc_onArsenalClose.sqf index 2cac9fd0d9..6803d2d5de 100644 --- a/addons/arsenal/functions/fnc_onArsenalClose.sqf +++ b/addons/arsenal/functions/fnc_onArsenalClose.sqf @@ -18,7 +18,7 @@ (_this select 1) params ["", "_exitCode"]; [QGVAR(displayClosed), []] call CBA_fnc_localEvent; -removeMissionEventHandler ["draw3D", GVAR(camPosUpdateHandle)]; +removeMissionEventHandler ["Draw3D", GVAR(camPosUpdateHandle)]; if (is3DEN) then { private _centerOriginParent = objectParent GVAR(centerOrigin); @@ -51,13 +51,6 @@ if (is3DEN) then { ["ShowInterface", true] call BIS_fnc_3DENInterface; GVAR(visionMode) call BIS_fnc_3DENVisionMode; } else { - // Select correct weapon - switch (GVAR(selectedWeaponType)) do { - case 0: {GVAR(center) selectWeapon (primaryWeapon GVAR(center))}; - case 1: {GVAR(center) selectWeapon (secondaryWeapon GVAR(center))}; - case 2: {GVAR(center) selectWeapon (handgunWeapon GVAR(center))}; - }; - if (!isNull curatorCamera && {ACE_player == player}) then { curatorCamera cameraEffect ["Internal", "BACK"]; } else { @@ -85,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; }; @@ -122,12 +115,11 @@ GVAR(currentVoice) = nil; GVAR(currentInsignia) = nil; GVAR(currentAction) = nil; -GVAR(showStats) = nil; GVAR(currentStatPage) = nil; GVAR(statsInfo) = nil; -GVAR(showActions) = nil; GVAR(currentActionPage) = nil; +GVAR(actionsInfo) = nil; profileNamespace setVariable [QGVAR(favorites), GVAR(favorites)]; GVAR(favoritesOnly) = nil; @@ -136,4 +128,6 @@ GVAR(favorites) = nil; GVAR(center) = nil; GVAR(centerNotPlayer) = nil; +GVAR(ignoredVirtualItems) = nil; + [QUOTE(ADDON), []] call EFUNC(common,showHud); diff --git a/addons/arsenal/functions/fnc_onArsenalOpen.sqf b/addons/arsenal/functions/fnc_onArsenalOpen.sqf index 5e35500248..0f0a5817c6 100644 --- a/addons/arsenal/functions/fnc_onArsenalOpen.sqf +++ b/addons/arsenal/functions/fnc_onArsenalOpen.sqf @@ -68,18 +68,17 @@ 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"; GVAR(shiftState) = false; -GVAR(showStats) = true; GVAR(currentStatPage) = 0; GVAR(statsInfo) = [true, controlNull, nil, nil]; -GVAR(showActions) = true; GVAR(currentActionPage) = 0; +GVAR(actionsInfo) = [controlNull, nil, nil]; // Update current item list call FUNC(updateCurrentItemsList); @@ -243,7 +242,15 @@ GVAR(refreshing) = false; _panel ctrlCommit 0; } forEach [IDC_leftTabContent, IDC_rightTabContent, IDC_rightTabContentListnBox]; -[_display, _display displayCtrl IDC_buttonPrimaryWeapon] call FUNC(fillLeftPanel); +// Open left panel for current weapon, do some math +GVAR(selectedWeaponType) = [primaryWeapon GVAR(center), secondaryWeapon GVAR(center), handgunWeapon GVAR(center), binocular GVAR(center)] find (currentWeapon GVAR(center)); +if (GVAR(selectedWeaponType) == -1) then { + GVAR(selectedWeaponType) = 0; // default to primary +}; + +private _leftPanelIDC = [IDC_buttonPrimaryWeapon, IDC_buttonSecondaryWeapon, IDC_buttonHandgun, IDC_buttonBinoculars] select GVAR(selectedWeaponType); + +[_display, _display displayCtrl _leftPanelIDC] call FUNC(fillLeftPanel); //--------------- Init camera if (isNil QGVAR(cameraPosition)) then { @@ -271,4 +278,4 @@ showCinemaBorder false; //--------------- Reset camera pos [nil, [controlNull, 0, 0]] call FUNC(handleMouse); -GVAR(camPosUpdateHandle) = addMissionEventHandler ["draw3D", {call FUNC(updateCamPos)}]; +GVAR(camPosUpdateHandle) = addMissionEventHandler ["Draw3D", {call FUNC(updateCamPos)}]; diff --git a/addons/arsenal/functions/fnc_onKeyDown.sqf b/addons/arsenal/functions/fnc_onKeyDown.sqf index 24fbd624f6..4d62075f78 100644 --- a/addons/arsenal/functions/fnc_onKeyDown.sqf +++ b/addons/arsenal/functions/fnc_onKeyDown.sqf @@ -147,7 +147,7 @@ if (!isNull _loadoutsDisplay) then { // Right panel lnb + and - buttons case (_keyPressed in [DIK_LEFT, DIK_RIGHT]): { if (GVAR(rightTabLnBFocus)) then { - [_display, [1, 0] select (_keyPressed == DIK_LEFT)] call FUNC(buttonCargo); + [_display, parseNumber (_keyPressed != DIK_LEFT)] call FUNC(buttonCargo); }; }; }; 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..e25016b303 100644 --- a/addons/arsenal/functions/fnc_onSelChangedLeft.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedLeft.sqf @@ -382,6 +382,9 @@ switch (GVAR(currentLeftPanel)) do { }; GVAR(currentItems) set [IDX_CURR_VEST, _item]; + + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER @@ -420,6 +423,9 @@ switch (GVAR(currentLeftPanel)) do { }; GVAR(currentItems) set [IDX_CURR_BACKPACK, _item]; + + [GVAR(center), ""] call BIS_fnc_setUnitInsignia; + [GVAR(center), GVAR(currentInsignia)] call BIS_fnc_setUnitInsignia; }; TOGGLE_RIGHT_PANEL_CONTAINER @@ -683,14 +689,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_onSelChangedRight.sqf b/addons/arsenal/functions/fnc_onSelChangedRight.sqf index ccb2988765..abec68ceee 100644 --- a/addons/arsenal/functions/fnc_onSelChangedRight.sqf +++ b/addons/arsenal/functions/fnc_onSelChangedRight.sqf @@ -69,7 +69,14 @@ switch (_currentItemsIndex) do { // Secondary weapon case IDX_CURR_SECONDARY_WEAPON_ITEMS: { private _currentItemInSlot = (GVAR(currentItems) select IDX_CURR_SECONDARY_WEAPON_ITEMS) select _itemIndex; - private _isDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon GVAR(center))}}; + private _isDisposable = CBA_disposable_replaceDisposableLauncher && {!isNil "CBA_disposable_loadedLaunchers"} && + { + if (CBA_disposable_loadedLaunchers isEqualType createHashMap) then { // after CBA 3.18 + (secondaryWeapon GVAR(center)) in CBA_disposable_loadedLaunchers + } else { + !isNil {CBA_disposable_loadedLaunchers getVariable (secondaryWeapon player)} + } + }; // If removal if (_item == "") then { diff --git a/addons/arsenal/functions/fnc_openBox.sqf b/addons/arsenal/functions/fnc_openBox.sqf index 1536862212..dd983776d1 100644 --- a/addons/arsenal/functions/fnc_openBox.sqf +++ b/addons/arsenal/functions/fnc_openBox.sqf @@ -28,13 +28,15 @@ if ( ) exitWith {}; // If object has no arsenal and chosen option is to not ignore virtual items of object, exit -if (isNil {_object getVariable QGVAR(virtualItems)} && {!_mode}) exitWith { +private _virtualItems = _object getVariable QGVAR(virtualItems); + +if (isNil "_virtualItems" && {!_mode}) exitWith { [LLSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); }; // Don't execute in scheduled environment if (canSuspend) exitWith { - [{_this call FUNC(openBox)}, _this] call CBA_fnc_directCall; + [FUNC(openBox), _this] call CBA_fnc_directCall; }; private _displayToUse = findDisplay IDD_RSCDISPLAYCURATOR; @@ -46,37 +48,23 @@ if (isNull _displayToUse || {!isNil QGVAR(camera)}) exitWith { [LLSTRING(CantOpenDisplay), false, 5, 1] call EFUNC(common,displayText); }; +GVAR(center) = _center; GVAR(currentBox) = _object; if (_mode) then { // Add all the items from the game that the arsenal has detected GVAR(virtualItems) = +(uiNamespace getVariable QGVAR(configItems)); GVAR(virtualItemsFlat) = +(uiNamespace getVariable QGVAR(configItemsFlat)); + + GVAR(ignoredVirtualItems) = true; } else { // Add only specified items to the arsenal - private _virtualItems = _object getVariable QGVAR(virtualItems); - - GVAR(virtualItems) = if (isNil "_virtualItems") then { - _virtualItems = [ - [IDX_VIRT_WEAPONS, createHashMapFromArray [[IDX_VIRT_PRIMARY_WEAPONS, createHashMap], [IDX_VIRT_SECONDARY_WEAPONS, createHashMap], [IDX_VIRT_HANDGUN_WEAPONS, createHashMap]]], - [IDX_VIRT_ATTACHMENTS, createHashMapFromArray [[IDX_VIRT_OPTICS_ATTACHMENTS, createHashMap], [IDX_VIRT_FLASHLIGHT_ATTACHMENTS, createHashMap], [IDX_VIRT_MUZZLE_ATTACHMENTS, createHashMap], [IDX_VIRT_BIPOD_ATTACHMENTS, createHashMap]]] - ]; - - _virtualItems = createHashMapFromArray _virtualItems; - - for "_index" from IDX_VIRT_ITEMS_ALL to IDX_VIRT_MISC_ITEMS do { - _virtualItems set [_index, createHashMap]; - }; - } else { - +_virtualItems - }; + GVAR(virtualItems) = +_virtualItems; // Flatten out hashmaps for easy checking later call FUNC(updateVirtualItemsFlat); }; -GVAR(center) = _center; - if (is3DEN) then { _displayToUse createDisplay QGVAR(display); } else { diff --git a/addons/arsenal/functions/fnc_refresh.sqf b/addons/arsenal/functions/fnc_refresh.sqf index eafc463955..849b49d16b 100644 --- a/addons/arsenal/functions/fnc_refresh.sqf +++ b/addons/arsenal/functions/fnc_refresh.sqf @@ -25,6 +25,11 @@ if (canSuspend) exitWith { [{_this call FUNC(refresh)}, _this] call CBA_fnc_directCall; }; +private _display = findDisplay IDD_ace_arsenal; + +// Exit quietly if no display found +if (isNull _display) exitWith {}; + if (_updateItems) then { // Update current item list call FUNC(updateCurrentItemsList); @@ -42,7 +47,8 @@ if (is3DEN) then { _animate = true; // CBA frame functions are disabled during preInit }; -if (isNil "_virtualItems") exitWith { +// Do not close an arsenal if it was opened with ignoring the existing content (see FUNC(openBox)) +if (isNil "_virtualItems" && {isNil QGVAR(ignoredVirtualItems)}) exitWith { [LLSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); // Delay a frame in case this is running on display open [{(findDisplay IDD_ace_arsenal) closeDisplay 0}] call CBA_fnc_execNextFrame; @@ -64,6 +70,4 @@ if (!_animate) then { [{GVAR(refreshing) = false}, nil, 3] call CBA_fnc_execAfterNFrames; }; -private _display = findDisplay IDD_ace_arsenal; - [_display, _display displayCtrl GVAR(currentLeftPanel), _animate] call FUNC(fillLeftPanel); diff --git a/addons/arsenal/functions/fnc_removeBox.sqf b/addons/arsenal/functions/fnc_removeBox.sqf index b4c410da62..9fa3ec377a 100644 --- a/addons/arsenal/functions/fnc_removeBox.sqf +++ b/addons/arsenal/functions/fnc_removeBox.sqf @@ -25,7 +25,7 @@ private _id = _object getVariable QGVAR(initBoxJIP); if (_global && {isMultiplayer} && {!isNil "_id"}) then { // Remove event from JIP queue - [_id] call CBA_fnc_removeGlobalEventJIP; + _id call CBA_fnc_removeGlobalEventJIP; // Reset JIP ID _object setVariable [QGVAR(initBoxJIP), nil, true]; @@ -41,9 +41,15 @@ if (_global && {isMultiplayer} && {!isNil "_id"}) then { [QGVAR(boxRemoved), _object] call CBA_fnc_localEvent; }; -// If the arsenal is already open, close arsenal display -if (!isNil QGVAR(currentBox) && {GVAR(currentBox) isEqualTo _object}) then { - [LLSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); - // Delay a frame in case this is running on display open - [{(findDisplay IDD_ace_arsenal) closeDisplay 0}] call CBA_fnc_execNextFrame; +// If the arsenal is already open and not ignoring content (see FUNC(openBox)), close arsenal display +// Deliberate == check, fail on objNull +if (!isNil QGVAR(currentBox) && {GVAR(currentBox) == _object} && {isNil QGVAR(ignoredVirtualItems)}) then { + // Delay a frame in case this is running on display open/close + [{ + private _display = findDisplay IDD_ace_arsenal; + if (isNull _display) exitWith {}; + + [LLSTRING(noVirtualItems), false, 5, 1] call EFUNC(common,displayText); + _display closeDisplay 0; + }] call CBA_fnc_execNextFrame; }; diff --git a/addons/arsenal/functions/fnc_removeDefaultLoadout.sqf b/addons/arsenal/functions/fnc_removeDefaultLoadout.sqf index e84aad5c04..3ca877f7fd 100644 --- a/addons/arsenal/functions/fnc_removeDefaultLoadout.sqf +++ b/addons/arsenal/functions/fnc_removeDefaultLoadout.sqf @@ -17,8 +17,10 @@ */ params [["_name", "", [""]], ["_global", false, [false]]]; -if (_global) then { - [QGVAR(removeDefaultLoadout), [_name]] call CBA_fnc_remoteEvent; +if (_global) exitWith { + private _eventID = format [QGVAR(loadouts_%1), _name]; + [_eventID] call CBA_fnc_removeGlobalEventJIP; + [QGVAR(removeDefaultLoadout), [_name]] call CBA_fnc_globalEvent; }; GVAR(defaultLoadoutsList) deleteAt (GVAR(defaultLoadoutsList) findIf {(_x select 0) == _name}); 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_removeVirtualItems.sqf b/addons/arsenal/functions/fnc_removeVirtualItems.sqf index f16cf6553f..71db2b15a1 100644 --- a/addons/arsenal/functions/fnc_removeVirtualItems.sqf +++ b/addons/arsenal/functions/fnc_removeVirtualItems.sqf @@ -100,9 +100,12 @@ if (_items isEqualType true) then { [_object, _global] call FUNC(removeBox); } else { _object setVariable [QGVAR(virtualItems), _cargo, _global]; + // If the arsenal is already open, refresh arsenal display - if (!isNil QGVAR(currentBox) && {GVAR(currentBox) isEqualTo _object}) then { - [true, true] call FUNC(refresh); + if (_global) then { + [QGVAR(refresh), _object] call CBA_fnc_globalEvent; + } else { + [QGVAR(refresh), _object] call CBA_fnc_localEvent; }; }; }; 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_showItem.sqf b/addons/arsenal/functions/fnc_showItem.sqf index 76a95e6981..f47f12d2bf 100644 --- a/addons/arsenal/functions/fnc_showItem.sqf +++ b/addons/arsenal/functions/fnc_showItem.sqf @@ -15,6 +15,10 @@ if (GVAR(centerNotPlayer)) exitWith {}; +if (EGVAR(common,isReloading)) exitWith { // if player is reloading then wait until it's done so we don't send magazines to the shadow realm + [{!EGVAR(common,isReloading)}, FUNC(showItem)] call CBA_fnc_waitUntilAndExecute; +}; + // Determine action to play based on current category selection private _nextAction = switch (GVAR(currentLeftPanel)) do { // Primary weapon @@ -54,10 +58,12 @@ if (_nextAction != GVAR(currentAction)) then { case "PrimaryWeapon": {0}; case "SecondaryWeapon": {1}; case "HandGunOn": {2}; + case "Binoculars": {3}; default {GVAR(selectedWeaponType)}; }; if (simulationEnabled GVAR(center)) then { + GVAR(center) call EFUNC(common,stopGesture); // reset gesture state (if arsenal is opened on animation transition, animations played whilst in the arsenal break) GVAR(center) playActionNow _nextAction; } else { GVAR(center) switchAction _nextAction; @@ -65,3 +71,7 @@ if (_nextAction != GVAR(currentAction)) then { GVAR(currentAction) = _nextAction; }; + +if !(GVAR(currentAction) in ["Civil", "Salute"]) then { + GVAR(center) selectWeapon ([primaryWeapon GVAR(center), secondaryWeapon GVAR(center), handgunWeapon GVAR(center), binocular GVAR(center)] select GVAR(selectedWeaponType)); // select correct weapon, prevents floating weapons +}; 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_illuminators.sqf b/addons/arsenal/functions/fnc_statTextStatement_illuminators.sqf index b677ec8210..3f982f575c 100644 --- a/addons/arsenal/functions/fnc_statTextStatement_illuminators.sqf +++ b/addons/arsenal/functions/fnc_statTextStatement_illuminators.sqf @@ -31,9 +31,9 @@ if (_allItems isEqualTo []) then { _allItems = [configName _config] }; || {_illum && {([_xCfg >> "Flashlight" >> "irLight", "NUMBER", 0] call CBA_fnc_getConfigEntry) == 1}}; private _text = switch (true) do { // shorthand roughly based on PEQ-15 - case (_laser && _illum): { if (_isIR) then { "IR-DUAL" } else { "VIS-DUAL" } }; - case (_laser): { if (_isIR) then { "IR-AIM" } else { "VIS-AIM" } }; // AIM - case (_illum): { if (_isIR) then { "IR-ILM" } else { "VIS-ILM" } }; // ILLUMIATION + case (_laser && _illum): { ["VIS-DUAL", "IR-DUAL"] select _isIR }; // DUAL + case (_laser): { ["VIS-AIM", "IR-AIM"] select _isIR }; // AIM + case (_illum): { ["VIS-ILM", "IR-ILM"] select _isIR }; // ILLUMIATION default { "_" }; // there are some purely cosmetic attachements }; _allModes pushBackUnique _text; 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 dca83cb381..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 @@ -67,7 +67,9 @@ if (!_primaryNVGSupported && {(_opticsModes select {_x select 1}) isEqualTo _opt _primaryNVGSupported = true; }; -if (_primaryNVGIntegrated) exitWith {LLSTRING(statVisionMode_IntPrim)}; +if (_primaryTiIntegrated && _primaryNVGIntegrated) exitWith {LLSTRING(statVisionMode_intPrimTi)}; +if (_primaryTiIntegrated) exitWith {LLSTRING(statVisionMode_ti)}; +if (_primaryNVGIntegrated) exitWith {LLSTRING(statVisionMode_intPrim)}; if (_primaryNVGSupported) exitWith {LLSTRING(statVisionMode_supPrim)}; if (_secondaryNVGSupported) exitWith {LLSTRING(statVisionMode_supSec)}; 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_updateRightPanel.sqf b/addons/arsenal/functions/fnc_updateRightPanel.sqf index e51f923655..e43f06c74f 100644 --- a/addons/arsenal/functions/fnc_updateRightPanel.sqf +++ b/addons/arsenal/functions/fnc_updateRightPanel.sqf @@ -18,19 +18,18 @@ params ["_control", "_container", "_hasItems"]; private _loadRemaining = maxLoad _container - loadAbs _container; -private _rightPanelCache = uiNamespace getVariable [QGVAR(rightPanelCache), createHashMap]; -private _mass = -1; +private _item = ""; private _color = []; private _alpha = 1; // Grey out items that are too big to fit in remaining space of the container for "_row" from 0 to (lnbSize _control select 0) - 1 do { - _mass = _rightPanelCache getOrDefault [_control lnbData [_row, 0], 0]; + _item = _control lnbData [_row, 0]; _color = _control lnbColor [_row, 1]; // Lower alpha on color for items that can't fit - _alpha = [0.25, 1] select (_mass <= _loadRemaining); + _alpha = [0.25, 1] select (_container canAdd _item); _color set [3, _alpha]; _control lnbSetColor [[_row, 1], _color]; _control lnbSetColor [[_row, 2], [1, 1, 1, _alpha]]; @@ -55,6 +54,6 @@ private _curSel = lnbCurSelRow _control; // Disable '+' button if item is unique or too big to fit in remaining space if (_curSel != -1) then { private _plusButtonCtrl = _display displayCtrl IDC_arrowPlus; - _plusButtonCtrl ctrlEnable !((_control lnbValue [_curSel, 2]) == 1 || {(_rightPanelCache getOrDefault [_control lnbData [_curSel, 0], 0]) > _loadRemaining}); + _plusButtonCtrl ctrlEnable ((_control lnbValue [_curSel, 2]) != 1 && {_container canAdd (_control lnbData [_curSel, 0])}); _plusButtonCtrl ctrlCommit FADE_DELAY; }; diff --git a/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf b/addons/arsenal/functions/fnc_updateUniqueItemsList.sqf index ccbf7b7abb..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; }; @@ -125,7 +130,8 @@ private _fnc_uniqueEquipment = { }; } forEach (getUnitLoadout GVAR(center)); // Only need items, not extended loadout - +// Get all items from unit +_items = itemsWithMagazines GVAR(center) + backpacks GVAR(center); private _isMagazine = false; private _isWeapon = false; private _isGrenade = false; @@ -136,6 +142,9 @@ private _simulationType = ""; private _configItemInfo = ""; private _hasItemInfo = false; private _itemInfoType = 0; +private _baseWeapon = ""; +private _weapons = GVAR(virtualItems) get IDX_VIRT_WEAPONS; +private _attachments = GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS; { _isMagazine = isClass (_cfgMagazines >> _x); @@ -184,8 +193,13 @@ private _itemInfoType = 0; // Unknown default { // Don't add items that are part of the arsenal - if !(_x in GVAR(virtualItemsFlatAll)) then { - (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, nil]; + if ( + !(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)) && + {!(_x in (GVAR(virtualItems) get IDX_VIRT_GRENADES))} && + {!(_x in (GVAR(virtualItems) get IDX_VIRT_EXPLOSIVES))} && + {!(_x in (GVAR(virtualItems) get IDX_VIRT_ITEMS_ALL))} + ) then { + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, true]; }; }; }; @@ -199,11 +213,17 @@ private _itemInfoType = 0; _itemInfoType = if (_hasItemInfo) then {getNumber (_configItemInfo >> "type")} else {0}; _isMiscItem = _x isKindOf ["CBA_MiscItem", _cfgWeapons]; + _baseWeapon = if (!_isMiscItem) then { + _x call FUNC(baseWeapon) + } else { + _x + }; + switch (true) do { // Optics case ( - !(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS)) && - {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) || + !(_baseWeapon in (_attachments get IDX_VIRT_OPTICS_ATTACHMENTS)) && + {_baseWeapon in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_OPTICS_ATTACHMENTS) || {_hasItemInfo && {!_isMiscItem} && {_itemInfoType == TYPE_OPTICS}}} @@ -212,8 +232,8 @@ private _itemInfoType = 0; }; // Flashlights case ( - !(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)) && - {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) || + !(_baseWeapon in (_attachments get IDX_VIRT_FLASHLIGHT_ATTACHMENTS)) && + {_baseWeapon in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_FLASHLIGHT_ATTACHMENTS) || {_hasItemInfo && {!_isMiscItem} && {_itemInfoType == TYPE_FLASHLIGHT}}} @@ -222,8 +242,8 @@ private _itemInfoType = 0; }; // Muzzle attachments case ( - !(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS)) && - {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) || + !(_baseWeapon in (_attachments get IDX_VIRT_MUZZLE_ATTACHMENTS)) && + {_baseWeapon in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_MUZZLE_ATTACHMENTS) || {_hasItemInfo && {!_isMiscItem} && {_itemInfoType == TYPE_MUZZLE}}} @@ -232,8 +252,8 @@ private _itemInfoType = 0; }; // Bipods case ( - !(_x in ((GVAR(virtualItems) get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS)) && - {_x in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) || + !(_baseWeapon in (_attachments get IDX_VIRT_BIPOD_ATTACHMENTS)) && + {_baseWeapon in ((_configItems get IDX_VIRT_ATTACHMENTS) get IDX_VIRT_BIPOD_ATTACHMENTS) || {_hasItemInfo && {!_isMiscItem} && {_itemInfoType == TYPE_BIPOD}}} @@ -242,7 +262,7 @@ private _itemInfoType = 0; }; // Misc. items case ( - !(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)) && + !(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS)) && // misc. items don't use 'baseWeapon' {_x in (_configItems get IDX_VIRT_MISC_ITEMS) || {_hasItemInfo && {_isMiscItem && @@ -254,9 +274,21 @@ private _itemInfoType = 0; }; // Unknown default { - // Don't add items that are part of the arsenal - if !(_x in GVAR(virtualItemsFlatAll)) then { - (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, nil]; + // Don't add attachments or misc. items + if ( + !(_baseWeapon in (_attachments get IDX_VIRT_OPTICS_ATTACHMENTS)) && + {!(_baseWeapon in (_attachments get IDX_VIRT_FLASHLIGHT_ATTACHMENTS))} && + {!(_baseWeapon in (_attachments get IDX_VIRT_MUZZLE_ATTACHMENTS))} && + {!(_baseWeapon in (_attachments get IDX_VIRT_BIPOD_ATTACHMENTS))} && + {!(_x in (GVAR(virtualItems) get IDX_VIRT_MISC_ITEMS))} + ) then { + // If item is a weapon (including binos), make it unique + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, + _baseWeapon in (_weapons get IDX_VIRT_PRIMARY_WEAPONS) || + {_baseWeapon in (_weapons get IDX_VIRT_HANDGUN_WEAPONS)} || + {_baseWeapon in (_weapons get IDX_VIRT_SECONDARY_WEAPONS)} || + {_baseWeapon in (GVAR(virtualItems) get IDX_VIRT_BINO)} + ]; }; }; }; @@ -267,14 +299,14 @@ private _itemInfoType = 0; }; // Facewear case (isClass (_cfgGlasses >> _x)): { - (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES) set [_x, nil]; + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_GOGGLES) set [_x, !(_x in (GVAR(virtualItems) get IDX_VIRT_GOGGLES))]; }; // Unknown default { // Don't add items that are part of the arsenal if !(_x in GVAR(virtualItemsFlatAll)) then { - (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, nil]; + (GVAR(virtualItems) get IDX_VIRT_UNIQUE_UNKNOWN_ITEMS) set [_x, true]; }; }; }; -} forEach (keys ([GVAR(center), 0, 3, 3, 3, false] call EFUNC(common,uniqueUnitItems))); // Get all items from unit +} forEach (_items arrayIntersect _items); diff --git a/addons/arsenal/functions/fnc_verifyLoadout.sqf b/addons/arsenal/functions/fnc_verifyLoadout.sqf index b5425c2117..10cd9a2553 100644 --- a/addons/arsenal/functions/fnc_verifyLoadout.sqf +++ b/addons/arsenal/functions/fnc_verifyLoadout.sqf @@ -13,289 +13,97 @@ * 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 + if (_extendedInfo isEqualType []) then { // Hashmaps are serialized as arrays, convert back to hashmap + _extendedInfo = createHashMapFromArray _extendedInfo; + _loadout set [1, _extendedInfo]; // Also fix source variable, technically not needed but doesn't hurt + }; _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 - if (_name != "") then { - _name - } else { - _x - }; + // 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/initSettings.sqf b/addons/arsenal/initSettings.inc.sqf similarity index 100% rename from addons/arsenal/initSettings.sqf rename to addons/arsenal/initSettings.inc.sqf diff --git a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf index 9f4b0aa538..3ce0dd54d0 100644 --- a/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf +++ b/addons/arsenal/missions/Arsenal.VR/XEH_postInit.sqf @@ -10,16 +10,18 @@ cba_diagnostic_projectileMaxLines = 10; // Player pose [{ - switch (true) do { - case (primaryWeapon _this != ""): { - _this switchMove "amovpercmstpslowwrfldnon"; - }; - case (handgunWeapon _this != ""): { - _this switchMove "amovpercmstpslowwpstdnon"; - }; - default { + switch (currentWeapon _this) do { + case (""): { _this switchMove "amovpercmstpsnonwnondnon"; }; + case (primaryWeapon _this): { + _this switchMove "amovpercmstpslowwrfldnon"; + }; + case (handgunWeapon _this): { + _this switchMove "amovpercmstpslowwpstdnon"; + }; + case (binocular _this); + case (secondaryWeapon _this): {}; // deliberately nothing }; }, _player] call CBA_fnc_execNextFrame; @@ -82,12 +84,13 @@ cba_diagnostic_projectileMaxLines = 10; _x hideObject false; } forEach allMissionObjects ""; - private _unit = objNull, + private _unit = objNull; // Update VR unit gear { _unit = _x; + removeVest _unit; if (vest _player != "") then { _unit addVest vest _player; }; removeBackpack _unit; diff --git a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf index a93611d329..502f7b888d 100644 --- a/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf +++ b/addons/arsenal/missions/Arsenal.VR/fnc_createTarget.sqf @@ -63,7 +63,7 @@ _target switchMove "amovpercmstpslowwrfldnon"; _target setVariable ["origin", _position]; // When killed, respawn AI -_target addEventHandler ["killed", { +_target addEventHandler ["Killed", { params ["_target"]; // Killed may fire twice, 2nd will be null - https://github.com/acemod/ACE3/pull/7561 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 64066d2554..38f41ef4a6 100644 --- a/addons/arsenal/stringtable.xml +++ b/addons/arsenal/stringtable.xml @@ -8,7 +8,7 @@ Verstecken Ukryj 隠す - Nascondere + Nascondi 숨김 隱藏 隐藏 @@ -23,7 +23,7 @@ Masque l'interface Oberfläche verstecken Ukryj interfejs - インターフェイスを隠す + インタフェースを隠す Nascondi interfaccia 인터페이스 숨기기 隱藏介面 @@ -103,7 +103,7 @@ Aucun objet virtuel disponible. Kein virtuelles Objekt verfügbar Brak dostępnych przedmiotów wirtualnych - 利用可能なバーチャル アイテムはありません + 利用可能な仮想アイテムはありません Nessun oggetto virtuale disponibile 가상장비 사용 불가 沒有可用的虛擬物品 @@ -149,14 +149,14 @@ [Shift+Click to save to mission defaults] [Shift+Click para guardar equipamiento predefinido [Umschalt+Linksklick um als Standard-Missionsausrüstung zu speichern] - [Shift + クリック] でミッション標準として保存します + [Shift + クリックでミッションの標準装備として保存します] Shift + Klik aby zapisac jako domyślne dla misji [Shift+Клик, чтобы сохранить в настройках по умолчанию] [Shift+Clique para salvar nos padrões da missão] [Shift+Clic pour enregistrer en tant qu'équipement prédéfini.] [Shift+左鍵來保存至任務預設] [Shift+左鍵 以保存至任务默认值] - [Shift+Click per salvare la missione con gli equipaggiamenti predefiniti] + [Shift+Click per salvare come equipaggiamento predefinito della missione] [Shift+Klik pro uložení jako standardního vybavení pro misi] [Shift+Click varsayılan kıyafetlere kaydet] [쉬프트+클릭 하여 임무 기본으로 설정] @@ -279,8 +279,8 @@ Équipements prédéfinis Standard-Ausrüstungen Domyślne zestawy - 標準の装備 - Equipaggiamenti standard + 標準装備 + Equipaggiamenti predefiniti 기본 로드아웃 預設裝備 默认负载 @@ -295,7 +295,7 @@ Sets d'équipement mis à disposition par le créateur de mission. Ausrüstungen, die durch den Missionsersteller zur Verfügung gestellt worden sind Zestawy udostępnione przez twórcę misji - 装備はミッション著者によって利用できます + ミッション著者によって作成された装備です Equipaggiamenti resi disponibili dal creatore della missione 미션메이커가 허용한 로드아웃 任務作者提供的預設裝備 @@ -343,7 +343,7 @@ Trier par poids Nach Gewicht sortieren Sortuj wg wagi - 重量で並び替え + 重量順に並び替え Ordina per peso 무게 순서로 정렬 以重量排序 @@ -359,8 +359,8 @@ Trier par quantité Nach Menge sortieren Sortuj wg ilości - 量で並び替え - Ordina per quantitativo + 数量順に並び替え + Ordina per quantità 갯수 순서로 정렬 以數量排序 以数量排序 @@ -373,81 +373,95 @@ Sort by load Nach Tragelast sortieren Trier par capacité de chargement - 容量で並び替え + Ordina per capacità di carico + 容量順に並び替え Ordenar por capacidad Сортировка по вместимости Sortuj po rozmiarze 공간 순서로 정렬 以容量排序 + Ordenar por capacidade Sort by accuracy Nach Genauigkeit sortieren Trier par précision - 精度で並び替え + Ordina per precisione + 精度順に並び替え Isabet doğruluğuna göre sırala Ordenar por precisión Сортировка по точности Sortuj po celności 정확도 순서로 정렬 以精度排序 + Ordenar por precisão Sort by rate of fire Nach Schussrate sortieren Trier par cadence de tir - 連射速度で並び替え + Ordina per cadenza di tiro + 連射速度順に並び替え Atış hızına göre sırala Ordenar por cadencia de tiro Сортировка по темпу стрельбы Sortuj po szybkostrzelności 발사속도 순서로 정렬 以射速排序 + Ordenar por cadência Sort by magnification Nach Vergrößerung sortieren Trier par grossissement - 倍率で並び替え + Ordina per ingrandimento + 倍率順に並び替え Ordenar por magnificación Сортировка по кратности приближения Sortuj po przybliżeniu 배율 순서로 정렬 以放大倍数排序 + Ordenar por magnificação Sort by ammo count Nach Munitionszahl sortieren Trier par nombre de munitions - 装弾数で並び替え + Ordina per numero di colpi + 装弾数順に並び替え Mermi sayısına göre sırala Ordenar por cantidad de munición Сортировка по количеству боеприпасов Sortuj po ilości amunicji 총알 갯수 순서롤 정렬 以弹量排序 + Ordenar por quantidade de munição Sort by ballistic protection Trier par protection balistique - 防弾性能で並び替え + Ordina per protezione balistica + 防弾性能順に並び替え Ordenar por protección balística Сортировка по баллистической защите Sortuj po ochronie balistycznej Nach ballistischem Schutz sortieren 방탄 성능 순서로 정렬 以防弹性能排序 + Ordenar por proteção balística Sort by explosive protection Trier par résistance aux explosifs - 防爆性能で並び替え + Ordina per protezione esplosiva + 防爆性能順に並び替え Ordenar por protección de explosivos Сортировка по защите от взрывов Sortuj po ochronie przeciw wybuchom Nach Explosionsschutz sortieren 방폭 성능 순서로 정렬 以防爆性能排序 + Ordenar por proteção a explosivos Share or stop sharing the selected loadout @@ -503,8 +517,8 @@ La liste des équipements prédéfinis est vide ! Die Standard-Ausrüstungen-Liste ist leer! Lista domyślnych zestawów jest pusta! - 標準の装備一欄が空です! - La lista degli equipaggiamenti standard è vuota! + 標準装備の一覧は空です! + La lista degli equipaggiamenti predefiniti è vuota! 기본 로드아웃 목록이 비어있습니다! 沒有預設的裝備清單! 没有默认负载清单! @@ -519,8 +533,8 @@ Liste des équipements prédéfinis exportée dans le presse-papier. Standard-Ausrüstungen-Liste in die Zwischenablage exportiert Lista domyślnych zestawów została eksportowana do schowka - 標準の装備一欄はクリップボードへエクスポートされました - La lista degli equipaggiamenti standard è stata esportata negli appunti + 標準装備の一覧をクリップボードへエクスポートしました + La lista degli equipaggiamenti predefiniti è stata esportata negli appunti 클립보드에 기본 로드아웃 목록 내보내기 預設的裝備清單已匯出到剪貼簿中 默认负载清单已导出到剪贴板 @@ -535,7 +549,7 @@ Équipement actuel exporté dans le presse-papier. Derzeitige Ausrüstung in die Zwischenablage exportiert Obecny zestaw został eksportowany do schowka - 現在の装備はクリップボードへ出力されました + 現在の装備をクリップボードへ出力しました Equipaggiamento corrente esportato negli appunti 현재 로드아웃을 클립보드로 내보냈습니다. 當前的裝備已匯出到剪貼簿中 @@ -567,8 +581,8 @@ Liste des équipements prédéfinis importée depuis le presse-papier. Standard-Ausrüstungen-Liste aus der Zwischenablage importiert Lista domyślnych zestawów została importowana ze schowka - 標準の装備一欄はクリップボードからインポートされました - La lista degli equipaggiamenti standard è stata importata dagli appunti + 標準装備の一覧をクリップボードからインポートしました + La lista degli equipaggiamenti predefiniti è stata importata dagli appunti 클립보드에서 기본 로드아웃 가져오기 預設的裝備清單已從剪貼簿中匯入 默认负载已从剪贴板导入 @@ -583,7 +597,7 @@ Set d'équipement importé depuis le presse-papier. Ausrüstung aus der Zwischenablage importiert Zestaw został importowany ze schowka - 装備はクリップボードからインポートされました + 装備をクリップボードからインポートしました Equipaggiamento importato dagli appunti 클립보드에서 로드아웃을 가져왔습니다. 裝備已從剪貼簿中匯入 @@ -599,7 +613,7 @@ Le set d'équipement suivant a été supprimé : Folgende Ausrüstung wurde entfernt: Następujący zestaw został skasowany: - 次の装備は削除されました: + 装備を削除しました: Il seguente equipaggiamento è stato eliminato: 다음 로드아웃이 삭제됨 : 以下的裝備已被刪除: @@ -615,7 +629,7 @@ Le set d'équipement suivant n'est plus public : Folgende Ausrüstung ist nicht mehr öffentlich: Następujący zestaw nie jest już publiczny: - 次の装備は非公開になりました: + 装備を非公開にしました: Il seguente equipaggiamento non è più pubblico: 다음 로드아웃이 더이상 공용이 아님: 以下的裝備已不再被分享: @@ -631,7 +645,7 @@ Le champ "nom" est vide ! Das Feld "Name" ist leer! Pole nazwy jest puste! - 名前が空白です! + 名前が空欄です! Il campo del nome è vuoto! 이름칸이 비었습니다! 名稱欄位為空! @@ -663,7 +677,7 @@ Un de vos sets d'équipement ayant le même nom est public. Eine deiner Ausrüstungen mit dem gleichen Namen ist öffentlich Jeden z Twoich zestawów nazwany tak samo jest już publiczny - あなたの装備は既に公開されているものと同名です + あなたのものと同じ名前の装備が既に公開されています Un tuo equipaggiamento con lo stesso nome è pubblico 같은 이름의 로드아웃이 공용에 있습니다. 已有相同名稱的裝備在公用分享區 @@ -679,7 +693,7 @@ Le set d'équipement suivant a été enregistré : Folgende Ausrüstung wurde gespeichert: Następujący zestaw został zapisany: - 次の装備は保存されました: + 装備を保存しました: Il seguente equipaggiamento è stato salvato: 다음 로드아웃이 저장됨: 以下的裝備已被保存: @@ -695,7 +709,7 @@ Le set d'équipement suivant a été chargé : Folgene Ausrüstung wurde geladen: Następujący zestaw został wczytany: - 次の装備が読み込みされました: + 装備を読み込みました: Il seguente equipaggiamento è stato caricato: 다음 로드아웃을 불러옴: 以下的裝備已被載入: @@ -711,7 +725,7 @@ Un set d'équipement ayant le même nom existe déjà ! Eine Ausrüstung mit dem gleichen Namen existiert bereits! Zestaw z tą nazwą już istnieje! - 既にその名前は装備に使われています! + 既に同じ名前の装備が存在しています! Un equipaggiamento con lo stesso nome è gia esistente! 같은 이름의 로드아웃이 이미 존재합니다! 已有相同名稱的裝備! @@ -727,8 +741,8 @@ a été renommé en wurde umbenannt in zmienił nazwę na - 次の名前に変更されました - E' stato rinominato in + を次の名前に変更しました: + È stato rinominato in 이름이 다음과 같이 변경됨: 已被改名為 已被改名为 @@ -775,7 +789,7 @@ Taille de police des panneaux Schrifthöhe für die linke und rechte Liste Wysokość czcionki - パネルにあるフォントの高さ + パネルのフォントの高さ Altezza carattere del pannello 패널 폰트 높이 面板字體高度 @@ -791,8 +805,8 @@ Autoriser les équipements prédéfinis Erlaubt die Benutzung der Standardausrüstungen Zezwól na użycie domyślnych zestawów - 標準の装備を許可 - Consenti equipaggiamenti standard + 標準装備を許可 + Consenti equipaggiamenti predefiniti 기본 로드아웃 허용 允許預設裝備 允许默认负载 @@ -807,7 +821,7 @@ Autoriser le partage des sets d'équipement Erlaubt das Teilen von Ausrüstungen Zezwól na udostępnianie zestawów - 装備の共有を許可 + 装備共有を許可 Consenti condivisione equipaggiamenti 로드아웃 공유 허용 允許分享裝備 @@ -902,8 +916,8 @@ Permitir el uso de la pestaña de equipamientos por defecto Active l'onglet "Équipements prédéfinis". Zezwól na użycie zakładki domyślnych zestawów - 標準の装備タブの使用を許可します - Consenti l'uso della sezione per gli equipaggiamenti standard + 標準装備タブの使用を許可します + Consenti l'uso della sezione per gli equipaggiamenti predefiniti 기본 로드아웃 탭 사용 허가 Erlaube die Nutzung des Standardausrüstungsreiters 允許使用預設的裝備 @@ -918,7 +932,7 @@ Mostrar / ocultar iconos de mods en el panel izquierdo Affiche/masque les icônes de mod du panneau gauche. Pokaż / ukryj ikony modów w lewym panelu - 左パネルにある MOD アイコンの表示 / 非表示をします + 左パネルにあるMODアイコンを表示/非表示します Mostra / nascondi le icone delle mod dal pannello sinistro 왼쪽 패널의 모드 아이콘 표시 / 숨기기 Zeigt/Versteckt Mod-Symbole in der linken Leiste @@ -934,7 +948,7 @@ Cambiar el tamaño de fuente para el texto de los paneles izquierdo y derecho Change la taille de police des panneaux latéraux. Zmień wysokość czcionki dla tekstu lewego i prawego panelu - パネルにあるフォントの高さを変更します。 + 左右パネル内の文字フォントの高さを変更します。 Cambia l'altezza del font per il testo sul pannello sinistro / destro 왼쪽 / 오른쪽 패널 텍스트의 글꼴 높이 변경 Ändert die Schriftgröße für die linke/rechte Leiste @@ -950,7 +964,7 @@ Registrar elementos no encontrados o no disponibles en el RPT Consigne les objets manquants ou indisponibles dans le RPT. Rejestruj brakujące / niedostępne przedmioty do pliku RPT - PRT で欠落 / 利用不可アイテムを記録します + PRTに欠落/利用不可アイテムを記録します Log mancante / oggetto non disponibile nell' RPT RPT에 누락 된 항목 / 사용할 수없는 항목 기록 Fehlende Gegenstände werden in der RPT aufgezeichnet @@ -982,7 +996,7 @@ Importar equipamientos de BI Arsenal hacia el arsenal de ACE Importer les sets BI VA dans l'arsenal ACE Importiert die BI-VA-Ausrüstungen in das ACE-Arsenal - 標準の VA 装備から ACE 武器庫へ取り込み + BI 武器庫の装備を ACE 武器庫へインポート 바닐라 로드아웃을 ACE 아스날로 가져오기 匯入BI原廠虛擬軍火庫的裝備到ACE虛擬軍火庫中 导入 BI 原版虚拟军火库的负载到 ACE 虚拟军火库中 @@ -997,7 +1011,7 @@ Ninguna unidad de jugador disponible! Coloca una unidad y márcala como "Jugador". Aucune unité joueur disponible ! Placez une unité et marquez-la en tant que "joueur". Keine Spielereinheit verfügbar. Setze eine Einheit und markiere sie als "Spieler". - プレイヤーユニットがありません!ユニットを設置し"Player"と名付けてください。 + プレイヤーユニットがありません!ユニットを設置し"プレイヤー"に設定してください。 플레이어 유닛을 사용할 수 없습니다! 유닛을 놓고 "플레이어"라고 표시하십시오. 沒有可用的玩家單位!請擺放一個單位並設定成"玩家" 没有可用的玩家单位!请摆放一个单位并设定成“玩家”。 @@ -1138,7 +1152,7 @@ Taux de potassium 钾水平 鉀水平 - Ilvello di potassio + Livello di potassio Poziomy potasu Уровень Калия Níveis de Potássio @@ -1167,7 +1181,7 @@ Nightvision Support Soporte de visión nocturna Nachtsicht Unterstützung - 暗視装置への対応有無 + 暗視装置への対応 Wsparcie noktowizyjne Supporto visore notturno Поддержка ночного видения @@ -1177,7 +1191,7 @@ 支持夜视仪 Podpora nočního vidění Gece Görüş Desteği - 야간투시 지원여부 + 야간투시 지원 Primary supported @@ -1192,7 +1206,7 @@ 主武器支援 主镜支持 Hlavní část hledí podporuje - 주무기 지원여부 + 주무기 지원 Secondary supported @@ -1207,9 +1221,9 @@ 次要武器支援 副镜支持 Vedlejší část hledí podporuje - 보조무기 지원여부 + 보조무기 지원 - + Primary integrated Primaria integrada Primär Integriert @@ -1222,13 +1236,33 @@ 整合主武器 主镜内置 Integrováno do hlavní části hledí - 주무기 내장여부 + 주무기 내장 + + + Thermal integrated + Termico integrato + 熱画像装置内蔵 + Интегрирован тепловизор. + 열화상 내장 + Thermique intégrée + Thermal integriert + Térmica integrada + + + Thermal & Primary integrated + Termico e Primario integrato + 熱画像装置内蔵・プライマリに内蔵 + Интегрирован тепловизор и осн.прицел. + 열화상과 주무기 내장 + Thermique et primaire intégrés + Thermal und in Primärwaffe integriert + Térmica y Primaria integrada Not Supported No soportada Nicht unterstützt - セカンダリに内蔵 + 非対応 Nie wspierane Non supportato Не поддерживается @@ -1243,7 +1277,7 @@ Vision Mode Sichtmodus - ビジョン モード + 映像モード Modalità Visiva 視覺模式 视觉模式 @@ -1282,7 +1316,7 @@ Nocturna Notturno Nocturne - 暗視装置 + 暗視 야간 夜视 夜視 @@ -1298,7 +1332,7 @@ Térmica Termico Thermique - 熱源画像 + 熱画像 열상 热成像 熱成像 @@ -1325,7 +1359,7 @@ Habilitar las pestañas de caras / voces / insignias Aktiviere die Gesichter-, Stimmen- und Abzeichenübersicht Activer les onglets visages/voix/insignes - 顔 / 声 / 記章(バッジ)タブを有効化 + 顔/声/バッジ(記章)タブを有効化 启用脸谱/语音/徽章选项 啟用臉譜/聲音/徽章選項 Abilita volti, voci e insegne @@ -1435,7 +1469,7 @@ Export current items list as an array for use in scripts Exportar la lista actual de objetos como una tabla para su uso en scripts Exportiert aktuelle Gegenstände als Array, um es in Scripten zu verwenden - スクリプト用に現在のアイテム リストをアレイでエクスポートします + スクリプト用に現在のアイテムリストをアレイでエクスポートします Esporta l'attuale lista di elementi come un array, per essere usati negli script Eksportuj obecną listę przedmiotów jako tablicę do wykorzystania w skryptach Exportar a lista atual de itens como uma matriz para usar em scripts @@ -1481,7 +1515,7 @@ Añade automáticamente accesorios o cargadores (de la categoría seleccionada) a todas las armas de la lista de objetos Es werden automatisch kompatible Aufsätze oder Magazine für alle ausgewählten Waffen hinzugefügt Automatycznie doda kompatybilne dodatki oraz magazynki (odpowiednio do każdej kategorii) dla wszystkich broni na liście - 現在のアイテム リスト内にある全武器に対応するアタッチメントと弾倉 (選択したカテゴリに基づき) を自動的に追加します + 現在のアイテムリスト内の全武器に対応する アタッチメントと弾倉(選択したカテゴリに基づく)を自動的に追加します Добавляет совместимые приспособления или магазины (в зависимости от выбранной категории) для всего оружия в текущем списке предметов Irá automaticamente adicionar acessórios ou carregadores (baseado na categoria selecionada) para todas as armas na lista de itens atual Ajoute automatiquement des accessoires ou des chargeurs compatibles (en fonction de la catégorie sélectionnée), pour toutes les armes de la liste actuelle. @@ -1496,9 +1530,9 @@ Tiempo de vida Lebenszeit Durée d'expiration - 有効時間 + 効力持続時間 Czas by żyć - Scadenza (TTL) + Tempo di vita Время действия Time to live 有效時間 @@ -1513,14 +1547,17 @@ Задержка детонации Opoźnienie zapalnika 信管設定時間 + Tempo di spoletta Tiempo de espoleta Detonationsverzögerung 引信时间 신관 시간 + Atraso de detonação Detonates on impact Aufschlagzünder + Spoletta a impatto Détonation à l'impact Детонация от удара Detonuj przy uderzeniu @@ -1528,52 +1565,67 @@ Detona mediante impacto 碰炸引信 충격 신관 + Detona por impacto Save Face 얼굴 저장 Сохранить лицо Guardar Cara + Salva faccia 顔の保存 Zapisz Twarz Gesicht Speichern Sauvegarder le visage + Salvar Rosto Save Voice 목소리 저장 Сохранить голос Guardar Voz + Salva voce 声の保存 Zapisz Głos Stimme Speichern Sauvegarder la voix + Salvar Voz Save Insignia 계급장 저장 Сохранить эмблему Guardar Insignia - 記章(バッジ)の保存 + Salva insegna + バッジ(記章)の保存 Zapisz Naszywkę Insignia Speichern Sauvegarder l'insigne + Salvar Insígnia Descending 降順 Malejąco Absteigend + Decrescente 내림차순 Décroissant + Decrescente + Нисходящий + Descendiente Ascending 昇順 Rosnąco Aufsteigend + Ascendente 오름차순 Croissant + Crescente + Восходящий + Ascendiente Tools @@ -1596,56 +1648,93 @@ 弾薬数 Ilość amunicji Munitionszahl + Numero di colpi 장탄 수 Nombre de munitions + Quantidade de munição + Количество боеприпасов + Cantidad de munición Illuminators Illuminateurs + Illuminanti + Leuchtmittel 조명 + Iluminadores + イルミネーター + Осветители + Iluminadores Default to Favorites - お気に入りをデフォルト + お気に入りを標準に Domyślnie do Ulubionych + Mostra solo Preferiti come predefinito Standardmäßig auf Favoriten eingestellt 즐겨찾기 기본값 Favoris par défaut + Favoritos por padrão + По умолчанию - Избранное + Favoritos por defecto Controls whether the ACE Arsenal defaults to showing all items or favorites. - ACE Arsenalがデフォルトで全てのアイテムを表示するか、お気に入りを表示するかを制御します。 + ACE 武器庫が標準ですべてのアイテムを表示するか、お気に入りを表示するかを制御します。 Kontroluje, czy ACE Arsenal domyślnie wyświetla wszystkie przedmioty, czy tylko ulubione. + Controlla se lo stato predefinito dell'arsenale ACE mostra tutti gli oggetti o solo i preferiti. Steuert, ob das ACE Arsenal standardmäßig alle Gegenstände oder nur Favoriten anzeigt. 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 по умолчанию отображаться все предметы или избранное. + Controla si el Arsenal de ACE muestra por defecto todos los objetos o sólo los favoritos Favorites Color お気に入りの色 Kolor Ulubionych Favoritenfarbe + Colore preferiti 즐겨찾기 색상 Couleurs favorites + Cor dos favoritos + Избранный цвет + Color de Favoritos Highlight color for favorited items. お気に入りアイテムのハイライト色。 Kolor podświetlenia ulubionych elementów. Hervorhebungsfarbe für Lieblingsgegenstände. + Colore che mette in mostra i preferiti nella lista. 즐겨찾기한 아이템을 색상으로 강조합니다. Met en surbrillance les éléments favoris. + Cor de destaque para itens favoritados. + Выделите цветом любимые предметы. + Color de marcado para los objetos favoritos Switch between displaying all items or your favorites.\nDouble click while holding Shift to add or remove an item. - Shiftを押しながらダブルクリックするとアイテムを追加・削除できます。 + アイテムをすべて表示するかお気に入りのみを表示するかを切り替えます。\nアイテムをお気に入りに追加または削除するには、Shiftキーを押しながらダブルクリックします。 Przełączanie między wyświetlaniem wszystkich przedmiotów lub tylko ulubionych. \nKliknij dwukrotnie, przytrzymując Shift, aby dodać lub usunąć przedmiot. Wechseln Sie zwischen der Anzeige aller Elemente oder Ihrer Favoriten.\nDoppelklicken Sie bei gedrückter Umschalttaste, um ein Element hinzuzufügen oder zu entfernen. + Cambia tra mostrare tutti gli oggetti o solo i tuoi preferiti.\nShift + Doppio Click per aggiungere o rimuovere un preferito. 모든 아이템을 표시하거나 즐겨찾기를 표시할 때 전환합니다\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, чтобы добавить или удалить элемент. + Alterna entre mostrar todos los objetos o sólo los favoritos.\nDoble click mientras se pulsa Shift para añadir o quitar un objeto. Search\nCTRL + Click to enable live results + Suche\nSTRG + Click für Live-Aktualisierung während des Schreibens + Cerca\nCTRL + Click per modificare i risultati mentre scrivi + 検索\nCTRL + クリックで検索結果の即時表示を有効化 + 검색\nCtrl + 클릭으로 실시간 검색 결과를 활성화 + Поиск\nCtrl + Click для включения результатов в реальном времени + Recherche\nCTRL + clic pour modifier les résultats tout en écrivant + Buscar\nCTRL + Click habilita los objetos en directo 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/CfgWeapons.hpp b/addons/artillerytables/CfgWeapons.hpp index 56aa257b46..f3716173f9 100644 --- a/addons/artillerytables/CfgWeapons.hpp +++ b/addons/artillerytables/CfgWeapons.hpp @@ -10,7 +10,7 @@ class CfgWeapons { picture = QPATHTOF(UI\icon_rangeTable.paa); ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 0.5; + mass = 0.1; }; }; }; diff --git a/addons/artillerytables/XEH_postInit.sqf b/addons/artillerytables/XEH_postInit.sqf index 6bc444d700..4f0e203208 100644 --- a/addons/artillerytables/XEH_postInit.sqf +++ b/addons/artillerytables/XEH_postInit.sqf @@ -31,6 +31,6 @@ }] call CBA_fnc_addEventHandler; #ifdef DEBUG_MODE_FULL -#include "dev\showShotInfo.sqf" -#include "dev\checkConfigs.sqf" +#include "dev\showShotInfo.inc.sqf" +#include "dev\checkConfigs.inc.sqf" #endif diff --git a/addons/artillerytables/XEH_preInit.sqf b/addons/artillerytables/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/artillerytables/XEH_preInit.sqf +++ b/addons/artillerytables/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/artillerytables/dev/checkConfigs.sqf b/addons/artillerytables/dev/checkConfigs.inc.sqf similarity index 100% rename from addons/artillerytables/dev/checkConfigs.sqf rename to addons/artillerytables/dev/checkConfigs.inc.sqf diff --git a/addons/artillerytables/dev/showShotInfo.sqf b/addons/artillerytables/dev/showShotInfo.inc.sqf similarity index 100% rename from addons/artillerytables/dev/showShotInfo.sqf rename to addons/artillerytables/dev/showShotInfo.inc.sqf diff --git a/addons/artillerytables/functions/fnc_firedEH.sqf b/addons/artillerytables/functions/fnc_firedEH.sqf index 01947b4ebe..5aa46c6969 100644 --- a/addons/artillerytables/functions/fnc_firedEH.sqf +++ b/addons/artillerytables/functions/fnc_firedEH.sqf @@ -25,7 +25,7 @@ params ["_vehicle", "", "", "", "", "_magazine", "_projectile", "_gunner"]; TRACE_4("firedEH",_vehicle,_magazine,_projectile,_gunner); -if (!([_gunner] call EFUNC(common,isPlayer))) exitWith {}; // AI don't know how to use (this does give them more range than a player) +if !([_gunner] call EFUNC(common,isPlayer)) exitWith {}; // AI don't know how to use (this does give them more range than a player) if ((gunner _vehicle) != _gunner) exitWith {}; // check if primaryGunner @@ -35,7 +35,7 @@ if (isNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(airFriction))) _airFriction = getNumber (configFile >> "CfgMagazines" >> _magazine >> QGVAR(airFriction)); }; TRACE_1("",_airFriction); -if (_airFriction >= 0) exitWith {}; // 0 disables everything, >0 makes no sense +if (_airFriction == 0) exitWith {}; // 0 disables everything BEGIN_COUNTER(adjustmentsCalc); @@ -60,6 +60,7 @@ if (_newMuzzleVelocityCoefficent != 1) then { _projectile setVelocity _bulletVelocity; }; +if (_airFriction > 0) exitWith {}; // positive value indicates it has vanilla airFriction, so we can just exit [{ params ["_projectile", "_kFactor", "_time"]; diff --git a/addons/artillerytables/functions/fnc_interactMenuOpened.sqf b/addons/artillerytables/functions/fnc_interactMenuOpened.sqf index b7d6371339..4ba6342fc8 100644 --- a/addons/artillerytables/functions/fnc_interactMenuOpened.sqf +++ b/addons/artillerytables/functions/fnc_interactMenuOpened.sqf @@ -19,7 +19,7 @@ params ["_menuType"]; TRACE_1("interactMenuOpened",_menuType); if (_menuType != 1) exitWith {}; -if (!("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems)))) exitWith {}; +if !("ACE_artilleryTable" in (ace_player call EFUNC(common,uniqueItems))) exitWith {}; private _vehicleAdded = ace_player getVariable [QGVAR(vehiclesAdded), []]; private _rangeTablesShown = ace_player getVariable [QGVAR(rangeTablesShown), []]; diff --git a/addons/artillerytables/functions/fnc_rangeTableOpen.sqf b/addons/artillerytables/functions/fnc_rangeTableOpen.sqf index 97c8dfe435..508b8c894c 100644 --- a/addons/artillerytables/functions/fnc_rangeTableOpen.sqf +++ b/addons/artillerytables/functions/fnc_rangeTableOpen.sqf @@ -41,8 +41,15 @@ _mags = _mags apply { private _initSpeed = getNumber (_magCfg >> _x >> "initSpeed"); _magParamsArray pushBackUnique _initSpeed; private _airFriction = 0; - if (_advCorrection) then { - _airFriction = if (isNumber (_magCfg >> _x >> QGVAR(airFriction))) then { getNumber (_magCfg >> _x >> QGVAR(airFriction)) } else { DEFAULT_AIR_FRICTION }; + private _magAirFriction = getNumber (_magCfg >> _x >> QGVAR(airFriction)); + if (_magAirFriction <= 0) then { + if (_advCorrection) then { + _airFriction = [DEFAULT_AIR_FRICTION, _magAirFriction] select (isNumber (_magCfg >> _x >> QGVAR(airFriction))); + }; + } else { + // positive value, use ammo's airFriction (regardless of setting) + private _ammo = getText (_magCfg >> _x >> "ammo"); + _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction"); }; _magParamsArray pushBackUnique _airFriction; [getText (_magCfg >> _x >> "displayNameShort"), getText (_magCfg >> _x >> "displayName"), _initSpeed, _airFriction] @@ -65,7 +72,7 @@ GVAR(magModeData) = []; { _x params ["_xDisplayNameShort", "_xDisplayName", "_xInitSpeed", "_xAirFriction"]; if (_allSameCharge) then { - _ctrlChargeList lbAdd format ["%1", _xDisplayNameShort]; + _ctrlChargeList lbAdd _xDisplayNameShort; _ctrlChargeList lbSetTooltip [count GVAR(magModeData), format ["%1\n%2 m/s\n%3", _xDisplayName, _xInitSpeed toFixed 1, _xAirFriction]]; GVAR(magModeData) pushBack [_xInitSpeed, _xAirFriction]; } else { 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/artillerytables/initSettings.sqf b/addons/artillerytables/initSettings.inc.sqf similarity index 82% rename from addons/artillerytables/initSettings.sqf rename to addons/artillerytables/initSettings.inc.sqf index 762010b2ca..f34190f910 100644 --- a/addons/artillerytables/initSettings.sqf +++ b/addons/artillerytables/initSettings.inc.sqf @@ -15,7 +15,5 @@ private _categoryName = [format ["ACE %1", localize "str_a3_cfgmarkers_nato_art" [LSTRING(disableArtilleryComputer_displayName), LSTRING(disableArtilleryComputer_description)], _categoryName, false, // default value - true, // isGlobal - {[QGVAR(disableArtilleryComputer), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/artillerytables/stringtable.xml b/addons/artillerytables/stringtable.xml index d9c44c5156..ba5962ae52 100644 --- a/addons/artillerytables/stringtable.xml +++ b/addons/artillerytables/stringtable.xml @@ -6,9 +6,9 @@ Artillerieschusstafel 火炮射程表 火炮射表 - Tavola balistica per artigliria + Tavola balistica per artiglieria Dělostřelecké tabulky střelby - 火砲射表 + 火砲用 射表 Tabela Strzelnicza Table de tir d'artillerie Tabela de Artilharia @@ -24,7 +24,7 @@ 通用火炮射表 Tavola balistica universale per artiglieria Univerzální dělostřelecká tabulka střelby - 汎用の火砲用射程表 + 砲兵火砲用の汎用射撃表 Uniwersalna Tabela Strzelnicza Table de tir universelle pour l'artillerie. Tabela de Artilharia Universal @@ -61,7 +61,7 @@ Játékos általi lövésekhez, legyen-e számított légellenállás és szélhatás Для выстрелов игрока. Моделирует сопротивление воздуха и эффект ветра Per Proiettili dei Giocatori, simula la Resistenza dell'Aria e gli Effetti del Vento - プレイヤが射撃すると、空気抵抗モデルと風による影響を与えます。 + プレイヤーが射撃すると、空気抵抗モデルと風による影響を与えます。 플레이어가 사격 시 공기저항과 바람에 영향을 받습니다 设定由玩家射击的炮弹是否受到空气阻力与风力的影响 設定由玩家射擊的迫擊砲,將會受到空氣阻力與風力的影響 @@ -72,9 +72,9 @@ Artilleriecomputer ausgeschaltet 停用火炮電腦 停用弹道计算机 - Computer artiglieria disattivato + Computer balistico disattivato Zakázat používání dělostřeleckého počítače - 砲撃コンピュータ無効化 + 砲撃コンピュータの無効化 Wyłączony Komputer Artyleryjski Désactiver l'ordinateur de tir Computador de Artilharia Desabilitado @@ -88,7 +88,7 @@ Deaktiviert die Vanilla-Artilleriecomputer 停用原本的火炮控制電腦 禁用游戏自带的弹道计算机 - Disattiva il computer artiglieria vanilla + Disattiva il computer balistico vanilla Zakázat používání dělostřeleckého počítače základní hry ゲームの砲撃コンピュータを無効化します。 Wyłącza komputer artyleryjski wprowadzony w vanili diff --git a/addons/atragmx/XEH_postInit.sqf b/addons/atragmx/XEH_postInit.sqf index 9034016212..01eb14d928 100644 --- a/addons/atragmx/XEH_postInit.sqf +++ b/addons/atragmx/XEH_postInit.sqf @@ -1,8 +1,10 @@ #include "script_component.hpp" -#include "initKeybinds.sqf" +if (!hasInterface) exitWith {}; + +#include "initKeybinds.inc.sqf" GVAR(active) = false; GVAR(initialised) = false; -[QEGVAR(vector,rangefinderData), {_this call FUNC(sord)}] call CBA_fnc_addEventHandler; +[QEGVAR(vector,rangefinderData), LINKFUNC(sord)] call CBA_fnc_addEventHandler; diff --git a/addons/atragmx/functions/fnc_initGunList.sqf b/addons/atragmx/functions/fnc_initGunList.sqf index 783a68202a..515bc9013e 100644 --- a/addons/atragmx/functions/fnc_initGunList.sqf +++ b/addons/atragmx/functions/fnc_initGunList.sqf @@ -15,7 +15,7 @@ * Public: No */ -LOG_2("Trying to load gunlist from profile [Version: %1][Count: %2]", profileNamespace getVariable [ARR_2(QGVAR(profileNamespaceVersion), 'none')], count (profileNamespace getVariable [ARR_2(QGVAR(gunList), [])])); +LOG_2("Trying to load gunlist from profile [Version: %1][Count: %2]",profileNamespace getVariable [ARR_2(QGVAR(profileNamespaceVersion),'none')],count (profileNamespace getVariable [ARR_2(QGVAR(gunList),[])])); private _resetGunList = true; if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == ATRAGMX_PROFILE_NAMESPACE_VERSION && {count (profileNamespace getVariable ["ACE_ATragMX_gunList", []]) > 0}) then { @@ -23,7 +23,7 @@ if ((profileNamespace getVariable ["ACE_ATragMX_profileNamespaceVersion", 0]) == _resetGunList = false; { // Verify each gun has correct param type - if (!(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false])) exitWith { + if !(_x isEqualTypeArray ["", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "", [], [], false]) exitWith { _resetGunList = true; }; } forEach GVAR(gunList); diff --git a/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf index 31451c7ff8..cbbb4603e3 100644 --- a/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf +++ b/addons/atragmx/functions/fnc_read_gun_list_entries_from_config.sqf @@ -74,7 +74,7 @@ private _validate_preset = { ERROR(_errorMsg); _valid = false; }; - if (!((_this select 17) in ["ASM", "ICAO"])) then { + if !((_this select 17) in ["ASM", "ICAO"]) then { private _errorMsg = format ["Invalid atmosphere model: %1", _this select 17]; ERROR(_errorMsg); _valid = false; diff --git a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf index b34dd666f2..5408edee3a 100644 --- a/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf +++ b/addons/atragmx/functions/fnc_target_speed_assist_timer.sqf @@ -26,7 +26,7 @@ if !(ctrlVisible 9000) then { params ["_args"]; _args params ["_startTime"]; - if (!(GVAR(speedAssistTimer))) exitWith { + if !(GVAR(speedAssistTimer)) exitWith { GVAR(speedAssistTimer) = true; ctrlSetText [8006, Str(Round((CBA_missionTime - _startTime) * 10) / 10)]; diff --git a/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf index bb581ad6ea..a8cd7ce52a 100644 --- a/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_c1_ballistic_coefficient_data.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 17000) then { false call FUNC(show_c1_ballistic_coefficient_data); diff --git a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf index 562ef30553..34326b251d 100644 --- a/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf +++ b/addons/atragmx/functions/fnc_toggle_muzzle_velocity_data.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 16000) then { false call FUNC(show_muzzle_velocity_data); diff --git a/addons/atragmx/functions/fnc_toggle_truing_drop.sqf b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf index 2c61b1776b..2d13619de0 100644 --- a/addons/atragmx/functions/fnc_toggle_truing_drop.sqf +++ b/addons/atragmx/functions/fnc_toggle_truing_drop.sqf @@ -15,7 +15,7 @@ * Public: No */ -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {}; if (ctrlVisible 18000) then { false call FUNC(show_truing_drop); diff --git a/addons/atragmx/functions/fnc_update_result.sqf b/addons/atragmx/functions/fnc_update_result.sqf index 4def2f87a6..cfd8f460a9 100644 --- a/addons/atragmx/functions/fnc_update_result.sqf +++ b/addons/atragmx/functions/fnc_update_result.sqf @@ -90,7 +90,7 @@ if (GVAR(showWind2)) then { _elevationAbs = Round(_elevationAbs * 100) / 100; if (_elevationAbs > 0) then { - ctrlSetText [400, format["%1", abs(_elevationAbs)]]; + ctrlSetText [400, str abs _elevationAbs]; } else { if (_elevationAbs < 0) then { ctrlSetText [400, format["%1D", abs(_elevationAbs)]]; @@ -100,7 +100,7 @@ if (_elevationAbs > 0) then { }; _elevationRel = Round(_elevationRel * 100) / 100; if (_elevationRel > 0) then { - ctrlSetText [401, format["%1", abs(_elevationRel)]]; + ctrlSetText [401, str abs _elevationRel]; } else { if (_elevationRel < 0) then { ctrlSetText [401, format["%1D", abs(_elevationRel)]]; @@ -110,7 +110,7 @@ if (_elevationRel > 0) then { }; _elevationCur = Round(_elevationCur * 100) / 100; if (_elevationCur > 0) then { - ctrlSetText [402, format["%1", abs(_elevationCur)]]; + ctrlSetText [402, str abs _elevationCur]; } else { if (_elevationCur < 0) then { ctrlSetText [402, format["%1D", abs(_elevationCur)]]; diff --git a/addons/atragmx/functions/fnc_update_zero_range.sqf b/addons/atragmx/functions/fnc_update_zero_range.sqf index 023a5a7ee2..8a3eca1344 100644 --- a/addons/atragmx/functions/fnc_update_zero_range.sqf +++ b/addons/atragmx/functions/fnc_update_zero_range.sqf @@ -35,7 +35,7 @@ if (!GVAR(atmosphereModeTBH)) then { _relativeHumidity = 0.5; }; -private _scopeBaseAngle = if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { +private _scopeBaseAngle = if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { diff --git a/addons/atragmx/initKeybinds.sqf b/addons/atragmx/initKeybinds.inc.sqf similarity index 100% rename from addons/atragmx/initKeybinds.sqf rename to addons/atragmx/initKeybinds.inc.sqf diff --git a/addons/atragmx/stringtable.xml b/addons/atragmx/stringtable.xml index 04f678ec21..a7c08712aa 100644 --- a/addons/atragmx/stringtable.xml +++ b/addons/atragmx/stringtable.xml @@ -46,7 +46,7 @@ Megerősített PDA, ATragMX-el PDA s ATragMX PDA Robusto com ATragMX - ATragMX 付きの携行型端末 + ATragMX を搭載した頑丈な携帯情報端末 ATragMX가 달린 PDA 裝有軍用PDA的ATragMX 装有 ATragMX 的军用 PDA diff --git a/addons/attach/functions/fnc_detach.sqf b/addons/attach/functions/fnc_detach.sqf index 2ae30f5663..d953b02bd1 100644 --- a/addons/attach/functions/fnc_detach.sqf +++ b/addons/attach/functions/fnc_detach.sqf @@ -16,7 +16,7 @@ * Public: No */ -params ["_attachToVehicle","_unit"], +params ["_attachToVehicle","_unit"]; TRACE_2("params",_attachToVehicle,_unit); private _attachedList = _attachToVehicle getVariable [QGVAR(attached), []]; @@ -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/attach/functions/fnc_handleKilled.sqf b/addons/attach/functions/fnc_handleKilled.sqf index ef08aff305..2183b05b42 100644 --- a/addons/attach/functions/fnc_handleKilled.sqf +++ b/addons/attach/functions/fnc_handleKilled.sqf @@ -28,7 +28,7 @@ if (_attachedList isEqualTo []) exitWith {}; TRACE_2("detaching",_xObject,_deadUnit); detach _xObject; //If it's a vehicle, also delete the attached - if (!(_deadUnit isKindOf "CAManBase")) then { + if !(_deadUnit isKindOf "CAManBase") then { _xObject setPos ((getPos _deadUnit) vectorAdd [0, 0, -1000]); [{deleteVehicle (_this select 0)}, [_xObject], 2] call CBA_fnc_waitAndExecute; }; diff --git a/addons/attach/stringtable.xml b/addons/attach/stringtable.xml index 9c25607693..2d5671dec1 100644 --- a/addons/attach/stringtable.xml +++ b/addons/attach/stringtable.xml @@ -182,7 +182,7 @@ La Strobo IR è una luce stroboscopica che ti permette di segnalare la tua posizione grazie all'emissione di impulsi ad infrarossi visibili solo con i visori notturni. Az infravörös jeladóval megjelölheted a helyzetedet úgy, hogy annak pulzáló fénye csak éjjellátó készülékkel látható. ИК-маяк позволяет сигнализировать о своём местоположении через пульсирующий свет, видимый только через ПНВ. - 赤外線ストロボはあなたの位置を知らせますが、夜間暗視装置を介してでしか見れません。 + 赤外線ストロボを使用すると、暗視装置を介してのみ見ることが出来る点滅表示で自分の位置を知らせることができます。 적외선 스트로브는 자신의 위치를 반짝이면서 표시합니다. 이는 야간투시경으로 밖에 보지 못합니다. 紅外線閃頻器,藉由紅外線閃頻信號來辨識你的位置,僅能使用夜視系統來辨識紅外線信號 红外频闪器制造只有用夜视仪才能看到的频闪信标,发出一个位置信号。 @@ -199,7 +199,7 @@ Posiziona Elhelyez Установить - 置く + 設置 놓기 放置 放置 @@ -250,7 +250,7 @@ %1<br/>attaccata %1<br/>hozzácsatolva %1<br/>присоединен(-а) - %1<br/>を取り付けました + %1 を<br/>取り付けました %1<br/>부착됨 %1<br/>已附掛 %1<br/>已附挂 @@ -267,7 +267,7 @@ %1<br/>staccata %1<br/>lecsatolva %1<br/>отсоединен(-а) - %1<br/>を外しました + %1 を<br/>外しました %1<br/>떼어냄 %1<br/>已取下 %1<br/>已取下 diff --git a/addons/ballistics/functions/fnc_statTextStatement_magazineMuzzleVelocity.sqf b/addons/ballistics/functions/fnc_statTextStatement_magazineMuzzleVelocity.sqf index 04e9f4d327..a57a52bba7 100644 --- a/addons/ballistics/functions/fnc_statTextStatement_magazineMuzzleVelocity.sqf +++ b/addons/ballistics/functions/fnc_statTextStatement_magazineMuzzleVelocity.sqf @@ -41,14 +41,18 @@ if (_initSpeedCoef > 0) then { }; private _abAdjustText = ""; -if (_magIsForCurrentWeapon && {["ace_advanced_ballistics"] call EFUNC(common,isModLoaded)}) then { +if ( + _magIsForCurrentWeapon && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]} && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} // this can be on while AB is off or vice-versa +) then { private _configAmmo = (configFile >> "CfgAmmo" >> (getText (_configMagazine >> "ammo"))); private _barrelLength = getNumber (_configWeapon >> "ACE_barrelLength"); private _muzzleVelocityTable = getArray (_configAmmo >> "ACE_muzzleVelocities"); private _barrelLengthTable = getArray (_configAmmo >> "ACE_barrelLengths"); private _abShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); if (_abShift != 0) then { - _abAdjustText = " [AB]", + _abAdjustText = " [AB]"; _muzzleVelocity = _abShift; }; }; diff --git a/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf b/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf index 4f6bdd0412..e11c7cf5fb 100644 --- a/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf +++ b/addons/ballistics/functions/fnc_statTextStatement_weaponMuzzleVelocity.sqf @@ -37,14 +37,17 @@ if (_magazine isEqualTo "") then { }; private _abAdjustText = ""; - if (["ace_advanced_ballistics"] call EFUNC(common,isModLoaded)) then { + if ( + missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} // this can be on while AB is off or vice-versa + ) then { private _configAmmo = (configFile >> "CfgAmmo" >> (getText (_configMagazine >> "ammo"))); private _barrelLength = getNumber (_configWeapon >> "ACE_barrelLength"); private _muzzleVelocityTable = getArray (_configAmmo >> "ACE_muzzleVelocities"); private _barrelLengthTable = getArray (_configAmmo >> "ACE_barrelLengths"); private _abShift = [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); if (_abShift != 0) then { - _abAdjustText = " [AB]", + _abAdjustText = " [AB]"; _muzzleVelocity = _abShift; }; }; diff --git a/addons/ballistics/stringtable.xml b/addons/ballistics/stringtable.xml index ffe390ca4b..7137735233 100644 --- a/addons/ballistics/stringtable.xml +++ b/addons/ballistics/stringtable.xml @@ -8,12 +8,12 @@ #00 Schrotmunition #00 鹿彈 #00 鹿弹 - #00 Buckshot + #00 Pallettoni #00 バックショット Chevrotine #00 #00 Broky velké #00 Śrut - #00 Chumbo + #00 Chumbo Grosso #00 Irisaçma #00 Картечь #00 벅샷 @@ -24,12 +24,12 @@ #00 Schrotmunition #00 鹿彈(8.38 mm) #00 鹿弹(8.38 mm) - #00 Buckshot - #00 バックショット + #00 Pallettoni + #00 バックショット - 直径 8.38 mm粒弾 Chevrotine #00 #00 Broky velké - kalibr 8.38 mm #00 Śrut - #00 Chumbo + #00 Chumbo Grosso #00 Irisaçma #00 Картечь #00 벅샷 @@ -40,12 +40,12 @@ #0 Schrotmunition #0 鹿彈 #0 鹿弹 - #0 Buckshot + #0 Pallettoni #0 バックショット Chevrotine #0 #0 Broky velké #0 Śrut - #0 Chumbo + #0 Chumbo Grosso #0 Irisaçma #0 Картечь #0 벅샷 @@ -56,12 +56,12 @@ #0 Schrotmunition #0 鹿彈 #0 鹿弹(8.1 mm) - #0 Buckshot - #0 バックショット + #0 Pallettoni + #0 バックショット - 直径 8.1 mm粒弾 Chevrotine #0 #0 Broky velké - kalibr 8.1 mm #0 Śrut - #0 Chumbo + #0 Chumbo Grosso #0 Irisaçma #0 Картечь #0 벅샷 @@ -72,12 +72,12 @@ #1 Schrotmunition #1 鹿彈 #1 鹿弹 - #1 Buckshot + #1 Pallettoni #1 バックショット Chevrotine #1 #1 Broky velké #1 Śrut - #1 Chumbo + #1 Chumbo Grosso #1 Irisaçma #1 Картечь #1 벅샷 @@ -88,12 +88,12 @@ #1 Schrotmunition #1 鹿彈 #1 鹿弹(7.6 mm) - #1 Buckshot - #1 バックショット + #1 Pallettoni + #1 バックショット - 直径 7.6 mm粒弾 Chevrotine #1 #1 Broky velké - kalibr 7.6 mm #1 Śrut - #1 Chumbo + #1 Chumbo Grosso #1 Irisaçma #1 Картечь #1 벅샷 @@ -104,12 +104,12 @@ #2 Schrotmunition #2 鹿彈 #2 鹿弹 - #2 Buckshot + #2 Pallettoni #2 バックショット Chevrotine #2 #2 Broky velké #2 Śrut - #2 Chumbo + #2 Chumbo Grosso #2 Irisaçma #2 Картечь #2 벅샷 @@ -120,12 +120,12 @@ #2 Schrotmunition #2 鹿彈 #2 鹿弹(6.9 mm) - #2 Buckshot - #2 バックショット + #2 Pallettoni + #2 バックショット - 直径 6.9 mm粒弾 Chevrotine #2 #2 Broky velké - kalibr 6.9 mm #2 Śrut - #2 Chumbo + #2 Chumbo Grosso #2 Irisaçma #2 Картечь #2 벅샷 @@ -136,12 +136,12 @@ #3 Schrotmunition #3 鹿彈 #3 鹿弹 - #3 Buckshot + #3 Pallettoni #3 バックショット Chevrotine #3 #3 Broky velké #3 Śrut - #3 Chumbo + #3 Chumbo Grosso #3 Irisaçma #3 Картечь #3 벅샷 @@ -152,12 +152,12 @@ #3 Schrotmunition #3 鹿彈 #3 鹿弹(6.4 mm) - #3 Buckshot - #3 バックショット + #3 Pallettoni + #3 バックショット - 直径 6.4 mm粒弾 Chevrotine #3 #3 Broky velké - kalibr 6.4 mm #3 Śrut - #3 Chumbo + #3 Chumbo Grosso #3 Irisaçma #3 Картечь #3 벅샷 @@ -168,12 +168,12 @@ #4 Schrotmunition #4 鹿彈 #4 鹿弹 - #4 Buckshot + #4 Pallettoni #4 バックショット Chevrotine #4 #4 Broky velké #4 Śrut - #4 Chumbo + #4 Chumbo Grosso #4 Irisaçma #4 Картечь #4 벅샷 @@ -184,12 +184,12 @@ #4 Schrotmunition #4 鹿彈 #4 鹿弹(6.10 mm) - #4 Buckshot - #4 バックショット + #4 Pallettoni + #4 バックショット - 直径 6.1 mm粒弾 Chevrotine #4 #4 Broky velké - kalibr 6.1 mm #4 Śrut - #4 Chumbo + #4 Chumbo Grosso #4 Irisaçma #4 Картечь #4 벅샷 @@ -200,14 +200,15 @@ #4 Vogelschrot #4 鳥彈 #4 鸟弹 - #4 Birdshot - #4 バックショット + #4 Pallini + #4 バードショット Grenaille No.4 #4 Broky malé #4 Śrut Drobny #4 Küçük saçma #4 Дробь #4 버드샷 + #4 Chumbo Fino #4 Birdshot @@ -215,14 +216,15 @@ #4 Vogelschrot #4 鳥彈 #4 鸟弹(3.30 mm) - #4 Birdshot - #4 バックショット + #4 Pallini + #4 バードショット - 直径 3.3 mm粒弾 Grenaille No.4 #4 Broky malé - kalibr 3.3 mm #4 Śrut Drobny (Birdshot) #4 Küçük saçma #4 Дробь #4 버드샷 + #4 Chumbo Fino 12 Gauge 2Rnd #00 Buckshot @@ -230,12 +232,12 @@ 12 Gauge 2Schuss #00 Schrotmunition 12鉛徑 2發 #00 鹿彈 12铅径 2发 #00 鹿弹 - 12 Gauge 2Rnd #00 Buckshot - 12 ゲージ 2 発入り #00 バックショット + Calibro 12 2cp #00 Pallettoni + 12 ゲージ 2Rnd #00 バックショット 2 balles cal. 12 Chevrotine #00 2x #00 Broky velké (kalibr 8.38 mm) 12 Gauge 2 naboje #00 Śrut - Chumbo #00 Calibre Doze 2 Tiros + Chumbo Grosso #00 Calibre Doze 2 Tiros 12 Калибр 2 патр. #00 Картечь 12 kalibre 2 mermi #00 İrisaçma 12 게이지 2발 #00 벅샷 @@ -246,12 +248,12 @@ 12 Gauge 2Schuss #0 Schrotmunition 12鉛徑 2發 #0 鹿彈 12铅径 2发 #0 鹿弹 - 12 Gauge 2Rnd #0 Buckshot - 12 ゲージ 2 発入り #0 バックショット + Calibro 12 2cp #0 Pallettoni + 12 ゲージ 2Rnd #0 バックショット 2 balles cal. 12 Chevrotine #0 2x #0 Broky velké (kalibr 8.1 mm) 12 Gauge 2 naboje #0 Śrut - Chumbo #0 Calibre Doze 2 Tiros + Chumbo Grosso #0 Calibre Doze 2 Tiros 12 Калибр 2 патр. #0 Картечь 12 kalibre 2 mermi #0 İrisaçma 12 게이지 2발 #00 벅샷 @@ -262,12 +264,12 @@ 12 Gauge 2Schuss #1 Schrotmunition 12鉛徑 2發 #1 鹿彈 12铅径 2发 #1 鹿弹 - 12 Gauge 2Rnd #1 Buckshot - 12 ゲージ 2 発入り #1 バックショット + Calibro 12 2cp #1 Pallettoni + 12 ゲージ 2Rnd #1 バックショット 2 balles cal. 12 Chevrotine #1 2x #1 Broky velké (kalibr 7.6 mm) 12 Gauge 2 naboje #1 Śrut - Chumbo #1 Calibre Doze 2 Tiros + Chumbo Grosso #1 Calibre Doze 2 Tiros 12 Калибр 2 патр. #1 Картечь 12 kalibre 2 mermi #1 İrisaçma 12 게이지 2발 #1 벅샷 @@ -278,12 +280,12 @@ 12 Gauge 2Schuss #2 Schrotmunition 12鉛徑 2發 #2 鹿彈 12铅径 2发 #2 鹿弹 - 12 Gauge 2Rnd #2 Buckshot - 12 ゲージ 2 発入り #2 バックショット + Calibro 12 2cp #2 Pallettoni + 12 ゲージ 2Rnd #2 バックショット 2 balles cal. 12 Chevrotine #2 2x #2 Broky velké (kalibr 6.9 mm) 12 Gauge 2 naboje #2 Śrut - Chumbo #2 Calibre Doze 2 Tiros + Chumbo Grosso #2 Calibre Doze 2 Tiros 12 Калибр 2 патр. #2 Картечь 12 kalibre 2 mermi #2 İrisaçma 12 게이지 2발 #2 벅샷 @@ -294,12 +296,12 @@ 12 Gauge 2Schuss #3 Schrotmunition 12鉛徑 2發 #3 鹿彈 12铅径 2发 #3 鹿弹 - 12 Gauge 2Rnd #3 Buckshot - 12 ゲージ 2 発入り #3 バックショット + Calibro 12 2cp #3 Pallettoni + 12 ゲージ 2Rnd #3 バックショット 2 balles cal. 12 Chevrotine #3 2x #3 Broky velké (kalibr 6.4 mm) 12 Gauge 2 naboje #3 Śrut - Chumbo #3 Calibre Doze 2 Tiros + Chumbo Grosso #3 Calibre Doze 2 Tiros 12 Калибр 2 патр. #3 Картечь 12 kalibre 2 mermi #3 İrisaçma 12 게이지 2발 #3 벅샷 @@ -310,12 +312,12 @@ 12 Gauge 2Schuss #4 Schrotmunition 12鉛徑 2發 #4 鹿彈 12铅径 2发 #4 鹿弹 - 12 Gauge 2Rnd #4 Buckshot - 12 ゲージ 2 発入り #4 バックショット + Calibro 12 2cp #4 Pallettoni + 12 ゲージ 2Rnd #4 バックショット 2 balles cal. 12 Chevrotine #4 2x #4 Broky velké (kalibr 6.1 mm) 12 Gauge 2 naboje #4 Śrut - Chumbo #4 Calibre Doze 2 Tiros + Chumbo Grosso #4 Calibre Doze 2 Tiros 12 Калибр 2 патр. #4 Картечь 12 kalibre 2 mermi #4 İrisaçma 12 게이지 2발 #4 벅샷 @@ -326,12 +328,12 @@ 12 Gauge 2Schuss #4 Schrotmunition 12鉛徑 2發 #4 鳥彈 12铅径 2发 #4 鸟弹 - 12 Gauge 2Rnd #4 Birdshot - 12 ゲージ 2 発入り #4 バックショット + Calibro 12 2cp #4 Pallini + 12 ゲージ 2Rnd #4 バードショット 2 balles cal. 12 Grenaille No.4 2x #4 Broky malé (kalibr 3.3 mm) 12 Gauge 2 naboje #4 Śrut - Chumbo #4 Calibre Doze 2 Tiros + Chumbo Fino #4 Calibre Doze 2 Tiros 12 Калибр 2 патр. #4 Дробь 12 kalibre 2 mermi #4 İrisaçma 12 게이지 2발 #4 버드샷 @@ -342,12 +344,12 @@ 12 Gauge 6Schuss #00 Schrotmunition 12鉛徑 6發 #00 鹿彈 12铅径 6发 #00 鹿弹 - 12 Gauge 6Rnd #00 Buckshot - 12 ゲージ 6 発入り #00 バックショット + Calibro 12 6cp #00 Pallettoni + 12 ゲージ 6Rnd #00 バックショット 6 balles cal. 12 Chevrotine #00 6x #00 Broky velké (kalibr 8.38 mm) 12 Gauge 6 naboi #00 Śrut - Chumbo #00 Calibre Doze 6 Tiros + Chumbo Grosso #00 Calibre Doze 6 Tiros 12 Калибр 6 патр. #00 Картечь 12 kalibre 6 mermi #00 İrisaçma 12 게이지 6발 #00 벅샷 @@ -358,12 +360,12 @@ 12 Gauge 6Schuss #0 Schrotmunition 12鉛徑 6發 #0 鹿彈 12铅径 6发 #0 鹿弹 - 12 Gauge 6Rnd #0 Buckshot - 12 ゲージ 6 発入り #0 バックショット + Calibro 12 6cp #0 Pallettoni + 12 ゲージ 6Rnd #0 バックショット 6 balles cal. 12 Chevrotine #0 6x #0 Broky velké (kalibr 8.1 mm) 12 Gauge 6 naboi #0 Śrut - Chumbo #0 Calibre Doze 6 Tiros + Chumbo Grosso #0 Calibre Doze 6 Tiros 12 Калибр 6 патр. #0 Картечь 12 kalibre 6 mermi #0 İrisaçma 12 게이지 6발 #0 벅샷 @@ -374,12 +376,12 @@ 12 Gauge 6Schuss #1 Schrotmunition 12鉛徑 6發 #1 鹿彈 12铅径 6发 #1 鹿弹 - 12 Gauge 6Rnd #1 Buckshot - 12 ゲージ 6 発入り #1 バックショット + Calibro 12 6cp #1 Pallettoni + 12 ゲージ 6Rnd #1 バックショット 6 balles cal. 12 Chevrotine #1 6x #1 Broky velké (kalibr 7.6 mm) 12 Gauge 6 naboi #1 Śrut - Chumbo #1 Calibre Doze 6 Tiros + Chumbo Grosso #1 Calibre Doze 6 Tiros 12 Калибр 6 патр. #1 Картечь 12 kalibre 6 mermi #1 İrisaçma 12 게이지 6발 #1 벅샷 @@ -390,12 +392,12 @@ 12 Gauge 6Schuss #2 Schrotmunition 12鉛徑 6發 #2 鹿彈 12铅径 6发 #2 鹿弹 - 12 Gauge 6Rnd #2 Buckshot - 12 ゲージ 6 発入り #2 バックショット + Calibro 12 6cp #2 Pallettoni + 12 ゲージ 6Rnd #2 バックショット 6 balles cal. 12 Chevrotine #2 6x #2 Broky velké (kalibr 6.9 mm) 12 Gauge 6 naboi #2 Śrut - Chumbo #2 Calibre Doze 6 Tiros + Chumbo Grosso #2 Calibre Doze 6 Tiros 12 Калибр 6 патр. #2 Картечь 12 kalibre 6 mermi #2 İrisaçma 12 게이지 6발 #2 벅샷 @@ -406,12 +408,12 @@ 12 Gauge 6Schuss #3 Schrotmunition 12鉛徑 6發 #3 鹿彈 12铅径 6发 #3 鹿弹 - 12 Gauge 6Rnd #3 Buckshot - 12 ゲージ 6 発入り #3 バックショット + Calibro 12 6cp #3 Pallettoni + 12 ゲージ 6Rnd #3 バックショット 6 balles cal. 12 Chevrotine #3 6x #3 Broky velké (kalibr 6.4 mm) 12 Gauge 6 naboi #3 Śrut - Chumbo #3 Calibre Doze 6 Tiros + Chumbo Grosso #3 Calibre Doze 6 Tiros 12 Калибр 6 патр. #3 Картечь 12 kalibre 6 mermi #3 İrisaçma 12 게이지 6발 #3 벅샷 @@ -422,12 +424,12 @@ 12 Gauge 6Schuss #4 Schrotmunition 12鉛徑 6發 #4 鹿彈 12铅径 6发 #4 鹿弹 - 12 Gauge 6Rnd #4 Buckshot - 12 ゲージ 6 発入り #4 バックショット + Calibro 12 6cp #4 Pallettoni + 12 ゲージ 6Rnd #4 バックショット 6 balles cal. 12 Chevrotine #4 6x #4 Broky velké (kalibr 6.1 mm) 12 Gauge 6 naboi #4 Śrut - Chumbo #4 Calibre Doze 6 Tiros + Chumbo Grosso #4 Calibre Doze 6 Tiros 12 Калибр 6 патр. #4 Картечь 12 kalibre 6 mermi #4 İrisaçma 12 게이지 6발 #4 벅샷 @@ -438,14 +440,15 @@ 12 Gauge 6Schuss #4 Schrotmunition 12鉛徑 6發 #4 鳥彈 12铅径 6发 #4 鸟弹 - 12 Gauge 6Rnd #4 Birdshot - 12 ゲージ 6 発入り #4 バックショット + Calibro 12 6cp #4 Pallini + 12 ゲージ 6Rnd #4 バードショット 6 balles cal. 12 Grenaille No.4 6x #4 Broky malé (kalibr 3.3 mm) 12 Gauge 6 naboi #4 Śrut 12 Калибр 6 патр. #4 Дробь 12 kalibre 6 mermi #4 İrisaçma 12 게이지 6발 #4 버드샷 + Chumbo Fino #4 Calibre Doze 6 Tiros 12 Gauge 15Rnd #00 Buckshot @@ -453,12 +456,12 @@ 12 Gauge 15Schuss #00 Schrotmunition 12鉛徑 15發 #00 鹿彈 12铅径 15发 #00 鹿弹 - 12 Gauge 15Rnd #00 Buckshot - 12 ゲージ 15 発入り #00 バックショット + Calibro 12 15cp #00 Pallettoni + 12 ゲージ 15Rnd #00 バックショット 15 balles cal. 12 Chevrotine #00 15x #00 Broky velké (kalibr 8.38 mm) 12 Gauge 15 naboi #00 Śrut - Chumbo #00 Calibre Doze 15 Tiros + Chumbo Grosso #00 Calibre Doze 15 Tiros 12 Калибр 15 патр. #00 Картечь 12 kalibre 15 mermi #00 İrisaçma 12 게이지 15발 #00 벅샷 @@ -471,11 +474,11 @@ Magazynek 6,5x47 mm 20rd (HPBT Scenar) Магазин из 20-ти 6,5x47 мм (экспансивные Scenar) 6,5x47 mm 20-Patronen-Magazin (HPBT Scenar) - 6.5x47 mm 20Rnd Mag (HPBT Scenar) + 6.5x47 mm 20cp Car (HPBT Scenar) 6.5x47 mm 20náb. Zásobník (HPBT Scenar) Carregador 6.5x47 mm com 20 cartuchos (HPBT Scenar) 6,5x47 mm 20-lövedékes tár (HPBT Scenar) - 6.5x47 mm 20発入り 弾倉 (HPBT Scenar) + 6.5x47 mm 20Rnd マガジン (HPBT Scenar) 20발 들이 6.5x47mm (HPBT Scenar) 6.5x47毫米 20發 彈匣 (拉普 空尖艇尾狙擊專用彈) 6.5x47 mm 20发 弹匣(HPBT Scenar) @@ -518,7 +521,7 @@ 6.5 mm Creedmor 20Rnd Mag Magazynek 6,5 mm Creedmor 20rd - 6.5 mm Creedmor 20Rnd Mag + 6.5 mm Creedmor 20cp Car Магазин из 20-ти 6,5 мм Creedmor 6,5 mm Creedmor 20-Patronen-Magazin Cargador de 20 balas Creedmor de 6.5 mm @@ -526,7 +529,7 @@ 6.5 mm Creedmor 20náb. Zásobník Carregador 6.5 mm com 20 cartuchos Creedmor 6,5 mm Creedmor 20-lövedékes tár - 6.5 mm Creedmor 20発入り 弾倉 + 6.5 mm クリードモア 20Rnd マガジン 20발 들이 6.5mm 크리드무어 탄창 6.5毫米 20發 彈匣 (克里德莫爾(CM) 狙擊專用彈) 6.5 mm 20发 弹匣(Creedmor) @@ -560,7 +563,7 @@ Ráže: 6.5x47 mm Creedmor<br />Nábojů: 20<br />Použití u: QBU-88 Calibre: 6.5x47 mm Creedmor<br/>Cartuchos: 20<br/>Usado em: QBU-88 Kaliber: 6,5x47 mm Creedmor<br />Lövedékek: 20<br />Használható: QBU-88 - 口径: 6.5x47 mm Creedmor<br />装填数: 20<br />次で使用: QBU-88 + 口径: 6.5x47 mm クリードモア<br />装填数: 20<br />次で使用: QBU-88 구경: 6.5x47mm 크리드무어<br/>장탄수: 20<br/>사용처: QBU-88 口徑: 6.5x47毫米 克里德莫爾 狙擊專用彈<br />發數: 20<br />使用於: QBU-88 口径:6.5x47 mm Creedmor 狙击专用弹<br />发数:20<br />使用于:QBU-88 @@ -569,7 +572,7 @@ 5.8 mm DBP88 10Rnd Mag Magazynek 5,8 mm DBP88 10rd - 5.8 mm DBP88 10Rnd Mag + 5.8 mm DBP88 10cp Car Магазин из 10-ти 5,8 мм DBP88 5,8 mm DBP88 10-Patronen-Magazin Cargador de 10 balas DBP88 de 5.8 mm @@ -577,7 +580,7 @@ 5.8 mm DBP88 10náb. Zásobník Carregador 5.8 mm com 10 cartuchos DBP88 5,8 mm DBP88 10-lövedékes tár - 5.8 mm DBP88 10発入り 弾倉 + 5.8 mm DBP88 10Rnd マガジン 10발 들이 5.8mm DBP88 탄창 5.8毫米 10發 彈匣 (DBP88) 5.8 mm 10发 弹匣(DBP88) @@ -627,9 +630,9 @@ Magazynek 6,5 mm 30rd Smugacz IR-DIM 6.5 mm 30náb. Svítící IR-DIM Zásobník Carregador de 30 projéteis traçantes IR-DIM de 6,5 mm - Caricatore 6.5 mm 30Rnd Traccianti IR-DIM + Caricatore 6.5 mm 30cp Traccianti IR-DIM Магазин из 30-ти 6,5 мм ИК-трассирующих - 6.5 mm 30発入り IR-DIM曳光弾 弾倉 + 6.5 mm 30Rnd IR-DIM トレーサー ケースレスマガジン 30발 들이 6.5mm IR-DIM 예광탄 탄창 6.5毫米 30發 低視度紅外線曳光彈 彈匣 6.5 mm 30发 弹匣(红外曳光) @@ -646,7 +649,7 @@ 6,5 mm IR-DIM 6.5 mm IR-DIM 6,5 мм ИК-трассирующие - 6.5 mm IR-DIM曳光弾 + 6.5 mm IR-DIM 6.5mm IR-DIM 예광탄 6.5毫米 低視紅外曳光彈 6.5 mm 红外曳光 @@ -661,9 +664,9 @@ Kaliber: 6,5x39 mm Smugacz IR-DIM<br />Pociski: 30<br />Używane w: MX/C/M/SW/3GL Ráže: 6.5x39 mm Svítící IR-DIM<br />Nábojů: 30<br />Použití u: MX Calibre: 6,5x39 mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: MX/C/M/SW/3GL - Calibro: 6.5x39 mm Traccianti IR-DIM <br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL + Calibro: 6.5x39 mm Tracciante IR-DIM <br />Munizioni: 30<br />In uso su: MX/C/M/SW/3GL Калибр: 6,5x39 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: MX/C/M/SW/3GL - 口径: 6.5x39 mm 曳光弾 IR-DIM<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL + 口径: 6.5x39 mm IR-DIM トレーサー<br />装填数: 30<br />次で使用: MX/C/M/SW/3GL 구경: 6.5x39mm IR-DIM 예광탄<br/>장탄수: 30<br/>사용처: MX/C/M/SW/3GL 口徑: 6.5x39毫米 低視度紅外線曳光彈<br />發數: 30<br />使用於: MX/C/M/SW/3GL 口径:6.5x39 mm 红外曳光<br />发数:30<br />使用于:MX/C/M/SW/3GL @@ -678,9 +681,9 @@ Magazynek 6,5 mm 30rd SD 6.5 mm 30náb. SD Zásobník Carregador de 30 projéteis SD de 6,5 mm - Caricatore 6.5 mm 30Rnd Sil. + Caricatore 6.5 mm 30cp Sil. Магазин из 30-ти 6,5 мм дозвуковых - 6.5 mm 30発入り 亜音速弾 弾倉 + 6.5 mm 30Rnd 亜音速弾 マガジン 30발 들이 6.5mm 아음속탄 탄창 6.5毫米 30發 消音彈 彈匣 6.5 mm 30发 弹匣(亚音速) @@ -697,7 +700,7 @@ 6,5 mm SD 6.5 mm Sil. 6,5 мм дозвуковые - 6.5 mm 亜音速弾 + 6.5 mm SD 6.5mm 아음속탄 6.5毫米 消音彈 6.5 mm 亚音速 @@ -729,9 +732,9 @@ Magazynek 6,5 mm 30rd AP 6.5 mm 30náb. AP Zásobník Carregador de 30 projéteis AP de 6,5 mm - Caricatore 6.5 mm 30Rnd AP + Caricatore 6.5 mm 30cp AP Магазин из 30-ти 6,5 мм бронебойных - 6.5 mm 30 発入り徹甲弾 弾倉 + 6.5 mm 30Rnd 徹甲弾 マガジン 30발 들이 6.5mm 철갑탄 탄창 6.5毫米30發 穿甲彈 彈匣 6.5 mm 30发 弹匣(穿甲) @@ -781,9 +784,9 @@ Magazynek 6,5 mm 30rd Smugacz IR-DIM 6.5 mm 30náb. Svítící IR-DIM Zásobník Carregador de 30 projéteis traçantes IR-DIM de 6,5 mm - Caricatore 6.5 mm 30Rnd Traccianti IR-DIM + Caricatore 6.5 mm 30cp Traccianti IR-DIM Магазин из 30-ти 6,5 мм ИК-трассирующих - 6.5 mm 30発入り IR-DIM曳光弾 弾倉 + 6.5 mm 30Rnd IR-DIM トレーサー マガジン 30발 들이 6.5mm IR-DIM 예광탄 탄창 6.5毫米 30發 低視度紅外線曳光彈 彈匣 6.5 mm 30发 弹匣(红外曳光) @@ -800,7 +803,7 @@ 6,5 mm IR-DIM 6.5 mm IR-DIM 6,5 мм ИК-трассирующие - 6.5 mm IR-DIM曳光弾 + 6.5 mm IR-DIM 6.5mm IR-DIM 예광탄 6.5毫米 低視紅外曳光彈 6.5 mm 红外曳光 @@ -817,7 +820,7 @@ Calibre: 6,5x39 mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: Katiba Calibro: 6.5x39 mm Tracciant IR-DIM<br />Munizioni: 30<br />In uso su: Katiba Калибр: 6,5x39 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: Katiba - 口径: 6.5x39 mm IR-DIM曳光弾<br />装填数: 30<br />次で使用: Katiba + 口径: 6.5x39 mm IR-DIM トレーサー<br />装填数: 30<br />次で使用: Katiba 구경: 6.5x39mm IR-DIM 예광탄<br/>장탄수: 30<br/>사용처: KH-2002 口徑: 6.5x39毫米 低視度紅外線曳光彈<br />發數: 30<br />使用於: Katiba 口径:6.5x39 mm 红外曳光<br />发数:30<br />使用于:Katiba @@ -832,9 +835,9 @@ Magazynek 6,5 mm 30rd SD 6.5 mm 30náb. SD Zásobník Carregador de 30 projéteis SD de 6,5 mm - Caricatore 6.5 mm 30Rnd Sil. + Caricatore 6.5 mm 30cp Sil. Магазин из 30-ти 6,5 мм дозвуковых - 6.5 mm 30発入り 亜音速弾 弾倉 + 6.5 mm 30Rnd 亜音速弾 マガジン 30발 들이 6.5mm 아음속탄 탄창 6.5毫米 30發 消音彈 彈匣 6.5 mm 30发 弹匣(亚音速) @@ -851,7 +854,7 @@ 6,5 mm SD 6.5 mm Sil. 6,5 мм дозвуковые - 6.5 mm 亜音速弾 + 6.5 mm SD 6.5mm 아음속탄 6.5毫米 消音彈 6.5 mm 亚音速 @@ -883,9 +886,9 @@ Magazynek 6,5 mm 30rd AP 6.5 mm 30náb. AP Zásobník Carregador de 30 projéteis AP de 6,5 mm - Caricatore 6.5 mm 30Rnd AP + Caricatore 6.5 mm 30cp AP Магазин из 30-ти 6,5 мм бронебойных - 6.5 mm 30 発入り徹甲弾 弾倉 + 6.5 mm 30Rnd 徹甲弾 マガジン 30발 들이 6.5mm 철갑탄 탄창 6.5毫米 30發 穿甲彈 彈匣 6.5 mm 30发 弹匣(穿甲) @@ -902,7 +905,7 @@ 6,5 mm AP 6.5 mm AP 6,5 мм бронебойные - 6.5 mm 徹甲弾 + 6.5 mm AP 6.5mm 철갑탄 6.5毫米 穿甲彈 6.5 mm 穿甲 @@ -935,9 +938,9 @@ Magazynek 5,56 mm 30rd Smugacz IR-DIM 5.56 mm 30náb. Svítící IR-DIM Zásobník Carregador de 30 projéteis traçantes IR-DIM de 5,56 mm - Caricatore 5.56 mm 30rnd Traccianti IR-DIM + Caricatore 5.56 mm 30cp Traccianti IR-DIM Магазин из 30-ти 5,56 мм ИК-трассирующих - 5.56 mm 30発入り IR-DIM曳光弾 弾倉 + 5.56mm 30Rnd IR-DIM トレーサー マガジン 30발 들이 5.56mm IR-DIM 예광탄 탄창 5.56毫米 30發 低視度紅外線曳光彈 彈匣 5.56 mm 30发 弹匣(红外曳光) @@ -954,7 +957,7 @@ 5,56 mm IR-DIM 5.56 mm IR-DIM 5,56 мм ИК-трассирующие - 5.56 mm IR-DIM曳光弾 + 5.56 mm IR-DIM 5.56mm IR-DIM 예광탄 5.56毫米 低視紅外曳光彈 5.56 mm 红外曳光 @@ -969,9 +972,9 @@ Kaliber: 5,56x45 mm Smugacz IR-DIM<br />Pociski: 30<br />Używane w: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR Ráže: 5.56x45 mm Svítící IR-DIM<br />Nábojů: 30<br />Použití u: CTAR-21, TAR-21, F2000, RFB SDAR Calibre: 5,56x45 mm Traçante IR-DIM<br />Projéteis: 30<br />Usado em: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - Calibro: 5.56x45 mm Traccianti IR-DIM<br />Munizioni: 30<br />In uso su: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + Calibro: 5.56x45 mm Tracciante IR-DIM<br />Munizioni: 30<br />In uso su: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR Калибр: 5,56x45 мм ИК-трассирующие<br />Патронов: 30<br />Используются с: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR - 口径: 5.56x45 mm IR-DIM曳光弾<br />装填数: 30<br />次で使用: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR + 口径: 5.56x45 mm IR-DIM トレーサー<br />装填数: 30<br />次で使用: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR 구경: 5.56x45 mm IR-DIM 예광탄<br/>장탄수: 30<br/>사용처: CTAR-21, TAR-21/GTAR-21 EGLM, F2000/택티컬/EGLM, SDAR 口徑: 5.56x45毫米 低視度紅外線曳光彈<br />發數: 30<br />使用於: TRG-20, TRG-21/EGLM, Mk20/C/EGLM, SDAR 口径:5.56x45 mm 红外曳光<br />发数:30<br />使用于:TRG-20,TRG-21/EGLM, Mk20/C/EGLM, SDAR @@ -987,9 +990,9 @@ Magazynek 7,62 mm 20rd Smugacz 7.62 mm 20náb. Svítící Zásobník Carregador de 20 projéteis traçantes de 7,62 mm - Caricatore 7.62 mm 20Rnd Traccianti + Caricatore 7.62 mm 20cp Traccianti Магазин из 20-ти 7,62 мм трассирующих - 7.62 mm 20発入り 曳光弾 + 7.62mm 20Rnd マガジン (トレーサー) 20발 들이 7.62mm 예광탄 탄창 7.62毫米 20發 曳光彈 彈匣 7.62 mm 20发 弹匣(曳光) @@ -1004,9 +1007,9 @@ 7,62 mm Smugacz 7.62 mm Svítící 7,62 mm Traçante - 7.62 mm Traccianti + 7.62 mm Tracciante 7,62 мм трассирущие - 7.62 mm 曳光弾 + 7.62 mm トレーサー 7.62mm 예광탄 7.62毫米 曳光彈 7.62 mm 曳光 @@ -1021,9 +1024,9 @@ Kaliber: 7,62x51 mm Smugacz<br />Pociski: 20<br />Używane w: Mk18 ABR Ráže: 7.62x51 mm Svítící<br />Nábojů: 20<br />Použití u: Mk14 Mod 1 EBR Calibre: 7,62x51 mm Traçante<br />Projéteis: 20<br />Usado em: Mk18 ABR - Calibro: 7.62x51 mm Traccianti<br />Munizioni: 20<br />In uso su: Mk18 ABR + Calibro: 7.62x51 mm Tracciante<br />Munizioni: 20<br />In uso su: Mk18 ABR Калибр: 7,62x51 мм трассирующие<br />Патронов: 20<br />Используются с: Mk18 ABR - 口径: 7.62x51 mm 曳光弾<br />装填数: 20<br />次で使用: Mk18 ABR + 口径: 7.62x51 mm トレーサー<br />装填数: 20<br />次で使用: Mk18 ABR 구경: 7.62x51mm 예광탄<br/>장탄수: 20<br/>사용처: Mk.14 Mod 1 EBR 口徑: 7.62x51毫米 曳光彈<br />發數: 20<br />使用於: Mk18 ABR 口径:7.62x51 mm 曳光<br />发数:20<br />使用于:Mk18 ABR @@ -1038,9 +1041,9 @@ Magazynek 7,62 mm 20rd Smugacz IR-DIM 7.62 mm 20náb. Svítící IR-DIM Zásobník Carregador de 20 projéteis IR-DIM de 7,62 mm - Caricatore 7.62 mm 20rnd Traccianti IR-DIM + Caricatore 7.62 mm 20cp Traccianti IR-DIM Магазин из 20-ти 7,62 мм ИК-трассирующих - 7.62 mm 20発入り IR-DIM曳光弾 + 7.62mm 20Rnd マガジン (IR-DIM) 20발 들이 7.62mm IR-DIM 예광탄 탄창 7.62毫米 20發 低視度紅外線曳光彈 彈匣 7.62 mm 20发 弹匣(红外曳光) @@ -1057,7 +1060,7 @@ 7,62 mm IR-DIM 7.62 mm IR-DIM 7,62 мм ИК-трассирующие - 7.62 mm IR-DIM曳光弾 + 7.62 mm IR-DIM 7.62mm IR-DIM 예광탄 7.62毫米 低視紅外曳光彈 7.62 mm 红外曳光 @@ -1074,7 +1077,7 @@ Calibre: 7,62x51 mm Traçante IR-DIM<br />Projéteis: 20<br />Usado em: Mk18 ABR Calibro: 7.62x51 mm Traccianti IR-DIM<br />Munizioni: 20<br />In uso su: Mk18 ABR Калибр: 7,62x51 мм ИК-трассирующие<br />Патронов: 20<br />Используются с: Mk18 ABR - 口径: 7.62x51 mm IR-DIM曳光弾<br />装填数: 20<br />次で使用: Mk18 ABR + 口径: 7.62x51 mm IR-DIM トレーサー<br />装填数: 20<br />次で使用: Mk18 ABR 구경: 7.62x51mm IR-DIM 예광탄<br/>장탄수: 20<br/>사용처: Mk.14 Mod 1 EBR 口徑: 7.62x51毫米 低視度紅外線曳光彈<br />發數: 20<br />使用於: Mk18 ABR 口径:7.62x51 mm 红外曳光<br />发数:20<br />使用于:Mk18 ABR @@ -1089,9 +1092,9 @@ Magazynek 7,62 mm 20rd SD 7.62 mm 20náb. SD Zásobník Carregador de 20 projéteis SD de 7,62 mm - Caricatore 7.62 mm 20Rnd Sil. + Caricatore 7.62 mm 20cp Sil. Магазин из 20-ти 7,62 мм дозвуковых - 7.62 mm 20発入り 亜音速弾 弾倉 + 7.62mm 20Rnd マガジン (亜音速弾) 20발 들이 7.62mm 아음속탄 탄창 7.62毫米 20發 消音彈 彈匣 7.62 mm 20发 弹匣(亚音速) @@ -1108,7 +1111,7 @@ 7,62 mm SD 7.62 mm Sil. 7,62 мм дозвуковые - 7.62 mm 亜音速弾 + 7.62 mm SD 7.62mm 아음속탄 7.62毫米 消音彈 7.62 mm 亚音速 @@ -1140,9 +1143,9 @@ Magazynek 7,62 mm 10rd Smugacz 7.62 mm 10náb. Svítící Zásobník Carregador de 10 projéteis traçantes de 7,62 mm - Caricatore 7.62 mm 10Rnd Traccianti + Caricatore 7.62 mm 10cp Traccianti Магазин из 10-ти 7,62 мм трассирующих - 7.62 mm 10発入り 曳光弾 + 7.62mm 10Rnd マガジン (トレーサー) 10발 들이 7.62mm 예광탄 탄창 7.62毫米 10發 曳光彈 彈匣 7.62 mm 10发 弹匣(曳光) @@ -1157,9 +1160,9 @@ 7,62 mm Smugacz 7.62 mm Svítící 7,62 mm Traçante - 7.62 mm Traccianti + 7.62 mm Tracciante 7,62 мм трассирущие - 7.62 mm 曳光弾 + 7.62 mm トレーサー 7.62mm 예광탄 7.62毫米 曳光彈 7.62 mm 曳光 @@ -1174,9 +1177,9 @@ Kaliber: 7,62x51 mm Smugacz<br />Pociski: 10<br />Używane w: Mk18 ABR Ráže: 7.62x51 mm Svítící<br />Nábojů: 10<br />Použití u: Mk14 Mod 1 EBR Calibre: 7,62x51 mm Traçante<br />Projéteis: 10<br />Usado em: Mk18 ABR - Calibro: 7.62x51 mm Traccianti<br />Munizioni: 10<br />In uso su: Mk18 ABR + Calibro: 7.62x51 mm Tracciante<br />Munizioni: 10<br />In uso su: Mk18 ABR Калибр: 7,62x51 мм трассирующие<br />Патронов: 10<br />Используются с: Mk18 ABR - 口径: 7.62x51 mm 曳光弾<br />装填数: 10<br />次で使用: Mk18 ABR + 口径: 7.62x51 mm トレーサー<br />装填数: 10<br />次で使用: Mk18 ABR 구경: 7.62x51mm 예광탄<br/>장탄수: 10<br/>사용처: Mk.14 Mod 1 EBR 口徑: 7.62x51毫米 曳光彈<br />發數: 10<br />使用於: Mk18 ABR 口径:7.62x51 mm 曳光<br />发数:10<br />使用于:Mk18 ABR @@ -1191,9 +1194,9 @@ Magazynek 7,62 mm 10rd Smugacz IR-DIM 7.62 mm 10náb. Svítící IR-DIM Zásobník Carregador de 10 projéteis IR-DIM de 7,62 mm - Caricatore 7.62 mm 10rnd Traccianti IR-DIM + Caricatore 7.62 mm 10cp Traccianti IR-DIM Магазин из 10-ти 7,62 мм ИК-трассирующих - 7.62 mm 10発入り IR-DIM曳光弾 + 7.62mm 10Rnd マガジン (IR-DIM) 10발 들이 7.62mm IR-DIM 예광탄 탄창 7.62毫米 10發 低視度紅外線曳光彈 彈匣 7.62 mm 10发 弹匣(红外曳光) @@ -1210,7 +1213,7 @@ 7,62 mm IR-DIM 7.62 mm IR-DIM 7,62 мм ИК-трассирующие - 7.62 mm IR-DIM曳光弾 + 7.62 mm IR-DIM 7.62mm IR-DIM 예광탄 7.62毫米 低視紅外曳光彈 7.62 mm 红外曳光 @@ -1225,9 +1228,9 @@ Kaliber: 7,62x51 mm Smugacz IR-DIM<br />Pociski: 10<br />Używane w: Mk18 ABR Ráže: 7.62x51 mm Svítící IR-DIM<br />Nábojů: 10<br />Použití u: Mk14 Mod 1 EBR Calibre: 7,62x51 mm Traçante IR-DIM<br />Projéteis: 10<br />Usado em: Mk18 ABR - Calibro: 7.62x51 mm Traccianti IR-DIM<br />Munizioni: 10<br />In uso su: Mk18 ABR + Calibro: 7.62x51 mm Tracciante IR-DIM<br />Munizioni: 10<br />In uso su: Mk18 ABR Калибр: 7,62x51 мм ИК-трассирующие<br />Патронов: 10<br />Используются с: Mk18 ABR - 口径: 7.62x51 mm IR-DIM曳光弾<br />装填数: 10<br />次で使用: Mk18 ABR + 口径: 7.62x51 mm IR-DIM トレーサー<br />装填数: 10<br />次で使用: Mk18 ABR 구경: 7.62x51mm IR-DIM 예광탄<br/>장탄수: 10<br/>사용처: Mk.14 Mod 1 EBR 口徑: 7.62x51毫米 低視度紅外線曳光彈<br />發數: 10<br />使用於: Mk18 ABR 口径:7.62x51 mm 红外曳光<br />发数:10<br />使用于:Mk18 ABR @@ -1242,9 +1245,9 @@ Magazynek 7,62 mm 10rd SD 7.62 mm 10náb. SD Zásobník Carregador de 10 projéteis SD de 7,62 mm - Caricatore 7.62 mm 10Rnd Sil. + Caricatore 7.62 mm 10cp Sil. Магазин из 10-ти 7,62 мм дозвуковых - 7.62 mm 10発入り 亜音速弾 弾倉 + 7.62mm 10Rnd マガジン (亜音速弾) 10발 들이 7.62mm 아음속탄 탄창 7.62毫米 10發 消音彈 彈匣 7.62 mm 10发 弹匣(亚音速) @@ -1261,7 +1264,7 @@ 7,62 mm SD 7.62 mm Sil. 7,62 мм дозвуковые - 7.62 mm 亜音速弾 + 7.62 mm SD 7.62mm 아음속탄 7.62毫米 消音彈 7.62 mm 亚音速 @@ -1292,11 +1295,11 @@ Bande .338 NM 130Cps Traçantes Cinta de 130 balas trazadoras de .338 NM Лента из 130-ти .338 NM трассирующих - .338 NM 130Rnd Tracciante Belt + .338 NM 130cp Nastro Tracciante .338 NM 130náb. Svítící Pás Cinto de munição .338 NM com 130 cartuchos .338 NM 130-lövedékes nyomkövető heveder - .338 NM 130発入り 曳光弾ベルト + .338 NM 130Rnd トレーサー ベルト 130발 들이 .338구경 노르마 매그넘 예광탄 벨트 .338 拉普麥格農(NM) 130發 曳光彈 彈鏈 .338 NM 130发 弹链(曳光) @@ -1310,10 +1313,10 @@ .338 NM Traçante .338 NM Trazadora .338 NM трассирующие - .338 NM 130Rnd Tracciante + .338 NM 130cp Traccianti .338 NM Traçante .338 NM nyomkövető - .338 NM 曳光弾 + .338 NM トレーサー .338구경 노르마 매그넘 예광탄 .338 NM 曳光彈 .338 NM 曳光 @@ -1330,7 +1333,7 @@ Ráže: .338 Norma Magnum Svítící<br />Nábojů: 130<br />Použití u: LWMMG Calibre: .338 Norma Magnum Traçante<br />Cartuchos: 130<br />Usado em: SPMG Kaliber: .338 Norma Magnum nyomkövető<br />Lövedékek: 130<br />Használható: SPMG - 口径: .338 Norma Magnum 曳光弾<br />装填数: 130<br />次で使用: SPMG + 口径: .338 Norma Magnum トレーサー<br />装填数: 130<br />次で使用: SPMG 구경: .338구경 노르마 매그넘 예광탄<br/>장탄수: 130<br/>사용처: LWMMG 口徑: .338 拉普麥格農 曳光彈<br />發數: 130<br />使用於: SPMG 口径:.338 Norma Magnum 曳光<br />发数:130<br />使用于:SPMG @@ -1343,11 +1346,11 @@ Bande .338 NM 130Cps IR-DIM Cinta de 130 balas IR-DIM de .338 NM Лента из 130-ти .338 NM ИК-трассирующих - .338 NM 130Rnd IR-DIM Belt + .338 NM 130cp Nastro IR-DIM .338 NM 130náb. IR-DIM Pás Cinto de munição traçante .338 NM IR-DIM com 130 cartuchos .338 NM 130-lövedékes infravörös nyomkövető heveder - .338 NM 130発入り IR-DIM曳光弾ベルト + .338 NM 130Rnd IR-DIM ベルト 130발 들이 .338rnrud 노르마 매그넘 IR-DIM 예광탄 벨트 .338 拉普麥格農(NM) 130發 低視度紅外線曳光彈 彈鏈 .338 NM 130发 弹链(红外曳光) @@ -1364,7 +1367,7 @@ .338 NM IR-DIM .338 NM IR-DIM .338 NM infravörös nyomkövető - .338 NM IR-DIM曳光弾 + .338 NM IR-DIM .338구경 노르마 매그넘 IR-DIM 예광탄 .338 NM 低視紅外曳光彈 .338 NM 红外曳光 @@ -1381,7 +1384,7 @@ Ráže: .338 Noma Magnum Svítící IR-DIM<br />Nábojů: 130<br />Použití u: LWMMG Calibre: .338 Norma Magnum Traçante IR-DIM<br />Cartuchos: 130<br />Usado em: SPMG Kaliber: .338 Norma Magnum infravörös nyomkövető<br />Lövedékek: 130<br />Használható: SPMG - 口径: .338 Norma Magnum IR-DIM曳光弾<br />装填数: 130<br />次で使用: SPMG + 口径: .338 Norma Magnum IR-DIM トレーサー<br />装填数: 130<br />次で使用: SPMG 구경: .338구경 노르마 매그넘 IR-DIM 예광탄<br/>장탄수: 130<br/>사용처: LWMMG 口徑: .338 拉普麥格農 低視度紅外線曳光彈<br />發數: 130<br />使用於: SPMG 口径:.338 Norma Magnum 红外曳光<br />发数:130<br />使用于:SPMG @@ -1394,11 +1397,11 @@ Bande .338 NM 130Cps AP Cinta de 130 balas AP de .338 NM Лента из 130-ти .338 NM бронебойных - .338 NM 130Rnd AP Belt + .338 NM 130cp Nastro AP .338 NM 130náb. AP Pás Cinto de munição .338 NM com 130 cartuchos AP .338 NM 130-lövedékes páncéltörő heveder - .338 NM 130発入り 徹甲弾ベルト + .338 NM 130Rnd 徹甲弾 ベルト 130발 들이 .338구경 노르마 매그넘 철갑탄 벨트 .338 拉普麥格農(NM) 130發 穿甲彈 彈鏈 .338 NM 130发 弹链(穿甲) @@ -1415,7 +1418,7 @@ .338 NM AP .338 NM AP .338 NM páncéltörő - .338 NM 徹甲弾 + .338 NM AP .338구경 노르마 매그넘 철갑탄 .338 NM 穿甲彈 .338 NM 穿甲 @@ -1446,11 +1449,11 @@ Ch. 9,3 mm 10Cps Traçantes Cargador de 10 balas trazadoras de 9.3 mm Магазин из 10-ти 9,3 мм трассирующих - 9.3 mm 10Rnd Tracer Mag + 9.3 mm 10cp Traccianti 9.3 mm 10náb. Svítící Zásobník Carregador de 10 cartuchos 9.3 mm traçantes 9,3 mm 10-lövedékes nyomkövető tár - 9.3 mm 10発入り 曳光弾 弾倉 + 9.3mm 10Rnd トレーサー マガジン 10발 들이 9.3 mm 예광탄 탄창 9.3毫米 10發 曳光彈 彈匣 9.3 mm 10发 弹匣(曳光) @@ -1464,10 +1467,10 @@ 9,3 mm Traçante 9.3 mm Trazadora 9,3 мм трассирующие - 9.3 mm Tracer + 9.3 mm Tracciante 9.3 mm Traçante 9,3 mm nyomkövető - 9.3 mm 曳光弾 + 9.3 mm トレーサー 9.3mm 예광탄 9.3毫米 曳光彈 9.3 mm 曳光 @@ -1480,11 +1483,11 @@ Calibre: 9,3x64 mm Traçante<br />Cartouches: 10<br />Utilisé avec: Cyrus Calibre: 9.3x64 mm trazadora<br />Balas: 10<br />Se usa en: Cyrus Калибр: 9,3x64 мм трассирующие<br />Патронов: 10<br />Используются с: Cyrus - Calibro: 9.3x64 mm Tracer<br />Munizioni: 10<br />In uso su: Cyrus + Calibro: 9.3x64 mm Tracciante<br />Munizioni: 10<br />In uso su: Cyrus Ráže: 9.3x64 mm Svítící<br />Nábojů: 10<br />Použití u: Cyrus Calibre: 9.3x64 mm Traçante<br />Cartuchos: 10<br />Usado em: Cyrus Kaliber: 9,3x64 mm nyomkövető<br />Lövedékek: 10<br />Használható: Cyrus - 口径: 9.3x64 mm 曳光弾<br />装填数: 10<br />次で使用: Cyrus + 口径: 9.3x64 mm トレーサー<br />装填数: 10<br />次で使用: Cyrus 구경: 9.3x64mm 예광탄<br/>장탄수: 10<br/>사용처: 사이러스 口徑: 9.3x64毫米 曳光彈<br />發數: 10<br />使用於: Cyrus 口径:9.3x64 mm 曳光<br />发数:10<br />使用于:"居鲁士" @@ -1497,12 +1500,12 @@ Ch. 9,3 mm 10Cps Traçantes IR-DIM Cargador de 10 balas trazadoras IR-DIM de 9.3 mm Магазин из 10-ти 9,3 мм ИК-трассирующих - 9.3 mm 10Rnd Tracciante IR-DIM Mag + 9.3 mm 10cp Traccianti IR-DIM 9.3 mm 10náb. Svítící IR-DIM Zásobník Carregador de 10 cartuchos 9.3 mm traçantes IR-DIM 9,3 mm 10-lövedékes infravörös nyomkövető tár - 9.3 mm 10発入り IR-DIM曳光弾 弾倉 - 10발들이 9.3mm IR-DIM 예광탄 탄창 + 9.3mm 10Rnd IR-DIM トレーサー マガジン + 10발 들이 9.3mm IR-DIM 예광탄 탄창 9.3毫米 10發 低視度紅外線曳光彈 彈匣 9.3 mm 10发 弹匣(红外曳光) 9.3 mm 10Rnd Tracer IR-DIM Mag @@ -1518,7 +1521,7 @@ 9.3 mm IR-DIM 9.3 mm IR-DIM 9,3 mm infravörös nyomkövető - 9.3 mm IR-DIM曳光弾 + 9.3 mm IR-DIM 9.3mm IR-DIM 예광탄 9.3毫米 低視紅外曳光彈 9.3 mm 红外曳光 @@ -1535,7 +1538,7 @@ Ráže: 9.3x64 mm Svítící IR-DIM<br />Nábojů: 10<br />Použití u: Cyrus Calibre: 9.3x64 mm Traçante IR-DIM<br />Cartuchos: 10<br />Usado em: Cyrus Kaliber: 9,3x64 mm infravörös nyomkövető<br />Lövedékek: 10<br /> Használható: Cyrus - 口径: 9.3x64 mm IR-DIM曳光弾<br />装填数: 10<br />次で使用: Cyrus + 口径: 9.3x64 mm IR-DIM トレーサー<br />装填数: 10<br />次で使用: Cyrus 구경: 9.3x64mm IR-DIM 예광탄<br/>장탄수: 10<br/>사용처: 사이러스 口徑: 9.3x64毫米 低視度紅外線曳光彈<br />發數: 10<br />使用於: Cyrus 口径:9.3x64 mm 红外曳光<br />发数:10<br />使用于:"居鲁士" @@ -1549,11 +1552,11 @@ Bande 9,3 mm 150Cps Traçantes Cinta de 150 balas trazadoras de 9.3 mm Лента из 150-ти 9,3 мм трассирующих - 9.3 mm 150Rnd Tracer Belt + 9.3 mm 150cp Nastro Tracciante 9.3 mm 150náb. Svítící Pás Cinto de munição traçante 9.3 mm com 150 cartuchos 9,3 mm 150-lövedékes nyomkövető heveder - 9.3 mm 150発入り 曳光弾ベルト + 9.3mm 150Rnd トレーサー ベルト 150발 들이 9.3mm 예광탄 벨트 9.3毫米 150發 曳光彈 彈鏈 9.3 mm 150发 弹链(曳光) @@ -1570,7 +1573,7 @@ 9.3 mm Tracciante 9.3 mm Traçante 9,3 mm nyomkövető - 9.3 mm 曳光弾 + 9.3 mm トレーサー 9.3mm 예광탄 9.3毫米 曳光彈 9.3 mm 曳光 @@ -1587,7 +1590,7 @@ Ráže: 9.3x64 mm Svítící<br />Nábojů: 150<br />Použití u: HK121 Calibre: 9.3x64 mm Traçante<br />Cartuchos: 150<br />Usado em: Navid Kaliber: 9,3x64 mm nyomkövető<br />Lövedékek: 150<br />Használható: Navid - 口径: 9.3x64 mm 曳光弾<br />装填数: 150<br />次で使用: Navid + 口径: 9.3x64 mm トレーサー<br />装填数: 150<br />次で使用: Navid 구경: 9.3x64mm 예광탄<br/>장탄수: 150<br/>사용처: HK121 口徑: 9.3x64m毫米 曳光彈<br />發數: 150<br />使用於: Navid 口径:9.3x64 mm 曳光<br />发数:150<br />使用于:Navid @@ -1600,12 +1603,12 @@ Bande 9,3 mm 150Cps Traçantes IR-DIM Cinta de 150 balas trazadoras IR-DIM de 9.3 mm Лента из 150-ти 9,3 мм ИК-трассирующих - 9.3 mm 150Rnd Tracciante IR-DIM Belt + 9.3 mm 150cp Nastro Tracciante IR-DIM 9.3 mm 150náb. Svítící IR-DIM Pás Cinto de munição traçante 9.3 mm IR-DIM com 150 cartuchos 9,3 mm 150-lövedékes infravörös nyomkövető heveder - 9.3 mm 150発入り IR-DIM曳光弾ベルト - 150발들이 9.3mm IR-DIM 예광탄 벨트 + 9.3mm 150Rnd IR-DIM トレーサー ベルト + 150발 들이 9.3mm IR-DIM 예광탄 벨트 9.3毫米 150發 低視度紅外線曳光彈 彈鏈 9.3 mm 150发 弹链(红外曳光) 9.3 mm 150Rnd Tracer IR-DIM Belt @@ -1621,7 +1624,7 @@ 9.3 mm IR-DIM 9.3 mm IR-DIM 9,3 mm infravörös nyomkövető - 9.3 mm IR-DIM曳光弾 + 9.3 mm IR-DIM 9.3mm IR-DIM 예광탄 9.3毫米 低視紅外曳光彈 9.3 mm 红外曳光 @@ -1638,7 +1641,7 @@ Ráže: 9.3x64 mm Svítící IR-DIM<br />Nábojů: 150<br />Použití u: HK121 Calibre: 9.3x64 mm Traçante IR-DIM<br />Cartuchos: 150<br />Usado em: Navid Kaliber: 9,3x64 mm infravörös nyomkövető<br />Lövedékek: 150<br />Használható: Navid - 口径: 9.3x64 mm IR-DIM曳光弾<br />装填数: 150<br />次で使用: Navid + 口径: 9.3x64 mm IR-DIM トレーサー<br />装填数: 150<br />次で使用: Navid 구경: 9.3x64mm IR-DIM 예광탄<br/>장탄수: 150<br/>사용처: HK121 口徑: 9.3x64毫米 低視度紅外線曳光彈<br />發數: 150<br />使用於: Navid 口径:9.3x64 mm 红外曳光<br />发数:150<br />使用于:Navid @@ -1651,12 +1654,12 @@ Bande 9,3 mm 150Cps AP Cinta de 150 balas AP de 9.3 mm Лента из 150-ти 9,3 мм бронебойных - 9.3 mm 150Rnd AP Belt + 9.3 mm 150cp Nastro AP 9.3 mm 150náb. AP Pás Cinto de munição 9.3 mm AP com 150 cartuchos 9,3 mm 150-lövedékes páncéltörő heveder - 9.3 mm 150発入り 徹甲弾ベルト - 150발들이 9.3mm 철갑탄 벨트 + 9.3mm 150Rnd 徹甲弾 ベルト + 150발 들이 9.3mm 철갑탄 벨트 9.3毫米 150發 穿甲彈 彈鏈 9.3 mm 150发 弹链(穿甲) 9.3 mm 150Rnd AP Belt @@ -1672,7 +1675,7 @@ 9.3 mm AP 9.3 mm AP 9,3 mm páncéltörő - 9.3 mm 徹甲弾 + 9.3 mm AP 9.3mm 철갑탄 9.3毫米 穿甲彈 9.3 mm 穿甲 @@ -1702,12 +1705,12 @@ Cargador de 16 balas de 9x19 mm Магазин из 16-ти 9х19 мм 9x19 mm 20-Patronen-Magazin - 9x19 mm 16Rnd Mag + 9x19 mm 16cp Car 9x19 mm 16náb. Zásobník Carregador de 16 cartuchos 9x19 mm 9x19 mm 16-lövedékes tár - 9x19 mm 16発入り 弾倉 - 17발들이 9x19mm 탄창 + 9x19 mm 16Rnd マガジン + 16발 들이 9x19mm 탄창 9x19毫米 16發 彈匣 9x19 mm 16发 弹匣 9x19 mm 16Rnd Mag @@ -1736,11 +1739,11 @@ Cargador de 16 balas de 9x19 mm Магазин из 16-ти 9х19 мм 9x19 mm 30-Patronen-Magazin - 9x19 mm 30Rnd Mag + 9x19 mm 30cp Car 9x19 mm 30náb. Zásobník Carregador de 16 cartuchos 9x19 mm 9x19 mm 16-lövedékes tár - 9x19 mm 30発入り 弾倉 + 9x19 mm 30Rnd マガジン 30발 들이 9x19mm 탄창 9x19毫米 30發 彈匣 9x19 mm 30发 弹匣 @@ -1753,11 +1756,11 @@ Cargador de 30 balas de 9x19 mm Магазин из 30-ти 9х19 мм 9x19 mm 30-Patronen-Magazin - 9x19 mm 30Rnd Mag + 9x19 mm 30cp Car 9x19 mm 30náb. Zásobník Carregador de 30 cartuchos 9x19 mm 9x19 mm 30-lövedékes tár - 9x19 mm 30発入り 弾倉 + 9x19 mm 30Rnd マガジン 30발 들이 9x19mm 탄창 9x19毫米 30發 彈匣 9x19 mm 30发 弹匣 @@ -1787,11 +1790,11 @@ Cargador de 30 balas de 9x19 mm Магазин из 30-ти 9х19 мм 9x19 mm 30-Patronen-Magazin - 9x19 mm 30Rnd Mag + 9x19 mm 30cp Car 9x19 mm 30náb. Zásobník Carregador de 30 cartuchos 9x19 mm 9x19 mm 30-lövedékes tár - 9x19 mm 30発入り 弾倉 + 9x19 mm 30Rnd マガジン 30발 들이 9x19mm 탄창 9x19毫米 30發 彈匣 9x19 mm 30发 弹匣 @@ -1802,47 +1805,47 @@ Magazynek 7,62x54 mm 10rd Smugacz Ch. 7,62x54 mm 10Cps Traçantes Cargador de 10 balas trazadoras de 7.62x54 mm - Магазин из 10-ти 7,62 мм ИК-трассирующих + Магазин из 10-ти 7,62 мм трассирующих 7,62x54 mm 10-Patronen-Magazin Leuchtspur - 7.62x54 mm 10Munizioni Traccianti IR-DIM Mag + 7.62x54 mm 10cp Traccianti 7.62x54 mm 10náb. Svítící Zásobník Carregador com 10 cartuchos 7.62x54 mm Traçante 7,62x54 mm 10-lövedékes nyomkövető tár - 7.62x54 mm 10発入り 曳光弾 弾倉 + 7.62mm 10Rnd マガジン (トレーサー) 10발 들이 7.62x54mm 예광탄 탄창 7.62x54毫米 10發 曳光彈 彈匣 7.62x54 mm 10发 弹匣(曳光) 7.62x54 mm 10Rnd Tracer Mag - 7.62 mm - 7,62 mm - 7,62 mm - 7.62 mm - 7,62 мм - 7,62 mm - 7.62 mm - 7.62 mm - 7.62 mm - 7,62 mm - 7.62 mm - 7.62mm - 7.62毫米 - 7.62 mm - 7.62 mm + Tracer + Smugacz + Traçantes + trazadoras + трассирующих + Leuchtspur + Tracciante + Svítící + Traçante + nyomkövető + トレーサー + 예광탄 + 曳光 + 曳光 + Tracer 7.62x54 mm 10Rnd Tracer Mag Magazynek 7,62x54 mm 10rd Smugacz Ch. 7,62x54 mm 10Cps Traçantes Cargador de 10 balas trazadoras de 7.62x54 mm - Магазин из 10-ти 7,62 мм ИК-трассирующих + Магазин из 10-ти 7,62 мм трассирующих 7,62x54 mm 10-Patronen-Magazin Leuchtspur - 7.62x54 mm 10Munizioni Traccianti IR-DIM Mag + 7.62x54 mm 10cp Traccianti 7.62x54 mm 10náb. Svítící Zásobník Carregador com 10 cartuchos 7.62x54 mm Traçante 7,62x54 mm 10-lövedékes nyomkövető tár - 7.62x54 mm 10発入り 曳光弾 弾倉 + 口径: 7.62x54 mm トレーサー<br />弾薬: 10<br />使用: ラヒム 10발 들이 7.62x54mm 예광탄 탄창 7.62x54毫米 10發 曳光彈 彈匣 7.62x54 mm 10发 弹匣(曳光) @@ -1855,11 +1858,11 @@ Cargador de 100 balas trazadoras IR-DIM de 6.5 mm Магазин из 100 6,5 мм ИК-трассирующих 6,5 mm 100-Patronen-Magazin IR-DIM Leuchtspur - 6.5 mm 100Munizioni Traccianti IR-DIM Mag + 6.5 mm 100cp Traccianti IR-DIM 6.5 mm 100náb. Svítící IR-DIM Zásobník Carregador com 100 cartuchos 6.5 mm IR-DIM Traçante 6,5 mm 100-lövedékes infravörös nyomkövető tár - 6.5 mm 100発入り IR-DIM曳光弾 弾倉 + 6.5mm 100Rnd IR-DIM トレーサー マガジン 100발 들이 6.5mm IR-DIM 예광탄 탄창 6.5毫米 100發 低視度紅外線曳光彈 彈匣 6.5 mm 100发 弹匣(红外曳光) @@ -1876,7 +1879,7 @@ 6.5 mm IR-DIM 6.5 mm IR-DIM 6,5 mm infravörös nyomkövető - 6.5 mm IR-DIM曳光弾 + 6.5 mm IR-DIM 6.5mm IR-DIM 예광탄 6.5毫米 低視紅外曳光彈 6.5 mm 红外曳光 @@ -1889,11 +1892,11 @@ Cargador de 100 balas trazadoras IR-DIM de 6.5 mm Магазин из 100 6,5 мм ИК-трассирующих 6,5 mm 100-Patronen-Magazin IR-DIM Leuchtspur<br />Patronen: 100<br />Eingesetzt von: MXLSW - 6.5 mm 100Rnd Tracer IR-DIM Mag<br />Munizioni: 100<br />In uso su: MX LSW + 6.5 mm 100cp Traccianti IR-DIM Car<br />Munizioni: 100<br />In uso su: MX LSW 6.5 mm 100náb. Svítící IR-DIM Zásobník<br />Nábojů: 100<br />Použití u: MX LSW Carregador 6.5 mm 100 Cartuchos Traçantes IR-DIM<br />Cartuchos: 100<br />Usado em: MX LSW 6.5 mm 100-lövedékes infravörös nyomkövető tár<br />Lövedékek: 100<br />Használható: MX LSW - 6.5 mm 100発入り IR-DIM曳光弾 弾倉<br />装填数: 100<br />次で使用: MX LSW + 6.5 mm 100Rnd IR-DIM トレーサー マガジン<br />装填数: 100<br />次で使用: MX LSW 6.5mm IR-DIM 예광탄<br/>장탄수: 100<br/>사용처: MX LSW 6.5毫米 100發 低視度紅外線曳光彈<br />發數: 100<br />使用於: MX LSW 口径:6.5 mm 100发 红外曳光<br />发数:100<br />使用于:MX LSW @@ -1906,11 +1909,11 @@ Cinta de 200 balas trazadoras IR-DIM de 6.5 mm Магазин из 200-т 6,5 мм ИК-трассирующих 6,5 mm 200-Patronen-Gurt IR-DIM Leuchtspur - 6.5 mm 200Rnd Belt Tracer (IR-DIM) + 6.5 mm 200cp Nastro Tracciante (IR-DIM) 6.5 mm 200náb. Svítící IR-DIM Pás Cinto de munição traçante 6.5 mm IR-DIM com 200 cartuchos 6,5 mm 200-lövedékes infravörös nyomkövető heveder - 6.5 mm 200発入り IR-DIM曳光弾ベルト + 6.5mm 200Rnd ベルト トレーサー(IR-DIM) 200발 들이 6.5mm IR-DIM 예광탄 탄창 6.5毫米 200發 低視度紅外線曳光彈 彈鏈 6.5 mm 200发 弹链(红外曳光) @@ -1927,7 +1930,7 @@ 6.5 mm IR-DIM 6.5 mm IR-DIM 6,5 mm infravörös nyomkövető - 6.5 mm IR-DIM曳光弾 + 6.5 mm IR-DIM 6.5mm IR-DIM 예광탄 6.5毫米 低視紅外曳光彈 6.5 mm 红外曳光 @@ -1940,11 +1943,11 @@ Cinta de 200 balas trazadoras IR-DIM de 6.5 mm Магазин из 200-т 6,5 мм ИК-трассирующих 6,5 mm 200-Patronen-Gurt IR-DIM Leuchtspur<br />Patronen: 200<br />Eingesetzt von: Stoner 99 LMG - 6.5 mm 200Rnd Belt Tracer (IR-DIM)<br />Munizioni: 200<br />In uso su: Stoner 99 LMG + 6.5 mm 200cp Nastro Tracciante (IR-DIM)<br />Munizioni: 200<br />In uso su: Stoner 99 LMG 6.5 mm 200náb. Svítící IR-DIM Pás<br />Nábojů: 200<br />Použití u: Stoner 99 LMG Cinto de munição traçante 6.5 mm IR-DIM com 200 cartuchos<br />Cartuchos: 200<br />Usado em: Stoner 99 LMG 6.5 mm 200-lövedékes infravörös nyomkövető heveder<br />Lövedékek: 200<br />Használható: Stoner 99 LMG - 6.5 mm 200発入り IR-DIM曳光弾ベルト<br />装填数: 200<br />次で使用: Stoner 99 LMG + 6.5 mm 200Rnd ベルト トレーサー (IR-DIM)<br />装填数: 200<br />次で使用: Stoner 99 LMG 200발 들이 6.5mm IR-DIM 예광탄 벨트<br/>장탄수: 200<br/>사용처: 스토너 99 LMG 6.5毫米 200發 低視度紅外線曳光彈<br />發數: 200<br />使用於: Stoner 99 重機槍 口径:6.5 mm 200发 红外曳光<br />发数:200<br />使用于:Stoner 99 LMG @@ -1957,11 +1960,11 @@ Cargador de 30 balas de 5.56 mm (Mk262) Магазин из 30-ти 5.56 мм Mk262 5,56 mm 30-Patronen-Magazin (Mk262) - 5.56 mm 30Rnd Mag (Mk262) + 5.56 mm 30cp Car (Mk262) 5.56 mm 30náb. Zásobník (Mk262) Carregador 5.56 mm com 30 cartuchos (Mk262) 5,56 mm 30-lövedékes tár (Mk262) - 5.56 mm 30発入り 弾倉 (Mk262) + 5.56mm 30Rnd マガジン (Mk262) 30발 들이 5.56mm 탄창 (Mk.262) 5.56毫米 30發 彈匣 (Mk262 狙擊專用彈) 5.56 mm 30发 弹匣(Mk262) @@ -2008,12 +2011,12 @@ Cargador de 30 balas de 5.56 mm (Mk318) Магазин из 30-ти 5.56 мм (Mk318) 5,56 mm 30-Patronen-Magazin (Mk318) - 5.56 mm 30Rnd Mag (Mk318) + 5.56 mm 30cp Car (Mk318) 5.56 mm 30Rnd Zásobník (Mk318) Carregador 5.56 mm com 30 cartuchos (Mk318) 5,56 mm 30-lövedékes tár (Mk318) - 5.56 mm 30発入り 弾倉 (Mk318) - 30발들이 5.56mm 탄창 (Mk.318) + 5.56mm 30Rnd マガジン (Mk318) + 30발 들이 5.56mm 탄창 (Mk.318) 5.56毫米 30發 彈匣 (Mk318 特戰專用彈) 5.56 mm 30发 弹匣(Mk318) 5.56 mm 30Rnd Mag (Mk318) @@ -2059,11 +2062,11 @@ Cargador de 30 balas de 5.56 mm (M995 AP) Магазин из 30-ти 5.56 мм (M995 бронебойные) 5,56 mm 30-Patronen-Magazin (M995AP) - 5.56 mm 30Rnd Mag (M995 AP) + 5.56 mm 30cp Car (M995 AP) 5.56 mm 30náb. Zásobník (M995 AP) Carregador 5.56 mm com 30 cartuchos (M995 AP) 5,56 mm 30-lövedékes tár (M995 páncéltörő) - 5.56 mm 30発入り 弾倉 (M995 徹甲弾) + 5.56mm 30Rnd マガジン (M995 徹甲弾) 30발 들이 5.56mm 탄창 (M995 철갑탄) 5.56毫米 30發 彈匣 (M995 穿甲彈) 5.56 mm 30发 弹匣(M995 穿甲) @@ -2080,7 +2083,7 @@ 5.56 mm AP 5.56 mm M995 AP 5,56 mm páncéltörő - 5.56 mm 徹甲弾 + 5.56 mm AP 5.56mm 철갑탄 5.56毫米 M995 穿甲彈 5.56 mm 穿甲 @@ -2110,11 +2113,11 @@ Cargador de 10 balas de 7.62 mm (M118LR) Магазин из 10-ти 7,62 мм (M118LR) 7,62 mm 10-Patronen-Magazin (M118LR) - 7.62 mm 10Rnd Mag (M118LR) + 7.62 mm 10cp Car (M118LR) 7.62 mm 10náb. Zásobník (M118LR) Carregador 7.62 mm com 10 cartuchos (M118LR) 7,62 mm 10-lövedékes tár (M118LR) - 7.62 mm 10発入り 弾倉 (M118LR) + 7.62mm 10Rnd マガジン (M118LR) 10발 들이 7.62mm 탄창 (M118LR) 7.62毫米 10發 彈匣 (M118LR 狙擊專用彈) 7.62 mm 10发 弹匣(M118LR) @@ -2161,11 +2164,11 @@ Cargador de 20 balas de 7.62 mm (M118LR) Магазин из 20-ти 7,62 мм (M118LR) 7,62 mm 20-Patronen-Magazin (M118LR) - 7.62 mm 20Rnd Mag (M118LR) + 7.62 mm 20cp Car (M118LR) 7.62 mm 20náb. Zásobník (M118LR) Carregador 7.62 mm com 20 cartuchos (M118LR) 7,62 mm 20-lövedékes tár (M118LR) - 7.62 mm 20発入り 弾倉 (M118LR) + 7.62mm 20Rnd マガジン (M118LR) 20발 들이 7.62mm 탄창 (M118LR) 7.62毫米 20發 彈匣 (M118LR 狙擊專用彈) 7.62 mm 20发 弹匣(M118LR) @@ -2212,11 +2215,11 @@ Cargador de 10 balas de 7.62 mm (Mk316 Mod 0) Магазин из 10-ти 7,62 мм (Mk316 Mod 0) 7,62 mm 10-Patronen-Magazin (Mk316 Mod 0) - 7.62 mm 10Rnd Mag (Mk316 Mod 0) + 7.62 mm 10cp Car (Mk316 Mod 0) 7.62 mm 10náb. Zásobník (Mk316 Mod 0) Carregador 7.62 mm com 10 cartuchos (Mk316 Mod 0) 7,62 mm 10-lövedékes tár (Mk316 Mod 0) - 7.62 mm 10発入り 弾倉 (Mk316 Mod 0) + 7.62mm 10Rnd マガジン (Mk316 Mod 0) 10발 들이 7.62mm 탄창 (Mk.316 Mod 0) 7.62毫米 10發 彈匣 (Mk316 Mod 0 狙擊專用彈) 7.62 mm 10发 弹匣(Mk316 Mod 0) @@ -2263,11 +2266,11 @@ Cargador de 20 balas de 7.62 mm (Mk316 Mod 0) Магазин из 20-ти 7,62 мм (Mk316 Mod 0) 7,62 mm 20-Patronen-Magazin (Mk316 Mod 0) - 7.62 mm 20Rnd Mag (Mk316 Mod 0) + 7.62 mm 20cp Car (Mk316 Mod 0) 7.62 mm 20náb. Zásobník (Mk316 Mod 0) Carregador 7.62 mm com 20 cartuchos (Mk316 Mod 0) 7,62 mm 20-lövedékes tár (Mk316 Mod 0) - 7.62 mm 20発入り 弾倉 (Mk316 Mod 0) + 7.62mm 20Rnd マガジン (Mk316 Mod 0) 20발 들이 7.62mm 탄창 (Mk.316 Mod 0) 7.62毫米 20發 彈匣 (Mk316 Mod 0 狙擊專用彈) 7.62 mm 20发 弹匣(Mk316 Mod 0) @@ -2314,12 +2317,12 @@ Cargador de 10 balas de 7.62 mm (Mk319 Mod 0) Магазин из 10-ти 7,62 мм (Mk319 Mod 0) 7,62 mm 10-Patronen-Magazin (Mk319 Mod 0) - 7.62 mm 10Rnd Mag (Mk319 Mod 0) + 7.62 mm 10cp Car (Mk319 Mod 0) 7.62 mm 10náb. Zásobník (Mk319 Mod 0) Carregador 7.62 mm com 10 cartuchos (Mk319 Mod 0) 7,62 mm 10-lövedékes tár (Mk319 Mod 0) - 7.62 mm 10発入り 弾倉 (Mk319 Mod 0) - 10발들이 7.62mm 탄창 (Mk.319 Mod 0) + 7.62mm 10Rnd マガジン (Mk319 Mod 0) + 10발 들이 7.62mm 탄창 (Mk.319 Mod 0) 7.62毫米 10發 彈匣 (Mk319 Mod 0 特戰專用彈) 7.62 mm 10发 弹匣(Mk319 Mod 0) 7.62 mm 10Rnd Mag (Mk319 Mod 0) @@ -2365,11 +2368,11 @@ Cargador de 20 balas de 7.62 mm (Mk319 Mod 0) Магазин из 20-ти 7,62 мм (Mk319 Mod 0) 7,62 mm 20-Patronen-Magazin (Mk319 Mod 0) - 7.62 mm 20Rnd Mag (Mk319 Mod 0) + 7.62 mm 20cp Car (Mk319 Mod 0) 7.62 mm 20náb. Zásobník (Mk319 Mod 0) Carregador 7.62 mm com 20 cartuchos (Mk319 Mod 0) 7,62 mm 20-lövedékes tár (Mk319 Mod 0) - 7.62 mm 20発入り 弾倉 (Mk319 Mod 0) + 7.62mm 20Rnd マガジン (Mk319 Mod 0) 20들이 7.62mm 탄창 (Mk.319 Mod 0) 7.62毫米 20發 彈匣 (Mk319 Mod 0 特戰專用彈) 7.62 mm 20发 弹匣(Mk319 Mod 0) @@ -2416,11 +2419,11 @@ Cargador de 10 balas de 7.62 mm (M993 AP) Магазин из 10-ти 7,62 мм (M993 бронебойные) 7,62 mm 10-Patronen-Magazin (M993 AP) - 7.62 mm 10Rnd Mag (M993 AP) + 7.62 mm 10cp Car (M993 AP) 7.62 10náb. Zásobník (M993 AP) Carregador 7.62 mm com 10 cartuchos (M993 AP) 7,62 mm 10-lövedékes tár (M993 páncéltörő) - 7.62 mm 10発入り 弾倉 (M993 徹甲弾) + 7.62mm 10Rnd マガジン (M993 徹甲弾) 10발 들이 7.62mm 탄창 (M993 철갑탄) 7.62毫米 10發 彈匣 (M993 穿甲專用彈) 7.62 mm 10发 弹匣(M993 穿甲) @@ -2437,7 +2440,7 @@ 7.62 mm AP 7.62 mm AP 7,62 mm páncéltörő - 7.62 mm 徹甲弾 + 7.62 mm AP 7.62mm 철갑탄 7.62毫米 M993 穿甲專用彈 7.62 mm M993 @@ -2467,11 +2470,11 @@ Cargador de 20 balas de 7.62 mm (M993 AP) Магазин из 20-ти 7,62 мм (M993 бронебойные) 7,62 mm 20-Patronen-Magazin (M993 AP) - 7.62 mm 20Rnd Mag (M993 AP) + 7.62 mm 20cp Car (M993 AP) 7.62 mm 20náb. Zásobník (M993 AP) Carregador 7.62 mm com 20 cartuchos (M993 AP) 7,62 mm 20-lövedékes tár (M993 páncéltörő) - 7.62 mm 20発入り 弾倉 (M993 徹甲弾) + 7.62mm 20Rnd マガジン (M993 徹甲弾) 20발 들이 7.62mm 탄창 (M993 철갑탄) 7.62毫米 20發 彈匣 (M993 穿甲專用彈) 7.62 mm 20发 弹匣(M993 穿甲) @@ -2488,7 +2491,7 @@ 7.62 mm AP 7.62 mm AP 7,62 mm páncéltörő - 7.62 mm 徹甲弾 + 7.62 mm AP 7.62mm 철갑탄 7.62毫米 M993 穿甲專用彈 7.62 mm M993 @@ -2518,11 +2521,11 @@ Cargador de 20 balas de .300 WM (Mk248 Mod 0) Магазин из 20-ти .300 WM (Mk248 Mod 0) .300 WM 20-Patronen-Magazin (Mk248 Mod 0) - .300 WM 20Rnd Mag (Mk248 Mod 0) + .300 WM 20cp Car (Mk248 Mod 0) .300 WM 20náb. Zásobník (Mk248 Mod 0) Carregador .300 WM com 20 cartuchos (Mk248 Mod 0) .300 WM 20-lövedékes tár (Mk248 Mod 0) - .300 WM 20発入り 弾倉 (Mk248 Mod 0) + .300 WM 20Rnd マガジン (Mk248 Mod 0) 20발 들이 .300구경 윈체스터 매그넘 탄창 (Mk.248 Mod 0) .300 萬能(WM) 20發 彈匣 (Mk248 Mod 0 狙擊專用彈) .300 WM 20发 弹匣(Mk248 Mod 0) @@ -2569,11 +2572,11 @@ Cargador de 20 balas de .300 WM (Mk248 Mod 1) Магазин из 20-ти .300 WM (Mk248 Mod 1) .300 WM 20-Patronen-Magazin (Mk248 Mod 1) - .300 WM 20Rnd Mag (Mk248 Mod 1) + .300 WM 20cp Car (Mk248 Mod 1) .300 WM 20náb. Zásobník (Mk248 Mod 1) Carregador .300 WM com 20 cartuchos (Mk248 Mod 1) .300 WM 20-lövedékes tár (Mk248 Mod 1) - .300 WM 20発入り 弾倉 (Mk248 Mod 1) + .300 WM 20Rnd マガジン (Mk248 Mod 1) 20발 들이 .300구경 윈체스터 매그넘 탄창 (Mk.248 Mod 1) .300 西米 20發 彈匣 (Mk248 Mod 1 狙擊專用彈) .300 WM 20发 弹匣(Mk248 Mod 1) @@ -2620,11 +2623,11 @@ Cargador de 20 balas de .300 WM (Berger Hybrid OTM) Магазин из 20-ти .300 WM (Berger Hybrid OTM) .300 WM 20-Patronen-Magazin (Berger Hybrid OTM) - .300 WM 20Rnd Mag (Berger Hybrid OTM) + .300 WM 20cp Car (Berger Hybrid OTM) .300 WM 20náb. Zásobník (Berger Hybrid OTM) Carregador .300 WM com 20 cartuchos (Berger Hybrid OTM) .300 WM 20-lövedékes tár (Berger Hybrid OTM) - .300 WM 20発入り 弾倉 (Berger Hybrid OTM) + .300 WM 20Rnd マガジン (Berger Hybrid OTM) 20발 들이 .300구경 윈체스터 매그넘 탄창 (Berger Hybrid OTM) .300 西米 20發 彈匣 (Berger Hybrid 空尖比賽專用彈) .300 WM 20发 弹匣(Berger Hybrid 空尖) @@ -2671,11 +2674,11 @@ Cargador de 10 balas de .300 WM (Mk248 Mod 0) Магазин из 10-ти .300 WM (Mk248 Mod 0) .300 WM 10-Patronen-Magazin (Mk248 Mod 0) - .300 WM 10Rnd Mag (Mk248 Mod 0) + .300 WM 10cp Car (Mk248 Mod 0) .300 WM 10náb. Zásobník (Mk248 Mod 0) Carregador .300 WM com 10 cartuchos (Mk248 Mod 0) .300 WM 10-lövedékes tár (Mk248 Mod 0) - .300 WM 10発入り 弾倉 (Mk248 Mod 0) + .300 WM 10Rnd マガジン (Mk248 Mod 0) 10발 들이 .300구경 윈체스터 매그넘 탄창 (Mk.248 Mod 0) .300 萬能(WM) 10發 彈匣 (Mk248 Mod 0 狙擊專用彈) .300 WM 10发 弹匣(Mk248 Mod 0) @@ -2722,11 +2725,11 @@ Cargador de 10 balas de .300 WM (Mk248 Mod 1) Магазин из 10-ти .300 WM (Mk248 Mod 1) .300 WM 10-Patronen-Magazin (Mk248 Mod 1) - .300 WM 10Rnd Mag (Mk248 Mod 1) + .300 WM 10cp Car (Mk248 Mod 1) .300 WM 10náb. Zásobník (Mk248 Mod 1) Carregador .300 WM com 10 cartuchos (Mk248 Mod 1) .300 WM 10-lövedékes tár (Mk248 Mod 1) - .300 WM 10発入り 弾倉 (Mk248 Mod 1) + .300 WM 10Rnd マガジン (Mk248 Mod 1) 10발 들이 .300구경 윈체스터 매그넘 탄창 (Mk.248 Mod 1) .300 西米 10發 彈匣 (Mk248 Mod 1 狙擊專用彈) .300 WM 10发 弹匣(Mk248 Mod 1) @@ -2773,11 +2776,11 @@ Cargador de 10 balas de .300 WM (Berger Hybrid OTM) Магазин из 10-ти .300 WM (Berger Hybrid OTM) .300 WM 10-Patronen-Magazin (Berger Hybrid OTM) - .300 WM 10Rnd Mag (Berger Hybrid OTM) + .300 WM 10cp Car (Berger Hybrid OTM) .300 WM 10náb. Zásobník (Berger Hybrid OTM) Carregador .300 WM com 10 cartuchos (Berger Hybrid OTM) .300 WM 10-lövedékes tár (Berger Hybrid OTM) - .300 WM 10発入り 弾倉 (Berger Hybrid OTM) + .300 WM 10Rnd マガジン (Berger Hybrid OTM) 10발 들이 .300구경 윈체스터 매그넘 탄창 (Berger Hybrid OTM) .300 西米 10發 彈匣 (Berger Hybrid 空尖比賽專用彈) .300 WM 10发 弹匣(Berger Hybrid 空尖) @@ -2819,47 +2822,55 @@ 6.5x47 mm 30Rnd Sand Mag (HPBT Scenar) - 6.5x47 mm 30発入り サンド 弾倉 (HPBT Scenar) + 6.5x47mm 30Rnd(砂色)マガジン (HPBT Scenar) Ch. 6,5x47 mm 30Cps Sable (HPBT Scenar) 6.5x47 mm 30-Patronen-Magazin Sandfarben (HPBT Scenar) + 6.5x47 mm 30cp Sabbia (HPBT Scenar) Magazynek 6.5x47 mm 30rd Piaskowy (HPBT Scenar) 6.5x47 mm 30发 沙色弹匣(HPBT Scenar) 6.5x47mm 30발 사막 탄창 (HPBT Scenar) Магазин из 30-ти 6.5x47 мм Песочный (HPBT Scenar) Cargador de 30 balas de 6.5x47mm Arena (HPBT Scenar) + Carregador 6.5x47 mm com 30 cartuchos Areia (HPBT Scenar) 6.5x47 mm 30Rnd Promet Mag (HPBT Scenar) - 6.5x47 mm 30発入り プロメット 弾倉 (HPBT Scenar) + 6.5x47 mm 30Rnd Promet マガジン (HPBT Scenar) Ch. 6,5x47 mm 30Cps Promet (HPBT Scenar) 6.5x47 mm 30-Patronen-Magazin für Promet (HPBT Scenar) + 6.5x47 mm 30cp Car Promet (HPBT Scenar) Magazynek 6.5x47 mm 30rd Promet (HPBT Scenar) 6.5x47 mm 30发 Promet 弹匣(HPBT Scenar) 6.5x47mm 30발 그롯 탄창 (HPBT Scenar) Магазин из 30-ти 6.5x47 мм Promet (HPBT Scenar) Cargador de 30 balas de 6.5x47mm Promet (HPBT Scenar) + Carregador 6.5x47 mm com 30 cartuchos Promet (HPBT Scenar) 6.5x47 mm 30Rnd Black Mag (HPBT Scenar) - 6.5x47 mm 30発入り ブラック 弾倉 (HPBT Scenar) + 6.5x47mm 30Rnd(黒)マガジン (HPBT Scenar) Ch. 6,5x47 mm 30Cps Noir (HPBT Scenar) 6.5x47 mm 30-Patronen-Magazin Schwarz (HPBT Scenar) + 6.5x47 mm 30cp Car Nero (HPBT Scenar) Magazynek 6.5x47 mm 30rd Czarny (HPBT Scenar) 6.5x47 mm 30发 黑色弹匣(HPBT Scenar) 6.5x47mm 30발 검정 탄창 (HPBT Scenar) Магазин из 30-ти 6.5x47 мм Чёрный (HPBT Scenar) Cargador de 30 balas de 6.5x47mm Negro (HPBT Scenar) + Carregador 6.5x47 mm com 30 cartuchos Preto (HPBT Scenar) 6.5x47 mm 30Rnd Khaki Mag (HPBT Scenar) - 6.5x47 mm 30発入り カーキ 弾倉 (HPBT Scenar) + 6.5x47mm 30Rnd(カーキ)マガジン (HPBT Scenar) Ch. 6,5x47 mm 30Cps Kaki (HPBT Scenar) 6.5x47 mm 30-Patronen-Magazin Khaki (HPBT Scenar) + 6.5x47 mm 30cp Car Cachi (HPBT Scenar) Magazynek 6.5x47 mm 30rd Khaki (HPBT Scenar) 6.5x47 mm 30发 卡其色弹匣(HPBT Scenar) 6.5x47mm 30발 카키 탄창 (HPBT Scenar) Магазин из 30-ти 6.5x47 мм Хаки (HPBT Scenar) Cargador de 30 balas de 6.5x47mm Caqui (HPBT Scenar) + Carregador 6.5x47 mm com 30 cartuchos Caqui (HPBT Scenar) 6.5 mm Lapua @@ -2914,47 +2925,55 @@ 6.5 mm Creedmor 30Rnd Sand Mag - 6.5 mm クリードモア 30発入り サンド 弾倉 + 6.5mm 30Rnd クリードモア(砂色)マガジン Ch. 6,5 mm Creedmor 30Cps Sable 6.5 mm Creedmor 30-Patronen-Magazin Sandfarben + 6.5 mm Creedmor 30cp Car Sabbia Magazynek 6.5 mm Creedmor 30Rnd Piaskowy 6.5 mm 30发 沙色弹匣(Creedmor) 6.5mm 크리드무어 30발 사막 탄창 Магазин из 30-ти 6.5 мм Creedmor Песочный Cargador de 30 balas de 6.5mm Creedmor Arena + Carregador 6.5 mm com 30 cartuchos Creedmor Areia 6.5 mm Creedmor 30Rnd Promet Mag - 6.5 mm クリードモア 30発入り プロメット 弾倉 + 6.5 mm 30Rnd Promet クリードモア・マガジン Ch. 6,5 mm Creedmor 30Cps Promet 6.5 mm Creedmor 30-Patronen-Magazin für Promet + 6.5 mm Creedmor 30cp Car Promet Magazynek 6.5 mm Creedmor 30Rnd Promet 6.5 mm 30发 Promet 弹匣(Creedmor) 6.5mm 크리드무어 30발 프로멧 탄창 Магазин из 30-ти 6.5 мм Creedmor Promet Cargador de 30 balas de 6.5mm Creedmor Promet + Carregador 6.5 mm com 30 cartuchos Creedmor Promet 6.5 mm Creedmor 30Rnd Black Mag - 6.5 mm クリードモア 30発入り ブラック 弾倉 + 6.5mm 30Rnd クリードモア(黒)マガジン Ch. 6,5 mm Creedmor 30Cps Noir 6.5 mm Creedmor 30-Patronen-Magazin Schwarz + 6.5 mm Creedmor 30cp Car Nero Magazynek 6.5 mm Creedmor 30Rnd Czarny 6.5 mm 30发 黑色弹匣(Creedmor) 6.5mm 크리드무어 30발 검정 탄창 Магазин из 30-ти 6.5 мм Creedmor Чёрный Cargador de 30 balas de 6.5mm Creedmor Negro + Carregador 6.5 mm com 30 cartuchos Creedmor Preto 6.5 mm Creedmor 30Rnd Khaki Mag - 6.5 mm クリードモア 30発入り カーキ 弾倉 + 6.5mm 30Rnd クリードモア(カーキ)マガジン Ch. 6,5 mm Creedmor 30Cps Kaki 6.5 mm Creedmor 30-Patronen-Magazin Khaki + 6.5 mm Creedmor 30cp Car Cachi Magazynek 6.5 mm Creedmor 30Rnd Khaki 6.5 mm 30发 卡其色弹匣(Creedmor) 6.5mm 크리드무어 30발 카키 탄창 Магазин из 30-ти 6.5 мм Creedmor Хаки Cargador de 30 balas de 6.5mm Creedmor Caqui + Carregador 6.5 mm com 30 cartuchos Creedmor Caqui 6.5 mm CM @@ -2984,7 +3003,7 @@ Ráže: 6.5x47 mm Creedmor<br />Nábojů: 30<br />Použití u: MXM Calibre: 6.5x47 mm Creedmor<br/>Cartuchos: 30<br/>Usado em: MXM Kaliber: 6,5x47 mm Creedmor<br />Lövedékek: 30<br />Használható: MXM - 口径: 6.5x47 mm Creedmor<br />装填数: 30<br />次で使用: MXM + 口径: 6.5x47 mm クリードモア<br />装填数: 30<br />次で使用: MXM 구경: 6.5x47mm 크리드무어<br/>장탄수: 30<br/>사용처: MXM 口徑: 6.5x47毫米 克里德莫爾 狙擊專用彈<br />發數: 30<br />使用於: MXM 口径:6.5x47 mm Creedmor 狙击专用弹<br />发数:30<br />使用于:MXM @@ -3001,7 +3020,7 @@ Ráže: 6.5x47 mm Creedmor<br />Nábojů: 30<br />Použití u: Promet MR Calibre: 6.5x47 mm Creedmor<br/>Cartuchos: 30<br/>Usado em: Promet MR Kaliber: 6,5x47 mm Creedmor<br />Lövedékek: 30<br />Használható: Promet MR - 口径: 6.5x47 mm Creedmor<br />装填数: 30<br />次で使用: Promet MR + 口径: 6.5x47 mm クリードモア<br />装填数: 30<br />次で使用: Promet MR 구경: 6.5x47mm 크리드무어<br/>장탄수: 30<br/>사용처: MSBS 그롯/GL/MR/SG 口徑: 6.5x47毫米 克里德莫爾 狙擊專用彈<br />發數: 30<br />使用於: Promet MR 口径:6.5x47 mm Creedmor 狙击专用弹<br />发数:30<br />使用于:Promet MR @@ -3014,11 +3033,11 @@ Magazynek .338 LM 10rd (300gr Lapua Scenar) Магазин из 10-ти .338 LM (300 гран Lapua Scenar) .338 LM 10-Patronen-Magazin (300gr Lapua Scenar) - .338 LM 10Munizioni Mag (300gr Lapua Scenar) + .338 LM 10cp Car (300gr Lapua Scenar) .338 LM 10náb. Zásobník (300gr Lapua Scenar) Carregador .338 LM (300gr Lapua Scenar) com 10 cartuchos .338 LM 10-lövedékes tár (300gr Lapua Scenar) - .338 LM 10発入り 弾倉 (300gr Lapua Scenar) + .338 LM 10Rnd マガジン (300gr Lapua Scenar) 10발 들이 .338구경 라푸아 매그넘 탄창 (300그레인 Scenar) .338 10發 彈匣 (300公克 Lapua Scenar) .338 LM 10发 弹匣(300gr Lapua Scenar) @@ -3065,11 +3084,11 @@ Magazynek .338 LM 10rd (API526) Магазин из 10-ти .338 LM (API526) .338 LM 10-Patronen-Magazin (API526) - .338 LM 10Rnd Mag (API526) + .338 LM 10cp Car (API526) .338 LM 10náb. Zásobník (API526) Carregador .338 LM (API526) com 10 cartuchos .338 LM 10-lövedékes tár (API526) - .338 LM 10発入り 弾倉 (API526) + .338 LM 10Rnd マガジン (API526) 10발 들이 .338구경 라푸아 매그넘 탄창 (API526) .338 10發 彈匣 (API526 穿甲燃燒彈) .338 LM 10发 弹匣(API526 穿燃) @@ -3086,7 +3105,7 @@ .338 AP .338 AP .338 páncéltörő - .338 徹甲弾 + .338 AP .338구경 라푸아 매그넘 철갑탄 .338 API526 穿甲燃燒彈 .338 穿燃 @@ -3116,11 +3135,11 @@ Magazynek .408 7rd (305gr) Магазин из 7-ти .408 (305gr) .408 7-Patronen-Magazin (305gr) - .408 7Rnd Mag (305gr) + .408 7cp Car (305gr) .408 7náb. Zásobník (305gr) Carregador .408 (305gr) com 7 cartuchos .408 7-lövedékes tár (305gr) - .408 7発入り 弾倉 (305gr) + .408 7Rnd マガジン (305gr) 7발 들이 .408구경 샤이택 탄창 (305그레인) .408 7發 彈匣 (305公克) .408 7发 弹匣(305gr) @@ -3167,11 +3186,11 @@ Magazynek 12,7x99 mm 5rd Магазин из 5-ти 12,7x99 мм 12,7x99 mm 5-Patronen-Magazin - 12.7x99 mm 5Rnd Mag + 12.7x99 mm 5cp Car 12.7x99 mm 5náb. Zásobník Carregador 12.7x99 mm com 5 cartuchos 12,7x99 mm 5-lövedékes tár - 12.7x99 mm 5発入り 弾倉 + 12.7x99mm 5Rnd マガジン 5발 들이 12.7x99mm 탄창 12.7x99毫米 5發 彈匣 12.7x99 mm 5发 弹匣 @@ -3201,11 +3220,11 @@ Magazynek 12,7x99 mm 10rd Магазин из 10-ти 12,7x99 мм 12,7x99 mm 10-Patronen-Magazin - 12.7x99 mm 10Rnd Mag + 12.7x99 mm 10cp Car 12.7x99 mm 10náb. Zásobník Carregador 12.7x99 mm com 10 cartuchos 12,7x99 mm 10-lövedékes tár - 12.7x99 mm 10発入り 弾倉 + 12.7x99mm 10Rnd マガジン 10발 들이 12.7x99mm 탄창 12.7x99毫米 10發 彈匣 12.7x99 mm 10发 弹匣 @@ -3250,13 +3269,13 @@ Ch. 12,7x99 mm API 5Cps Cargador de 5 balas de 12.7x99 mm API Magazynek 12,7x99 mm API 5rd - 12.7x99 mm API 5Rnd Mag + 12.7x99 mm API 5cp Car Магазин из 5-ти 12,7x99 мм (бронебойно-зажигательные) 12,7x99 mm 5-Patronen-Magazin (API) 12.7x99 mm API 5náb. Zásobník Carregador 12.7x99 mm API com 5 cartuchos 12,7x99 mm 5-lövedékes tár (páncéltörő-gyújtó) - 12.7x99 mm 5発入り焼夷徹甲弾 弾倉 + 12.7x99mm 5Rnd 焼夷徹甲弾 マガジン 5발 들이 12.7x99mm 철갑소이탄 탄창 12.7x99毫米 穿甲燃燒彈 5發 彈匣 12.7x99 mm 穿燃 5发 弹匣 @@ -3284,13 +3303,13 @@ Ch. 12,7x99 mm API 10Cps Cargador de 10 balas de 12.7x99 mm API Magazynek 12,7x99 mm API 10rd - 12.7x99 mm API 10Rnd Mag + 12.7x99 mm API 10cp Car Магазин из 10-ти 12,7x99 мм (бронебойно-зажигательные) 12,7x99 mm 10-Patronen-Magazin (API) 12.7x99 mm API 10náb. Zásobník Carregador 12.7x99 mm API com 10 cartuchos 12,7x99 mm 10-lövedékes tár (páncéltörő-gyújtó) - 12.7x99 mm 10発入り焼夷徹甲弾 弾倉 + 12.7x99mm 10Rnd 焼夷徹甲弾 マガジン 10발 들이 12.7x99mm 철갑소이탄 탄창 12.7x99毫米 穿甲燃燒彈 10發 彈匣 12.7x99 mm 穿燃 10发 弹匣 @@ -3320,12 +3339,12 @@ Magazynek 12,7x99 mm 5rd (AMAX) Магазин из 5-ти 12,7x99 мм (A-MAX) 12,7x99 mm 5-Patronen-Magazin (AMAX) - 12.7x99 mm 5Rnd Mag (AMAX) + 12.7x99 mm 5cp Car (AMAX) 12.7x99 mm 5náb. Zásobník (AMAX) Carregador 12.7x99 mm (AMAX) com 5 cartuchos 12,7x99 mm 5-lövedékes tár (AMAX) - 12.7x99 mm 5発入り 弾倉 (AMAX) - 5발들이 12.7x99mm 탄창 (AMAX) + 12.7x99mm 5Rnd マガジン (AMAX) + 5발 들이 12.7x99mm 탄창 (AMAX) 12.7x99毫米 5發 彈匣 (AMAX 比賽專用彈) 12.7x99 mm 5发 弹匣(AMAX) 12.7x99 mm 5Rnd Şarjör (AMAX) @@ -3354,12 +3373,12 @@ Magazynek 12,7x99 mm 10rd (AMAX) Магазин из 10-ти 12,7x99 мм (A-MAX) 12,7x99 mm 10-Patronen-Magazin (AMAX) - 12.7x99 mm 10Rnd Mag (AMAX) + 12.7x99 mm 10cp Car (AMAX) 12.7x99 mm 10náb. Zásobník (AMAX) Carregador 12.7x99 mm (AMAX) com 10 cartuchos 12,7x99 mm 10-lövedékes tár (AMAX) - 12.7x99 mm 10発入り 弾倉 (AMAX) - 10발들이 12.7x99mm 탄창 (AMAX) + 12.7x99mm 10Rnd マガジン (AMAX) + 10발 들이 12.7x99mm 탄창 (AMAX) 12.7x99毫米 10發 彈匣 (AMAX 比賽專用彈) 12.7x99 mm 10发 弹匣(AMAX) 12.7x99 mm 10Rnd Şarjör (AMAX) @@ -3382,21 +3401,21 @@ Kalibre: 12.7x99 mm (AMAX)<br />Mermi: 10 - 12.7 mm - 12,7 mm - 12.7 mm - 12,7 mm - 12,7 мм - 12,7 mm - 12.7 mm - 12.7 mm - 12.7 mm - 12,7 mm - 12.7 mm - 12.7mm + 12.7 mm AMAX + 12,7 mm AMAX + 12.7 mm AMAX + 12,7 mm AMAX + 12,7 мм AMAX + 12,7 mm AMAX + 12.7 mm AMAX + 12.7 mm AMAX + 12.7 mm AMAX + 12,7 mm AMAX + 12.7 mm AMAX + 12.7mm AMAX 12.7毫米 AMAX 比賽專用彈 - 12.7 mm - 12.7 mm + 12.7 mm AMAX + 12.7 mm AMAX 12.7 mm API @@ -3409,7 +3428,7 @@ 12.7 mm API 12.7 mm API 12,7 mm páncéltörő-gyújtó - 12.7 mm 焼夷徹甲弾 + 12.7 mm API 12.7mm 철갑소이탄 12.7毫米 穿甲燃燒彈 12.7 mm 穿燃 @@ -3425,7 +3444,7 @@ [ACE] Caisse de munitions [ACE] Lőszeres láda [ACE] Ящик с боеприпасами - [ACE] Cassa munizioni + [ACE] Cassa Munizioni [ACE] 弾薬物資箱 [ACE] 탄약 보급상자 [ACE] 彈藥補給箱 @@ -3435,7 +3454,7 @@ Barrel twist Dralllänge - 銃身の転度 + 銃身転度 膛线缠距 膛線扭度 Rigatura della canna @@ -3470,7 +3489,7 @@ 弾道係数 弹道系数 彈道係數 - Coefficente balistico + Coefficiente balistico Współczynnik balistyczny Баллистический коэффициент Coeficiente balístico @@ -3502,7 +3521,7 @@ 銃口初速 枪口初速 槍口初速 - Velocità iniziale + Velocità alla volata Prędkość wylotowa Начальная скорость Velocidade de Saída @@ -3516,56 +3535,84 @@ AIの使用 Wykorzystanie przez AI KI Verwendet + Utilizzo IA 인공지능 사용 Utilisation de l'IA + Utilização por IA + Использование ИИ + Uso de la IA Illum 照明弾 Flary Leuchtmittel + Illuminante 조명탄 Fusées éclairantes + Sinalizadoras + Осветители + Iluminación Smoke 発煙弾 Granaty dymne Rauch + Fumogeno 연막탄 Fumigènes + Fumígenas + Дым + Humo Inf 歩兵 Piechota Infanterie + Fanti 보병 Infanterie + Infantaria + Пехота + Infantería Veh 車両 Pojazdy Fahrzeug + Veicoli 차량 Véhicule + Veículo + Техника + Vehículo Armor 機甲 Pojazdy opancerzone Panzerung + Blidati 기갑 Blindage + Blindagem + Бронетехника + Blindados Air 航空 Lotnictwo Luft + Velivoli 항공 Aviation + Aeronaves + Авиация + Aeronaves diff --git a/addons/captives/CfgWeapons.hpp b/addons/captives/CfgWeapons.hpp index 23c7d0c2ce..ce3c989ee5 100644 --- a/addons/captives/CfgWeapons.hpp +++ b/addons/captives/CfgWeapons.hpp @@ -11,7 +11,7 @@ class CfgWeapons { picture = QPATHTOF(UI\ace_cabletie_ca.paa); scope = 2; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.3; }; }; }; diff --git a/addons/captives/XEH_postInit.sqf b/addons/captives/XEH_postInit.sqf index 8d34c4fb40..2580e72463 100644 --- a/addons/captives/XEH_postInit.sqf +++ b/addons/captives/XEH_postInit.sqf @@ -24,15 +24,15 @@ if (isServer) then { }]; }; -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; -[QGVAR(moveInCaptive), FUNC(vehicleCaptiveMoveIn)] call CBA_fnc_addEventHandler; -[QGVAR(moveOutCaptive), FUNC(vehicleCaptiveMoveOut)] call CBA_fnc_addEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +[QGVAR(moveInCaptive), LINKFUNC(vehicleCaptiveMoveIn)] call CBA_fnc_addEventHandler; +[QGVAR(moveOutCaptive), LINKFUNC(vehicleCaptiveMoveOut)] call CBA_fnc_addEventHandler; -[QGVAR(setHandcuffed), FUNC(setHandcuffed)] call CBA_fnc_addEventHandler; -[QGVAR(setSurrendered), FUNC(setSurrendered)] call CBA_fnc_addEventHandler; +[QGVAR(setHandcuffed), LINKFUNC(setHandcuffed)] call CBA_fnc_addEventHandler; +[QGVAR(setSurrendered), LINKFUNC(setSurrendered)] call CBA_fnc_addEventHandler; //Medical Integration Events -["ace_unconscious", FUNC(handleOnUnconscious)] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleOnUnconscious)] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; diff --git a/addons/captives/XEH_preInit.sqf b/addons/captives/XEH_preInit.sqf index 09ea454f03..8104e55b39 100644 --- a/addons/captives/XEH_preInit.sqf +++ b/addons/captives/XEH_preInit.sqf @@ -11,6 +11,6 @@ GVAR(captivityEnabled) = false; GVAR(restraints) = keys (uiNamespace getVariable QGVAR(restraints)); GVAR(blindfolds) = keys (uiNamespace getVariable QGVAR(blindfolds)); -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/captives/functions/fnc_canEscortCaptive.sqf b/addons/captives/functions/fnc_canEscortCaptive.sqf index f39ff2ac5f..204206e506 100644 --- a/addons/captives/functions/fnc_canEscortCaptive.sqf +++ b/addons/captives/functions/fnc_canEscortCaptive.sqf @@ -21,7 +21,6 @@ params ["_unit", "_target"]; (_target getVariable [QGVAR(isHandcuffed), false]) && {isNull (attachedTo _target)} && -{alive _target} && -{!(_target getVariable ["ACE_isUnconscious", false])} && +{_target call EFUNC(common,isAwake)} && {(vehicle _unit) == _unit} && {(vehicle _target) == _target} diff --git a/addons/captives/functions/fnc_canLoadCaptive.sqf b/addons/captives/functions/fnc_canLoadCaptive.sqf index 982e4025a2..46da188238 100644 --- a/addons/captives/functions/fnc_canLoadCaptive.sqf +++ b/addons/captives/functions/fnc_canLoadCaptive.sqf @@ -20,7 +20,7 @@ params ["_unit", "_target", "_vehicle"]; // Don't show "Load Captive" if unit is unconscious (already has "Load Patient") -if (_target getVariable ["ACE_isUnconscious", false]) exitWith {false}; +if !(_target call EFUNC(common,isAwake)) exitWith {false}; if ((isNull _target) && {_unit getVariable [QGVAR(isEscorting), false]}) then { //Looking at a vehicle while escorting, get target from attached objects: diff --git a/addons/captives/functions/fnc_canUnloadCaptive.sqf b/addons/captives/functions/fnc_canUnloadCaptive.sqf index 0eb64e7373..58899f088d 100644 --- a/addons/captives/functions/fnc_canUnloadCaptive.sqf +++ b/addons/captives/functions/fnc_canUnloadCaptive.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: commy2 + * Author: commy2, LinkIsGrim * Check if the unit can unload a captive from the vehicle. * * Arguments: @@ -19,4 +19,6 @@ params ["_player", "_unit"]; // Don't show "Unload Captive" if unit is unconscious (already has "Unload Patient") -(vehicle _unit != _unit) && {vehicle _player == _player} && {_unit getVariable [QGVAR(isHandcuffed), false]} && {!(_unit getVariable ["ACE_isUnconscious", false])} +!isNull objectParent _unit && +{_unit getVariable [QGVAR(isHandcuffed), false]} && +{lifeState _unit in ["HEALTHY", "INJURED"]} diff --git a/addons/captives/functions/fnc_doEscortCaptive.sqf b/addons/captives/functions/fnc_doEscortCaptive.sqf index 1d94b30b87..86cc52cb9c 100644 --- a/addons/captives/functions/fnc_doEscortCaptive.sqf +++ b/addons/captives/functions/fnc_doEscortCaptive.sqf @@ -39,20 +39,25 @@ if (_state) then { _args params ["_unit", "_target", "_actionID"]; if (_unit getVariable [QGVAR(isEscorting), false]) then { - if (!alive _target || {!alive _unit} || {!canStand _target} || {!canStand _unit} || {_target getVariable ["ACE_isUnconscious", false]} || {_unit getVariable ["ACE_isUnconscious", false]} || {!isNull (attachedTo _unit)}) then { + if (!canStand _target || {!canStand _unit} || {!(_target call EFUNC(common,isAwake))} || {!(_unit call EFUNC(common,isAwake))} || {!isNull (attachedTo _unit)}) then { _unit setVariable [QGVAR(isEscorting), false, true]; }; }; - if (!(_unit getVariable [QGVAR(isEscorting), false])) then { + if !(_unit getVariable [QGVAR(isEscorting), false]) then { [(_this select 1)] call CBA_fnc_removePerFrameHandler; [objNull, _target, false] call EFUNC(common,claim); detach _target; _unit removeAction _actionID; _unit setVariable [QGVAR(escortedUnit), objNull, true]; + + // Public event + [QGVAR(escortingCaptive), [_target, false, _unit]] call CBA_fnc_localEvent; }; }, 0, [_unit, _target, _actionID]] call CBA_fnc_addPerFrameHandler; + // Public event + [QGVAR(escortingCaptive), [_target, true, _unit]] call CBA_fnc_localEvent; } else { _unit setVariable [QGVAR(isEscorting), false, true]; _unit setVariable [QGVAR(escortedUnit), objNull, true]; diff --git a/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf b/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf index 4341867b29..2e07a353df 100644 --- a/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf +++ b/addons/captives/functions/fnc_findEmptyNonFFVCargoSeat.sqf @@ -16,7 +16,7 @@ */ params ["_vehicle"]; -TRACE_1("params", _vehicle); +TRACE_1("params",_vehicle); scopeName "main"; diff --git a/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf b/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf index 3363ca923e..8ce4391783 100644 --- a/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf +++ b/addons/captives/functions/fnc_handleAnimChangedHandcuffed.sqf @@ -19,7 +19,7 @@ params ["_unit", "_newAnimation"]; TRACE_2("AnimChanged",_unit,_newAnimation); if (_unit == (vehicle _unit)) then { - if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {!(_unit getVariable ["ACE_isUnconscious", false])}) then { + if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {_unit call EFUNC(common,isAwake)}) then { TRACE_1("Handcuff animation interrupted",_newAnimation); [_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation); }; diff --git a/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf b/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf index b9164ddbe5..7d69c8c7fa 100644 --- a/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf +++ b/addons/captives/functions/fnc_handleAnimChangedSurrendered.sqf @@ -19,7 +19,7 @@ params ["_unit", "_newAnimation"]; TRACE_2("AnimChanged",_unit,_newAnimation); -if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {!(_unit getVariable ["ACE_isUnconscious", false])}) then { +if ((_newAnimation != "ACE_AmovPercMstpSsurWnonDnon") && {_unit call EFUNC(common,isAwake)}) then { TRACE_1("Surrender animation interrupted",_newAnimation); [_unit, "ACE_AmovPercMstpSsurWnonDnon", 1] call EFUNC(common,doAnimation); }; diff --git a/addons/captives/functions/fnc_handleOnUnconscious.sqf b/addons/captives/functions/fnc_handleOnUnconscious.sqf index 1527038ce9..a43207fc84 100644 --- a/addons/captives/functions/fnc_handleOnUnconscious.sqf +++ b/addons/captives/functions/fnc_handleOnUnconscious.sqf @@ -27,7 +27,7 @@ if (_isUnconc) then { }; } else { //Woke up: if handcuffed, goto animation - if (_unit getVariable [QGVAR(isHandcuffed), false] && {vehicle _unit == _unit}) then { + if (_unit getVariable [QGVAR(isHandcuffed), false] && {isNull objectParent _unit}) then { [_unit] call EFUNC(common,fixLoweredRifleAnimation); [_unit, "ACE_AmovPercMstpScapWnonDnon", 1] call EFUNC(common,doAnimation); }; diff --git a/addons/captives/functions/fnc_setHandcuffed.sqf b/addons/captives/functions/fnc_setHandcuffed.sqf index c13da8f927..d3d9fa4e6b 100644 --- a/addons/captives/functions/fnc_setHandcuffed.sqf +++ b/addons/captives/functions/fnc_setHandcuffed.sqf @@ -58,7 +58,7 @@ if (_state) then { // fix anim on mission start (should work on dedicated servers) [{ params ["_unit"]; - if (!(_unit getVariable [QGVAR(isHandcuffed), false])) exitWith {}; + if !(_unit getVariable [QGVAR(isHandcuffed), false]) exitWith {}; if ((vehicle _unit) == _unit) then { [_unit] call EFUNC(common,fixLoweredRifleAnimation); @@ -91,7 +91,7 @@ if (_state) then { _unit removeEventHandler ["AnimChanged", _animChangedEHID]; _unit setVariable [QGVAR(handcuffAnimEHID), -1]; - if (((vehicle _unit) == _unit) && {!(_unit getVariable ["ACE_isUnconscious", false])}) then { + if (((vehicle _unit) == _unit) && {_unit call EFUNC(common,isAwake)}) then { //Break out of hands up animation loop [_unit, "ACE_AmovPercMstpScapWnonDnon_AmovPercMstpSnonWnonDnon", 2] call EFUNC(common,doAnimation); }; diff --git a/addons/captives/functions/fnc_setSurrendered.sqf b/addons/captives/functions/fnc_setSurrendered.sqf index 393465e08e..887bfb2680 100644 --- a/addons/captives/functions/fnc_setSurrendered.sqf +++ b/addons/captives/functions/fnc_setSurrendered.sqf @@ -81,13 +81,12 @@ if (_state) then { if (_unit == ACE_player) then { //only re-enable HUD if not handcuffed - if (!(_unit getVariable [QGVAR(isHandcuffed), false])) then { + if !(_unit getVariable [QGVAR(isHandcuffed), false]) then { ["captive", []] call EFUNC(common,showHud); //same as showHud true; }; }; - if (!alive _unit) exitWith {}; - if (_unit getVariable ["ACE_isUnconscious", false]) exitWith {}; //don't touch animations if unconscious + if !(_unit call EFUNC(common,isAwake)) exitWith {}; //don't touch animations if unconscious //if we are in "hands up" animationState, crack it now if (((vehicle _unit) == _unit) && {(animationState _unit) == "ACE_AmovPercMstpSsurWnonDnon"}) then { @@ -99,7 +98,7 @@ if (_state) then { params ["_args", "_pfID"]; _args params ["_unit", "_maxTime"]; //If waited long enough or they re-surrendered or they are unconscious, exit loop - if ((CBA_missionTime > _maxTime) || {_unit getVariable [QGVAR(isSurrendering), false]} || {_unit getVariable ["ACE_isUnconscious", false]}) exitWith { + if ((CBA_missionTime > _maxTime) || {_unit getVariable [QGVAR(isSurrendering), false]} || {!(_unit call EFUNC(common,isAwake))}) exitWith { [_pfID] call CBA_fnc_removePerFrameHandler; }; //Only break animation if they are actualy the "hands up" animation (because we are using switchmove there won't be an transition) diff --git a/addons/captives/initSettings.sqf b/addons/captives/initSettings.inc.sqf similarity index 100% rename from addons/captives/initSettings.sqf rename to addons/captives/initSettings.inc.sqf diff --git a/addons/captives/stringtable.xml b/addons/captives/stringtable.xml index 1a6fbf2fd8..4fc86ec58f 100644 --- a/addons/captives/stringtable.xml +++ b/addons/captives/stringtable.xml @@ -62,7 +62,7 @@ Escoltar Prisioneiro Fogoly kísérése Конвоировать пленного - 捕虜を移動させる + 捕虜を移送する 포로 호송하기 護送俘虜 护送俘虏 @@ -79,7 +79,7 @@ Largar Prisioneiro Fogoly elengedése Прекратить конвоирование - 捕虜を解放する + 捕虜を手放す 포로 풀어주기 停止護送俘虜 停止护送俘虏 @@ -96,7 +96,7 @@ Você deve tomá-lo como prisioneiro primeiro! Először foglyul kell ejtened őt! Вы должны сначала арестовать его! - 捕虜を取っている必要があります! + 先に対象を捕虜にする必要があります! 먼저 포로로 만들어야합니다! 你必須先逮捕他! 你必须先俘获他! @@ -144,6 +144,9 @@ Benda gli occhi Załóż opaskę na oczy 포로 눈 가리기 + 目隠しをする + Завязать глаза пленному + Vendar ojos al prisionero Remove blindfold @@ -152,6 +155,9 @@ Rimuovi la benda per gli occhi Zdejmij opaskę z oczu 눈가리개 풀기 + 目隠しを外す + Снять повязку с глаз + Quitar vendas de los ojos Cable Tie @@ -161,7 +167,7 @@ Serflex Stahovací pásek Algema Plástica - Fascietta + Fascetta Gyorskötöző Кабельная стяжка ケーブル タイ @@ -181,7 +187,7 @@ Fascetta per arrestare i prigionieri Gyorskötöző, emberek foglyulejtéséhez használható. Кабельные стяжки используются для связывания рук при аресте - ケーブル タイは捕虜を制圧できます。 + ケーブル タイによって捕虜を拘束することが出来る。 케이블 타이는 포로를 구류시킬때 씁니다. 束線帶可以綁住俘虜 束线带可以绑住俘虏 @@ -248,7 +254,7 @@ Synchronise l'unité pour qu'elle se rende. Egység szinkronizálása, hogy kapituláljon. Синхронизируйте с юнитами, чтобы заставить их сдаться. - Sincronizza una unità per farla arrendere. + Sincronizza un'unità per farla arrendere. 同期されたユニットを投降させます。 투항시키기 위해 동기화합니다. 同步此模塊到一個單位,使該單位投降 @@ -264,7 +270,7 @@ Metti manette all'unità Hacer que la unidad esté esposada Est menottée - ユニットを拘束する + ユニットを拘束させる 포박하기 使單位戴上手銬 使单位戴上手铐 @@ -330,7 +336,7 @@ Saját oldal megbilincselhető Можно связывать руки союзникам Puoi ammanettare unità alleate - 拘束ユニットを自陣営へ + 自陣営を拘束可能に 자기편을 포박 할 수 있습니다. 可以銬住同陣營隊友 可以铐住同阵营队友 @@ -345,8 +351,8 @@ Les joueurs peuvent menotter les unités de leur propre camp. A játékosok megkötözhetik-e a saját oldalukon lévő egységeket Разрешить игрокам арестовывать юнитов своей стороны - I giocatori possono ammanettare unità alleate - プレイヤーが拘束したユニットの陣営を自陣営に変更させます。 + I giocatori possono ammanettare unità della tua fazione + プレーヤーが自陣営のユニットをケーブルタイで拘束ができるようにします 자기 편에게 케이블 타이를 사용할 수 있게 합니다 玩家可以使用束線帶銬住同陣營隊友 玩家可以使用束线带铐住同阵营队友 @@ -376,7 +382,7 @@ Vyžaduje, aby se hráč nejdříve vzdal, poté může být spoután I giocatori devono arrendersi prima che possano essere arrestati Définit si les joueurs doivent d'abord s'être rendus avant qu'on ne puisse les arrêter. - プレイヤーは拘束される前に、投降する必要があります。 + プレイヤーを拘束する前に、投降を必要とさせます 체포하기 전에 먼저 플레이어가 투항을 해야만 합니다 玩家須先要求目標投降,才可以進行逮捕 玩家须先要求目标投降,才可以进行俘获 @@ -438,7 +444,7 @@ A játékosok megadhatják magukat a fegyverük elrakása után Игроки могут сдаваться после того, как уберут оружие I giocatori possono arrendersi dopo aver messo via le proprie armi - プレイヤーは武器を収めたあと投降できるようにします。 + プレイヤーが武器を収めたあとに投降できるようにします 비무장한 플레이어가 투항할 수 있게 합니다 玩家能在收起自己武器後投降 玩家能在收起自己武器后投降 @@ -446,7 +452,7 @@ Require AI surrendering Benötigt für KI Kapitulation - Necessita arresa AI + Necessita arresa IA AIの投降を必要とする 需要AI先行投降 需要 AI 先行投降 @@ -461,8 +467,8 @@ Require AI to surrender before they can be arrested KI muss sich erst ergeben, bevor sie gefangen genommen werden kann - Necessita che le AI si arrendano prima di essere arrestate - AIの拘束はAIが投降している場合に限り可能にします。 + Necessita che le IA si arrendano prima di poter essere arrestate + AIを拘束する前に、投降を必要とさせます 在逮捕AI之前該AI必須先進入投降狀態 在俘获 AI 之前该 AI 必须先进入投降状态。 포박하기 전에 먼저 AI가 투항해야만 합니다. @@ -477,12 +483,12 @@ Sets the unit under the cursor captive. Nimmt die Einheit unter dem Cursor fest. カーソル先のユニットを拘束 - Imposta l'unità nello stato di prigioniero. + Imposta l'unità puntata come prigioniero. 設置在游標下的單位成俘虜狀態 设置在光标下的单位成俘虏状态。 커서의 병력을 포박합니다. 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/CfgEden.hpp b/addons/cargo/CfgEden.hpp index 844d6207a2..0a4cc7ba1b 100644 --- a/addons/cargo/CfgEden.hpp +++ b/addons/cargo/CfgEden.hpp @@ -9,7 +9,7 @@ class Cfg3DEN { property = QGVAR(customName); control = "Edit"; - expression = QUOTE(_this setVariable [ARR_3(QQGVAR(customName),_value,true)];); + expression = QUOTE(_this setVariable [ARR_3(QQGVAR(customName),_value,true)]); defaultValue = "''"; condition = "objectHasInventoryCargo - objectVehicle"; diff --git a/addons/cargo/CfgEventHandlers.hpp b/addons/cargo/CfgEventHandlers.hpp index 6c29240403..29a0c6b277 100644 --- a/addons/cargo/CfgEventHandlers.hpp +++ b/addons/cargo/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); @@ -16,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/CfgVehicles.hpp b/addons/cargo/CfgVehicles.hpp index f3b6f2af5b..66fa98159e 100644 --- a/addons/cargo/CfgVehicles.hpp +++ b/addons/cargo/CfgVehicles.hpp @@ -48,15 +48,7 @@ class CfgVehicles { class Car: LandVehicle { GVAR(space) = 4; GVAR(hasCargo) = 1; - class ACE_Cargo { - /* - class Cargo { - class ACE_medicalSupplyCrate { - type = "ACE_medicalSupplyCrate"; - amount = 1; - }; - };*/ - }; + class ADDON {}; }; class Tank: LandVehicle { @@ -75,7 +67,7 @@ class CfgVehicles { GVAR(hasCargo) = 1; }; - // HEMTTs - Default at 10, some variants are altered based on model size and/or expected level of free space inside. + // HEMTTs - Default at 30, some variants are altered based on model size and/or expected level of free space inside. class Truck_01_base_F: Truck_F { GVAR(space) = 30; }; @@ -173,7 +165,7 @@ class CfgVehicles { }; - // misc. vehicles + // Misc. vehicles class Quadbike_01_base_F: Car_F { GVAR(space) = 0; GVAR(hasCargo) = 0; @@ -184,7 +176,7 @@ class CfgVehicles { GVAR(hasCargo) = 0; }; - // helicopters + // Helicopters class Air; class Helicopter: Air { GVAR(space) = 8; @@ -224,7 +216,7 @@ class CfgVehicles { }; class Heli_Transport_04_base_F: Helicopter_Base_H { - // note the double brackets are because loadmasterTurrets is an array of arrays / turret paths + // Note the double brackets are because loadmasterTurrets is an array of arrays / turret paths GVAR(loadmasterTurrets)[] = {{1}}; GVAR(space) = 0; GVAR(hasCargo) = 0; @@ -363,8 +355,9 @@ class CfgVehicles { GVAR(size) = 6; }; + // Slingload pallets class Slingload_base_F: ReammoBox_F {}; - class CargoNet_01_base_F: Slingload_base_F { //Slingload pallets + class CargoNet_01_base_F: Slingload_base_F { GVAR(size) = 6; }; @@ -509,7 +502,7 @@ class CfgVehicles { }; GVAR(space) = 2; - GVAR(hasCargo) = 2; + GVAR(hasCargo) = 1; GVAR(size) = 3; GVAR(canLoad) = 1; @@ -522,8 +515,9 @@ class CfgVehicles { class EventHandlers { class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; }; + GVAR(space) = 3; - GVAR(hasCargo) = 3; + GVAR(hasCargo) = 1; GVAR(size) = 3; GVAR(canLoad) = 1; diff --git a/addons/cargo/XEH_PREP.hpp b/addons/cargo/XEH_PREP.hpp index 95fefb4ba0..10281e2967 100644 --- a/addons/cargo/XEH_PREP.hpp +++ b/addons/cargo/XEH_PREP.hpp @@ -2,11 +2,15 @@ PREP(addCargoItem); PREP(addCargoVehiclesActions); PREP(canLoadItemIn); PREP(canUnloadItem); +PREP(deployCancel); +PREP(deployConfirm); PREP(getCargoSpaceLeft); PREP(getNameItem); +PREP(getSelectedItem); PREP(getSizeItem); -PREP(handleDeleted); PREP(handleDestroyed); +PREP(handleDeployInterrupt); +PREP(handleScrollWheel); PREP(initObject); PREP(initVehicle); PREP(loadItem); @@ -17,8 +21,8 @@ PREP(removeCargoItem); PREP(renameObject); PREP(setSize); PREP(setSpace); +PREP(startDeploy); PREP(startLoadIn); PREP(startUnload); PREP(unloadCarryItem); PREP(unloadItem); -PREP(validateCargoSpace); 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 7245b45e2f..f48849b50b 100644 --- a/addons/cargo/XEH_postInit.sqf +++ b/addons/cargo/XEH_postInit.sqf @@ -1,6 +1,62 @@ #include "script_component.hpp" -["ace_addCargo", {_this call FUNC(addCargoItem)}] call CBA_fnc_addEventHandler; +["ace_addCargo", LINKFUNC(addCargoItem)] call CBA_fnc_addEventHandler; + +["ace_loadCargo", { + params ["_item", "_vehicle"]; + TRACE_2("LoadCargo EH",_item,_vehicle); + + private _loaded = [_item, _vehicle] call FUNC(loadItem); // returns true if successful + + // Show hint as feedback + private _hint = [LSTRING(loadingFailed), LSTRING(loadedItem)] select _loaded; + private _itemName = [_item, true] call FUNC(getNameItem); + private _vehicleName = getText (configOf _vehicle >> "displayName"); + + [[_hint, _itemName, _vehicleName], 3] call EFUNC(common,displayTextStructured); +}] call CBA_fnc_addEventHandler; + +["ace_unloadCargo", { + params ["_item", "_vehicle", ["_unloader", objNull], ["_place", []]]; + TRACE_4("UnloadCargo EH",_item,_vehicle,_unloader,_place); + + 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; + private _itemName = [_item, true] call FUNC(getNameItem); + private _vehicleName = getText (configOf _vehicle >> "displayName"); + + [[_hint, _itemName, _vehicleName], 3] call EFUNC(common,displayTextStructured); + + if (_unloaded && {GVAR(openAfterUnload) in [1, 3]}) then { + GVAR(interactionVehicle) = _vehicle; + GVAR(interactionParadrop) = false; + createDialog QGVAR(menu); + }; +}] 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); + + // 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), { params ["_item", "_vehicle", ["_showHint", true]]; @@ -13,61 +69,12 @@ }; }] call CBA_fnc_addEventHandler; -["ace_loadCargo", { - params ["_item", "_vehicle"]; - TRACE_2("LoadCargo EH",_item,_vehicle); - - private _loaded = [_item, _vehicle] call FUNC(loadItem); - - // Show hint as feedback - private _hint = [LSTRING(LoadingFailed), LSTRING(LoadedItem)] select _loaded; - private _itemName = [_item, true] call FUNC(getNameItem); - private _vehicleName = getText (configOf _vehicle >> "displayName"); - - [[_hint, _itemName, _vehicleName], 3.0] call EFUNC(common,displayTextStructured); - - if (_loaded) then { - // Invoke listenable event - ["ace_cargoLoaded", [_item, _vehicle]] call CBA_fnc_globalEvent; - }; -}] call CBA_fnc_addEventHandler; - -["ace_unloadCargo", { - params ["_item", "_vehicle", ["_unloader", objNull]]; - TRACE_3("UnloadCargo EH",_item,_vehicle,_unloader); - - private _unloaded = [_item, _vehicle, _unloader] call FUNC(unloadItem); //returns true if sucessful - - // Show hint as feedback - private _hint = [LSTRING(UnloadingFailed), LSTRING(UnloadedItem)] select _unloaded; - private _itemName = [_item, true] call FUNC(getNameItem); - private _vehicleName = getText (configOf _vehicle >> "displayName"); - - [[_hint, _itemName, _vehicleName], 3.0] call EFUNC(common,displayTextStructured); - - if (_unloaded && {GVAR(openAfterUnload) in [1, 3]}) then { - GVAR(interactionVehicle) = _vehicle; - GVAR(interactionParadrop) = false; - createDialog QGVAR(menu); - }; -}] call CBA_fnc_addEventHandler; - -[QGVAR(serverUnload), { - params ["_item", "_emptyPosAGL"]; - - _item hideObjectGlobal false; - _item setPosASL (AGLtoASL _emptyPosAGL); - - [_item, "blockDamage", "ACE_cargo", false] call EFUNC(common,statusEffect_set); -}] call CBA_fnc_addEventHandler; - // Private events to handle adding actions globally via public functions -[QGVAR(initObject), DFUNC(initObject)] call CBA_fnc_addEventHandler; -[QGVAR(initVehicle), DFUNC(initVehicle)] call CBA_fnc_addEventHandler; - +[QGVAR(initObject), LINKFUNC(initObject)] call CBA_fnc_addEventHandler; +[QGVAR(initVehicle), LINKFUNC(initVehicle)] call CBA_fnc_addEventHandler; GVAR(vehicleAction) = [ - QGVAR(openMenu), localize LSTRING(openMenu), "", + QGVAR(openMenu), LLSTRING(openMenu), "", { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(interactionVehicle) = _target; @@ -77,17 +84,17 @@ GVAR(vehicleAction) = [ { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(enable) && - {(_target getVariable [QGVAR(hasCargo), getNumber (configOf _target >> QGVAR(hasCargo)) == 1])} && - {locked _target < 2} && - {([_player, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} && {alive _target} && + {locked _target < 2} && + {_target getVariable [QGVAR(hasCargo), getNumber (configOf _target >> QGVAR(hasCargo)) == 1]} && {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && - {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} + {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} && + {([_player, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} } ] call EFUNC(interact_menu,createAction); GVAR(objectActions) = [ - [QGVAR(renameObject), LELSTRING(common,rename), "", //TODO: add icon, maybe a pencil couldn't find it before. + [QGVAR(renameObject), LELSTRING(common,rename), "\a3\Modules_F_Curator\Data\iconMissionName_ca.paa", { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(interactionVehicle) = _target; @@ -97,59 +104,67 @@ GVAR(objectActions) = [ //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(enable) && {GVAR(enableRename)} && - {(_target getVariable [QGVAR(canLoad), getNumber (configOf _target >> QGVAR(canLoad))]) in [true, 1]} && {alive _target} && + {_target getVariable [QGVAR(canLoad), getNumber (configOf _target >> QGVAR(canLoad)) == 1]} && + {!(_target getVariable [QGVAR(noRename), getNumber (configOf _target >> QGVAR(noRename)) == 1])} && {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && - {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} && - {(_target getVariable [QGVAR(noRename), getNumber (configOf _target >> QGVAR(noRename))]) in [false, 0]} + {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} } ] call EFUNC(interact_menu,createAction), - [QGVAR(load), localize LSTRING(loadObject), "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa", + [QGVAR(load), LLSTRING(loadObject), "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa", { - params ["_target", "_player"]; + //IGNORE_PRIVATE_WARNING ["_target", "_player"]; [_player, _target] call FUNC(startLoadIn); }, { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(enable) && - {(_target getVariable [QGVAR(canLoad), getNumber (configOf _target >> QGVAR(canLoad))]) in [true, 1]} && - {locked _target < 2} && {alive _target} && + {locked _target < 2} && + {_target getVariable [QGVAR(canLoad), getNumber (configOf _target >> QGVAR(canLoad)) == 1]} && {[_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)} && {[_player, _target] call EFUNC(interaction,canInteractWithVehicleCrew)} && - {((nearestObjects [_target, GVAR(cargoHolderTypes), (MAX_LOAD_DISTANCE + 10)]) findIf { - private _hasCargoConfig = 1 == getNumber (configOf _x >> QGVAR(hasCargo)); - private _hasCargoPublic = _x getVariable [QGVAR(hasCargo), false]; - (_hasCargoConfig || {_hasCargoPublic}) && {_x != _target} && {alive _x} && {locked _x < 2} && + {((nearestObjects [_target, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]) findIf { + _x != _target && + {alive _x} && + {locked _x < 2} && + {_x getVariable [QGVAR(hasCargo), getNumber (configOf _x >> QGVAR(hasCargo)) == 1]} && {([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} - }) > -1} + }) != -1} }, LINKFUNC(addCargoVehiclesActions) ] call EFUNC(interact_menu,createAction) ]; -// find all remaining configured classes and init them, see XEH_preStart.sqf +// Find all remaining configured classes and init them, see XEH_preStart.sqf private _vehicleClassesAddAction = call (uiNamespace getVariable [QGVAR(initializedVehicleClasses), {[]}]); + { [_x, 0, ["ACE_MainActions"], GVAR(vehicleAction)] call EFUNC(interact_menu,addActionToClass); } forEach _vehicleClassesAddAction; + GVAR(initializedVehicleClasses) append _vehicleClassesAddAction; private _objectClassesAddAction = call (uiNamespace getVariable [QGVAR(initializedItemClasses), {[]}]); + { private _objectClass = _x; + { [_objectClass, 0, ["ACE_MainActions"], _x] call EFUNC(interact_menu,addActionToClass); } forEach GVAR(objectActions); } forEach _objectClassesAddAction; + GVAR(initializedItemClasses) append _objectClassesAddAction; private _vehicleClassesAddClassEH = call (uiNamespace getVariable [QGVAR(vehicleClasses_classEH), {[]}]); + { [_x, "initPost", DFUNC(initVehicle), nil, nil, true] call CBA_fnc_addClassEventHandler; } forEach _vehicleClassesAddClassEH; private _objectClassesAddClassEH = call (uiNamespace getVariable [QGVAR(objectClasses_classEH), {[]}]); + { [_x, "initPost", DFUNC(initObject), nil, nil, true] call CBA_fnc_addClassEventHandler; } forEach _objectClassesAddClassEH; @@ -157,7 +172,44 @@ private _objectClassesAddClassEH = call (uiNamespace getVariable [QGVAR(objectCl if (isServer) then { ["ace_placedInBodyBag", { params ["_target", "_bodyBag", "_isGrave"]; + if (_isGrave) exitWith {}; // assume graves aren't cargo + _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/XEH_preInit.sqf b/addons/cargo/XEH_preInit.sqf index f14ccc5958..35f2d78e45 100644 --- a/addons/cargo/XEH_preInit.sqf +++ b/addons/cargo/XEH_preInit.sqf @@ -6,15 +6,15 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(initializedItemClasses) = []; GVAR(initializedVehicleClasses) = []; -GVAR(cargoHolderTypes) = ["Car", "Air", "Tank", "Ship", "Cargo_base_F", "Land_PaperBox_closed_F"]; -GVAR(disableParadropEffectsClasstypes) = ["Car_F"]; +GVAR(cargoHolderTypes) = ["Car", "Air", "Tank", "Ship", "Cargo_base_F", "Land_PaperBox_closed_F"] apply {_x call EFUNC(common,getConfigName)}; // make sure they are config case +GVAR(disableParadropEffectsClasstypes) = ["Car_F"] apply {_x call EFUNC(common,getConfigName)}; if (isServer) then { - ["All", "Deleted", LINKFUNC(handleDeleted)] call CBA_fnc_addClassEventHandler; + ["All", "Deleted", LINKFUNC(handleDestroyed)] call CBA_fnc_addClassEventHandler; }; ["All", "Killed", LINKFUNC(handleDestroyed)] call CBA_fnc_addClassEventHandler; diff --git a/addons/cargo/XEH_preStart.sqf b/addons/cargo/XEH_preStart.sqf index e7b3f5c59b..e5ef507556 100644 --- a/addons/cargo/XEH_preStart.sqf +++ b/addons/cargo/XEH_preStart.sqf @@ -2,36 +2,38 @@ #include "XEH_PREP.hpp" - -//See XEH_postInit.sqf +// See XEH_postInit.sqf private _vehicleClasses_addClassEH = ["ThingX", "LandVehicle", "Air", "Ship_F"]; private _objectClasses_addClassEH = ["ThingX", "StaticWeapon"]; private _vehicleClasses_addAction = []; private _itemClasses_addAction = []; +private _class = ""; -// find all remaining configured classes and init them +// Find all remaining configured classes and init them { - private _class = configName _x; - // init vehicle + _class = configName _x; + + // Init vehicle if ( - 1 == getNumber (_x >> QGVAR(hasCargo)) - && {-1 == _vehicleClasses_addClassEH findIf {_class isKindOf _x}} + getNumber (_x >> QGVAR(hasCargo)) == 1 && + {_vehicleClasses_addClassEH findIf {_class isKindOf _x} == -1} ) then { if (_class isKindOf "Static") then { - if (2 == getNumber (_x >> "scope")) then { + if (getNumber (_x >> "scope") == 2) then { _vehicleClasses_addAction pushBackUnique _class; }; } else { _vehicleClasses_addClassEH pushBackUnique _class; }; }; - // init object + + // Init object if ( - 1 == getNumber (_x >> QGVAR(canLoad)) - && {-1 == _objectClasses_addClassEH findIf {_class isKindOf _x}} + getNumber (_x >> QGVAR(canLoad)) == 1 && + {_objectClasses_addClassEH findIf {_class isKindOf _x} == -1} ) then { if (_class isKindOf "Static") then { - if (2 == getNumber (_x >> "scope")) then { + if (getNumber (_x >> "scope") == 2) then { _itemClasses_addAction pushBackUnique _class; }; } else { @@ -40,7 +42,6 @@ private _itemClasses_addAction = []; }; } forEach ("true" configClasses (configFile >> "CfgVehicles")); - uiNamespace setVariable [QGVAR(vehicleClasses_classEH), compileFinal str _vehicleClasses_addClassEH]; uiNamespace setVariable [QGVAR(objectClasses_classEH), compileFinal str _objectClasses_addClassEH]; uiNamespace setVariable [QGVAR(initializedVehicleClasses), compileFinal str _vehicleClasses_addAction]; diff --git a/addons/cargo/functions/fnc_addCargoItem.sqf b/addons/cargo/functions/fnc_addCargoItem.sqf index ecaa4e316f..d5c7925a6f 100644 --- a/addons/cargo/functions/fnc_addCargoItem.sqf +++ b/addons/cargo/functions/fnc_addCargoItem.sqf @@ -4,26 +4,45 @@ * Adds a cargo item to the vehicle. * * Arguments: - * 0: Item Classname - * 1: Vehicle + * 0: Item to be loaded or + * 1: Holder object (vehicle) * 2: Amount (default: 1) - * 3: Show Hint (default: false) + * 3: Ignore interaction distance and stability checks (default: false) * * Return Value: - * None + * Objects loaded * * Example: - * ["item", vehicle] call ace_cargo_fnc_addCargoItem + * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_addCargoItem * * Public: No */ -params ["_itemClass", "_vehicle", ["_amount", 1], ["_showHint", false, [false]]]; -TRACE_3("params",_itemClass,_vehicle,_amount); +params ["_item", "_vehicle", ["_amount", 1], ["_ignoreInteraction", false]]; +TRACE_4("params",_item,_vehicle,_amount,_ignoreInteraction); -for "_i" from 1 to _amount do { - [_itemClass, _vehicle] call FUNC(loadItem); +private _loaded = 0; + +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); + + for "_i" from 1 to _amount do { + if !([_item, _vehicle, _ignoreInteraction] call FUNC(loadItem)) exitWith {}; + + _loaded = _loaded + 1; + }; +} else { + _loaded = parseNumber ([_item, _vehicle, _ignoreInteraction] call FUNC(loadItem)); + + _item = typeOf _item; }; +TRACE_1("loaded",_loaded); + // Invoke listenable event -["ace_cargoAdded", [_itemClass, _vehicle, _amount]] call CBA_fnc_globalEvent; +if (_loaded > 0) then { + ["ace_cargoAdded", [_item, _vehicle, _loaded]] call CBA_fnc_globalEvent; +}; + +_loaded // return diff --git a/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf b/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf index 811ccd2b36..4aa18867d6 100644 --- a/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf +++ b/addons/cargo/functions/fnc_addCargoVehiclesActions.sqf @@ -1,32 +1,34 @@ #include "..\script_component.hpp" /* * Author: Dystopian - * Create actions for nearest vehicles with cargo. + * Creates actions for nearest vehicles with cargo. * * Arguments: - * 0: Target + * 0: Holder object (vehicle) * * Return Value: * Child actions * * Example: - * [cursorObject] call ace_cargo_fnc_addCargoVehiclesActions + * cursorObject call ace_cargo_fnc_addCargoVehiclesActions * * Public: No */ -params ["_target"]; +params ["_vehicle"]; private _statement = { - params ["_target", "_player", "_vehicle"]; - [_player, _target, _vehicle] call FUNC(startLoadIn); + params ["_item", "_loader", "_vehicle"]; + + [_loader, _item, _vehicle] call FUNC(startLoadIn); }; -private _vehicles = (nearestObjects [_target, GVAR(cargoHolderTypes), (MAX_LOAD_DISTANCE + 10)]) select { - private _hasCargoConfig = 1 == getNumber (configOf _x >> QGVAR(hasCargo)); - private _hasCargoPublic = _x getVariable [QGVAR(hasCargo), false]; - (_hasCargoConfig || {_hasCargoPublic}) && {_x != _target} && {alive _x} && {locked _x < 2} && - {([_target, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} +private _vehicles = (nearestObjects [_vehicle, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]) select { + _x != _vehicle && + {alive _x} && + {locked _x < 2} && + {_x getVariable [QGVAR(hasCargo), getNumber (configOf _x >> QGVAR(hasCargo)) == 1]} && + {([_vehicle, _x] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} }; -[_vehicles, _statement, _target] call EFUNC(interact_menu,createVehiclesActions) +[_vehicles, _statement, _vehicle] call EFUNC(interact_menu,createVehiclesActions) diff --git a/addons/cargo/functions/fnc_canLoadItemIn.sqf b/addons/cargo/functions/fnc_canLoadItemIn.sqf index 9f0b7ceae2..6a45593297 100644 --- a/addons/cargo/functions/fnc_canLoadItemIn.sqf +++ b/addons/cargo/functions/fnc_canLoadItemIn.sqf @@ -1,48 +1,57 @@ #include "..\script_component.hpp" /* * Author: Glowbal - * Check if item can be loaded into other Object. + * Checks if the item can be loaded into another object. * * Arguments: - * 0: Item - * 1: Holder Object (Vehicle) - * 2: Ignore interaction distance and stability checks + * 0: Item to be loaded or + * 1: Holder object (vehicle) + * 2: Ignore interaction distance and stability checks (default: false) * * Return Value: - * Can load in + * Can be loaded * * Example: - * [item, holder] call ace_cargo_fnc_canLoadItemIn + * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_canLoadItemIn * * Public: No */ -params [["_item", "", [objNull,""]], "_vehicle", ["_ignoreInteraction", false]]; +params ["_item", "_vehicle", ["_ignoreInteraction", false]]; -if ((!_ignoreInteraction) && {speed _vehicle > 1 || {((getPos _vehicle) select 2) > 3}}) exitWith {TRACE_1("vehicle not stable",_vehicle); false}; +// Check if vehicle is stable +if (!_ignoreInteraction && {speed _vehicle > 1 || {((getPos _vehicle) select 2) > 3}}) exitWith { + TRACE_1("vehicle not stable",_vehicle); -if (_item isEqualType objNull && {{alive _x && {getText (configOf _x >> "simulation") != "UAVPilot"}} count crew _item > 0}) exitWith { - TRACE_1("item is occupied",_item); - false + false // return }; -private _itemSize = [_item] call FUNC(getSizeItem); -private _validItem = false; -if (_item isEqualType "") then { - _validItem = - isClass (configFile >> "CfgVehicles" >> _item) && - {getNumber (configFile >> "CfgVehicles" >> _item >> QGVAR(canLoad)) == 1}; +// If there is crew that isn't UAV crew, exit +if (_item isEqualType objNull && {(crew _item) findIf {alive _x && {!unitIsUAV _x}} != -1}) exitWith { + TRACE_1("item is occupied",_item); + + false // return +}; + +private _itemSize = _item call FUNC(getSizeItem); + +private _validItem = if (_item isEqualType "") then { + private _config = configFile >> "CfgVehicles" >> _item; + + isClass _config && + {getNumber (_config >> QGVAR(canLoad)) == 1} } else { - _validItem = - (alive _item) && - {_ignoreInteraction || {([_item, _vehicle] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}} && - {!(_item getVariable [QEGVAR(cookoff,isCookingOff), false])} && - {isNull(_item getVariable [QEGVAR(refuel,nozzle), objNull])} && // Objects which have a refueling nozzle connected to them cannot be loaded - {isNull(_item getVariable [QEGVAR(refuel,ownedNozzle), objNull])}; // Fuel sources which have their nozzle out cannot be loaded + alive _item && + {_item getVariable [QGVAR(canLoad), getNumber (configOf _item >> QGVAR(canLoad)) == 1]} && + {_ignoreInteraction || {([_item, _vehicle] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}} && + {!(_item getVariable [QEGVAR(cookoff,isCookingOff), false])} && // do not load items that are cooking off + {isNull (_item getVariable [QEGVAR(refuel,nozzle), objNull])} && // objects which have a refueling nozzle connected to them cannot be loaded + {isNull (_item getVariable [QEGVAR(refuel,ownedNozzle), objNull])} // fuel sources which have their nozzle out cannot be loaded }; _validItem && -{_itemSize > 0} && {alive _vehicle} && -{_itemSize <= ([_vehicle] call FUNC(getCargoSpaceLeft))} && -{locked _vehicle < 2} +{locked _vehicle < 2} && +{_vehicle getVariable [QGVAR(hasCargo), getNumber (configOf _vehicle >> QGVAR(hasCargo)) == 1]} && +{_itemSize >= 0} && +{_itemSize <= (_vehicle call FUNC(getCargoSpaceLeft)) max 0} diff --git a/addons/cargo/functions/fnc_canUnloadItem.sqf b/addons/cargo/functions/fnc_canUnloadItem.sqf index fd69d5f9bd..357ba78f21 100644 --- a/addons/cargo/functions/fnc_canUnloadItem.sqf +++ b/addons/cargo/functions/fnc_canUnloadItem.sqf @@ -1,30 +1,44 @@ #include "..\script_component.hpp" /* * Author: Glowbal, ViperMaul - * Check if item can be unloaded. + * Checks if the item can be unloaded from another object. * * Arguments: - * 0: loaded Object - * 1: Object - * 2: Unloader (player) (default: objNull) + * 0: Item to be unloaded or + * 1: Holder object (vehicle) + * 2: Unit doing the unloading (default: objNull) + * 3: Ignore interaction distance and stability checks (default: false) + * 4: Ignore finding a suitable position (default: false) * * Return Value: * Can be unloaded * * Example: - * [item, holder] call ace_cargo_fnc_canUnloadItem + * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_canUnloadItem * * Public: No */ -params ["_item", "_vehicle", ["_unloader", objNull]]; +params ["_item", "_vehicle", ["_unloader", objNull], ["_ignoreInteraction", false], ["_ignoreFindPosition", false]]; TRACE_2("params",_item,_vehicle); -private _loaded = _vehicle getVariable [QGVAR(loaded), []]; -if !(_item in _loaded) exitWith {false}; +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); +}; -private _itemClass = if (_item isEqualType "") then {_item} else {typeOf _item}; +if !(_item in (_vehicle getVariable [QGVAR(loaded), []])) exitWith {false}; -private _emptyPos = [_vehicle, _itemClass, _unloader] call EFUNC(common,findUnloadPosition); +private _validItem = if (_item isEqualType objNull) then { + alive _item +} else { + true +}; -(count _emptyPos) == 3 +_validItem && +{alive _vehicle} && +{locked _vehicle < 2} && +{_vehicle getVariable [QGVAR(hasCargo), getNumber (configOf _vehicle >> QGVAR(hasCargo)) == 1]} && +{_item call FUNC(getSizeItem) >= 0} && +{_ignoreInteraction || {([_unloader, _vehicle] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE}} && +{_ignoreFindPosition || {([_vehicle, _item, _unloader, MAX_LOAD_DISTANCE, !_ignoreInteraction] call EFUNC(common,findUnloadPosition)) isNotEqualTo []}} 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_getCargoSpaceLeft.sqf b/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf index a0e8d2993d..e797b0820d 100644 --- a/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf +++ b/addons/cargo/functions/fnc_getCargoSpaceLeft.sqf @@ -1,21 +1,20 @@ #include "..\script_component.hpp" /* * Author: Glowbal - * Get the cargo space left on object. + * Gets the object's remaining cargo space. * * Arguments: - * 0: Object + * 0: Holder object (vehicle) * * Return Value: * Cargo space left * * Example: - * [object] call ace_cargo_fnc_getCargoSpaceLeft + * cursorObject call ace_cargo_fnc_getCargoSpaceLeft * * Public: No */ -params ["_object"]; -// TRACE_1("params",_object); +params ["_vehicle"]; -(_object getVariable [QGVAR(space), getNumber (configOf _object >> QGVAR(space))]) max 0 +_vehicle getVariable [QGVAR(space), getNumber (configOf _vehicle >> QGVAR(space))] diff --git a/addons/cargo/functions/fnc_getNameItem.sqf b/addons/cargo/functions/fnc_getNameItem.sqf index a28d128c63..b71ae073cb 100644 --- a/addons/cargo/functions/fnc_getNameItem.sqf +++ b/addons/cargo/functions/fnc_getNameItem.sqf @@ -4,31 +4,31 @@ * Gets the name of the item, and alternatively the custom name if requested and available. * * Arguments: - * 0: Target - * 1: Add custom name part (default: false) + * 0: Item or (default: "") + * 1: Add custom name (default: false) * * Return Value: - * Item Name + * Item name * * Example: - * [crate_7] call ace_cargo_fnc_getNameItem + * cursorObject call ace_cargo_fnc_getNameItem * * Public: Yes */ -params ["_object", ["_addCustomPart", false]]; +params [["_item", "", [objNull, ""]], ["_addCustomName", false, [false]]]; -private _displayName = if (_object isEqualType "") then { - getText (configFile >> "CfgVehicles" >> _object >> "displayName") +private _displayName = if (_item isEqualType "") then { + getText (configFile >> "CfgVehicles" >> _item >> "displayName") } else { - getText ((configOf _object) >> "displayName") + getText (configOf _item >> "displayName") }; -if (_addCustomPart && {!(_object isEqualType "")}) then { - private _customPart = _object getVariable [QGVAR(customName), ""]; +if (_addCustomName && {_item isEqualType objNull}) then { + private _customName = _item getVariable [QGVAR(customName), ""]; - if (_customPart isNotEqualTo "") then { - _displayName = _displayName + " [" + _customPart + "]"; + if (_customName isNotEqualTo "") then { + _displayName = _displayName + " [" + _customName + "]"; }; }; 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_getSizeItem.sqf b/addons/cargo/functions/fnc_getSizeItem.sqf index 24b47f70b2..bf049b71b3 100644 --- a/addons/cargo/functions/fnc_getSizeItem.sqf +++ b/addons/cargo/functions/fnc_getSizeItem.sqf @@ -1,29 +1,25 @@ #include "..\script_component.hpp" /* * Author: Glowbal, kymckay - * Get the cargo size of an object. + * Gets the cargo size of an object. * * Arguments: - * 0: Item + * 0: Item or * * Return Value: * Cargo size (default: -1) * * Example: - * [object] call ace_cargo_fnc_getSizeItem + * cursorObject call ace_cargo_fnc_getSizeItem * * Public: No */ params ["_item"]; -// Virtual items are much easier to deal with +// Default cargo size is -1 as 0 is a valid size if (_item isEqualType "") then { - CARGO_SIZE(_item) + GET_NUMBER(configFile >> "CfgVehicles" >> _item >> QGVAR(size),-1) } else { - if (isNil {_item getVariable QGVAR(size)}) then { - CARGO_SIZE(typeOf _item) - } else { - _item getVariable QGVAR(size) - }; + _item getVariable [QGVAR(size), GET_NUMBER(configOf _item >> QGVAR(size),-1)] }; diff --git a/addons/cargo/functions/fnc_handleDeleted.sqf b/addons/cargo/functions/fnc_handleDeleted.sqf deleted file mode 100644 index a4300aea25..0000000000 --- a/addons/cargo/functions/fnc_handleDeleted.sqf +++ /dev/null @@ -1,25 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: mharis001 - * Handles an object being deleted by deleting all loaded cargo. - * - * Arguments: - * 0: Object - * - * Return Value: - * None - * - * Example: - * [_object] call ace_cargo_fnc_handleDeleted - * - * Public: No - */ - -params ["_object"]; - -{ - if (_x isEqualType objNull) then { - detach _x; - deleteVehicle _x; - }; -} forEach (_object getVariable [QGVAR(loaded), []]); 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_handleDestroyed.sqf b/addons/cargo/functions/fnc_handleDestroyed.sqf index 016917f5f7..cc5777723d 100644 --- a/addons/cargo/functions/fnc_handleDestroyed.sqf +++ b/addons/cargo/functions/fnc_handleDestroyed.sqf @@ -1,7 +1,9 @@ #include "..\script_component.hpp" /* - * Author: Glowbal - * Handle object being destroyed. + * Author: mharis001, Glowbal + * Handles an object being destroyed/deleted. + * If object contained loaded cargo, the cargo is deleted. + * If object was loaded cargo, it's removed from loaded cargo list. * * Arguments: * 0: Object @@ -10,23 +12,34 @@ * None * * Example: - * [_object] call ace_cargo_fnc_handleDestroyed + * cursorObject call ace_cargo_fnc_handleDestroyed * * Public: No */ -params ["_vehicle"]; -TRACE_1("params",_vehicle); +params ["_object"]; -private _loaded = _vehicle getVariable [QGVAR(loaded), []]; -if (_loaded isEqualTo []) exitWith {}; +private _loaded = _object getVariable [QGVAR(loaded), []]; -{ - // TODO Do we want to be able to recover destroyed equipment? - if (_x isEqualType objNull) then { - detach _x; - deleteVehicle _x; - }; -} forEach _loaded; +if (_loaded isNotEqualTo []) then { + // Delete all cargo + { + if (_x isEqualType objNull) then { + detach _x; + deleteVehicle _x; + }; + } forEach _loaded; -[_vehicle] call FUNC(validateCargoSpace); + // In case vehicle is killed, but not deleted, reset loaded list + _object setVariable [QGVAR(loaded), [], true]; +}; + +// Update remaining cargo space, if loaded as cargo in a vehicle +private _vehicle = attachedTo _object; + +if (!isNull _vehicle && {_object in (_vehicle getVariable [QGVAR(loaded), []])}) then { + private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); + private _itemSize = (_object call FUNC(getSizeItem)) max 0; // don't let negative size items increase space + + _vehicle setVariable [QGVAR(space), _cargoSpace + _itemSize, true]; +}; 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_initObject.sqf b/addons/cargo/functions/fnc_initObject.sqf index 0842d51faa..734fe99c39 100644 --- a/addons/cargo/functions/fnc_initObject.sqf +++ b/addons/cargo/functions/fnc_initObject.sqf @@ -4,51 +4,57 @@ * Initializes variables for loadable objects. Called from init EH. * * Arguments: - * 0: Object + * 0: Item * * Return Value: * None * * Example: - * [object] call ace_cargo_fnc_initObject + * cursorObject call ace_cargo_fnc_initObject * * Public: No */ -params ["_object"]; -private _type = typeOf _object; -private _config = configOf _object; -TRACE_2("params",_object,_type); +// Dedicated servers and HCs do not require action menus +if (!hasInterface) exitWith {}; -// If object had size given to it via eden/public then override config canLoad setting -private _canLoadPublic = _object getVariable [QGVAR(canLoad), false]; -if (!(_canLoadPublic isEqualType false)) then { - WARNING_4("%1[%2] - Variable %3 is %4 - Should be bool",_object,_type,QGVAR(canLoad),_canLoadPublic); +params ["_item"]; +private _type = typeOf _item; +TRACE_2("params",_item,_type); + +// If object had size given to it via eden/public, then override config canLoad setting +private _canLoadPublic = _item getVariable QGVAR(canLoad); +private _canLoadPublicDefined = !isNil "_canLoadPublic"; + +if (_canLoadPublicDefined && {!(_canLoadPublic isEqualType false)}) then { + WARNING_4("%1[%2] - Variable %3 is %4 - Should be bool",_item,_type,QGVAR(canLoad),_canLoadPublic); }; -private _canLoadConfig = getNumber (_config >> QGVAR(canLoad)) == 1; + +private _canLoadConfig = getNumber (configOf _item >> QGVAR(canLoad)) == 1; // Nothing to do here if object can't be loaded -if !(_canLoadConfig || {_canLoadPublic in [true, 1]}) exitWith {}; - -// Servers and HCs do not require action menus (beyond this point) -if !(hasInterface) exitWith {}; +if !((_canLoadPublicDefined && {_canLoadPublic in [true, 1]}) || {!_canLoadPublicDefined && {_canLoadConfig}}) exitWith {}; // Unnecessary to add actions to an object class that's already got them if (_type in GVAR(initializedItemClasses)) exitWith {}; -if (_object getVariable [QGVAR(initObject),false]) exitWith {}; +if (_item getVariable [QGVAR(initObject),false]) exitWith {}; // Objects given size via eden have their actions added to the object // So this function may run for multiple of the same class in that case if (_canLoadConfig) then { GVAR(initializedItemClasses) pushBack _type; - TRACE_1("Adding load cargo action to class", _type); + + TRACE_1("Adding load cargo action to class",_type); + { [_type, 0, ["ACE_MainActions"], _x] call EFUNC(interact_menu,addActionToClass); } forEach GVAR(objectActions); } else { - _object setVariable [QGVAR(initObject),true]; - TRACE_1("Adding load cargo action to object", _object); + _item setVariable [QGVAR(initObject), true]; + + TRACE_1("Adding load cargo action to object",_item); + { - [_object, 0, ["ACE_MainActions"], _x] call EFUNC(interact_menu,addActionToObject); + [_item, 0, ["ACE_MainActions"], _x] call EFUNC(interact_menu,addActionToObject); } forEach GVAR(objectActions); }; diff --git a/addons/cargo/functions/fnc_initVehicle.sqf b/addons/cargo/functions/fnc_initVehicle.sqf index 948fdf525e..25cebe5b13 100644 --- a/addons/cargo/functions/fnc_initVehicle.sqf +++ b/addons/cargo/functions/fnc_initVehicle.sqf @@ -10,60 +10,85 @@ * None * * Example: - * [vehicle] call ace_cargo_fnc_initVehicle + * cursorObject call ace_cargo_fnc_initVehicle * * Public: No */ params ["_vehicle"]; -TRACE_1("params", _vehicle); +TRACE_1("params",_vehicle); 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]; +// If vehicle had space given to it via eden/public, then override config hasCargo setting +private _hasCargoPublic = _vehicle getVariable QGVAR(hasCargo); +private _hasCargoPublicDefined = !isNil "_hasCargoPublic"; + +if (_hasCargoPublicDefined && {!(_hasCargoPublic isEqualType false)}) then { + WARNING_4("%1[%2] - Variable %3 is %4 - Should be bool",_vehicle,_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 = true; -{ - if (_type isKindOf _x) exitWith {_addCargoType = false}; -} forEach GVAR(cargoHolderTypes); +private _addCargoType = GVAR(cargoHolderTypes) findIf {_type isKindOf _x} == -1; + TRACE_2("",_addCargoType,_type); + if (_addCargoType) then { GVAR(cargoHolderTypes) pushBack _type; }; -// Vehicle can have default ace cargo in its config +// If already initialised (both actions and cargo), then skip +if (_vehicle getVariable [QGVAR(initVehicle), false]) exitWith {}; + +// Vehicles can have default ace cargo in their config if (isServer) then { + _vehicle setVariable [QGVAR(initVehicle), true]; + + private _cargoClassname = ""; + private _cargoCount = 0; + private _loaded = 0; + { - private _cargoClassname = getText (_x >> "type"); - private _cargoCount = getNumber (_x >> "amount"); - TRACE_3("adding ACE_Cargo", (configName _x), _cargoClassname, _cargoCount); - ["ace_addCargo", [_cargoClassname, _vehicle, _cargoCount]] call CBA_fnc_localEvent; - } forEach ("true" configClasses (_config >> QUOTE(ADDON) >> "Cargo")); + _cargoClassname = getText (_x >> "type"); + _cargoCount = getNumber (_x >> "amount"); + + TRACE_3("adding ace_cargo",configName _x,_cargoClassname,_cargoCount); + + // Ignore stability check (distance check is also ignored with this, but it's ignored by default if item is a string) + _loaded = [_cargoClassname, _vehicle, _cargoCount, true] call FUNC(addCargoItem); + + // Let loop continue until the end, so that it prints everything into the rpt (there might be smaller items that could still fit in cargo) + if (_loaded != _cargoCount) then { + WARNING_5("%1 (%2) could not fit %3 %4 inside its cargo, only %5 were loaded.",_vehicle,_type,_cargoCount,_cargoClassname,_loaded); + }; + } forEach ("true" configClasses (_config >> QUOTE(ADDON) >> "cargo")); }; // Servers and HCs do not require action menus (beyond this point) -if !(hasInterface) exitWith {}; +if (!hasInterface) exitWith {}; // Unnecessary to add actions to a vehicle class that's already got them if (_type in GVAR(initializedVehicleClasses)) exitWith {}; -if (_vehicle getVariable [QGVAR(initVehicle),false]) exitWith {}; // Vehicles given cargo via eden have their actions added to the object // So this function may run for multiple of the same class in that case if (_hasCargoConfig) then { GVAR(initializedVehicleClasses) pushBack _type; - TRACE_1("Adding unload cargo action to class", _type); + + TRACE_1("Adding unload cargo action to class",_type); + [_type, 0, ["ACE_MainActions"], GVAR(vehicleAction)] call EFUNC(interact_menu,addActionToClass); } else { - _vehicle setVariable [QGVAR(initVehicle),true]; - TRACE_1("Adding unload cargo action to object", _vehicle); + _vehicle setVariable [QGVAR(initVehicle), true]; + + TRACE_1("Adding unload cargo action to object",_vehicle); + [_vehicle, 0, ["ACE_MainActions"], GVAR(vehicleAction)] call EFUNC(interact_menu,addActionToObject); }; @@ -71,24 +96,31 @@ if (_hasCargoConfig) then { if (_vehicle isKindOf "Air") then { private _condition = { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; - GVAR(enable) && {[_player, _target, []] call EFUNC(common,canInteractWith)} && { - private _turretPath = _player call CBA_fnc_turretPath; - (_player == (driver _target)) || // pilot - {(getNumber (([_target, _turretPath] call CBA_fnc_getTurret) >> "isCopilot")) == 1} || // coPilot - {_turretPath in (getArray (configOf _target >> QGVAR(loadmasterTurrets)))}} // loadMaster turret from config + GVAR(enable) && + {[_player, _target, []] call EFUNC(common,canInteractWith)} && { + private _turretPath = _target unitTurret _player; + + (_player == currentPilot _target) || // Pilot/Co-pilot + {(getNumber ([_target, _turretPath] call CBA_fnc_getTurret >> "isCopilot")) == 1} || // Co-pilot + {_turretPath in (getArray (configOf _target >> QGVAR(loadmasterTurrets)))} + } }; + private _statement = { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; GVAR(interactionVehicle) = _target; GVAR(interactionParadrop) = true; createDialog QGVAR(menu); }; - private _text = localize LSTRING(openMenu); + + private _text = LLSTRING(openMenu); private _icon = ""; private _action = [QGVAR(openMenu), _text, _icon, _statement, _condition] call EFUNC(interact_menu,createAction); + + // Self action on the vehicle if (_hasCargoConfig) then { - [_type, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToClass); // self action on the vehicle + [_type, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToClass); } else { [_vehicle, 1, ["ACE_SelfActions"], _action] call EFUNC(interact_menu,addActionToObject); }; diff --git a/addons/cargo/functions/fnc_loadItem.sqf b/addons/cargo/functions/fnc_loadItem.sqf index 587543f776..aa3117c7dd 100644 --- a/addons/cargo/functions/fnc_loadItem.sqf +++ b/addons/cargo/functions/fnc_loadItem.sqf @@ -1,27 +1,36 @@ #include "..\script_component.hpp" /* * Author: Glowbal - * Load object into vehicle. + * Loads an object into a vehicle. * Objects loaded via classname remain virtual until unloaded. * * Arguments: - * 0: Item - * 1: Vehicle - * 2: Ignore interaction distance and stability checks + * 0: Item to be loaded or (default: "") + * 1: Holder object (vehicle) (default: objNull) + * 2: Ignore interaction distance and stability checks (default: false) * * Return Value: * Object loaded * * Example: - * [object, vehicle] call ace_cargo_fnc_loadItem + * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_loadItem * * Public: Yes */ -params [["_item","",[objNull,""]], ["_vehicle",objNull,[objNull]], ["_ignoreInteraction", false]]; -TRACE_2("params",_item,_vehicle); +params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_ignoreInteraction", false, [false]]]; +TRACE_3("params",_item,_vehicle,_ignoreInteraction); -if !([_item, _vehicle, _ignoreInteraction] call FUNC(canLoadItemIn)) exitWith {TRACE_2("cannot load",_item,_vehicle); false}; +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); +}; + +if !([_item, _vehicle, _ignoreInteraction] call FUNC(canLoadItemIn)) exitWith { + TRACE_3("cannot load",_item,_vehicle,_ignoreInteraction); + + false // return +}; private _loaded = _vehicle getVariable [QGVAR(loaded), []]; _loaded pushBack _item; @@ -29,13 +38,15 @@ _vehicle setVariable [QGVAR(loaded), _loaded, true]; TRACE_1("added to loaded array",_loaded); -private _space = [_vehicle] call FUNC(getCargoSpaceLeft); -private _itemSize = [_item] call FUNC(getSizeItem); -_vehicle setVariable [QGVAR(space), _space - _itemSize, true]; +// Update cargo space remaining +private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); +private _itemSize = (_item call FUNC(getSizeItem)) max 0; // don't let negative size items increase space +_vehicle setVariable [QGVAR(space), _cargoSpace - _itemSize, true]; +// Attach object 100m below vehicle if (_item isEqualType objNull) then { detach _item; - _item attachTo [_vehicle,[0,0,-100]]; + _item attachTo [_vehicle, [0, 0, -100]]; [QEGVAR(common,hideObjectGlobal), [_item, true]] call CBA_fnc_serverEvent; if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { @@ -49,8 +60,22 @@ if (_item isEqualType objNull) then { [QEGVAR(zeus,removeObjects), [[_item], _objectCurators]] call CBA_fnc_serverEvent; }; - // Some objects below water will take damage over time and eventualy become "water logged" and unfixable (because of negative z attach) - [_item, "blockDamage", "ACE_cargo", true] call EFUNC(common,statusEffect_set); + // Some objects below water will take damage over time, eventually becoming "water logged" and unfixable (because of negative z attach) + [_item, "blockDamage", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + + // Prevent UAVs from firing + private _UAVCrew = _item call EFUNC(common,getVehicleUAVCrew); + + if (_UAVCrew isNotEqualTo []) then { + { + [_x, true] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _item setVariable [QGVAR(isUAV), _UAVCrew, true]; + }; }; -true +// Invoke listenable event +["ace_cargoLoaded", [_item, _vehicle]] call CBA_fnc_globalEvent; + +true // return diff --git a/addons/cargo/functions/fnc_onMenuOpen.sqf b/addons/cargo/functions/fnc_onMenuOpen.sqf index 16e66a6ed1..f99999aabf 100644 --- a/addons/cargo/functions/fnc_onMenuOpen.sqf +++ b/addons/cargo/functions/fnc_onMenuOpen.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Glowbal - * Handle the UI data display. + * Handles the UI data display. * * Arguments: * 0: Display @@ -10,7 +10,7 @@ * None * * Example: - * [display] call ace_cargo_fnc_onMenuOpen + * display call ace_cargo_fnc_onMenuOpen * * Public: No */ @@ -22,37 +22,81 @@ params ["_display"]; uiNamespace setVariable [QGVAR(menuDisplay), _display]; if (GVAR(interactionParadrop)) then { - (_display displayCtrl 12) ctrlSetText (localize LSTRING(paradropButton)); + (_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"]; + disableSerialization; + private _display = uiNamespace getVariable QGVAR(menuDisplay); - if (isnil "_display") exitWith { - [_this select 1] call CBA_fnc_removePerFrameHandler; + + if (isNil "_display") exitWith { + GVAR(interactionParadrop) = nil; + + _pfhID call CBA_fnc_removePerFrameHandler; }; - if (isNull GVAR(interactionVehicle) || {(([ACE_player, GVAR(interactionVehicle)] call EFUNC(interaction,getInteractionDistance)) >= MAX_LOAD_DISTANCE) && {(vehicle ACE_player) != GVAR(interactionVehicle)}}) exitWith { + // Close menu if in invalid state + if ( + !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 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; - [_this select 1] call CBA_fnc_removePerFrameHandler; + + GVAR(interactionParadrop) = nil; + + _pfhID call CBA_fnc_removePerFrameHandler; }; - private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; private _ctrl = _display displayCtrl 100; private _label = _display displayCtrl 2; + // Remove previous entries lbClear _ctrl; + + // Display item names + private _displayName = ""; + private _itemSize = 0; + private _index = -1; + private _damageStr = "0%"; + private _damage = 0; + { - private _class = if (_x isEqualType "") then {_x} else {typeOf _x}; - private _displayName = [_x, true] call FUNC(getNameItem); - if (GVAR(interactionParadrop)) then { - _ctrl lbAdd format ["%1 (%2s)", _displayName, GVAR(paradropTimeCoefficent) * ([_class] call FUNC(getSizeItem))]; + _displayName = [_x, true] call FUNC(getNameItem); + _itemSize = _x call FUNC(getSizeItem); + _damage = if (_x isEqualType "") then {0} else {damage _x}; + _damageStr = ((_damage * 100) toFixed 0) + "%"; + + if (_itemSize >= 0) then { + _index = if (GVAR(interactionParadrop)) then { + _ctrl lbAdd format ["%1. %2 (%3s)", _forEachIndex + 1, _displayName, GVAR(paradropTimeCoefficent) * _itemSize] + } else { + _ctrl lbAdd format ["%1. %2", _forEachIndex + 1, _displayName] + }; + + private _tooltip = format ["%1\n%2", format [LLSTRING(sizeMenu), _itemSize], format ["%1: %2", localize "str_a3_normaldamage1", _damageStr]]; + _ctrl lbSetTooltip [_index, _tooltip]; } else { - _ctrl lbAdd _displayName; + // If item has a size < 0, it means it's not loadable + _index = _ctrl lbAdd _displayName; + + _ctrl lbSetTooltip [_index, LLSTRING(unloadingImpossible)]; + _ctrl lbSetColor [_index, [1, 0, 0, 1]]; // set text to red + _ctrl lbSetSelectColor [_index, [1, 0, 0, 1]]; }; + } forEach (_vehicle getVariable [QGVAR(loaded), []]); - true - } count _loaded; - - _label ctrlSetText format[localize LSTRING(labelSpace), [GVAR(interactionVehicle)] call DFUNC(getCargoSpaceLeft)]; -}, 0, []] call CBA_fnc_addPerFrameHandler; + _label ctrlSetText format [LLSTRING(labelSpace), (_vehicle call FUNC(getCargoSpaceLeft)) max 0]; +}, 0, GVAR(interactionVehicle)] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cargo/functions/fnc_paradropItem.sqf b/addons/cargo/functions/fnc_paradropItem.sqf index d1f61fb6a2..6a84a20799 100644 --- a/addons/cargo/functions/fnc_paradropItem.sqf +++ b/addons/cargo/functions/fnc_paradropItem.sqf @@ -1,18 +1,18 @@ #include "..\script_component.hpp" /* * Author: marc_book, commy2, CAA-Picard - * Unload and paradrop object from plane or helicopter. + * Unloads and paradrops an object from a plane or helicopter. * * Arguments: - * 0: Object - * 1: Vehicle + * 0: Item or + * 1: Holder object (vehicle) * 2: Show Hint (default: true) * * Return Value: * Object unloaded * * Example: - * [object, vehicle] call ace_cargo_fnc_paradropItem + * ["ACE_Wheel", vehicle player] call ace_cargo_fnc_paradropItem * * Public: No */ @@ -20,51 +20,68 @@ params ["_item", "_vehicle", ["_showHint", true]]; TRACE_2("params",_item,_vehicle); +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); +}; + +// Check if item is actually part of cargo private _loaded = _vehicle getVariable [QGVAR(loaded), []]; -if !(_item in _loaded) exitWith {false}; +if !(_item in _loaded) exitWith { + false // return +}; -// unload item from cargo +// Check if item can be unloaded +private _itemSize = _item call FUNC(getSizeItem); + +if (_itemSize < 0) exitWith { + false // return +}; + +// Unload item from cargo _loaded deleteAt (_loaded find _item); _vehicle setVariable [QGVAR(loaded), _loaded, true]; -private _cargoSpace = [_vehicle] call FUNC(getCargoSpaceLeft); -private _itemSize = [_item] call FUNC(getSizeItem); -_vehicle setVariable [QGVAR(space), (_cargoSpace + _itemSize), true]; +// Update cargo space remaining +private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); +_vehicle setVariable [QGVAR(space), _cargoSpace + _itemSize, true]; (boundingBoxReal _vehicle) params ["_bb1", "_bb2"]; private _distBehind = ((_bb1 select 1) min (_bb2 select 1)) - 4; // 4 meters behind max bounding box -TRACE_1("",_distBehind); private _posBehindVehicleAGL = _vehicle modelToWorld [0, _distBehind, -2]; +TRACE_1("",_distBehind); private _object = _item; + if (_item 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 + // Do both on server to ensure they are executed in the correct order [QGVAR(serverUnload), [_object, _posBehindVehicleAGL]] call CBA_fnc_serverEvent; } else { _object = createVehicle [_item, _posBehindVehicleAGL, [], 0, "NONE"]; _object setPosASL (AGLtoASL _posBehindVehicleAGL); }; -[QEGVAR(common,setVelocity), [_object, ((velocity _vehicle) vectorAdd ((vectorNormalized (vectorDir _vehicle)) vectorMultiply -5))], _object] call CBA_fnc_targetEvent; +[QEGVAR(common,setVelocity), [_object, (velocity _vehicle) vectorAdd ((vectorNormalized (vectorDir _vehicle)) vectorMultiply -5)], _object] call CBA_fnc_targetEvent; -// open parachute and ir light effect +// Open parachute and IR light effect [{ params ["_object"]; if (isNull _object || {getPos _object select 2 < 1}) exitWith {}; - private _parachute = createVehicle ["B_Parachute_02_F", [0,0,0], [], 0, "CAN_COLLIDE"]; + private _parachute = createVehicle ["B_Parachute_02_F", [0, 0, 0], [], 0, "CAN_COLLIDE"]; // Prevent collision damage [QEGVAR(common,fixCollision), _parachute] call CBA_fnc_localEvent; [QEGVAR(common,fixCollision), _object, _object] call CBA_fnc_targetEvent; - // cannot use setPos on parachutes without them closing down - _parachute attachTo [_object, [0,0,0]]; + // Cannot use setPos on parachutes without them closing down + _parachute attachTo [_object, [0, 0, 0]]; detach _parachute; private _velocity = velocity _object; @@ -76,35 +93,45 @@ if (_item isEqualType objNull) then { _parachute setVelocity _velocity; if ((GVAR(disableParadropEffectsClasstypes) findIf {_object isKindOf _x}) == -1) then { - private _light = "Chemlight_yellow" createVehicle [0,0,0]; - _light attachTo [_object, [0,0,0]]; + private _light = "Chemlight_yellow" createVehicle [0, 0, 0]; + _light attachTo [_object, [0, 0, 0]]; }; +}, _object, 0.7] call CBA_fnc_waitAndExecute; -}, [_object], 0.7] call CBA_fnc_waitAndExecute; - -// smoke effect when crate landed +// Create smoke effect when crate landed [{ - (_this select 0) params ["_object"]; + params ["_object", "_pfhID"]; if (isNull _object) exitWith { - [_this select 1] call CBA_fnc_removePerFrameHandler; + _pfhID call CBA_fnc_removePerFrameHandler; }; - if (getPos _object select 2 < 1) then { - if ((GVAR(disableParadropEffectsClasstypes) findIf {_object isKindOf _x}) == -1) then { - private _smoke = "SmokeshellYellow" createVehicle [0,0,0]; - _smoke attachTo [_object, [0,0,0]]; + if (getPos _object select 2 < 1) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + + // Reenable UAV crew + private _UAVCrew = _object getVariable [QGVAR(isUAV), []]; + + if (_UAVCrew isNotEqualTo []) then { + // Reenable AI + { + [_x, false] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _object setVariable [QGVAR(isUAV), nil, true]; }; - [_this select 1] call CBA_fnc_removePerFrameHandler; + if ((GVAR(disableParadropEffectsClasstypes) findIf {_object isKindOf _x}) == -1) then { + private _smoke = "SmokeshellYellow" createVehicle [0, 0, 0]; + _smoke attachTo [_object, [0, 0, 0]]; + }; }; - -}, 1, [_object]] call CBA_fnc_addPerFrameHandler; +}, 1, _object] call CBA_fnc_addPerFrameHandler; if (_showHint) then { [ [ - LSTRING(UnloadedItem), + LSTRING(unloadedItem), [_object, true] call FUNC(getNameItem), getText (configOf _vehicle >> "displayName") ], @@ -115,4 +142,4 @@ if (_showHint) then { // Invoke listenable event ["ace_cargoUnloaded", [_object, _vehicle, "paradrop"]] call CBA_fnc_globalEvent; -true +true // return diff --git a/addons/cargo/functions/fnc_removeCargoItem.sqf b/addons/cargo/functions/fnc_removeCargoItem.sqf index b15a5a7434..6e95893992 100644 --- a/addons/cargo/functions/fnc_removeCargoItem.sqf +++ b/addons/cargo/functions/fnc_removeCargoItem.sqf @@ -4,23 +4,28 @@ * Removes a cargo item from the vehicle. * * Arguments: - * 0: Item or - * 1: Vehicle + * 0: Item to be removed or (default: "") + * 1: Holder object (vehicle) (default: objNull) * 2: Amount (default: 1) * * Return Value: * Number of items removed * * Example: - * ["ACE_Wheel", vehicle, 2] call ace_cargo_fnc_removeCargoItem + * ["ACE_Wheel", cursorObject, 2] call ace_cargo_fnc_removeCargoItem * [crate_7, truck] call ace_cargo_fnc_removeCargoItem * * Public: Yes */ -params ["_item", "_vehicle", ["_amount", 1]]; +params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_amount", 1, [0]]]; TRACE_3("params",_item,_vehicle,_amount); +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); +}; + private _loaded = _vehicle getVariable [QGVAR(loaded), []]; private _addedSpace = 0; @@ -29,31 +34,40 @@ private _itemsRemoved = 0; private _continue = if (_item isEqualType objNull) then { if !(_item in _loaded) exitWith {false}; - _addedSpace = [_item] call FUNC(getSizeItem); + + _addedSpace = (_item call FUNC(getSizeItem)) max 0; // don't let negative size items increase space _loaded deleteAt (_loaded find _item); + _itemClass = typeOf _item; + + // Delete item deleteVehicle _item; + _itemsRemoved = 1; + true } else { { if (_itemsRemoved == _amount) exitWith {}; if ( - (_x isEqualType "" && {_x == _item}) || // Check for classname, case-insensitive - {_x isEqualType objNull && {typeOf _x isEqualTo _item}} + (_x isEqualType "" && {_x == _item}) || + {_x isEqualType objNull && {typeOf _x == _item}} ) then { INC(_itemsRemoved); - ADD(_addedSpace,[_x] call FUNC(getSizeItem)); + _addedSpace = _addedSpace + ((_x call FUNC(getSizeItem)) max 0); // don't let negative size items increase space + // Delete item if (_x isEqualType objNull) then { deleteVehicle _x; }; + _loaded set [_forEachIndex, nil]; }; } forEach _loaded; FILTER(_loaded,!isNil "_x"); + true }; @@ -61,8 +75,9 @@ if (!_continue) exitWith {0}; _vehicle setVariable [QGVAR(loaded), _loaded, true]; -private _space = [_vehicle] call FUNC(getCargoSpaceLeft); -_vehicle setVariable [QGVAR(space), _space + _addedSpace, true]; +// Update remaining cargo space +private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); +_vehicle setVariable [QGVAR(space), _cargoSpace + _addedSpace, true]; // Invoke listenable event ["ace_cargoRemoved", [_itemClass, _vehicle, _amount, _itemsRemoved]] call CBA_fnc_globalEvent; diff --git a/addons/cargo/functions/fnc_renameObject.sqf b/addons/cargo/functions/fnc_renameObject.sqf index c088dcf62a..a10d54df7e 100644 --- a/addons/cargo/functions/fnc_renameObject.sqf +++ b/addons/cargo/functions/fnc_renameObject.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: JasperRab - * Renames object. + * Renames an object. * * Arguments: * None @@ -10,19 +10,23 @@ * None * * Example: - * [] call ace_cargo_fnc_renameObject + * call ace_cargo_fnc_renameObject * - * Public: Yes + * Public: No */ private _display = uiNamespace getVariable QGVAR(menuDisplay); + if (isNil "_display") exitWith {}; private _ctrlEditText = ctrlText 100; -_ctrlEditText = _ctrlEditText select [0,32]; -if (_ctrlEditText isEqualTo "") then { // custom name has been removed +_ctrlEditText = _ctrlEditText select [0, 32]; + +// Check if custom name has been removed +if (_ctrlEditText isEqualTo "") then { [LSTRING(clearedCustomName), 3] call EFUNC(common,displayTextStructured); } else { [[LSTRING(renamedObject), _ctrlEditText], 3] call EFUNC(common,displayTextStructured); }; + GVAR(interactionVehicle) setVariable [QGVAR(customName), _ctrlEditText, true]; diff --git a/addons/cargo/functions/fnc_setSize.sqf b/addons/cargo/functions/fnc_setSize.sqf index 523bbdbb61..8804c81266 100644 --- a/addons/cargo/functions/fnc_setSize.sqf +++ b/addons/cargo/functions/fnc_setSize.sqf @@ -1,57 +1,55 @@ #include "..\script_component.hpp" /* * Author: kymckay - * Set the cargo size of any object. Has global effect. + * Sets the cargo size of any object. Has global effect. * Adds the load action menu if necessary. - * Negative size makes unloadable. + * A negative size disables the object's cargo interactions. * * Arguments: - * 0: Object - * 1: Cargo size + * 0: Object (default: objNull) + * 1: Cargo size (default: nil) * * Return Value: * None * * Example: - * [cursorTarget, 3] call ace_cargo_fnc_setSize + * [cursorObject, 3] call ace_cargo_fnc_setSize * * Public: Yes */ -// Only run this after the settings are initialized -if !(EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(setSize), _this]; -}; - params [ - ["_object",objNull,[objNull]], - ["_size",nil,[0]] // Default can't be a number since all are valid + ["_object", objNull, [objNull]], + ["_size", nil, [0]] // default can't be a number since all are valid ]; TRACE_2("setSize",_object,_size); +private _oldSize = _object call FUNC(getSizeItem); + // Nothing to do here -if ( - (isNil "_size") || - {isNull _object} || - {_size == _object getVariable [QGVAR(size), CARGO_SIZE(typeOf _object)]} -) exitWith {}; +if (isNil "_size" || {isNull _object} || {_size == _oldSize}) exitWith {}; // Apply new size globally -// Necessary to update value, even if unloadable, as API could be used again +// Necessary to update value, even if disabled, as API could be used again _object setVariable [QGVAR(canLoad), _size >= 0, true]; _object setVariable [QGVAR(size), _size, true]; -// If no size no need for load action -if (_size < 0) exitWith {}; +// Update remaining cargo space, if loaded as cargo in a vehicle +private _vehicle = attachedTo _object; -// If an existing ID is present, load action has already been added globally -private _jipID = _object getVariable QGVAR(setSize_jipID); +if (!isNull _vehicle && {_object in (_vehicle getVariable [QGVAR(loaded), []])}) then { + private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); -// Actions should be added to all future JIP players too -if (isNil "_jipID") then { - _jipID = [QGVAR(initObject), [_object]] call CBA_fnc_globalEventJIP; + _vehicle setVariable [QGVAR(space), _cargoSpace + (_oldSize max 0) - (_size max 0), true]; // don't let negative size items increase space +}; + +// Actions should be added for all future JIP players too, regardless of size +private _jipID = format [QGVAR(sizeJipID_%1), hashValue _object]; +[QGVAR(initObject), _object, _jipID] call CBA_fnc_globalEventJIP; + +// Remove from JIP queue if object is deleted +if !(_object getVariable [QGVAR(setSizeRemoveJip), false]) then { [_jipID, _object] call CBA_fnc_removeGlobalEventJIP; - // Store the ID for any future calls to this function - _object setVariable [QGVAR(setSize_jipID), _jipID, true]; + _object setVariable [QGVAR(setSizeRemoveJip), true, true]; }; diff --git a/addons/cargo/functions/fnc_setSpace.sqf b/addons/cargo/functions/fnc_setSpace.sqf index f573019a11..01c078496c 100644 --- a/addons/cargo/functions/fnc_setSpace.sqf +++ b/addons/cargo/functions/fnc_setSpace.sqf @@ -1,12 +1,12 @@ #include "..\script_component.hpp" /* * Author: kymckay - * Set the cargo space of any object. Has global effect. + * Sets the cargo space of any object. Has global effect. * Adds the cargo action menu if necessary. * * Arguments: - * 0: Object - * 1: Cargo space + * 0: Vehicle (default: objNull) + * 1: Cargo space (default: nil) * * Return Value: * None @@ -17,49 +17,38 @@ * Public: Yes */ -// Only run this after the settings are initialized -if !(EGVAR(common,settingsInitFinished)) exitWith { - EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(setSpace), _this]; -}; - params [ - ["_vehicle",objNull,[objNull]], - ["_space",nil,[0]] // Default can't be a number since all are valid + ["_vehicle", objNull, [objNull]], + ["_space", nil, [0]] // default can't be a number since all are valid ]; -TRACE_2("setSpace",_vehicle,_size); +TRACE_2("setSpace",_vehicle,_space); // Nothing to do here -if ( - (isNil "_space") || - {isNull _vehicle} -) exitWith {}; +if (isNil "_space" || {isNull _vehicle}) exitWith {}; // Account for cargo already in the vehicle private _loaded = _vehicle getVariable [QGVAR(loaded), []]; -private _newSpace = _space; +private _cargoSpace = _space; + { - _newSpace = _newSpace - ([_x] call FUNC(getSizeItem)); + _cargoSpace = _cargoSpace - ((_x call FUNC(getSizeItem)) max 0); } forEach _loaded; // If the new value is the same as the old, do nothing -if (_newSpace == (_vehicle getVariable [QGVAR(space), CARGO_SPACE(typeOf _vehicle)])) exitwith {}; +if (_cargoSpace == (_vehicle call FUNC(getCargoSpaceLeft))) exitwith {}; // Apply new space globally -_vehicle setVariable [QGVAR(space), _newSpace, true]; // Necessary to update value, even if no space, as API could be used again _vehicle setVariable [QGVAR(hasCargo), _space > 0, true]; +_vehicle setVariable [QGVAR(space), _cargoSpace, true]; -// If no cargo space no need for cargo menu -if (_space <= 0) exitWith {}; +// Space should be added for all future JIP players too, regardless of space +private _jipID = format [QGVAR(spaceJipID_%1), hashValue _vehicle]; +[QGVAR(initVehicle), _vehicle, _jipID] call CBA_fnc_globalEventJIP; -// If an existing ID is present, cargo menu has already been added globally -private _jipID = _vehicle getVariable QGVAR(setSpace_jipID); - -// Cargo menu should be added to all future JIP players too -if (isNil "_jipID") then { - _jipID = [QGVAR(initVehicle), [_vehicle]] call CBA_fnc_globalEventJIP; +// Remove from JIP queue if vehicle is deleted +if !(_vehicle getVariable [QGVAR(setSpaceRemoveJip), false]) then { [_jipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; - // Store the ID for any future calls to this function - _vehicle setVariable [QGVAR(setSpace_jipID), _jipID, true]; + _vehicle setVariable [QGVAR(setSpaceRemoveJip), true, true]; }; 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_startLoadIn.sqf b/addons/cargo/functions/fnc_startLoadIn.sqf index 5add1386ed..7212d89c22 100644 --- a/addons/cargo/functions/fnc_startLoadIn.sqf +++ b/addons/cargo/functions/fnc_startLoadIn.sqf @@ -1,67 +1,108 @@ #include "..\script_component.hpp" /* * Author: Glowbal - * Start load item. + * Starts loading item. * * Arguments: - * 0: Player - * 1: Object - * 2: Vehicle (Optional) + * 0: Unit doing the loading + * 1: Item to be loaded + * 2: Holder object (vehicle) (default: objNull) * * Return Value: * Load ProgressBar Started * * Example: - * [player, cursorTarget] call ace_cargo_fnc_startLoadIn + * [player, cursorObject] call ace_cargo_fnc_startLoadIn * * Public: No */ -params ["_player", "_object", ["_cargoVehicle", objNull]]; -TRACE_3("params",_player,_object,_cargoVehicle); +params ["_loader", "_item", ["_vehicle", objNull]]; +TRACE_3("params",_loader,_item,_vehicle); -private _vehicle = _cargoVehicle; if (isNull _vehicle) then { { - if ([_object, _x] call FUNC(canLoadItemIn)) exitWith {_vehicle = _x}; - } forEach (nearestObjects [_player, GVAR(cargoHolderTypes), (MAX_LOAD_DISTANCE + 10)]); + if ([_item, _x] call FUNC(canLoadItemIn)) exitWith { + _vehicle = _x; + }; + } forEach (nearestObjects [_loader, GVAR(cargoHolderTypes), MAX_LOAD_DISTANCE + 10]); }; if (isNull _vehicle) exitWith { - TRACE_3("Could not find vehicle",_player,_object,_vehicle); - false + TRACE_3("Could not find vehicle",_loader,_item,_vehicle); + + false // return }; -private _return = false; // Start progress bar -if ([_object, _vehicle] call FUNC(canLoadItemIn)) then { - [_player, _object, true] call EFUNC(common,claim); - private _size = [_object] call FUNC(getSizeItem); +if ([_item, _vehicle] call FUNC(canLoadItemIn)) then { + private _duration = GVAR(loadTimeCoefficient) * (_item call FUNC(getSizeItem)); + + // If load time is 0, don't show a progress bar + if (_duration <= 0) exitWith { + ["ace_loadCargo", [_item, _vehicle]] call CBA_fnc_localEvent; + + true // return + }; + + // Claim so nobody else can interact with it + [_loader, _item, true] call EFUNC(common,claim); [ - GVAR(loadTimeCoefficient) * _size, - [_object, _vehicle], + _duration, + [_item, _vehicle], { TRACE_1("load finish",_this); + [objNull, _this select 0 select 0, true] call EFUNC(common,claim); + ["ace_loadCargo", _this select 0] call CBA_fnc_localEvent; }, { TRACE_1("load fail",_this); - [objNull, _this select 0 select 0, true] call EFUNC(common,claim); + (_this select 0) params ["_item", "_vehicle"]; + + [objNull, _item, true] call EFUNC(common,claim); + + [[LSTRING(loadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured); + + // Fix cancelling loading a carried item + if (!isNull attachedTo _item) then { + detach _item; + + // Prevent coliisions between item and vehicle + [QEGVAR(common,fixCollision), _vehicle, _vehicle] call CBA_fnc_targetEvent; + [QEGVAR(common,fixCollision), _item, _item] call CBA_fnc_targetEvent; + + [QEGVAR(common,fixPosition), _item, _item] call CBA_fnc_targetEvent; + [QEGVAR(common,fixFloating), _item, _item] call CBA_fnc_targetEvent; + }; }, - localize LSTRING(LoadingItem), + format [LLSTRING(loadingItem), [_item, true] call FUNC(getNameItem), getText (configOf _vehicle >> "displayName")], { - (_this select 0) params ["_item", "_target"]; - (alive _target) && {locked _target < 2} && {alive _item} - && {([_item, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} + (_this select 0) call FUNC(canLoadItemIn) }, ["isNotSwimming"] ] call EFUNC(common,progressBar); - _return = true; -} else { - private _displayName = [_object, true] call FUNC(getNameItem); - [[LSTRING(LoadingFailed), _displayName], 3] call EFUNC(common,displayTextStructured); -}; -_return + true // return +} else { + // Unlock the object + [objNull, _item, true] call EFUNC(common,claim); + + [[LSTRING(loadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured); + + // Fix cancelling loading a carried item + if (!isNull attachedTo _item) then { + detach _item; + + // Prevent coliisions between item and vehicle + [QEGVAR(common,fixCollision), _vehicle, _vehicle] call CBA_fnc_targetEvent; + [QEGVAR(common,fixCollision), _item, _item] call CBA_fnc_targetEvent; + + [QEGVAR(common,fixPosition), _item, _item] call CBA_fnc_targetEvent; + [QEGVAR(common,fixFloating), _item, _item] call CBA_fnc_targetEvent; + }; + + false // return +}; diff --git a/addons/cargo/functions/fnc_startUnload.sqf b/addons/cargo/functions/fnc_startUnload.sqf index cf00327dcc..39dbf59f48 100644 --- a/addons/cargo/functions/fnc_startUnload.sqf +++ b/addons/cargo/functions/fnc_startUnload.sqf @@ -1,92 +1,112 @@ #include "..\script_component.hpp" /* * Author: Glowbal - * Start unload action. + * Starts unloading item selected in the cargo menu. * * Arguments: - * None + * 0: Unit doing the unloading * * Return Value: * None * * Example: - * [] call ace_cargo_fnc_startUnload + * player call ace_cargo_fnc_startUnload * * Public: No */ -disableSerialization; +// This can be an object or a classname string +private _item = call FUNC(getSelectedItem); -private _display = uiNamespace getVariable QGVAR(menuDisplay); -if (isNil "_display") exitWith {}; +if (isNil "_item") exitWith {}; -private _loaded = GVAR(interactionVehicle) getVariable [QGVAR(loaded), []]; -if (_loaded isEqualTo []) exitWith {}; - -private _ctrl = _display displayCtrl 100; - -private _selected = (lbCurSel _ctrl) max 0; - -if (count _loaded <= _selected) exitWith {}; -private _item = _loaded select _selected; // This can be an object or a classname string +params ["_unit"]; if (GVAR(interactionParadrop)) exitWith { - // If drop time is 0 don't show a progress bar - if (GVAR(paradropTimeCoefficent) == 0) exitWith { + // Close the cargo menu + closeDialog 0; + + private _duration = GVAR(paradropTimeCoefficent) * (_item call FUNC(getSizeItem)); + + // If drop time is 0, don't show a progress bar + if (_duration <= 0) exitWith { [QGVAR(paradropItem), [_item, GVAR(interactionVehicle)]] call CBA_fnc_localEvent; }; // Start progress bar - paradrop - private _size = [_item] call FUNC(getSizeItem); - [ - GVAR(paradropTimeCoefficent) * _size, - [_item, GVAR(interactionVehicle), ACE_player], + // Delay execution by a frame, to avoid progress bar stopping prematurely because of the cargo menu still being open + [EFUNC(common,progressBar), [ + _duration, + [_item, GVAR(interactionVehicle)], { - (_this select 0) params ["_item", "_target", "_player"]; - [QGVAR(paradropItem), [_item, _target]] call CBA_fnc_localEvent; + [QGVAR(paradropItem), _this select 0] call CBA_fnc_localEvent; }, { - params ["_args", "", "", "_errorCode"]; // show warning if we failed because of flight conditions - if (_errorCode == 3) then { - _args params ["_item", "_target", "_player"]; - [localize LSTRING(unlevelFlightWarning)] call EFUNC(common,displayTextStructured); + params ["", "", "", "_errorCode"]; + + if (_errorCode == 3) then { // show warning if we failed because of flight conditions + [LSTRING(unlevelFlightWarning)] call EFUNC(common,displayTextStructured); }; }, - localize LSTRING(UnloadingItem), + format [LLSTRING(unloadingItem), [_item, true] call FUNC(getNameItem), getText (configOf GVAR(interactionVehicle) >> "displayName")], { - (_this select 0) params ["_item", "_target", "_player"]; - 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 + (_this select 0) params ["", "_vehicle"]; + + 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 }, - ["isNotSwimming", "isNotInside"] - ] call EFUNC(common,progressBar); + ["isNotSwimming", "isNotInside"], + false + ]] call CBA_fnc_execNextFrame; }; +// If in zeus +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); + }; + + // Close the cargo menu + closeDialog 1; + + ["ace_unloadCargo", [_item, GVAR(interactionVehicle)]] call CBA_fnc_localEvent; +}; // Start progress bar - normal ground unload -if ([_item, GVAR(interactionVehicle), ACE_player] call FUNC(canUnloadItem)) then { - private _size = [_item] call FUNC(getSizeItem); +if ([_item, GVAR(interactionVehicle), _unit] call FUNC(canUnloadItem)) then { + // Close the cargo menu + closeDialog 0; + + private _duration = GVAR(loadTimeCoefficient) * (_item call FUNC(getSizeItem)); + + // If unload time is 0, don't show a progress bar + if (_duration <= 0) exitWith { + ["ace_unloadCargo", [_item, GVAR(interactionVehicle), _unit]] call CBA_fnc_localEvent; + }; [ - GVAR(loadTimeCoefficient) * _size, - [_item, GVAR(interactionVehicle), ACE_player], - {TRACE_1("unload finish",_this); ["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent}, - {TRACE_1("unload fail",_this);}, - localize LSTRING(UnloadingItem), + _duration, + [_item, GVAR(interactionVehicle), _unit], { - (_this select 0) params ["_item", "_target", "_player"]; + TRACE_1("unload finish",_this); - (alive _target) - && {locked _target < 2} - && {([_player, _target] call EFUNC(interaction,getInteractionDistance)) < MAX_LOAD_DISTANCE} - && {_item in (_target getVariable [QGVAR(loaded), []])} + ["ace_unloadCargo", _this select 0] call CBA_fnc_localEvent; + }, + { + TRACE_1("unload fail",_this); + }, + format [LLSTRING(unloadingItem), [_item, 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 every frame }, ["isNotSwimming"] ] call EFUNC(common,progressBar); } else { - private _displayName = [_item, true] call FUNC(getNameItem); - - [[LSTRING(UnloadingFailed), _displayName], 3] call EFUNC(common,displayTextStructured); + [[LSTRING(unloadingFailed), [_item, true] call FUNC(getNameItem)], 3] call EFUNC(common,displayTextStructured); }; diff --git a/addons/cargo/functions/fnc_unloadCarryItem.sqf b/addons/cargo/functions/fnc_unloadCarryItem.sqf index 3b97cf1599..7baac21b73 100644 --- a/addons/cargo/functions/fnc_unloadCarryItem.sqf +++ b/addons/cargo/functions/fnc_unloadCarryItem.sqf @@ -4,17 +4,18 @@ * Dragging integration. Unloader starts carrying unloaded object. * * Arguments: - * 0: Unloader - * 1: Item + * 0: Unit doing the unloading + * 1: Unloaded item * * Return Value: * None * * Example: - * [player, object] call ace_cargo_fnc_unloadCarryItem + * [player, cursorObject] call ace_cargo_fnc_unloadCarryItem * * Public: No */ + params ["_unloader", "_object"]; TRACE_2("unloadCarryItem-start",_unloader,_object); @@ -24,17 +25,21 @@ if (!GVAR(carryAfterUnload) || {getNumber (configOf _object >> QGVAR(blockUnload // When unloading attached objects, this code will run before server has finished moving object to the safe position [{ params ["_unloader", "_object"]; + (_unloader distance _object) < 10 }, { params ["_unloader", "_object"]; + TRACE_2("unloadCarryItem-unloaded",_unloader,_object); + if ([_unloader, _object] call EFUNC(dragging,canCarry)) exitWith { [_unloader, _object] call EFUNC(dragging,startCarry); }; + if ([_unloader, _object] call EFUNC(dragging,canDrag)) exitWith { [_unloader, _object] call EFUNC(dragging,startDrag); }; -}, _this, 1.0, { // delay is based on how long it will take server event to trigger and take effect - // not a hard error if this fails, could have just unloaded to other side of vehicle because of findSafePos +}, _this, 1, { // Delay is based on how long it will take server event to trigger and take effect + // Not a hard error if this fails, could have just unloaded to other side of vehicle because of findSafePos TRACE_1("unloadCarryItem-failed to unload nearby player",_this); }] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/cargo/functions/fnc_unloadItem.sqf b/addons/cargo/functions/fnc_unloadItem.sqf index 93fdfaa099..7580de8488 100644 --- a/addons/cargo/functions/fnc_unloadItem.sqf +++ b/addons/cargo/functions/fnc_unloadItem.sqf @@ -1,58 +1,92 @@ #include "..\script_component.hpp" /* * Author: Glowbal, ViperMaul - * Unload object from vehicle. + * Unloads an object from a vehicle. * * Arguments: - * 0: Item - * 1: Vehicle + * 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 was unloaded + * Object unloaded * * Example: - * [object, vehicle] call ace_cargo_fnc_unloadItem + * ["ACE_Wheel", cursorObject] call ace_cargo_fnc_unloadItem * * Public: Yes */ -params ["_item", "_vehicle", ["_unloader", objNull]]; -TRACE_3("params",_item,_vehicle,_unloader); +params [["_item", "", [objNull, ""]], ["_vehicle", objNull, [objNull]], ["_unloader", objNull, [objNull]], ["_deploy", []]]; +_deploy params ["_emptyPosAGL", "_direction"]; -//This covers testing vehicle stability and finding a safe position -private _emptyPosAGL = [_vehicle, _item, _unloader] call EFUNC(common,findUnloadPosition); -TRACE_1("findUnloadPosition",_emptyPosAGL); +TRACE_4("params",_item,_vehicle,_unloader,_deploy); -if ((count _emptyPosAGL) != 3) exitWith { - TRACE_4("Could not find unload pos",_vehicle,getPosASL _vehicle,isTouchingGround _vehicle,speed _vehicle); - if ((!isNull _unloader) && {_unloader == ACE_player}) then { - //display text saying there are no safe places to exit the vehicle - [localize ELSTRING(common,NoRoomToUnload)] call EFUNC(common,displayTextStructured); - }; - false +// Get config sensitive case name +if (_item isEqualType "") then { + _item = _item call EFUNC(common,getConfigName); }; +// Check if item is actually part of cargo private _loaded = _vehicle getVariable [QGVAR(loaded), []]; if !(_item in _loaded) exitWith { - ERROR_3("Tried to unload item [%1] not in vehicle[%2] cargo[%3]", _item, _vehicle, _loaded); - false + ERROR_3("Tried to unload item [%1] not in vehicle[%2] cargo[%3]",_item,_vehicle,_loaded); + + false // return }; +// Check if item can be unloaded +private _itemSize = _item call FUNC(getSizeItem); + +if (_itemSize < 0) exitWith { + false // return +}; + +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 + if (!isNull _unloader && {_unloader == ACE_player}) then { + [ELSTRING(common,NoRoomToUnload)] call EFUNC(common,displayTextStructured); + }; + + false // return +}; + +// Unload item from cargo _loaded deleteAt (_loaded find _item); _vehicle setVariable [QGVAR(loaded), _loaded, true]; -private _space = [_vehicle] call FUNC(getCargoSpaceLeft); -private _itemSize = [_item] call FUNC(getSizeItem); -_vehicle setVariable [QGVAR(space), (_space + _itemSize), true]; +// Update cargo space remaining +private _cargoSpace = _vehicle call FUNC(getCargoSpaceLeft); +_vehicle setVariable [QGVAR(space), _cargoSpace + _itemSize, true]; 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 @@ -62,8 +96,26 @@ if (_object isEqualType objNull) then { [QEGVAR(zeus,addObjects), [[_object], _objectCurators]] call CBA_fnc_serverEvent; }; + + // Reenable UAV crew + private _UAVCrew = _object getVariable [QGVAR(isUAV), []]; + + if (_UAVCrew isNotEqualTo []) then { + // Reenable AI + { + [_x, false] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _object setVariable [QGVAR(isUAV), nil, true]; + }; } else { _object = createVehicle [_item, _emptyPosAGL, [], 0, "NONE"]; + + // 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; @@ -71,8 +123,11 @@ 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; -true + +true // return diff --git a/addons/cargo/functions/fnc_validateCargoSpace.sqf b/addons/cargo/functions/fnc_validateCargoSpace.sqf deleted file mode 100644 index f5b976c395..0000000000 --- a/addons/cargo/functions/fnc_validateCargoSpace.sqf +++ /dev/null @@ -1,37 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Glowbal - * Validate the vehicle cargo space. - * - * Arguments: - * 0: Object - * - * Return Value: - * None - * - * Example: - * [object] call ace_cargo_fnc_validateCargoSpace - * - * Public: No - */ - -params ["_vehicle"]; -TRACE_1("params",_vehicle); - -private _loaded = _vehicle getVariable [QGVAR(loaded), []]; - -private _newLoaded = []; -private _totalSpaceOccupied = 0; -{ - if ((_x isEqualType "") || {!isNull _x}) then { - _newLoaded pushback _x; - _totalSpaceOccupied = _totalSpaceOccupied + ([_x] call FUNC(getSizeItem)); - }; - true -} count _loaded; - -if (count _loaded != count _newLoaded) then { - _vehicle setVariable [QGVAR(loaded), _newLoaded, true]; -}; - -_vehicle setVariable [QGVAR(space), getNumber (configOf _vehicle >> QGVAR(space)) - _totalSpaceOccupied, true]; diff --git a/addons/cargo/initSettings.inc.sqf b/addons/cargo/initSettings.inc.sqf new file mode 100644 index 0000000000..4f92934d46 --- /dev/null +++ b/addons/cargo/initSettings.inc.sqf @@ -0,0 +1,61 @@ +private _category = [ELSTRING(main,Category_Logistics), LSTRING(openMenu)]; + +[ + QGVAR(enable), + "CHECKBOX", + [LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(loadTimeCoefficient), + "SLIDER", + [LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)], + _category, + [0, 10, 5, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(paradropTimeCoefficent), + "SLIDER", + [LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)], + _category, + [0, 10, 2.5, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(openAfterUnload), + "LIST", + [LSTRING(openAfterUnload), LSTRING(openAfterUnload_description)], + _category, + [[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0] +] call CBA_fnc_addSetting; + +[ + QGVAR(carryAfterUnload), + "CHECKBOX", + [LSTRING(carryAfterUnload), LSTRING(carryAfterUnload_description)], + _category, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(enableDeploy), + "CHECKBOX", + [LSTRING(enableDeploy), LSTRING(enableDeploy_description)], + _category, + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(enableRename), + "CHECKBOX", + [LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)], + _category, + true +] call CBA_fnc_addSetting; diff --git a/addons/cargo/initSettings.sqf b/addons/cargo/initSettings.sqf deleted file mode 100644 index e971d2d9c7..0000000000 --- a/addons/cargo/initSettings.sqf +++ /dev/null @@ -1,53 +0,0 @@ -[ - QGVAR(enable), "CHECKBOX", - [LSTRING(ModuleSettings_enable), LSTRING(ModuleSettings_enable_Description)], - [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(openMenu)], - true, - true, - {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_fnc_addSetting; - -[ - QGVAR(loadTimeCoefficient), "SLIDER", - [LSTRING(loadTimeCoefficient), LSTRING(loadTimeCoefficient_description)], - [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(openMenu)], - [0, 10, 5, 1], - true, - {[QGVAR(loadTimeCoefficient), _this, true] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_fnc_addSetting; - -[ - QGVAR(paradropTimeCoefficent), "SLIDER", - [LSTRING(paradropTimeCoefficent), LSTRING(paradropTimeCoefficent_description)], - [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(openMenu)], - [0, 10, 2.5, 1], - true, - {[QGVAR(paradropTimeCoefficent), _this, true] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_fnc_addSetting; - -[ - QGVAR(openAfterUnload), "LIST", - [LSTRING(openAfterUnload), LSTRING(openAfterUnload_description)], - [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(openMenu)], - [[0, 1, 2, 3], [ELSTRING(common,never), LSTRING(unloadObject), LSTRING(paradropButton), ELSTRING(common,both)], 0], - false, - {[QGVAR(openAfterUnload), _this, true] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_fnc_addSetting; - -[ - QGVAR(enableRename), "CHECKBOX", - [LSTRING(ModuleSettings_enableRename), LSTRING(ModuleSettings_enableRename_Description)], - [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(openMenu)], - true, - false, - {[QGVAR(enableRename), _this, true] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_fnc_addSetting; - -[ - QGVAR(carryAfterUnload), "CHECKBOX", - [LSTRING(carryAfterUnload), LSTRING(carryAfterUnload_description)], - [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(openMenu)], - true, - false, - {[QGVAR(carryAfterUnload), _this] call EFUNC(common,cbaSettings_settingChanged)} -] call CBA_fnc_addSetting; diff --git a/addons/cargo/menu.hpp b/addons/cargo/menu.hpp index 03761eb73d..1811369d7d 100644 --- a/addons/cargo/menu.hpp +++ b/addons/cargo/menu.hpp @@ -4,7 +4,7 @@ class GVAR(menu) { idd = 314614; movingEnable = 1; onLoad = QUOTE([_this select 0] call FUNC(onMenuOpen)); - onUnload = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(menuDisplay)),nil)];); + onUnload = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(menuDisplay),nil)]); class controlsBackground { class HeaderBackground: ACE_gui_backgroundBase { idc = -1; @@ -17,10 +17,10 @@ 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])"}; + colorBackground[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; }; }; @@ -46,8 +46,8 @@ class GVAR(menu) { w = "13 * (((safezoneW / safezoneH) min 1.2) / 40)"; h = "1 * ((((safezoneW / safezoneH) min 1.2) / 1.2) / 25)"; style = ST_CENTER; - colorText[] = {1, 1, 1.0, 0.9}; - colorBackground[] = {0,0,0,0}; + colorText[] = {1, 1, 1, 0.9}; + colorBackground[] = {0, 0, 0, 0}; SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1.2)"; text = ""; }; @@ -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)"; @@ -83,12 +83,12 @@ class GVAR(menu) { animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; color[] = {1, 1, 1, 1}; - color2[] = {0,0,0, 1}; - colorBackgroundFocused[] = {1,1,1,1}; - colorBackground[] = {1,1,1,1}; - colorbackground2[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,1}; - colorFocused[] = {0,0,0,1}; + color2[] = {0, 0, 0, 1}; + colorBackgroundFocused[] = {1, 1, 1, 1}; + colorBackground[] = {1, 1, 1, 1}; + colorbackground2[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 1}; + colorFocused[] = {0, 0, 0, 1}; periodFocus = 1; periodOver = 1; action = QUOTE(closeDialog 0); @@ -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)"; - action = QUOTE([] call FUNC(startUnload)); + 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/renameMenu.hpp b/addons/cargo/renameMenu.hpp index ac841e9ff1..b6acc9ad4e 100644 --- a/addons/cargo/renameMenu.hpp +++ b/addons/cargo/renameMenu.hpp @@ -3,8 +3,8 @@ class GVAR(renameMenu) { idd = 314615; movingEnable = 0; - onLoad = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(menuDisplay)),_this select 0)];); - onUnload = QUOTE(uiNamespace setVariable [ARR_2(QUOTE(QGVAR(menuDisplay)),nil)];); + onLoad = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(menuDisplay),_this select 0)]); + onUnload = QUOTE(uiNamespace setVariable [ARR_2(QQGVAR(menuDisplay),nil)]); class controlsBackground { class HeaderBackground: ACE_gui_backgroundBase { idc = -1; @@ -20,7 +20,7 @@ class GVAR(renameMenu) { h = "2.9 * ((((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])"}; + colorBackground[] = {0, 0, 0, "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; }; }; @@ -36,11 +36,11 @@ class GVAR(renameMenu) { font = "RobotoCondensed"; SizeEx = "(((((safezoneW / safezoneH) min 1.2) / 1.2) / 25) * 1)"; colorText[] = {0.95, 0.95, 0.95, 0.75}; - colorBackground[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.69])","(profilenamespace getVariable ['GUI_BCG_RGB_G',0.75])","(profilenamespace getVariable ['GUI_BCG_RGB_B',0.5])", "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; + colorBackground[] = {"(profilenamespace getVariable ['GUI_BCG_RGB_R',0.69])", "(profilenamespace getVariable ['GUI_BCG_RGB_G',0.75])", "(profilenamespace getVariable ['GUI_BCG_RGB_B',0.5])", "(profilenamespace getVariable ['GUI_BCG_RGB_A',0.9])"}; text = CSTRING(renameObjectUI); }; class edit: ACE_gui_editBase { - onLoad = QUOTE((_this select 0) ctrlSetText (GVAR(interactionVehicle) getVariable [ARR_2(QUOTE(QGVAR(customName)),'')])); + onLoad = QUOTE((_this select 0) ctrlSetText (GVAR(interactionVehicle) getVariable [ARR_2(QQGVAR(customName),'')])); idc = 100; canModify = 1; x = "13.1 * (((safezoneW / safezoneH) min 1.2) / 40) + (safezoneX + (safezoneW - ((safezoneW / safezoneH) min 1.2))/2)"; @@ -65,12 +65,12 @@ class GVAR(renameMenu) { animTexturePressed = "#(argb,8,8,3)color(1,1,1,1)"; animTextureDefault = "#(argb,8,8,3)color(1,1,1,1)"; color[] = {1, 1, 1, 1}; - color2[] = {0,0,0, 1}; - colorBackgroundFocused[] = {1,1,1,1}; - colorBackground[] = {1,1,1,1}; - colorbackground2[] = {1,1,1,1}; - colorDisabled[] = {1,1,1,1}; - colorFocused[] = {0,0,0,1}; + color2[] = {0, 0, 0, 1}; + colorBackgroundFocused[] = {1, 1, 1, 1}; + colorBackground[] = {1, 1, 1, 1}; + colorbackground2[] = {1, 1, 1, 1}; + colorDisabled[] = {1, 1, 1, 1}; + colorFocused[] = {0, 0, 0, 1}; periodFocus = 1; periodOver = 1; action = QUOTE(closeDialog 0); diff --git a/addons/cargo/script_component.hpp b/addons/cargo/script_component.hpp index d5cee60c39..00629c73d2 100644 --- a/addons/cargo/script_component.hpp +++ b/addons/cargo/script_component.hpp @@ -19,7 +19,3 @@ #define MAX_LOAD_DISTANCE 5 #define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) - -// Default cargo size is -1 as 0 is a valid size -#define CARGO_SIZE(classname) GET_NUMBER(configFile >> "CfgVehicles" >> (classname) >> QGVAR(size),-1) -#define CARGO_SPACE(classname) GET_NUMBER(configFile >> "CfgVehicles" >> (classname) >> QGVAR(space),0) diff --git a/addons/cargo/stringtable.xml b/addons/cargo/stringtable.xml index 62f2603791..8e16f50090 100644 --- a/addons/cargo/stringtable.xml +++ b/addons/cargo/stringtable.xml @@ -27,22 +27,65 @@ Descargar Scarica Décharger - 下ろす + 降ろす 내리기 卸載 卸载 Boşalt + + Deploy + Piazza + Разместить + 配置する + 배치하기 + Déployer + Aufstellen + Desplegar + + + 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 Renommé en :<br/>%1 Переименовано в:<br/>%1 - Neu Bewaffnet: <br/>%1 + Neu umbenannt zu: <br/>%1 + Rinominato in: <br/>%1 Nazwa zmieniona na:<br/>%1 重命名为:<br/>%1 %1(으)로 명칭을 바꿈 Renombrado a:<br/>%1 + Renomeado para: <br/>%1 Custom name has been cleared. @@ -50,10 +93,12 @@ Le nom personnalisé a été supprimé. Пользовательское название удалено. Eigener Name wurde gelöscht. + Nome personalizzato cancellato. Własna nazwa została usunięta 自定义名称已被清除。 임의로 지은 명칭을 지웠습니다. El nombre personalizado ha sido borrado. + O nome personalizado foi apagado. Set New Name: @@ -61,10 +106,12 @@ Définir un nouveau nom : Задать новое название: Neuen Namen setzen: + Imposta nome personalizzato: Ustaw nową nazwę: 设定新名称: 새로운 명칭 설정: Establecer nuevo nombre: + Definir novo nome: Enable Rename Action @@ -72,21 +119,25 @@ Possibilité de renommage Вкл. возможность переименования Aktiviere Umbenennungs-Aktion + Attiva azione di rinomina Włącz możliwość zmiany nazwy 启用重命名动作 새로 명칭 짓기 행동 활성화 Habilitar renombrado + Habilitar ação de renomear Enables the rename action for renamable objects. - 名前変更が可能なオブジェクトに対して、名前変更動作を有効化します。 + 名前変更が可能なオブジェクトに対して、名前変更アクションを有効化します。 Active la possibilité de donner un nom personnalisé aux objets transportables (si renommables). Включает переименование для объектов, допускающих переименование. Aktiviert die Umbenennungs-Aktion für neu benennbare Objekte. + Attiva la funzione di rinomina per nuovi oggetti rinominabili. Włącza akcję zmiany nazwy dla obiektów z możliwością zmiany nazwy. 启用可重命名物体的重命名动作。 개체의 명칭을 새로 짓는 것을 허가합니다. Habilitar renombrado para los objetos renombrables. + Habilita a ação de renomear para objetos renomeáveis. Cargo @@ -96,9 +147,9 @@ Грузовой отсек Náklad Carga - Cargo + Carico Cargaison - カーゴ + 貨物 화물 貨物 货物 @@ -112,9 +163,9 @@ Грузовой отсек Menu nákladu Menu de carga - Menù Cargo + Menù del Carico Menu de cargaison - カーゴ メニュー + 貨物メニュー 화물 메뉴 貨物選單 货物菜单 @@ -128,9 +179,9 @@ Осталось мест: %1 Zbývající prostor: %1 Espacio de carga restante: %1 - Spazio cargo rimanente: %1 + Spazio di carico rimanente: %1 Espace de chargement restant : %1 - カーゴの空き容量: %1 + 貨物室の空き容量: %1 선적 공간 남음: %1 貨物剩餘空間: %1 货物剩余空间:%1 @@ -144,9 +195,9 @@ Вкл. модуль перевозки грузов Povolit náklad Habilitar carga - Abilita Cargo + Abilita Carico Activer la cargaison - カーゴを有効化 + 貨物を有効化 화물 활성화 啟用貨物裝載 启用货物装载 @@ -160,9 +211,9 @@ Включает модуль погрузки и перевозки грузов Habilitar la carga en el módulo de carga Umožňuje naložit předměty do nákladového prostoru vozidla - Abilita il modulo di caricamento in cargo + Abilita il modulo di caricamento nel carico Active la possibilité de charger du matériel dans un module de fret (véhicule/container). - カーゴ モジュールで積み込みを有効化 + 貨物積載モジュールを有効化 화물 모듈을 활성화합니다 啟用貨物裝載功能 启用货物装载功能 @@ -175,9 +226,9 @@ Перевозка грузов Nastavení nákladu Ajustes de carga - Impostazioni Cargo + Impostazioni Carico Paramètres de cargaison - カーゴ設定 + 貨物設定 화물 설정 貨物設定 货物设定 @@ -191,9 +242,9 @@ Конфигурирует настройки модуля перевозки грузов Configure los ajustes del módulo de carga Konfigurace nákladního modulu - Configura le impostazioni del modulo cargo + Configura le impostazioni del modulo carico Configure les paramètres du module de cargaison. - カーゴ モジュールの設定を構成 + 貨物モジュールの設定を変更します 화물 모듈의 환경 설정을 바꿉니다 配置貨物模塊設定 配置货物模块设定 @@ -209,7 +260,7 @@ %1<br/>caricato su<br/>%2 %1<br/>berakodva ide:<br/>%2 %1<br/>загружен в<br/>%2 - %1<br/>は<br/>%2へ積み込まれました + %1 を<br/>%2 に<br/>積み込みました %1은(는)<br/>%2 에 실림 %1<br/>裝載至<br/>%2 %1<br/>装载至<br/>%2 @@ -225,42 +276,30 @@ Hai scaricato<br/>%1 da<br/>%2 1%<br/>kirakodva ebből:<br/>%2 %1<br/>разгружен из<br/>%2 - <br/>%1が<br/>%2から降ろされました + %1 を<br/>%2 から<br/>降ろしました %1은(는)<br/>%2에서 내려짐 從<br/>%2卸載<br/>%1 从<br/>%2卸载<br/>%1 - Loading Cargo - Belade - Carregando carga - Ładowanie cargo - Nakládám - Погрузка - Caricando - Cargando - Chargement de la cargaison - カーゴへ積み込んでいます - 화물 싣기 - 裝載貨物中 - 正在装载货物 - Kargo Yükleniyor + Loading %1 into %2... + Cargando %1 en %2... + Caricando %1 in %2... + %1 を %2 に積み込んでいます・・・ + Загружаем %1 в %2... + %1을(를) %2에 싣는 중... + Chargement %1 dans %2... + %1 wird in %2 geladen... - Unloading Cargo - Entlade - Descarregando carga - Rozładowywanie cargo - Vykládám - Выгрузка - Scaricando - Descargando - Déchargement de la cargaison - カーゴから降ろしています - 화물 내리기 - 卸載貨物中 - 正在卸载货物 - Kargo Boşaltılıyor + Unloading %1 from %2... + Descargando %1 de %2... + Scaricando %1 da %2... + %1 を %2 から降ろしています・・・ + Выгружаем %1 из %2... + %1을(를) %2(으)로부터 내리는 중... + Déchargement %1 de %2... + %1 wird von %2 entladen... %1<br/>could not be loaded @@ -272,7 +311,7 @@ %1<br/>non può essere caricato %1<br/>no pudo ser cargado %1<br />n'a pas pu être chargé - %1<br/>は積み込めませんでした + %1 は<br/>積み込めませんでした %1을(를) 싣을 수가 없습니다 %1<br/>無法被裝載 %1<br/>无法被装载 @@ -288,39 +327,63 @@ %1<br/>non può essere scaricato %1<br/>no pudo ser descargado %1<br />n'a pas pu être déchargé - %1<br/>は降ろせませんでした + %1 は<br/>降ろせませんでした %1을(를) 하역할 수가 없습니다 %1<br/>無法被卸載 %1<br/>无法被卸载 %1<br/> kargo boşaltılamadı + + Can't be unloaded + Kann nicht entladen werden + Impossibile da scaricare + Ne peut pas être déchargé + 荷降ろし不可能です + 하역할 수가 없습니다 + Не может быть выгружен + No puede ser descargado + + + Cargo Size: %1 + Frachtgröße: %1 + Dimensione Carico: %1 + Encombrement fret: %1 + 貨物のサイズ: %1 + 화물 크기: %1 + Размер груза: %1 + Tamaño de carga: %1 + Custom Name カスタム名 Nom personnalisé Eigener Name + Nome Personalizzato Własna nazwa 自定义名称 임의 명칭 Собственное название Nombre personalizado + Nome personalizado Set a custom cargo name used in the cargo interface. - カーゴ欄で使われるカスタム名を設定します。 + 貨物インターフェイスで使用されるカスタム名を設定します。 Définit un nom de fret personnalisé qui sera visible dans le menu de cargaison. Установить пользовательское имя груза, используемое в интерфейсе погрузки. Definiere eigenen Frachtnamen, welcher im Frachtraum genutzt wird. + Definisce nome personalizzato, verrà mostrato nel menù del carico. Ustaw własną nazwę ładunku, używaną w menu ładunku. 设置货物界面中使用的一个自定义货物名称。 화물 인터페이스에 쓰일 화물의 명칭을 설정합니다. Establecer un nombre personalizado de carga en la interfaz de carga. + Defina um nome de carga personalizado usado na interface de carga. Cargo Space Frachtraum - Spazio Cargo - カーゴ スペース + Spazio di Carico + 貨物室の容量 貨物空間 货物空间 Przestrzeń ładunkowa @@ -336,7 +399,7 @@ The cargo space available in this vehicle/container Verfügbarer Frachtraum in diesem Fahrzeug/Container Lo spazio disponibile in questo veicolo/container - この車両/コンテナでカーゴ スペースを使えるようにします + この車両/コンテナで使用可能な貨物室の容量 設定此載具/集裝箱可裝載多少貨物 设定此载具/集装箱可装载多少货物 Dostępna przestrzeń ładunkowa w tym pojeździe/kontenerze @@ -350,8 +413,8 @@ Cargo Size Frachtgröße - Dimensioni Cargo - カーゴ サイズ + Dimensioni nel Carico + 貨物のサイズ 貨物的大小 货物的大小 Wielkość ładunku @@ -364,10 +427,10 @@ Kargo Boyutu - The cargo space required to hold this object (-1 for unloadable) + The cargo space required to hold this object (-1 for not loadable) Frachtraumgröße, welche zum Einladen dieses Objektes benötigt wird (-1 nicht einladbar) - Lo spazio del cargo necessita di mantenere questo oggetto (-1 per scaricabile) - オブジェクトを積載するのに必要なカーゴ スペース (-1 で積載不可) + Lo spazio di carico necessario per contenere questo oggetto (-1 per non caricabile) + このオブジェクトの積載に必要な貨物室の容量 (-1 で積載不可に) 此貨物會佔掉多少空間(設定-1的話此貨物就不能被裝載) 此货物会占掉多少空间(设定 -1 的话此货物就不能被装载) Wymagana przestrzeń ładunkowa dla tego obiektu (-1 dla niemożliwych do załadowania) @@ -411,8 +474,8 @@ Paradrop Time Coefficient Türlast Zeitfaktor - 空中投下までの時間係数 - Coefficente Tempo Lancio Paracadute + 空中投下の所要時間係数 + Coefficiente Tempo Lancio Aereo Coefficient du temps de paralargage 空投時間係數 空投时间系数 @@ -426,8 +489,8 @@ Modifier for how long it takes to paradrop a cargo item. Beeinflusst die zusätzliche Zeit für Türlastabwürfe. - カーゴ アイテムを空中投下するまでの時間を変更します。 - Modificato per quanto tempo ci impiega a paracadutare un oggetto cargo. + 貨物の空中投下に掛かる時間を変更します。 + Modifica quanto tempo viene impiegato per paracadutare oggetti dal carico. Modifie le temps nécessaire au paralargage d'une cargaison. 設定空投所需消耗的時間 设定空投所需消耗的时间。 @@ -441,9 +504,9 @@ Load Time Coefficient Ladezeitmultiplikator - 積載時間の係数 + 積載の所要時間係数 Współczynnik czasu załadowania - Coefficente Tempo Caricamento + Coefficiente Tempo Caricamento Коэф. времени погрузки Fator de tempo para carregar Coefficient du temps de chargement @@ -456,10 +519,10 @@ Modifies how long it takes to load/unload items.\nTime, in seconds, is the size of the item multiplied by this value. Gibt an, wie lange das Laden / Entladen von Gegenständen dauern soll.\nZeit in Sekunden, die mit der Größe des Gegenstandes multipliziert wird. - アイテムの積み下ろし作業にかかる時間を編集できます。\nアイテムの大きさにこの値が乗法され、時間 (秒) を変更できます。 + 貨物の積み込み/積み下ろしに掛かる時間を変更します。\n時間 (秒単位) は、貨物のサイズにこの値を掛けたものです。 Modyfikuje, jak długo zajmuje załadowywanie/wyładowywanie przedmiotów. \nCzasem, w sekundach, jest wielkość przedmiotu razy jego wartość. - Modifica quanto tempo ci impiega a caricare o scaricare gli oggetti.\n Tempo, in secondi, è la dimensione dell'oggetto moltiplicata per questo valore - Изменяет время для загрузки/выгрузки предметов. \n Время (сек) - это размер предмета, умноженный на это значение. + Modifica il tempo impiegato per caricare o scaricare gli oggetti.\nIl tempo, in secondi, equivale alla dimensione dell'oggetto moltiplicata per questo valore + Изменяет время для загрузки/выгрузки предметов. \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時間,以秒為單位,而物品的大小數值與這個係數成比。 @@ -471,46 +534,74 @@ Reopen Cargo Menu Kargo Menüsünü Tekrar Aç - カーゴ メニューを再度開く + 貨物メニューを再度開く Rouvrir le menu de cargaison Переоткрыть меню погрузки Frachtmenü erneut öffnen + Riapri Menù del Carico Ponownie otwórz menu załadunku 重新打开货物菜单 화물 메뉴 다시 열기 Reabrir menú de carga + Reabrir menu de carga Reopen the Cargo Menu after successful unload. Başarılı bir yük indirmeden sonra Kargo Menüsünü tekrar göster. - カーゴを降ろした後に再びカーゴ メニューを開きます。 + 貨物を降ろした後に再び貨物メニューを開きます。 Réouvre le menu de cargaison après un déchargement réussi. Переоткрыть меню погрузки после успешной выгрузки. Frachtmenü erneut öffnen, nach erfolgreichen Entladen. + Riapri il Menù del Carico dopo aver scaricato un oggetto con successo. Ponownie otwórz menu załadunku po udanym wyładowaniu. 成功卸货后,重新打开货物菜单。 화물을 성공적으로 내리고 난 다음 화물 메뉴를 열지 결정합니다. Reabrir menú de carga despues de una descarga satisfactoria. + Reabre o menu de carga após uma descarga bem sucedida. Carry After Unload 화물 내린 후 운반 Нести после выгрузки Llevar encima tras la descarga - 荷降ろし後の運搬 + 荷降ろし後に持ち運ぶ Niesienie Po Rozładowaniu Nach dem Entladen tragen + Trasporta dopo aver Scaricato Porter après déchargement + Transporte após descarregar Controls whether cargo items are carried or dragged after unloading. 화물 아이템을 내린 후 들거나 끌지 여부를 결정합니다. Нужно ли переносить или тащить предметы после их выгрузки. Controla si los objetos de carga son llevados encima o arrastrados despues de la descarga. - 荷降ろし後、貨物アイテムを運ぶか引きずるかを制御する。 + 荷降ろし後、貨物を運ぶか引きずるかを制御する。 Kontroluje, czy przedmioty z ładunku są przenoszone lub ciągnięte po ich wyładowaniu. Steuert, ob Objekte nach dem Entladen getragen oder gezogen werden. + Determina se un oggetto verrà subito trasportato o trascinato dopo essere stato scaricato. 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 + Включить размещение + 配置機能を有効化 + 배치 활성화 + Permettre le placement + Aktiviere Aufbauen + Habilitar despliegue + + + Controls whether cargo items can be unloaded via the deploy method. + Determina se oggetti in carico possono essere scaricati e piazzati direttamente. + Определяет, можно ли выгружать грузы с помощью метода размещения. + 配置機能を介して貨物アイテムを降ろすことが出来るかどうかを制御します。 + 배치 방법을 통해 화물 아이템을 내릴 수 있는지 여부를 제어합니다. + Contrôler si les éléments de cargaison peuvent être déchargés via la méthode de déploiement. + Steuert, ob Frachtgegenstände über die Aufbaumethode entladen werden können. + Controla si los objetos de la carga pueden ser descargados mediante el método de despliegue. diff --git a/addons/casings/CfgVehicles.hpp b/addons/casings/CfgVehicles.hpp new file mode 100644 index 0000000000..73d06bc0ac --- /dev/null +++ b/addons/casings/CfgVehicles.hpp @@ -0,0 +1,6 @@ +class CfgVehicles { + class FxCartridge; + class FxCartridge_65_caseless: FxCartridge { + GVAR(model) = ""; // note: the vanilla 6.5 caseless don't actually use this, just being safe + }; +}; diff --git a/addons/casings/XEH_postInit.sqf b/addons/casings/XEH_postInit.sqf index e91ab96c0d..47737c4e04 100644 --- a/addons/casings/XEH_postInit.sqf +++ b/addons/casings/XEH_postInit.sqf @@ -1,7 +1,12 @@ #include "script_component.hpp" -if (!hasInterface || !GVAR(enabled)) exitWith {}; +if (!hasInterface) exitWith {}; -GVAR(cachedCasings) = createHashMap; -GVAR(casings) = []; -["CAManBase", "FiredMan", {call FUNC(createCasing)}] call CBA_fnc_addClassEventHandler; +["CBA_settingsInitialized", { + if (!GVAR(enabled)) exitWith {}; + + GVAR(cachedCasings) = createHashMap; + GVAR(casings) = []; + + ["CAManBase", "FiredMan", LINKFUNC(createCasing)] call CBA_fnc_addClassEventHandler; +}] call CBA_fnc_addEventHandler; diff --git a/addons/casings/XEH_preInit.sqf b/addons/casings/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/casings/XEH_preInit.sqf +++ b/addons/casings/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/casings/config.cpp b/addons/casings/config.cpp index 815048a082..29d0b7cb89 100644 --- a/addons/casings/config.cpp +++ b/addons/casings/config.cpp @@ -15,3 +15,4 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/casings/functions/fnc_createCasing.sqf b/addons/casings/functions/fnc_createCasing.sqf index 22347d36a7..fe35ad5945 100644 --- a/addons/casings/functions/fnc_createCasing.sqf +++ b/addons/casings/functions/fnc_createCasing.sqf @@ -20,31 +20,30 @@ params ["_unit", "", "", "", "_ammo"]; if (!isNull objectParent _unit) exitWith {}; -private _modelPath = GVAR(cachedCasings) get _ammo; -if (isNil "_modelPath") then { +private _modelPath = GVAR(cachedCasings) getOrDefaultCall [_ammo, { private _cartridge = getText (configFile >> "CfgAmmo" >> _ammo >> "cartridge"); - //Default cartridge is a 5.56mm model - _modelPath = switch (_cartridge) do { - case "FxCartridge_9mm": { "A3\Weapons_f\ammo\cartridge_small.p3d" }; - case "FxCartridge_65": { "A3\weapons_f\ammo\cartridge_65.p3d" }; - case "FxCartridge_762": { "A3\weapons_f\ammo\cartridge_762.p3d" }; - case "FxCartridge_762x39": { "A3\weapons_f_enoch\ammo\cartridge_762x39.p3d" }; - case "FxCartridge_93x64_Ball": { "A3\Weapons_F_Mark\Ammo\cartridge_93x64.p3d" }; - case "FxCartridge_338_Ball": { "A3\Weapons_F_Mark\Ammo\cartridge_338_LM.p3d" }; - case "FxCartridge_338_NM": { "A3\Weapons_F_Mark\Ammo\cartridge_338_NM.p3d" }; - case "FxCartridge_127": { "A3\weapons_f\ammo\cartridge_127.p3d" }; - case "FxCartridge_127x54": { "A3\Weapons_F_Mark\Ammo\cartridge_127x54.p3d" }; - case "FxCartridge_slug": { "A3\weapons_f\ammo\cartridge_slug.p3d" }; - case "FxCartridge_12Gauge_HE_lxWS": { "lxWS\weapons_1_f_lxws\Ammo\cartridge_he_lxws.p3d" }; - case "FxCartridge_12Gauge_Slug_lxWS": { "lxWS\weapons_1_f_lxws\Ammo\cartridge_slug_lxws.p3d" }; - case "FxCartridge_12Gauge_Smoke_lxWS": { "lxWS\weapons_1_f_lxws\Ammo\cartridge_smoke_lxws.p3d" }; - case "FxCartridge_12Gauge_Pellet_lxWS": { "lxWS\weapons_1_f_lxws\Ammo\cartridge_pellet_lxws.p3d" }; - case "": { "" }; - default { "A3\Weapons_f\ammo\cartridge.p3d" }; + if (_cartridge == "") then { // return (note: can't use exitWith) + "" + } else { + private _cartridgeConfig = configFile >> "CfgVehicles" >> _cartridge; + + // if explicitly defined, use ACE's config + if (isText (_cartridgeConfig >> QGVAR(model))) exitWith { + getText (_cartridgeConfig >> QGVAR(model)) + }; + // use casing's default model + private _model = getText (_cartridgeConfig >> "model"); + if ("a3\weapons_f\empty" in toLowerANSI _model) exitWith { "" }; + + // Add file extension if missing (fileExists needs file extension) + if ((_model select [count _model - 4]) != ".p3d") then { + _model = _model + ".p3d"; + }; + + ["", _model] select (fileExists _model) }; - GVAR(cachedCasings) set [_ammo, _modelPath]; -}; +}, true]; if (_modelPath isEqualTo "") exitWith {}; diff --git a/addons/casings/initSettings.sqf b/addons/casings/initSettings.inc.sqf similarity index 100% rename from addons/casings/initSettings.sqf rename to addons/casings/initSettings.inc.sqf diff --git a/addons/casings/stringtable.xml b/addons/casings/stringtable.xml index d08d46d7a2..bf30ac36d9 100644 --- a/addons/casings/stringtable.xml +++ b/addons/casings/stringtable.xml @@ -6,22 +6,26 @@ ACE 薬莢 ACE Łuski ACE 탄피 + ACE Bossoli ACE 弹壳 ACE Гильзы ACE Casquillos ACE Patronenhülsen ACE Douilles + ACE Cartuchos Casings Enabled 薬莢の有効化 Łuski włączone + Abilita Bossoli 탄피 활성화 开启弹壳生成 Гильзы включены Habilitar Casquillos Patronenhülsen aktiviert Douilles activées + Cartuchos habilitados Enable persistent casings (POTENTIAL performance impact on old/weak systems) @@ -32,7 +36,9 @@ Включить постоянные гильзы (ПОТЕНЦИАЛЬНО может повлиять на производительность на старых/слабых системах) Habilitar persistencia de casquillos (POTENCIAL impacto en el rendimiento de ordenadores antiguos o no potentes) Persistente Patronenhülsen aktivieren (POTENZIELLE Leistungseinbußen bei alten/schwachen Systemen) + Abilita bossoli persistenti (POTENZIALE impatto sulla perfomance su sistemi vecchi/deboli) Active la persistance des douilles (POTENTIEL impact sur les performances sur les anciens/faibles systèmes) + Habilitar persistência de cartuchos (POTENCIAL impacto no desempenho de sistemas antigos/fracos) Maximum casings @@ -43,7 +49,9 @@ Макс. кол-во гильз Casquillos máximos Maximale Patronenhülsen + Numero massimo di bossoli Nombre maximum de douilles + Máxima de cartuchos Maximum amount of casings to display @@ -54,7 +62,9 @@ Максимальное количество гильз для отображения Máxima cantidad de casquillos para mostrar Maximale Anzahl an Patronenhülsen, die angezeigt werden + Numero massimo di bossoli renderizzati Nombre maximum de douilles à afficher + Quantidade máxima de cartuchos para exibir diff --git a/addons/chemlights/XEH_postInit.sqf b/addons/chemlights/XEH_postInit.sqf index 6b22de4a3c..b40ffb764e 100644 --- a/addons/chemlights/XEH_postInit.sqf +++ b/addons/chemlights/XEH_postInit.sqf @@ -2,6 +2,6 @@ if (!hasInterface) exitWith {}; -["ace_firedPlayer", DFUNC(throwEH)] call CBA_fnc_addEventHandler; -// ["ace_firedPlayerNonLocal", DFUNC(throwEH)] call CBA_fnc_addEventHandler; -// ["ace_firedNonPlayer", DFUNC(throwEH)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(throwEH)] call CBA_fnc_addEventHandler; +// ["ace_firedPlayerNonLocal", LINKFUNC(throwEH)] call CBA_fnc_addEventHandler; +// ["ace_firedNonPlayer", LINKFUNC(throwEH)] call CBA_fnc_addEventHandler; diff --git a/addons/chemlights/stringtable.xml b/addons/chemlights/stringtable.xml index 3454acd9d8..76f937df61 100644 --- a/addons/chemlights/stringtable.xml +++ b/addons/chemlights/stringtable.xml @@ -35,12 +35,12 @@ %1<br/>Prepared - %1<br/>を使った + %1 を<br/>使った %1<br/>Przygotowany %1<br/>vorbereitet %1<br/>준비됨 %1<br/>prêt - %1 <br/> Preparata + %1 <br/>Preparata %1<br/>已使用 %1<br/>已使用 %1<br/>Приготовлен @@ -51,12 +51,12 @@ [ACE] Chemlights - [ACE] ケミライト + [ACE] ケミカルライト [ACE] Świetliki [ACE] Knicklichter [ACE] 화학조명 [ACE] Cyalumes - [ACE] Luci chimiche + [ACE] Luci Chimiche [ACE] 螢光棒 [ACE] 荧光棒 [ACE] Химсвет @@ -67,7 +67,7 @@ Chemlight (Orange) - ケミライト (オレンジ) + ケミカルライト(橙) Świetlik (pomarańczowy) Knicklicht (orange) 화학조명 (주황) @@ -83,7 +83,7 @@ Orange Light - オレンジ色 + 橙ライト Pomarańczowe światło Oranges Knicklicht 주황색 @@ -99,7 +99,7 @@ Type: Light - Orange<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - オレンジ<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 橙<br />弾薬: 1<br />使用: 手 Typ: Światło - pomarańczowe<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - orange<br />Anzahl: 1<br />Benutzt in: Hand 종류: 밝은 오렌지<br />수량: 1<br />사용처: 손 @@ -115,7 +115,7 @@ Chemlight (White) - ケミライト (白) + ケミカルライト(白) Świetlik (biały) Knicklicht (weiß) 화학조명 (하양) @@ -131,7 +131,7 @@ White Light - 白色 + 白ライト Białe światło Weißes Knicklicht 하얀색 @@ -147,7 +147,7 @@ Type: Light - White<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - 白<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 白<br />弾薬: 1<br />使用: 手 Typ: Światło - białe<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - weiß<br />Anzahl: 1<br />Benutzt in: Hand 종류: 하얀색<br />수량: 1<br />사용처: 손 @@ -163,12 +163,12 @@ Chemlight (Hi Red) - ケミライト (高輝度 赤) + ケミカルライト(高輝度 赤) Świetlik (jaskrawy czerwony) Knicklicht (rot, hell) 화학조명 (밝은 빨간색) Cyalume HL (rouge) - Luce chimica (Hi Rossa) + Luce chimica (Rossa Intensa) 螢光棒 (超亮紅色) 荧光棒(高亮红色) Химсвет (ярко-красный) @@ -179,12 +179,12 @@ Red Hi Light - 高輝度の赤色 + 赤ライト 高輝度 Jaskrawe czerwone światło Helles, rotes Knicklicht 밝은 빨간색 Lum. rouge HL - Luce Hi Rossa + Luce Rossa Intensa 超亮紅色光 高亮红色光 Яркий красный свет @@ -195,12 +195,12 @@ Type: Light - Red Hi (30 minute)<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - 高輝度 赤 (30分間)<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 高輝度 赤 (30分間)<br />弾薬: 1<br />使用: 手 Typ: Światło - jaskrawe czerwone (30 minut)<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - rot, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand 종류: 밝은 빨간색 (30분)<br />수량: 1<br />사용처: 손 Type : lumière HL (30 minutes) - Rouge<br />Munitions : 1<br />Application : main - Tipo: Luce - Rossa Hi (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano + Tipo: Luce - Rossa Intensa (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 超亮紅色 (30分鐘)<br />發數: 1<br />使用於: 手 类型:光—高亮红色(30分钟)<br />发数:1<br />使用于:手 Тип: Свет - ярко-красный (30 минут)<br />1 штука<br />В руках @@ -211,12 +211,12 @@ Chemlight (Hi Yellow) - ケミライト (高輝度 黄) + ケミカルライト(高輝度 黄) Świetlik (jaskrawy żółty) Knicklicht (gelb, hell) 화학조명 (밝은 노란색) Cyalume HL (jaune) - Luce chimica (Hi Gialla) + Luce chimica (Gialla Intensa) 螢光棒 (超亮黃色) 荧光棒(高亮黄色) Химсвет (ярко-жёлтый) @@ -227,12 +227,12 @@ Yellow Hi Light - 高輝度の黄色 + 黄ライト 高輝度 Jaskrawe żółte światło Helles, gelbes Knicklicht 밝은 노란색 Lum. jaune HL - Luce Hi Gialla + Luce Gialla Intensa 超亮黃色光 高亮黄色光 Яркий жёлтый свет @@ -243,12 +243,12 @@ Type: Light - Yellow Hi (30 minute)<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - 高輝度 黄 (30分間)<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 高輝度 黄 (30分間)<br />弾薬: 1<br />使用: 手 Typ: Światło - jaskrawe żółte (30 minut)<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - gelb, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand 종류: 밝은 노란색 (30분)<br />수량: 1<br />사용처: Hand Type : lumière HL (30 minutes) - Jaune<br />Munitions : 1<br />Application : main - Tipo: Luce - Gialla Hi (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano + Tipo: Luce - Gialla Intensa (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 超亮黃色 (30分鐘)<br />發數: 1<br />使用於: 手 类型:光—高亮黄色(30分钟)<br />发数:1<br />使用于:手 Тип: Свет - ярко-жёлтый (30 минут)<br />1 штука<br />В руках @@ -259,12 +259,12 @@ Chemlight (Hi White) - ケミライト (高輝度 白) + ケミカルライト(高輝度 白) Świetlik (jaskrawy biały) Knicklicht (weiß, hell) 화학조명 (밝은 하얀색) Cyalume HL (blanc) - Luce chimica (Hi Bianca) + Luce chimica (Bianca Intensa) 螢光棒 (超亮白色) 荧光棒(高亮白色) Химсвет (ярко-белый) @@ -275,12 +275,12 @@ White Hi Light - 高輝度の白色 + 白ライト 高輝度 Jaskrawe białe światło Helles, weißes Knicklicht 밝은 하얀색 Lum. blanche HL - Luce Hi Bianca + Luce Bianca Intensa 超亮白色光 高亮白色光 Яркий белый свет @@ -291,12 +291,12 @@ Type: Light - White Hi (30 minute)<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - 高輝度 白 (30分間)<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 高輝度 白 (30分間)<br />弾薬: 1<br />使用: 手 Typ: Światło - jaskrawe białe (30 minut)<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - weiß, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand 종류: 밝은 하얀색 (30분)<br />수량: 1<br />사용처: 손 Type : lumière HL (30 minutes) - Blanche<br />Munitions : 1<br />Application : main - Tipo: Luce - Bianca Hi (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano + Tipo: Luce - Bianca Intensa (30 minuti)<br />Rimanenti: 1<br/>Usata in: Mano 類型: 光 - 超亮白色 (30分鐘)<br />發數: 1<br />使用於: 手 类型:光—高亮白色(30分钟)<br />发数:1<br />使用于:手 Тип: Свет - ярко-белый (30 минут)<br />1 штука<br />В руках @@ -308,10 +308,10 @@ Chemlight (Hi Blue) Cyalume HL (bleu) - ケミライト (高輝度 青) + ケミカルライト(高輝度 青) Świetlik (jaskrawy niebieski) Knicklicht (Blau, Hell) - Luce chimica (Hi Blu) + Luce chimica (Blu Intensa) Химсвет (ярко-синий) Bastão de Luz (Azul Forte) 螢光棒(超亮藍色) @@ -325,9 +325,9 @@ Blue Hi Light Lum. bleue HL Helles, blaues Knicklicht - 高輝度の青色 + 青ライト 高輝度 Jaskrawe niebieskie światło - Luce Hi Blu + Luce Blu Intensa Яркий синий свет Luz forte azul 超亮藍色光 @@ -341,9 +341,9 @@ Type: Light - Blue Hi (30 minute)<br />Rounds: 1<br />Used in: Hand Type : lumière HL (30 minutes) - Bleue<br />Munitions : 1<br />Application : main Typ: Licht - blau, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand - 種類: 照明 - 高輝度 青 (30分間)<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 高輝度 青 (30分間)<br />弾薬: 1<br />使用: 手 Typ: Światło - jaskrawe niebieskie (30 minut)<br/>Pociski: 1<br/>Używany w: ręce - Tipo: Luce - Hi blu (30 minuti)<br/>Rimanenti:1 <br/>Usata in: Mano + Tipo: Luce - Blu Intensa (30 minuti)<br/>Rimanenti: 1<br/>Usata in: Mano Тип: Свет - ярко-синий (30 минут)<br />1 штука<br />В руках Tipo: Luz - Azul Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão 類型: 光 - 超亮藍色 (30分鐘)<br />發數: 1<br />使用於: 手 @@ -355,11 +355,11 @@ Chemlight (Hi Green) - Cyalume HL (vert) + Cyalume HL (Vert) Knicklicht (Grün, Hell) - ケミライト (高輝度 緑) + ケミカルライト(高輝度 緑) Świetlik (jaskrawy zielony) - Luce chimica (Hi Verde) + Luce chimica (Verde Intensa) Химсвет (ярко-зелёный) Bastão de Luz (Verde Forte) 螢光棒(超亮綠色) @@ -373,9 +373,9 @@ Green Hi Light Lum. verte HL Helles, grünes Knicklicht - 高輝度の青色 + 緑ライト 高輝度 Jaskrawe zielone światło - Luce Hi Verde + Luce Verde Intensa Яркий зелёный свет Luz forte verde 超亮綠色光 @@ -389,9 +389,9 @@ Type: Light - Green Hi (30 minute)<br />Rounds: 1<br />Used in: Hand Type : lumière HL (30 minutes) - Verte<br />Munitions : 1<br />Application : main Typ: Licht - grün, hell (30 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand - 種類: 照明 - 高輝度 緑 (30分間)<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 高輝度 緑 (30分間)<br />弾薬: 1<br />使用: 手 Typ: Światło - jaskrawe zielone (30 minut)<br/>Pociski: 1<br/>Używany w: ręce - Tipo: Luce - Hi verde (30 minuti)<br/>Rimanenti: 1<br/>Usata in: Mano + Tipo: Luce - Verde Intensa (30 minuti)<br/>Rimanenti: 1<br/>Usata in: Mano Тип: Свет - ярко-зелёный (30 минут)<br />1 штука<br />В руках Tipo: Luz - Verde Forte (30 minutos)<br/>Usos: 1<br/>Usado em: Mão 類型: 光 - 超亮綠色 (30分鐘)<br />發數: 1<br />使用於: 手 @@ -405,9 +405,9 @@ Chemlight (Ultra-Hi Orange) Cyalume UHL (orange) Knicklicht (Orange, Hell) - ケミライト (高輝度 オレンジ) + ケミカルライト(超高輝度 橙) Świetlik (ultra-jaskrawy pomarańczowy) - Luce chimica (Ultra-Hi Arancione) + Luce chimica (Ultra-Intensa Arancione) Химсвет (ультраяркий оранжевый) Bastão de Luz (Laranja Ultra Forte) 螢光棒(極亮橘色) @@ -421,9 +421,9 @@ Orange Ultra-Hi Light Lum. orange UHL Helles, orangenes Knicklicht - ウルトラ高輝度のオレンジ色 + 橙ライト 超高輝度 Ultra-jaskrawe pomarańczowe światło - Luce Ultra-Hi Arancione + Luce Ultra-Intensa Arancione Ультраяркий оранжевый свет Luz ultra forte laranja 極亮橘色光 @@ -437,9 +437,9 @@ Type: Light - Orange Ultra-Hi (5 minute)<br />Rounds: 1<br />Used in: Hand Type : lumière UHL (5 minutes) - Orange<br />Munitions : 1<br />Application : main Typ: Licht - orange, hell (5 Minuten)<br />Anzahl: 1<br />Benutzt in: Hand - 種類: 照明 - ウルトラ高輝度 オレンジ (5分間)<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 超高輝度 橙 (5分間)<br />弾薬: 1<br />使用: 手 Typ: Światło - ultra-jaskrawe pomarańczowe (5 minut)<br/>Pociski: 1<br/>Używany w: ręce - Tipo: Luce - Ultra-Hi (5 minuti)<br/>Rimanenti: 1<br/>Usata in: Mano + Tipo: Luce - Ultra-Intensa (5 minuti)<br/>Rimanenti: 1<br/>Usata in: Mano Тип: Свет - ультраяркий оранжевый (5 минут)<br />1 штука<br />В руках Tipo: Luz - Laranja Ultra Forte (5 minutos)<br/>Usos: 1<br/>Usado em: Mão 類型: 光 - 極亮橘色 (5分鐘)<br />發數: 1<br />使用於: 手 @@ -451,7 +451,7 @@ Chemlight (IR) - ケミライト (IR) + ケミカルライト(IR) Świetlik (podczerwony) Knicklicht (IR) 화학조명 (적외선) @@ -467,7 +467,7 @@ IR Light - 赤外線光 + 赤外線ライト Światło podczerwone IR-Knicklicht 적외선 화학조명 @@ -483,7 +483,7 @@ Type: Light - Infrared<br />Rounds: 1<br />Used in: Hand - 種類: 照明 - 赤外線<br />装填数: 1<br />次で使用: 携帯 + タイプ: ライト - 赤外線<br />弾薬: 1<br />使用: 手 Typ: Światło - podczerwone<br/>Pociski: 1<br/>Używany w: ręce Typ: Licht - infrarot<br />Anzahl: 1<br />Benutzt in: Hand 종류: 적외선<br />수량: 1<br />사용처: 손 @@ -499,7 +499,7 @@ Chemlight Shield (Empty) - ケミライト シールド (空) + ケミカルライト シールド(空) Osłona na świetlik (pusta) Knicklicht-Abschirmung (leer) 화학조명 가림막 (비어있음) @@ -508,19 +508,19 @@ 螢光棒保護殼 (空) 荧光棒保护壳(空) Контейнер для химсвета (пустой) - Estojo de Luz (Vazio) + Protetor de Bastão de Luz (Vazio) Clona na chemické světlo Protector de luz química (Vacía) Işık çubuğu koruması (Boş) Shield for chemlights. Combine with chemlight to prepare reading light. - ケミライトを入れられます。シールドとケミライトを組み合わせることで、照明にもなりえます。 + ケミカルライトのためのシールド。ケミカルライトと組み合わせることで、読書灯に出来る。 Osłona na świetliki. Połącz ją ze świetlikiem by stworzyć lampkę do czytania. Abschirmung für Knicklichter. Mit Knicklicht kombinieren, um Leselicht zu erhalten. 화학조명을 위한 가림막입니다. 화학조명과 같이 사용하여 읽을 때 씁니다. Étui pour cyalume. Le combiner avec un cyalume pour obtenir une lampe de lecture. - Scudo per luci chimiche. Combina con una luce chimica per una luce da lettura. + Scudo per luci chimiche. Combina con una luce chimica per creare una luce da lettura. 螢光棒的保護殼. 與螢光棒結合後可充當閱讀燈 荧光棒的保护壳。与萤光棒结合后可充当阅读灯。 Защитный контейнер для химсвета. Объедините с химсветом, чтобы подготовить ночник. @@ -531,23 +531,23 @@ Chemlight Shield (Green) - ケミライト シールド (緑) + ケミカルライト シールド(緑) Osłona na świetlik (zielona) - Knicklicht-Abschirmung (grün) + Knicklicht-Abschirmung (Grün) 화학조명 가림막 (초록) - Etui avec cyalume (vert) + Etui avec cyalume (Vert) Scudo Luce Chimica (Verde) 螢光棒保護殼 (綠色) 荧光棒保护壳(绿色) Контейнер для химсвета (зелёный) - Estojo de Luz (Verde) + Protetor de Bastão de Luz (Verde) Clona s vloženým chemickým světlem (Zelené) Protector de luz química (Verde) Işık çubuğu koruması (Yeşil) Green reading light. - 緑色の照明。 + 緑色の読書灯。 Zielona lampka. Grünes Leselicht. 초록빛 조명 @@ -563,7 +563,7 @@ Chemlight Shield (Red) - ケミライト シールド (赤) + ケミカルライト シールド(赤) Osłona na świetlik (czerwona) Knicklicht-Abschirmung (rot) 화학조명 가림막 (빨강) @@ -572,14 +572,14 @@ 螢光棒保護殼 (紅色) 荧光棒保护壳(红色) Контейнер для химсвета (красный) - Estojo de Luz (Vermelho) + Protetor de Bastão de Luz (Vermelho) Clona s vloženým chemickým světlem (Červené) Protector de luz química (Roja) Işık çubuğu koruması (Kırmızıl) Red reading light. - 赤色の照明。 + 赤色の読書灯。 Czerwona lampka. Rotes Leselicht. 빨간색 조명 @@ -595,7 +595,7 @@ Chemlight Shield (Blue) - ケミライト シールド (青) + ケミカルライト シールド(青) Osłona na świetlik (niebieska) Knicklicht-Abschirmung (blau) 화학조명 가림막 (파랑) @@ -604,14 +604,14 @@ 螢光棒保護殼 (藍色) 荧光棒保护壳(蓝色) Контейнер для химсвета (синий) - Estojo de Luz (Azul) + Protetor de Bastão de Luz (Azul) Clona s vloženým chemickým světlem (Modré) Protector de luz química (Azul) Işık çubuğu koruması (Mavi) Blue reading light. - 青色の照明。 + 青色の読書灯。 Niebieska lampka. Blaues Leselicht. 파란색 조명 @@ -627,7 +627,7 @@ Chemlight Shield (Yellow) - ケミライト シールド (黄) + ケミカルライト シールド(黄) Osłona na świetlik (żółta) Knicklicht-Abschirmung (gelb) 화학조명 가림막 (노랑) @@ -636,14 +636,14 @@ 螢光棒保護殼 (黃色) 荧光棒保护壳(黄色) Контейнер для химсвета (жёлтый) - Estojo de Luz (Amarelo) + Protetor de Bastão de Luz (Amarelo) Clona s vloženým chemickým světlem (Žluté) Protector de luz química (Amarilla) Işık çubuğu koruması (Sarı) Yellow reading light. - 黄色の照明。 + 黄色の読書灯。 Żółta lampka. Gelbes Leselicht. 노란색 조명 @@ -659,7 +659,7 @@ Chemlight Shield (Orange) - ケミライト シールド (オレンジ) + ケミカルライト シールド(橙) Osłona na świetlik (pomarańczowa) Knicklicht-Abschirmung (orange) 화학조명 가림막 (주황) @@ -668,14 +668,14 @@ 螢光棒保護殼 (橘色) 荧光棒保护壳(橘色) Контейнер для химсвета (оранжевый) - Estojo de Luz (Laranja) + Protetor de Bastão de Luz (Laranja) Clona s vloženým chemickým světlem (Oranžové) Protector de luz química (Naranja) Işık çubuğu koruması (Turuncu) Orange reading light. - オレンジの照明。 + 橙色の読書灯。 Pomarańczowa lampka. Oranges Leselicht. 주황색 조명 @@ -691,7 +691,7 @@ Chemlight Shield (White) - ケミライト シールド (白) + ケミカルライト シールド(白) Osłona na świetlik (biała) Knicklicht-Abschirmung (weiß) 화학조명 가림막 (하양) @@ -700,14 +700,14 @@ 螢光棒保護殼 (白色) 荧光棒保护壳(白色) Контейнер для химсвета (белый) - Estojo de Luz (Branco) + Protetor de Bastão de Luz (Branco) Clona s vloženým chemickým světlem (Bílé) Protector de luz química (Blanca) Işık çubuğu koruması (Beyazl) White reading light. - 白色の照明。 + 白色の読書灯。 Biała lampka. Weißes Leselicht. 주황색 조명 diff --git a/addons/common/CfgGesturesMale.hpp b/addons/common/CfgGesturesMale.hpp new file mode 100644 index 0000000000..0d3737cb62 --- /dev/null +++ b/addons/common/CfgGesturesMale.hpp @@ -0,0 +1,14 @@ +// From ACRE +class CfgGesturesMale { + skeletonName = "OFP2_ManSkeleton"; + class States { + class GestureNod; + class GVAR(stop): GestureNod { + file = "a3\anims_f\data\anim\sdr\gst\gestureEmpty.rtm"; + disableWeapons = 0; + disableWeaponsLong = 0; + enableOptics = 1; + mask = "empty"; + }; + }; +}; diff --git a/addons/common/CfgMoves.hpp b/addons/common/CfgMoves.hpp index b0df9a4466..da83153b15 100644 --- a/addons/common/CfgMoves.hpp +++ b/addons/common/CfgMoves.hpp @@ -1,9 +1,16 @@ - class CfgMovesBasic { class Default; + + // From ACRE + class ManActions { + GVAR(stop) = QGVAR(stop); + }; class Actions { + class NoActions: ManActions { + GVAR(stop)[] = {QGVAR(stop), "Gesture"}; + }; + // fixes grab animation with equipped pistol - class NoActions; class PistolStandActions: NoActions { grabDrag = "AmovPercMstpSlowWrflDnon_AcinPknlMwlkSlowWrflDb_2"; }; @@ -62,8 +69,12 @@ class CfgMovesMaleSdr: CfgMovesBasic { // fix falling back to unconsciousness animation and disable rotating in that state class Unconscious: Default { - ConnectTo[] = {}; + // Prevents AI from moving torso and head when unconscious + aiming = "aimingNo"; + aimingBody = "aimingUpNo"; head = "headNo"; + + ConnectTo[] = {}; forceAim = 1; static = 1; }; @@ -72,5 +83,14 @@ class CfgMovesMaleSdr: CfgMovesBasic { class AinvPknlMstpSnonWnonDnon_medic0: HealBase { variantsPlayer[] = {}; }; + + // Idle affects legs when weapon switching - fixes units sliding when holstering weapons + class AmovPercMstpSnonWnonDnon: StandBase { + idle = ""; + }; + // Need to reset idle, as it breaks animations otherwise + class CutSceneAnimationBase: AmovPercMstpSnonWnonDnon { + idle = "idleDefault"; + }; }; }; diff --git a/addons/common/HintConfig.hpp b/addons/common/HintConfig.hpp index 72fd7f6233..c299bee8df 100644 --- a/addons/common/HintConfig.hpp +++ b/addons/common/HintConfig.hpp @@ -10,6 +10,11 @@ class GVAR(debug_structuredText): ctrlStructuredText { }; class RscTitles { + class GVAR(ProgressBar_Display): GVAR(ProgressBar_Dialog) { + duration = 1e11; // forever, essentially + fadeIn = 0; + fadeOut = 0; + }; class GVAR(watchVariableUI) { idd = -1; onLoad = QUOTE(with uiNameSpace do {GVAR(watchVariableUI) = _this select 0};); diff --git a/addons/common/XEH_PREP.hpp b/addons/common/XEH_PREP.hpp index 25899db1ae..5b85d63dda 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); @@ -29,6 +30,7 @@ PREP(changeProjectileDirection); PREP(checkFiles); PREP(checkFiles_diagnoseACE); PREP(checkPBOs); +PREP(checkVersionNumber); PREP(claim); PREP(claimSafeServer); PREP(codeToString); @@ -41,6 +43,7 @@ PREP(deviceKeyFindValidIndex); PREP(deviceKeyRegisterNew); PREP(deprecateComponent); PREP(disableAI); +PREP(disableAiUAV); PREP(disableUserInput); PREP(displayIcon); PREP(displayText); @@ -102,6 +105,7 @@ PREP(getWeaponAzimuthAndInclination); PREP(getWeaponIndex); PREP(getWeaponState); PREP(getWeight); +PREP(getWheelHitPointsWithSelections); PREP(getWindDirection); PREP(getZoom); PREP(goKneeling); @@ -160,6 +164,7 @@ PREP(sendRequest); PREP(serverLog); PREP(setAimCoef); PREP(setApproximateVariablePublic); +PREP(setDead); PREP(setDefinedVariable); PREP(setDisableUserInputStatus); PREP(setHearingCapability); @@ -181,6 +186,7 @@ PREP(statusEffect_resetVariables); PREP(statusEffect_respawnEH); PREP(statusEffect_sendEffects); PREP(statusEffect_set); +PREP(stopGesture); PREP(stringCompare); PREP(stringToColoredText); PREP(swayLoop); @@ -262,6 +268,7 @@ PREP(_handleRequestAllSyncedEvents); PREP(addActionEventHandler); PREP(addActionMenuEventHandler); PREP(addMapMarkerCreatedEventHandler); +PREP(addPlayerEH); PREP(removeActionEventHandler); PREP(removeActionMenuEventHandler); diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index c250bda652..8b7568f75e 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -18,7 +18,7 @@ ////////////////////////////////////////////////// //Status Effect EHs: -[QGVAR(setStatusEffect), {_this call FUNC(statusEffect_set)}] call CBA_fnc_addEventHandler; +[QGVAR(setStatusEffect), LINKFUNC(statusEffect_set)] call CBA_fnc_addEventHandler; ["forceWalk", false, ["ace_advanced_fatigue", "ACE_SwitchUnits", "ACE_Attach", "ace_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_Trenches", "ace_medical_fracture"]] call FUNC(statusEffect_addType); ["blockSprint", false, ["ace_advanced_fatigue", "ace_dragging", "ace_medical_fracture"]] call FUNC(statusEffect_addType); ["setCaptive", true, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered)]] call FUNC(statusEffect_addType); @@ -28,7 +28,8 @@ ["setHidden", true, ["ace_unconscious"]] call FUNC(statusEffect_addType); ["blockRadio", false, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered), "ace_unconscious"]] call FUNC(statusEffect_addType); ["blockSpeaking", false, ["ace_unconscious"]] call FUNC(statusEffect_addType); -["lockInventory", true, []] call FUNC(statusEffect_addType); +["disableWeaponAssembly", false, ["ace_common", "ace_common_lockVehicle", "ace_csw"]] call FUNC(statusEffect_addType); +["lockInventory", true, [], true] call FUNC(statusEffect_addType); [QGVAR(forceWalk), { params ["_object", "_set"]; @@ -95,7 +96,7 @@ _object setVariable ["acre_sys_core_isDisabled", _set > 0, true]; }; if (["task_force_radio"] call FUNC(isModLoaded)) then { - _object setVariable ["tf_voiceVolume", [1, 0] select (_set > 0), true]; + _object setVariable ["tf_voiceVolume", parseNumber (_set == 0), true]; }; }] call CBA_fnc_addEventHandler; @@ -121,12 +122,41 @@ _object setMass _mass; }] call CBA_fnc_addEventHandler; +[QGVAR(disableWeaponAssembly), { + params ["_object", "_set"]; + _object enableWeaponDisassembly (_set < 1); +}] call CBA_fnc_addEventHandler; + [QGVAR(lockInventory), { params ["_object", "_set"]; TRACE_2("lockInventory EH",_object,_set); _object lockInventory (_set > 0); }] call CBA_fnc_addEventHandler; +[QGVAR(disableAiUAV), { + params ["_unit", "_disable"]; + + if (_disable) then { + private _features = ["AUTOTARGET", "TARGET", "WEAPONAIM"/*, "FIREWEAPON"*/, "RADIOPROTOCOL"]; // TODO: Uncomment in 2.18 + + // Save current status + _unit setVariable [QGVAR(featuresAiUAV), _features apply {[_x, _unit checkAIFeature _x]}]; + + { + _unit enableAIFeature [_x, false]; + } forEach _features; + } else { + // Restore previous status + private _features = _unit getVariable [QGVAR(featuresAiUAV), []]; + + { + _unit enableAIFeature [_x select 0, _x select 1]; + } forEach _features; + + _unit setVariable [QGVAR(featuresAiUAV), nil]; + }; +}] call CBA_fnc_addEventHandler; + //Add a fix for BIS's zeus remoteControl module not reseting variables on DC when RC a unit //This variable is used for isPlayer checks if (isServer) then { @@ -136,11 +166,10 @@ if (isServer) then { if ((!isNil "_zeusLogic") && {!isNull _zeusLogic}) then { { if ((_x getvariable ["bis_fnc_moduleRemoteControl_owner", objnull]) isEqualTo _dcPlayer) exitWith { - INFO_3("[%1] DC - Was Zeus [%2] while controlling unit [%3] - manually clearing `bis_fnc_moduleRemoteControl_owner`", [_x] call FUNC(getName), _dcPlayer, _x); + INFO_3("[%1] DC - Was Zeus [%2] while controlling unit [%3] - manually clearing `bis_fnc_moduleRemoteControl_owner`",[_x] call FUNC(getName),_dcPlayer,_x); _x setVariable ["bis_fnc_moduleRemoteControl_owner", nil, true]; }; - nil - } count (curatorEditableObjects _zeusLogic); + } forEach (curatorEditableObjects _zeusLogic); }; }]; }; @@ -151,9 +180,9 @@ if (isServer) then { INFO_2("Headbug Used: Name: %1, Animation: %2",_profileName,_animation); }] call CBA_fnc_addEventHandler; -[QGVAR(fixCollision), FUNC(fixCollision)] call CBA_fnc_addEventHandler; -[QGVAR(fixFloating), FUNC(fixFloating)] call CBA_fnc_addEventHandler; -[QGVAR(fixPosition), FUNC(fixPosition)] call CBA_fnc_addEventHandler; +[QGVAR(fixCollision), LINKFUNC(fixCollision)] call CBA_fnc_addEventHandler; +[QGVAR(fixFloating), LINKFUNC(fixFloating)] call CBA_fnc_addEventHandler; +[QGVAR(fixPosition), LINKFUNC(fixPosition)] call CBA_fnc_addEventHandler; ["ace_loadPersonEvent", LINKFUNC(loadPersonLocal)] call CBA_fnc_addEventHandler; ["ace_unloadPersonEvent", LINKFUNC(unloadPersonLocal)] call CBA_fnc_addEventHandler; @@ -161,10 +190,16 @@ if (isServer) then { [QGVAR(lockVehicle), { _this setVariable [QGVAR(lockStatus), locked _this]; _this lock 2; + if ([] isNotEqualTo getArray (configOf _this >> "assembleInfo" >> "dissasembleTo")) then { + [_this, "disableWeaponAssembly", QGVAR(lockVehicle), true] call FUNC(statusEffect_set); + }; }] call CBA_fnc_addEventHandler; [QGVAR(unlockVehicle), { _this lock (_this getVariable [QGVAR(lockStatus), locked _this]); + if ([] isNotEqualTo getArray (configOf _target >> "assembleInfo" >> "dissasembleTo")) then { + [_this, "disableWeaponAssembly", QGVAR(lockVehicle), false] call FUNC(statusEffect_set); + }; }] call CBA_fnc_addEventHandler; [QGVAR(setDir), {(_this select 0) setDir (_this select 1)}] call CBA_fnc_addEventHandler; @@ -180,6 +215,7 @@ if (isServer) then { [QGVAR(switchMove), {(_this select 0) switchMove (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(setVectorDirAndUp), {(_this select 0) setVectorDirAndUp (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(addWeaponItem), {(_this select 0) addWeaponItem [(_this select 1), (_this select 2)]}] call CBA_fnc_addEventHandler; +[QGVAR(removeMagazinesTurret), {(_this select 0) removeMagazinesTurret [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler; [QGVAR(setVanillaHitPointDamage), { params ["_object", "_hitPointAnddamage"]; @@ -197,8 +233,8 @@ if (isServer) then { }] call CBA_fnc_addEventHandler; // Request framework -[QGVAR(requestCallback), FUNC(requestCallback)] call CBA_fnc_addEventHandler; -[QGVAR(receiveRequest), FUNC(receiveRequest)] call CBA_fnc_addEventHandler; +[QGVAR(requestCallback), LINKFUNC(requestCallback)] call CBA_fnc_addEventHandler; +[QGVAR(receiveRequest), LINKFUNC(receiveRequest)] call CBA_fnc_addEventHandler; [QGVAR(systemChatGlobal), {systemChat _this}] call CBA_fnc_addEventHandler; @@ -207,10 +243,13 @@ if (isServer) then { [QGVAR(enableSimulationGlobal), {(_this select 0) enableSimulationGlobal (_this select 1)}] call CBA_fnc_addEventHandler; [QGVAR(setShotParents), {(_this select 0) setShotParents [_this select 1, _this select 2]}] call CBA_fnc_addEventHandler; ["ace_setOwner", {(_this select 0) setOwner (_this select 1)}] call CBA_fnc_addEventHandler; - [QGVAR(serverLog), FUNC(serverLog)] call CBA_fnc_addEventHandler; + [QGVAR(serverLog), LINKFUNC(serverLog)] call CBA_fnc_addEventHandler; [QGVAR(claimSafe), LINKFUNC(claimSafeServer)] call CBA_fnc_addEventHandler; }; +["CBA_SettingChanged", { + ["ace_settingChanged", _this] call CBA_fnc_localEvent; +}] call CBA_fnc_addEventHandler; ////////////////////////////////////////////////// // Set up remote execution @@ -224,14 +263,14 @@ if (!isServer) then { ["ACEa", [player]] call CBA_fnc_serverEvent; }] call CBA_fnc_addEventHandler; } else { - ["ACEa", FUNC(_handleRequestAllSyncedEvents)] call CBA_fnc_addEventHandler; + ["ACEa", LINKFUNC(_handleRequestAllSyncedEvents)] call CBA_fnc_addEventHandler; }; -["ACEe", FUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler; -["ACEs", FUNC(_handleRequestSyncedEvent)] call CBA_fnc_addEventHandler; +["ACEe", LINKFUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler; +["ACEs", LINKFUNC(_handleRequestSyncedEvent)] call CBA_fnc_addEventHandler; if (isServer) then { - [FUNC(syncedEventPFH), 0.5, []] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(syncedEventPFH), 0.5, []] call CBA_fnc_addPerFrameHandler; }; @@ -349,7 +388,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 }; @@ -380,8 +419,8 @@ addMissionEventHandler ["PlayerViewChanged", { // Eventhandlers for player controlled machines ////////////////////////////////////////////////// -[QGVAR(displayTextStructured), {_this call FUNC(displayTextStructured)}] call CBA_fnc_addEventHandler; -[QGVAR(displayTextPicture), {_this call FUNC(displayTextPicture)}] call CBA_fnc_addEventHandler; +[QGVAR(displayTextStructured), LINKFUNC(displayTextStructured)] call CBA_fnc_addEventHandler; +[QGVAR(displayTextPicture), LINKFUNC(displayTextPicture)] call CBA_fnc_addEventHandler; ["ace_unconscious", { params ["_unit", "_isUnconscious"]; @@ -391,7 +430,7 @@ addMissionEventHandler ["PlayerViewChanged", { }; }] call CBA_fnc_addEventHandler; -["ace_useItem", DFUNC(useItem)] call CBA_fnc_addEventHandler; +["ace_useItem", LINKFUNC(useItem)] call CBA_fnc_addEventHandler; ////////////////////////////////////////////////// @@ -487,10 +526,24 @@ GVAR(reloadMutex_lastMagazines) = []; // Start the sway loop ////////////////////////////////////////////////// ["CBA_settingsInitialized", { + ["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 FUNC(addSwayFactor); + [{ // frame after settingsInitialized to ensure all other addons have added their factors - if ((GVAR(swayFactorsBaseline) + GVAR(swayFactorsMultiplier)) isNotEqualTo []) then { - call FUNC(swayLoop) + if (GVAR(enableSway)) then { + call FUNC(swayLoop); }; // check for pre-3.16 sway factors being added if (!isNil {missionNamespace getVariable "ACE_setCustomAimCoef"}) then { diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index efe9b10c0c..b559cb5dd9 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -10,6 +10,7 @@ PREP_RECOMPILE_END; GVAR(syncedEvents) = createHashMap; GVAR(showHudHash) = createHashMap; GVAR(vehicleIconCache) = createHashMap; // for getVehicleIcon +GVAR(wheelSelections) = createHashMap; GVAR(blockItemReplacement) = false; @@ -32,6 +33,7 @@ ACE_COUNTERS = []; GVAR(statusEffect_Names) = []; GVAR(statusEffect_isGlobal) = []; +GVAR(statusEffect_sendJIP) = []; GVAR(setHearingCapabilityMap) = []; @@ -78,6 +80,6 @@ isHC = !hasInterface && !isDedicated; // deprecated because no tag missionNamespace setVariable ["ACE_isHC", ACE_isHC]; uiNamespace setVariable ["ACE_isHC", ACE_isHC]; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/common/XEH_preStart.sqf b/addons/common/XEH_preStart.sqf index b872756af8..208adea7b1 100644 --- a/addons/common/XEH_preStart.sqf +++ b/addons/common/XEH_preStart.sqf @@ -5,7 +5,7 @@ if (isFilePatchingEnabled) then { private _notLoaded = configProperties [configfile >> "ace_notLoaded", "isText _x"]; { - INFO_2("%1 not loaded because %2",configName _x, getText _x); + INFO_2("%1 not loaded because %2",configName _x,getText _x); } forEach _notLoaded; }; diff --git a/addons/common/config.cpp b/addons/common/config.cpp index 758957987e..144e7d96c6 100644 --- a/addons/common/config.cpp +++ b/addons/common/config.cpp @@ -4,7 +4,7 @@ class CfgPatches { class ADDON { name = COMPONENT_NAME; units[] = {"ACE_Box_Misc", "ACE_bananaItem", "ACE_Flag_Black", "ACE_Flag_White"}; - weapons[] = {"ACE_ItemCore","ACE_FakePrimaryWeapon", "ACE_Banana"}; + weapons[] = {"ACE_ItemCore", "ACE_FakePrimaryWeapon", "ACE_Banana"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_main","ace_modules"}; author = CSTRING(ACETeam); @@ -17,6 +17,7 @@ class CfgPatches { #include "CfgEden.hpp" #include "CfgEventHandlers.hpp" #include "CfgLocationTypes.hpp" +#include "CfgGesturesMale.hpp" #include "CfgMagazines.hpp" #include "CfgMoves.hpp" #include "CfgSounds.hpp" 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 bd00869360..c5f3c81ef5 100644 --- a/addons/common/dev/test_cfgPatches.sqf +++ b/addons/common/dev/test_cfgPatches.sqf @@ -13,16 +13,16 @@ 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; if (isNull _class) then { - WARNING_1("in units[] but null - %1", _x); + WARNING_1("in units[] but null - %1",_x); _testPass = false; } else { // if (((getNumber (_class >> "scope")) != 2) && {((getNumber (_class >> "scopeCurator")) != 2)}) then { - // WARNING_2("in units[] but not public - %1 from %2", configName _class, configSourceMod _class); + // WARNING_2("in units[] but not public - %1 from %2",configName _class,configSourceMod _class); // _testPass = false; // }; }; @@ -31,16 +31,16 @@ 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; if (isNull _class) then { - WARNING_1("in weapons[] but null - %1", _x); + WARNING_1("in weapons[] but null - %1",_x); _testPass = false; } else { // if (((getNumber (_class >> "scope")) != 2) && {((getNumber (_class >> "scopeCurator")) != 2)}) then { - // WARNING_2("in weapons[] but not public - %1 from %2", configName _class, configSourceMod _class); + // WARNING_2("in weapons[] but not public - %1 from %2",configName _class,configSourceMod _class); // _testPass = false; // }; }; @@ -50,8 +50,8 @@ 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 { - WARNING_2("Not in any units[] - %1 from %2", configName _x, configSourceMod _x); + if !((toLowerANSI configName _x) in _allUnits) then { + WARNING_2("Not in any units[] - %1 from %2",configName _x,configSourceMod _x); _testPass = false; }; }; @@ -60,10 +60,10 @@ 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 { - WARNING_2("Not in any weapons[] - %1 from %2", configName _x, configSourceMod _x); + 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__handleRequestSyncedEvent.sqf b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf index a5bb286768..1924ed22ff 100644 --- a/addons/common/functions/fnc__handleRequestSyncedEvent.sqf +++ b/addons/common/functions/fnc__handleRequestSyncedEvent.sqf @@ -27,7 +27,7 @@ if (isServer) then { params ["_eventName", "_client"]; if !(_eventName in GVAR(syncedEvents)) exitWith { - ERROR_1("Request for synced event - key [%1] not found.", _eventName); + ERROR_1("Request for synced event - key [%1] not found.",_eventName); false }; @@ -43,8 +43,7 @@ if (isServer) then { { _x params ["", "_eventArgs","_ttl"]; [_eventName, _eventArgs, _ttl] call FUNC(_handleSyncedEvent); - false - } count _eventLog; + } forEach _eventLog; INFO_1("[%1] synchronized",_eventName); }; diff --git a/addons/common/functions/fnc__handleSyncedEvent.sqf b/addons/common/functions/fnc__handleSyncedEvent.sqf index a7b28de1a6..aac8ac873e 100644 --- a/addons/common/functions/fnc__handleSyncedEvent.sqf +++ b/addons/common/functions/fnc__handleSyncedEvent.sqf @@ -20,7 +20,7 @@ params ["_name", "_args", "_ttl"]; if !(_name in GVAR(syncedEvents)) exitWith { - ERROR_1("Synced event key [%1] not found (_handleSyncedEvent).", _name); + ERROR_1("Synced event key [%1] not found (_handleSyncedEvent).",_name); false }; diff --git a/addons/common/functions/fnc_actionKeysNamesConverted.sqf b/addons/common/functions/fnc_actionKeysNamesConverted.sqf index dd62fc8789..27c3597a9b 100644 --- a/addons/common/functions/fnc_actionKeysNamesConverted.sqf +++ b/addons/common/functions/fnc_actionKeysNamesConverted.sqf @@ -43,10 +43,10 @@ if (isNil "_keyTable") then { }; }; -private _keyCache = uiNamespace getVariable [QGVAR(keyNameCache), locationNull]; +private _keyCache = uiNamespace getVariable QGVAR(keyNameCache); // @TODO: Move cache creation to preStart/somewhere else -if (isNull _keyCache) then { - _keyCache = call CBA_fnc_createNamespace; +if (isNil "_keyCache") then { + _keyCache = createHashMap; uiNamespace setVariable [QGVAR(keyNameCache), _keyCache]; }; @@ -54,7 +54,7 @@ params [["_action", "", [""]]]; private _keybinds = actionKeysNamesArray _action apply { private _keyName = _x; - private _keybind = _keyCache getVariable _keyName; + private _keybind = _keyCache get _keyName; if (isNil "_keybind") then { private _key = -1; @@ -101,7 +101,7 @@ private _keybinds = actionKeysNamesArray _action apply { // cache _keybind = [_key, _shift, _ctrl, _alt]; - _keyCache setVariable [_keyName, _keybind]; + _keyCache set [_keyName, _keybind]; }; _keybind 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_addPlayerEH.sqf b/addons/common/functions/fnc_addPlayerEH.sqf new file mode 100644 index 0000000000..c20fde9da1 --- /dev/null +++ b/addons/common/functions/fnc_addPlayerEH.sqf @@ -0,0 +1,63 @@ +#include "..\script_component.hpp" +/* + * Author: PabstMirror + * Adds event handler just to ACE_player + * Can be removed after cba 3.18 is released for CBA_fnc_addBISPlayerEventHandler + * This never was public in a release + * + * Arguments: + * 0: Key + * 1: Event Type + * 2: Event Code + * 3: Ignore Virtual Units (spectators, virtual zeus, uav RC) (default: true) + * + * Return Value: + * None + * + * Example: + * ["example", "FiredNear", {systemChat str _this}] call ace_common_fnc_addPlayerEH + * + * Public: No +*/ +params [["_key", "", [""]], ["_type", "", [""]], ["_code", {}, [{}]], ["_ignoreVirtual", true, [true]]]; +TRACE_3("addPlayerEH",_key,_type,_ignoreVirtual); + +if (isNil QGVAR(playerEventsHash)) then { // first-run init + GVAR(playerEventsHash) = createHashMap; + ["unit", { + params ["_newPlayer", "_oldPlayer"]; + // uav check only applies to direct controlling UAVs from zeus, no effect on normal UAV operation + private _isVirutal = (unitIsUAV _newPlayer) || {getNumber (configOf _newPlayer >> "isPlayableLogic") == 1}; + + TRACE_4("",_newPlayer,_oldPlayer,_isVirutal,count GVAR(playerEventsHash)); + { + _y params ["_type", "_code", "_ignoreVirtual"]; + + private _oldEH = _oldPlayer getVariable [_x, -1]; + if (_oldEH != -1) then { + _oldPlayer removeEventHandler [_type, _oldEH]; + _oldPlayer setVariable [_x, nil]; + }; + + _oldEH = _newPlayer getVariable [_x, -1]; + if (_oldEH != -1) then { continue }; // if respawned then var and EH already exists + if (_ignoreVirtual && _isVirutal) then { continue }; + + private _newEH = _newPlayer addEventHandler [_type, _code]; + _newPlayer setVariable [_x, _newEH]; + } forEach GVAR(playerEventsHash); + }, false] call CBA_fnc_addPlayerEventHandler; +}; + + +_key = format [QGVAR(playerEvents_%1), toLower _key]; +if (_key in GVAR(playerEventsHash)) exitWith { ERROR_1("bad key %1",_this); }; + +GVAR(playerEventsHash) set [_key, [_type, _code, _ignoreVirtual]]; + +if (isNull ACE_player) exitWith {}; +if (_ignoreVirtual && {(unitIsUAV ACE_player) || {getNumber (configOf ACE_player >> "isPlayableLogic") == 1}}) exitWith {}; + +// Add event now +private _newEH = ACE_player addEventHandler [_type, _code]; +ACE_player setVariable [_key, _newEH]; 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_addSyncedEventHandler.sqf b/addons/common/functions/fnc_addSyncedEventHandler.sqf index dbe0612e95..616897842b 100644 --- a/addons/common/functions/fnc_addSyncedEventHandler.sqf +++ b/addons/common/functions/fnc_addSyncedEventHandler.sqf @@ -24,7 +24,7 @@ if (_name in GVAR(syncedEvents)) exitWith { false }; -private _eventId = [_name, FUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler; +private _eventId = [_name, LINKFUNC(_handleSyncedEvent)] call CBA_fnc_addEventHandler; private _data = [_handler, [], _ttl, _eventId]; GVAR(syncedEvents) set [_name, _data]; diff --git a/addons/common/functions/fnc_addToInventory.sqf b/addons/common/functions/fnc_addToInventory.sqf index 39e6903390..38476ad5fc 100644 --- a/addons/common/functions/fnc_addToInventory.sqf +++ b/addons/common/functions/fnc_addToInventory.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Garth 'L-H' de Wet - * Adds an item, weapon, or magazine to the unit's inventory or places it in a weaponHolder if no space. + * Adds an item, weapon, or magazine to the unit's inventory or places it in a weapon holder if no space. * * Arguments: * 0: Unit @@ -11,10 +11,10 @@ * * Return Value: * 0: Added to player - * 1: weaponholder + * 1: Weapon holder item was placed in * * Example: - * [bob, "classname", "", 5] call ace_common_fnc_addToInventory + * [player, "30Rnd_65x39_caseless_mag", "", 5] call ace_common_fnc_addToInventory * * Public: Yes */ @@ -26,6 +26,7 @@ private _type = _classname call FUNC(getItemType); private _canAdd = false; private _canFitWeaponSlot = false; private _addedToUnit = false; +private _weaponHolder = _unit; switch (_container) do { case "vest": { @@ -58,6 +59,21 @@ switch (_container) do { }; }; +if (_type select 0 == "magazine") then { + private _configAmmoCount = getNumber (configFile >> "CfgMagazines" >> _classname >> "count"); + + // https://feedback.bistudio.com/T74244 + // When adding throwables with the addXXXCargo(Global) commands, they don't show up in the throwables list + // If a throwable has more than 1 ammo count, adding it with addItem(XXX) commands also renders the throwable unusable + if (_configAmmoCount == 1 && {_ammoCount in [-1, 1]} && {_classname call BIS_fnc_isThrowable}) then { // TODO: replace with https://community.bistudio.com/wiki/isThrowable in 2.18 + _type set [0, "item"]; + }; + + if (_ammoCount == -1) then { + _ammoCount = _configAmmoCount; + }; +}; + switch (_type select 0) do { case "weapon": { if (_canAdd || {_canFitWeaponSlot}) then { @@ -94,31 +110,29 @@ switch (_type select 0) do { } else { _addedToUnit = false; - private _pos = _unit modelToWorldVisual [0,1,0.05]; + _weaponHolder = nearestObject [_unit, "WeaponHolder"]; - _unit = createVehicle ["WeaponHolder_Single_F", _pos, [], 0, "NONE"]; - _unit addWeaponCargoGlobal [_classname, 1]; - _unit setPosATL _pos; + if (isNull _weaponHolder || {_unit distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", _unit, [], 0, "CAN_COLLIDE"]; + }; + + _weaponHolder addWeaponCargoGlobal [_classname, 1]; }; }; case "magazine": { - if (_ammoCount == -1) then { - _ammoCount = getNumber (configFile >> "CfgMagazines" >> _classname >> "count"); - }; - if (_canAdd) then { _addedToUnit = true; 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]; @@ -127,11 +141,13 @@ switch (_type select 0) do { } else { _addedToUnit = false; - private _pos = _unit modelToWorldVisual [0,1,0.05]; + _weaponHolder = nearestObject [_unit, "WeaponHolder"]; - _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 setPosATL _pos; + if (isNull _weaponHolder || {_unit distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", _unit, [], 0, "CAN_COLLIDE"]; + }; + + _weaponHolder addMagazineAmmoCargo [_classname, 1, _ammoCount]; }; }; @@ -156,11 +172,13 @@ switch (_type select 0) do { } else { _addedToUnit = false; - private _pos = _unit modelToWorldVisual [0,1,0.05]; + _weaponHolder = nearestObject [_unit, "WeaponHolder"]; - _unit = createVehicle ["WeaponHolder_Single_F", _pos, [], 0, "NONE"]; - _unit addItemCargoGlobal [_classname, 1]; - _unit setPosATL _pos; + if (isNull _weaponHolder || {_unit distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", _unit, [], 0, "CAN_COLLIDE"]; + }; + + _weaponHolder addItemCargoGlobal [_classname, 1]; }; }; @@ -170,4 +188,4 @@ switch (_type select 0) do { }; }; -[_addedToUnit, _unit] +[_addedToUnit, _weaponHolder] diff --git a/addons/common/functions/fnc_addWeapon.sqf b/addons/common/functions/fnc_addWeapon.sqf index 16ae92c4f5..787c9fb24a 100644 --- a/addons/common/functions/fnc_addWeapon.sqf +++ b/addons/common/functions/fnc_addWeapon.sqf @@ -2,22 +2,33 @@ /* * Author: commy2, johnb43 * Adds weapon to unit without taking a magazine. - * Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items. + * Same as CBA_fnc_addWeaponWithoutItems, but doesn't remove linked items by default. * * Arguments: - * 0: Unit to add the weapon to + * 0: Unit to add the weapon to * 1: Weapon to add + * 2: If linked items should be removed or not (default: false) + * 3: Magazines that should be added to the weapon (default: []) + * - 0: Magazine classname + * - 1: Ammo count * * Return Value: * None * * Example: - * [player, "arifle_AK12_F"] call ace_common_fnc_addWeapon + * [player, "arifle_MX_GL_F", true, [["30Rnd_65x39_caseless_mag", 30], ["1Rnd_HE_Grenade_shell", 1]]] call ace_common_fnc_addWeapon * * Public: Yes */ -params ["_unit", "_weapon"]; +params [ + ["_unit", objNull, [objNull]], + ["_weapon", "", [""]], + ["_removeLinkedItems", false, [false]], + ["_magazines", [], [[]]] +]; + +if (isNull _unit || {_weapon == ""}) exitWith {}; // Config case private _compatibleMagazines = compatibleMagazines _weapon; @@ -45,6 +56,35 @@ private _backpackMagazines = (magazinesAmmoCargo _backpack) select { // Add weapon _unit addWeapon _weapon; +// This doesn't remove magazines, but linked items can't be magazines, so it's fine +if (_removeLinkedItems) then { + switch (_weapon call FUNC(getConfigName)) do { + case (primaryWeapon _unit): { + removeAllPrimaryWeaponItems _unit; + }; + case (secondaryWeapon _unit): { + removeAllSecondaryWeaponItems _unit; + }; + case (handgunWeapon _unit): { + removeAllHandgunItems _unit; + }; + case (binocular _unit): { + removeAllBinocularItems _unit; + }; + }; +}; + +// Add magazines directly now, so that AI don't reload +if (_magazines isNotEqualTo []) then { + { + _x params [["_magazine", "", [""]], ["_ammoCount", -1, [0]]]; + + if (_magazine != "" && {_ammoCount > -1}) then { + _unit addWeaponItem [_weapon, [_magazine, _ammoCount], true]; + }; + } forEach _magazines; +}; + // Add all magazines back { _uniform addMagazineAmmoCargo [_x select 0, 1, _x select 1]; 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_assignObjectsInList.sqf b/addons/common/functions/fnc_assignObjectsInList.sqf index 23d373c310..0928812cd4 100644 --- a/addons/common/functions/fnc_assignObjectsInList.sqf +++ b/addons/common/functions/fnc_assignObjectsInList.sqf @@ -28,18 +28,13 @@ if (_list isEqualType "") then { }; { - if (!isNil "_x") then { - if (_x isEqualType objNull) then { - if (local _x) then { - if (_vehicle) then { - (vehicle _x) setVariable [_variable, _setting, _global]; - TRACE_6("Set variable vehicle",_x,vehicle _x,typeOf (vehicle _x),_variable,_setting,_global); - } else { - _x setVariable [_variable, _setting, _global]; - TRACE_5("Set variable",_x,typeOf _x,_variable,_setting,_global); - }; - }; + if (!isNil "_x" && {_x isEqualType objNull} && {local _x}) then { + if (_vehicle) then { + (vehicle _x) setVariable [_variable, _setting, _global]; + TRACE_6("Set variable vehicle",_x,vehicle _x,typeOf (vehicle _x),_variable,_setting,_global); + } else { + _x setVariable [_variable, _setting, _global]; + TRACE_5("Set variable",_x,typeOf _x,_variable,_setting,_global); }; }; - false -} count _list; +} forEach _list; 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..29e4d532b1 100644 --- a/addons/common/functions/fnc_cbaSettings.sqf +++ b/addons/common/functions/fnc_cbaSettings.sqf @@ -66,8 +66,7 @@ GVAR(settingsMovedToSQF) = []; INFO_1("%1 delayed functions running.",count GVAR(runAtSettingsInitialized)); { (_x select 1) call (_x select 0); - false - } count GVAR(runAtSettingsInitialized); + } forEach GVAR(runAtSettingsInitialized); GVAR(runAtSettingsInitialized) = nil; //cleanup #ifdef DEBUG_MODE_FULL @@ -104,7 +103,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 4597cf3d40..02fdfa0193 100644 --- a/addons/common/functions/fnc_cbaSettings_convertHelper.sqf +++ b/addons/common/functions/fnc_cbaSettings_convertHelper.sqf @@ -22,7 +22,7 @@ private _output = [format ["// CBA Settings [ADDON: %1]:", _addon]]; private _addonSearch = _addon + "_"; private _addonSearchCount = count _addonSearch; -TRACE_2("",_addonSearch, _addonSearchCount); +TRACE_2("",_addonSearch,_addonSearchCount); private _settings = configProperties [configFile >> "ACE_Settings", "(isClass _x) && {((configName _x) select [0, _addonSearchCount]) == _addonSearch}"]; @@ -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_cbaSettings_settingChanged.sqf b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf index 43711d4c97..cf9f18166a 100644 --- a/addons/common/functions/fnc_cbaSettings_settingChanged.sqf +++ b/addons/common/functions/fnc_cbaSettings_settingChanged.sqf @@ -1,8 +1,8 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Function for handeling a cba setting being changed. - * Adds warning if global setting is changed after ace_settingsInitialized + * Function for handling a cba setting being changed. + * Adds warning if global setting is changed after ace_settingsInitialized. * * Arguments: * 0: Setting Name @@ -21,9 +21,7 @@ params ["_settingName", "_newValue", ["_canBeChanged", false]]; TRACE_2("",_settingName,_newValue); -["ace_settingChanged", [_settingName, _newValue]] call CBA_fnc_localEvent; - -if (!((toLower _settingName) in CBA_settings_needRestart)) exitWith {}; +if !((toLower _settingName) in CBA_settings_needRestart) exitWith {}; if (_canBeChanged) exitWith {WARNING_1("update cba setting [%1] to use correct Need Restart param",_settingName);}; if (!GVAR(settingsInitFinished)) exitWith {}; // Ignore changed event before CBA_settingsInitialized diff --git a/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf b/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf index eaa9d089fc..8b6e62cbf6 100644 --- a/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf +++ b/addons/common/functions/fnc_cbaSettings_transferUserSettings.sqf @@ -34,7 +34,7 @@ private _aceSettings = configProperties [configFile >> "ACE_Settings", "isClass if (_isClientSettable && {_currentValue isNotEqualTo _profileVar}) then { // CBA_settings_fnc_set will do type checking for the old profile var private _ret = [_settingName, _profileVar, 0, "client", true] call CBA_settings_fnc_set; - INFO_3("Transfering setting [%1: %2] returned %3", _settingName, _profileVar, _ret); + INFO_3("Transfering setting [%1: %2] returned %3",_settingName,_profileVar,_ret); }; }; } forEach _aceSettings; diff --git a/addons/common/functions/fnc_checkFiles.sqf b/addons/common/functions/fnc_checkFiles.sqf index a5110aee6c..7b90a1b0a8 100644 --- a/addons/common/functions/fnc_checkFiles.sqf +++ b/addons/common/functions/fnc_checkFiles.sqf @@ -15,15 +15,20 @@ * Public: No */ -/////////////// -// check addons -/////////////// -private _mainCfg = configFile >> "CfgPatches" >> "ace_main"; -private _mainVersion = getText (_mainCfg >> "versionStr"); -private _mainSource = configSourceMod _mainCfg; +// Don't execute in scheduled environment +if (canSuspend) exitWith { + [FUNC(checkFiles), nil] call CBA_fnc_directCall; +}; -//CBA Versioning check - close main display if using incompatible version -private _cbaVersionAr = getArray (configFile >> "CfgPatches" >> "cba_main" >> "versionAr"); +/////////////// +// Check addons +/////////////// +private _cfgPatches = configFile >> "CfgPatches"; +private _mainVersion = getText (_cfgPatches >> "ace_main" >> "versionStr"); +private _mainSource = configSourceMod (_cfgPatches >> "ace_main"); + +// CBA Versioning check - close main display if using incompatible version +private _cbaVersionAr = getArray (_cfgPatches >> "cba_main" >> "versionAr"); private _cbaRequiredAr = getArray (configFile >> "CfgSettings" >> "CBA" >> "Versioning" >> "ACE" >> "dependencies" >> "CBA") select 1; private _cbaVersionStr = _cbaVersionAr joinString "."; @@ -31,63 +36,73 @@ private _cbaRequiredStr = _cbaRequiredAr joinString "."; INFO_3("ACE is version %1 - CBA is version %2 (min required %3)",_mainVersion,_cbaVersionStr,_cbaRequiredStr); -if ([_cbaRequiredAr, _cbaVersionAr] call cba_versioning_fnc_version_compare) then { +if ([_cbaRequiredAr, _cbaVersionAr] call CBA_versioning_fnc_version_compare) then { private _errorMsg = format ["CBA version %1 is outdated (required %2)", _cbaVersionStr, _cbaRequiredStr]; ERROR(_errorMsg); + if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; }; -//private _addons = activatedAddons; // broken with High-Command module, see #2134 -private _addons = (cba_common_addons select {(_x select [0,4]) == "ace_"}) apply {toLower _x}; +//private _addons = activatedAddons; // Broken with High-Command module, see #2134 +private _addons = (CBA_common_addons select {(_x select [0, 4]) == "ace_"}) apply {toLowerANSI _x}; + private _oldAddons = []; private _oldSources = []; private _oldCompats = []; + { private _addonCfg = configFile >> "CfgPatches" >> _x; private _addonVersion = getText (_addonCfg >> "versionStr"); + if (_addonVersion != _mainVersion) then { private _addonSource = configSourceMod _addonCfg; + _oldSources pushBackUnique _addonSource; + + // Check ACE install call FUNC(checkFiles_diagnoseACE); + // Don't block game if it's just an old compat pbo if ((_x select [0, 10]) != "ace_compat") then { - if (hasInterface) then { - _oldAddons pushBack _x; - }; + _oldAddons pushBack _x; } else { - _oldCompats pushBack [_x, _addonVersion]; // Don't block game if it's just an old compat pbo + _oldCompats pushBack [_x, _addonVersion]; }; }; } forEach _addons; if (_oldAddons isNotEqualTo []) then { - _oldAddons = _oldAddons apply {"%1.pbo", _x}; - private _errorMsg = ""; - if (count _oldAddons > 3) then { - _errorMsg = format ["The following files are outdated: %1, and %2 more.
ACE Main version is %3 from %4.
Loaded mods with outdated ACE files: %5", (_oldAddons select [0, 3]) joinString ", ", (count _oldAddons) -3, _mainVersion, _mainSource, (_oldSources joinString ", ")]; + _oldAddons = _oldAddons apply {format ["%1.pbo", _x]}; + + private _errorMsg = if (count _oldAddons > 3) then { + format ["The following files are outdated: %1, and %2 more.
ACE Main version is %3 from %4.
Loaded mods with outdated ACE files: %5", (_oldAddons select [0, 3]) joinString ", ", (count _oldAddons) - 3, _mainVersion, _mainSource, _oldSources joinString ", "]; } else { - _errorMsg = format ["The following files are outdated: %1.
ACE Main version is %2 from %3.
Loaded mods with outdated ACE files: %4", (_oldAddons) joinString ", ", _mainVersion, _mainSource, (_oldSources) joinString ", "]; + format ["The following files are outdated: %1.
ACE Main version is %2 from %3.
Loaded mods with outdated ACE files: %4", _oldAddons joinString ", ", _mainVersion, _mainSource, _oldSources joinString ", "]; }; + if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; + ERROR(_errorMsg); }; if (_oldCompats isNotEqualTo []) then { _oldCompats = _oldCompats apply {format ["%1 (%2)", _x select 0, _x select 1]}; + [{ // Lasts for ~10 seconds - ERROR_WITH_TITLE_3("The following ACE compatiblity PBOs are outdated", "%1. ACE Main version is %2 from %3.",_this select 0,_this select 1,_this select 2); + ERROR_WITH_TITLE_3("The following ACE compatiblity PBOs are outdated","%1. ACE Main version is %2 from %3.",_this select 0,_this select 1,_this select 2); }, [_oldCompats, _mainVersion, _mainSource], 1] call CBA_fnc_waitAndExecute; }; /////////////// -// check extensions +// 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"); @@ -101,8 +116,10 @@ if (!isServer && {_platform in ["linux", "osx"]}) then { if ((_isWindows || _isLinux) && {_isClient || _isServer}) then { private _versionEx = _extension callExtension "version"; + if (_versionEx == "") then { private _extensionFile = _extension; + if (productVersion select 7 == "x64") then { _extensionFile = format ["%1_x64", _extensionFile]; }; @@ -114,7 +131,7 @@ if (!isServer && {_platform in ["linux", "osx"]}) then { ERROR(_errorMsg); if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; } else { // Print the current extension version @@ -123,54 +140,66 @@ if (!isServer && {_platform in ["linux", "osx"]}) then { }; } forEach ("true" configClasses (configFile >> "ACE_Extensions")); }; + if (isArray (configFile >> "ACE_Extensions" >> "extensions")) then { WARNING("extensions[] array no longer supported"); }; /////////////// -// check server version/addons +// Check server version/addons /////////////// if (isMultiplayer) then { - // don't check optional addons - _addons = _addons select {getNumber (configFile >> "CfgPatches" >> _x >> "ACE_isOptional") != 1}; + // Don't check optional addons + _addons = _addons select {getNumber (_cfgPatches >> _x >> "ACE_isOptional") != 1}; if (isServer) then { - // send servers version of ACE to all clients - GVAR(ServerVersion) = _mainVersion; - GVAR(ServerAddons) = _addons; - publicVariable QGVAR(ServerVersion); - publicVariable QGVAR(ServerAddons); + // Send server's version of ACE to all clients + GVAR(serverVersion) = _mainVersion; + GVAR(serverAddons) = _addons; + GVAR(serverSource) = _mainSource; + + publicVariable QGVAR(serverVersion); + publicVariable QGVAR(serverAddons); + publicVariable QGVAR(serverSource); } else { - // clients have to wait for the variables - [{ - if (isNil QGVAR(ServerVersion) || isNil QGVAR(ServerAddons)) exitWith {}; + GVAR(clientVersion) = _version; + GVAR(clientAddons) = _addons; - (_this select 0) params ["_mainVersion", "_addons"]; - - if (_mainVersion != GVAR(ServerVersion)) then { - private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2.", GVAR(ServerVersion), _mainVersion]; + private _fnc_check = { + if (GVAR(clientVersion) != GVAR(serverVersion)) then { + private _errorMsg = format ["Client/Server Version Mismatch. Server: %1, Client: %2. Server modDir: %3", GVAR(serverVersion), GVAR(clientVersion), GVAR(serverSource)]; + // Check ACE install call FUNC(checkFiles_diagnoseACE); + ERROR(_errorMsg); if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; }; - _addons = _addons - GVAR(ServerAddons); + private _addons = GVAR(clientAddons) - GVAR(serverAddons); + if (_addons isNotEqualTo []) then { - private _errorMsg = format ["Client/Server Addon Mismatch. Client has extra addons: %1.",_addons]; + private _errorMsg = format ["Client/Server Addon Mismatch. Client has additional addons: %1. Server modDir: %2", _addons, GVAR(serverSource)]; + // Check ACE install call FUNC(checkFiles_diagnoseACE); + ERROR(_errorMsg); if (hasInterface) then { - ["[ACE] ERROR", _errorMsg, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); + ["[ACE] ERROR", _errorMsg] call FUNC(errorMessage); }; }; + }; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }, 1, [_mainVersion,_addons]] call CBA_fnc_addPerFrameHandler; + // Clients have to wait for the variables + if (isNil QGVAR(serverVersion) || isNil QGVAR(serverAddons)) then { + GVAR(serverVersion) addPublicVariableEventHandler _fnc_check; + } else { + call _fnc_check; + }; }; }; diff --git a/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf b/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf index 5b7f80198b..f9271ca213 100644 --- a/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf +++ b/addons/common/functions/fnc_checkFiles_diagnoseACE.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Diagnose ACE install problems, this will only be called if there is a known problem + * Diagnoses ACE install problems, this will only be called if there is a known problem. * * Arguments: * None * * Return Value: - * None + * ACE addons' WS IDs * * Example: * [] call ace_common_fnc_checkFiles_diagnoseACE @@ -16,43 +16,59 @@ */ // Only run once -if (missionNameSpace getVariable [QGVAR(checkFiles_diagnoseACE), false]) exitWith {}; +if (missionNameSpace getVariable [QGVAR(checkFiles_diagnoseACE), false]) exitWith { + createHashMap // return +}; + GVAR(checkFiles_diagnoseACE) = true; -private _addons = cba_common_addons select {(_x select [0,4]) == "ace_"}; +private _addons = CBA_common_addons select {(_x select [0, 4]) == "ace_"}; private _cfgPatches = configFile >> "CfgPatches"; private _allMods = createHashMap; +private _getLoadedModsInfo = getLoadedModsInfo; -// Check ACE_ADDONs are in expected mod DIR +// Check if ACE_ADDONs are in expected mod DIR { - private _cfg = (_cfgPatches >> _x); + private _cfg = _cfgPatches >> _x; private _actualModDir = configSourceMod _cfg; private _expectedModDir = getText (_cfg >> "ACE_expectedModDir"); - if (_expectedModDir == "") then { _expectedModDir = "@ace" }; + + if (_expectedModDir == "") then { + _expectedModDir = "@ace"; + }; + private _expectedSteamID = getText (_cfg >> "ACE_expectedSteamID"); - if (_expectedSteamID == "") then { _expectedSteamID = "463939057" }; + + if (_expectedSteamID == "") then { + _expectedSteamID = "463939057" + }; (_allMods getOrDefault [_actualModDir, [], true]) pushBackUnique _expectedSteamID; + if (_actualModDir != _expectedModDir) then { - private _errorMsg = format ["%1 loading from unexpected modDir [%2]",_x,_actualModDir]; + private _errorMsg = format ["%1 loading from unexpected modDir [%2]", _x, _actualModDir]; systemChat _errorMsg; WARNING_1("%1",_errorMsg); }; } forEach _addons; -// Check all ACE ModDirs have expected steam WS ID +// Check if all ACE ModDirs have expected steam WS ID { private _modDir = _x; - if ((count _y) != 1) then { ERROR_2("Unexpected multiple steamIDs %1 - %2",_modDir,_y) }; - private _expectedSteamID = _y # 0; - private _index = getLoadedModsInfo findIf {_x#1 == _modDir}; - (getLoadedModsInfo param [_index, []]) params [["_modName", "$Error$"], "", "", "", "", "", "", ["_actualID", ""]]; + + if (count _y != 1) then { + ERROR_2("Unexpected multiple steamIDs %1 - %2",_modDir,_y); + }; + + private _expectedSteamID = _y select 0; + private _index = _getLoadedModsInfo findIf {_x select 1 == _modDir}; + (_getLoadedModsInfo param [_index, []]) params [["_modName", "$Error$"], "", "", "", "", "", "", ["_actualID", ""]]; if (_actualID != _expectedSteamID) then { - private _errorMsg = format ["%1 [%2] unexpected workshopID [%3]",_modDir,_modName,_actualID]; + private _errorMsg = format ["%1 [%2] unexpected workshopID [%3]", _modDir, _modName, _actualID]; systemChat _errorMsg; WARNING_1("%1",_errorMsg); }; } forEach _allMods; -_allMods +_allMods // return diff --git a/addons/common/functions/fnc_checkPBOs.sqf b/addons/common/functions/fnc_checkPBOs.sqf index f69f486d5e..4f2e3f4fa6 100644 --- a/addons/common/functions/fnc_checkPBOs.sqf +++ b/addons/common/functions/fnc_checkPBOs.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: commy2 + * Author: commy2, johnb43 * Used to execute the checkPBOs module without placing the module. Don't use this together with the module. * Checks PBO versions and compares to the one running on server. * @@ -9,8 +9,8 @@ * 0 = Warn once * 1 = Warn permanently * 2 = Kick - * 1: Check all PBOs? (default: false) - * 2: Whitelist (default: "") + * 1: Check all PBOs? (default: false) + * 2: Whitelist (default: "") * * Return Value: * None @@ -24,83 +24,75 @@ params ["_mode", ["_checkAll", false], ["_whitelist", "", [""]]]; TRACE_3("params",_mode,_checkAll,_whitelist); -//lowercase and convert whiteList String into array of strings: -_whitelist = toLower _whitelist; +// Lowercase and convert whiteList string into array of strings +_whitelist = toLowerANSI _whitelist; _whitelist = _whitelist splitString "[,""']"; TRACE_1("Array",_whitelist); ACE_Version_CheckAll = _checkAll; ACE_Version_Whitelist = _whitelist; -if (!_checkAll) exitWith {}; //ACE is checked by FUNC(checkFiles) +// ACE is checked by FUNC(checkFiles) +if (!_checkAll) exitWith {}; if (!isServer) then { - [{ - if (isNil "ACE_Version_ClientErrors") exitWith {}; + ["ace_versioning_clientCheckDone", { + // Don't let this event get triggered again + [_thisType, _thisId] call CBA_fnc_removeEventHandler; - ACE_Version_ClientErrors params ["_missingAddon", "_missingAddonServer", "_oldVersionClient", "_oldVersionServer"]; + params ["_clientErrors"]; + _clientErrors params ["_missingAddonClient", "_additionalAddonClient", "_olderVersionClient", "_newerVersionClient"]; + _thisArgs params ["_mode"]; - (_this select 0) params ["_mode", "_checkAll", "_whitelist"]; + // Display error message(s) + if (_missingAddonClient || {_additionalAddonClient} || {_olderVersionClient} || {_newerVersionClient}) then { + private _errorMsg = "[ACE] Version mismatch:

"; + private _error = []; - // Display error message. - if (_missingAddon || {_missingAddonServer} || {_oldVersionClient} || {_oldVersionServer}) then { - private _text = "[ACE] Version mismatch:

"; - private _error = format ["ACE version mismatch: %1: ", profileName]; - - if (_missingAddon) then { - _text = _text + "Detected missing addon on client
"; - _error = _error + "Missing file(s); "; - }; - if (_missingAddonServer) then { - _text = _text + "Detected missing addon on server
"; - _error = _error + "Additional file(s); "; - }; - if (_oldVersionClient) then { - _text = _text + "Detected old client version
"; - _error = _error + "Older version; "; - }; - if (_oldVersionServer) then { - _text = _text + "Detected old server version
"; - _error = _error + "Newer version; "; + if (_missingAddonClient) then { + _errorMsg = _errorMsg + "Detected missing addon on client
"; + _error pushBack "Missing file(s)"; }; - //[QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; + if (_additionalAddonClient) then { + _errorMsg = _errorMsg + "Detected additional addon on client
"; + _error pushBack "Additional file(s)"; + }; - ERROR(_error); + if (_olderVersionClient) then { + _errorMsg = _errorMsg + "Detected older client version
"; + _error pushBack "Older version"; + }; + if (_newerVersionClient) then { + _errorMsg = _errorMsg + "Detected newer client version
"; + _error pushBack "Newer version"; + }; + + ERROR_2("[ACE] Version mismatch: %1: %2",profileName,_error joinString ", "); + + _errorMsg = parseText format ["%1", _errorMsg]; + + // Warn if (_mode < 2) then { - _text = composeText [lineBreak, parseText format ["%1", _text]]; - private _rscLayer = "ACE_RscErrorHint" call BIS_fnc_rscLayer; _rscLayer cutRsc ["ACE_RscErrorHint", "PLAIN", 0, true]; - disableSerialization; - private _ctrlHint = uiNamespace getVariable "ACE_ctrlErrorHint"; - _ctrlHint ctrlSetStructuredText _text; + (uiNamespace getVariable "ACE_ctrlErrorHint") ctrlSetStructuredText composeText [lineBreak, _errorMsg]; if (_mode == 0) then { [{ - params ["_rscLayer"]; - TRACE_2("Hiding Error message after 10 seconds",time,_rscLayer); - _rscLayer cutFadeOut 0.2; - }, [_rscLayer], 10] call CBA_fnc_waitAndExecute; + TRACE_2("Hiding Error message after 10 seconds",time,_this); + _this cutFadeOut 0.2; + }, _rscLayer, 10] call CBA_fnc_waitAndExecute; }; - }; - - if (_mode == 2) then { - [{alive player}, { // To be able to show list if using checkAll - params ["_text"]; - TRACE_2("Player is alive, showing msg and exiting",time,_text); - _text = composeText [parseText format ["%1", _text]]; - ["[ACE] ERROR", _text, {findDisplay 46 closeDisplay 0}] call FUNC(errorMessage); - }, [_text]] call CBA_fnc_waitUntilAndExecute; + } else { + // Kick + ["[ACE] ERROR", composeText [_errorMsg]] call FUNC(errorMessage); }; }; - - [_this select 1] call CBA_fnc_removePerFrameHandler; - }, 1, [_mode, _checkAll, _whitelist]] call CBA_fnc_addPerFrameHandler; + }, [_mode]] call CBA_fnc_addEventHandlerArgs; }; -if (_checkAll) then { - 0 spawn COMPILE_FILE(scripts\checkVersionNumber); // @todo -}; +// Check file version numbers +[_whitelist] call FUNC(checkVersionNumber); diff --git a/addons/common/functions/fnc_checkVersionNumber.sqf b/addons/common/functions/fnc_checkVersionNumber.sqf new file mode 100644 index 0000000000..a286129917 --- /dev/null +++ b/addons/common/functions/fnc_checkVersionNumber.sqf @@ -0,0 +1,161 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Compares version numbers from loaded addons. + * + * Arguments: + * 0: Lowercase addon whitelist (default: missionNamespace getVariable ["ACE_Version_Whitelist", []]) + * + * Return Value: + * None + * + * Example: + * call ace_common_fnc_checkVersionNumber + * + * Public: No + */ + +// Don't execute in scheduled environment +if (canSuspend) exitWith { + [FUNC(checkVersionNumber), _this] call CBA_fnc_directCall; +}; + +params [["_whitelist", missionNamespace getVariable ["ACE_Version_Whitelist", []]]]; + +private _files = CBA_common_addons select { + (_x select [0, 3] != "a3_") && + {_x select [0, 4] != "ace_"} && + {!((toLowerANSI _x) in _whitelist)} +}; + +private _cfgPatches = configFile >> "CfgPatches"; +private _versions = []; + +{ + (getText (_cfgPatches >> _x >> "version") splitString ".") params [["_major", "0"], ["_minor", "0"]]; + private _version = parseNumber _major + parseNumber _minor / 100; + _versions pushBack _version; +} forEach _files; + +if (isServer) exitWith { + ACE_Version_ServerVersions = [_files, _versions]; + publicVariable "ACE_Version_ServerVersions"; + + // Raise event when done + ["ace_versioning_serverCheckDone", [+ACE_Version_ServerVersions]] call CBA_fnc_localEvent; +}; + +// Begin client version check +ACE_Version_ClientVersions = [_files, _versions]; + +private _fnc_check = { + ACE_Version_ClientVersions params [["_files", []], ["_versions", []]]; + ACE_Version_ServerVersions params [["_serverFiles", []], ["_serverVersions", []]]; + + // Compare client and server files and versions + private _client = profileName; + private _missingAddonsClient = []; + private _olderVersionsClient = []; + private _newerVersionsClient = []; + + { + private _serverVersion = _serverVersions select _forEachIndex; + + private _index = _files find _x; + + if (_index == -1) then { + if (_x != "ace_server") then { + _missingAddonsClient pushBack _x; + }; + } else { + private _clientVersion = _versions select _index; + + if (_clientVersion < _serverVersion) then { + _olderVersionsClient pushBack [_x, _clientVersion, _serverVersion]; + }; + + if (_clientVersion > _serverVersion) then { + _newerVersionsClient pushBack [_x, _clientVersion, _serverVersion]; + }; + }; + } forEach _serverFiles; + + // Find client files which the server doesn't have + private _additionalAddonsClient = _files select {!(_x in _serverFiles)}; + + // Check for client missing addons, server missing addons, client outdated addons and server outdated addons + private _clientErrors = []; + + #define DISPLAY_NUMBER_ADDONS (10 + 1) // +1 to account for header + + { + _x params ["_items", "_string"]; + + // Check if something is either missing or outdated + private _isMissingItems = _items isNotEqualTo []; + + if (_isMissingItems) then { + // Generate error message + private _errorLog = +_items; + private _header = format ["[ACE] %1: ERROR %2 addon(s): ", _client, _string]; + + // Don't display all missing items, as they are logged + private _errorMsg = _header + ((_errorLog select [0, DISPLAY_NUMBER_ADDONS]) joinString ", "); + _errorLog = _header + (_errorLog joinString ", "); + + private _count = count _items; + + if (_count > DISPLAY_NUMBER_ADDONS) then { + _errorMsg = _errorMsg + format [", and %1 more.", _count - DISPLAY_NUMBER_ADDONS]; + }; + + // Wait until in briefing screen + [{ + getClientStateNumber >= 9 // "BRIEFING SHOWN" + }, { + params ["_errorLog", "_errorMsg"]; + + // Log and display error messages + diag_log text _errorLog; + [QGVAR(serverLog), _errorLog] call CBA_fnc_serverEvent; + [QGVAR(systemChatGlobal), _errorMsg] call CBA_fnc_globalEvent; + + // Wait until after map screen + [{ + !isNull (call BIS_fnc_displayMission) + }, { + params ["_errorMsg", "_timeOut"]; + + // If the briefing screen was shown for less than 5 seconds, display the error message again, but locally + if (_timeOut < CBA_missionTime) exitWith {}; + + // Make sure systemChat is ready by waiting a bit + [{ + systemChat _this; + }, _errorMsg, 1] call CBA_fnc_waitAndExecute; + }, [_errorMsg, CBA_missionTime + 5]] call CBA_fnc_waitUntilAndExecute; + }, [_errorLog, _errorMsg]] call CBA_fnc_waitUntilAndExecute; + }; + + _clientErrors pushBack _isMissingItems; + } forEach [ + [_missingAddonsClient, "client missing"], + [_additionalAddonsClient, "client additional"], + [_olderVersionsClient, "older client"], + [_newerVersionsClient, "newer client"] + ]; + + TRACE_4("",_missingAddonsClient,_additionalAddonsClient,_olderVersionsClient,_newerVersionsClient); + + ACE_Version_ClientErrors = _clientErrors; + + // Raise event when done + ["ace_versioning_clientCheckDone", [+ACE_Version_ClientErrors]] call CBA_fnc_localEvent; +}; + +// Wait for server to send the servers files and version numbers +if (isNil "ACE_Version_ServerVersions") then { + ACE_Version_ServerVersions addPublicVariableEventHandler _fnc_check; +} else { + call _fnc_check; +}; diff --git a/addons/common/functions/fnc_claim.sqf b/addons/common/functions/fnc_claim.sqf index 06b13d0778..997d54f33b 100644 --- a/addons/common/functions/fnc_claim.sqf +++ b/addons/common/functions/fnc_claim.sqf @@ -30,17 +30,10 @@ _target setVariable [QGVAR(owner), _unit, true]; // lock target object if (_lockTarget) then { - private _canBeDisassembled = ([] isNotEqualTo getArray (configOf _target >> "assembleInfo" >> "dissasembleTo")) && { !([false, true] select (_target getVariable [QEGVAR(csw,assemblyMode), 0])) }; if (!isNull _unit) then { [QGVAR(lockVehicle), _target, _target] call CBA_fnc_targetEvent; - if (_canBeDisassembled) then { - _target enableWeaponDisassembly false; - }; } else { [QGVAR(unlockVehicle), _target, _target] call CBA_fnc_targetEvent; - if (_canBeDisassembled) then { - _target enableWeaponDisassembly true; - }; }; }; diff --git a/addons/common/functions/fnc_claimSafeServer.sqf b/addons/common/functions/fnc_claimSafeServer.sqf index b8d761c22a..6ebee7cb4f 100644 --- a/addons/common/functions/fnc_claimSafeServer.sqf +++ b/addons/common/functions/fnc_claimSafeServer.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: commy2, PabstMirror - * Unit claims the ownership over an object. This is used to prevent multiple players from draging the same ammo box or using up the same wheel when repairing etc. + * Unit claims the ownership over an object. This is used to prevent multiple players from dragging the same ammo box or using up the same wheel when repairing etc. * This function only runs on the server and handles the "ace_common_claimSafe" event. It provides a network safe way claiming objects as all claims are run on server. * Return event is passed [_unit, _target, _success] for new claims, no event on claim release * @@ -36,17 +36,10 @@ _target setVariable [QGVAR(owner), _unit, true]; // lock target object if (_lockTarget) then { - private _canBeDisassembled = ([] isNotEqualTo getArray (configOf _target >> "assembleInfo" >> "dissasembleTo")) && { !([false, true] select (_target getVariable [QEGVAR(csw,assemblyMode), 0])) }; if (!isNull _unit) then { [QGVAR(lockVehicle), _target, _target] call CBA_fnc_targetEvent; - if (_canBeDisassembled) then { - _target enableWeaponDisassembly false; - }; } else { [QGVAR(unlockVehicle), _target, _target] call CBA_fnc_targetEvent; - if (_canBeDisassembled) then { - _target enableWeaponDisassembly true; - }; }; }; diff --git a/addons/common/functions/fnc_defineVariable.sqf b/addons/common/functions/fnc_defineVariable.sqf index 6cf537b1f8..85eb7b447f 100644 --- a/addons/common/functions/fnc_defineVariable.sqf +++ b/addons/common/functions/fnc_defineVariable.sqf @@ -24,7 +24,7 @@ params ["_name", "_value", "_defaultGlobal", "_category", ["_code", 0], ["_persi if (isNil "_defaultGlobal") exitWith {}; -if (!(_name isEqualType "")) exitwith { +if !(_name isEqualType "") exitwith { [format ["Tried to the deinfe a variable with an invalid name: %1 Arguments: %2", _name, _this]] call FUNC(debug); }; diff --git a/addons/common/functions/fnc_disableAI.sqf b/addons/common/functions/fnc_disableAI.sqf index 52f1ed37c3..a0c725c7db 100644 --- a/addons/common/functions/fnc_disableAI.sqf +++ b/addons/common/functions/fnc_disableAI.sqf @@ -29,7 +29,7 @@ if !([_unit] call EFUNC(common,isPlayer)) then { _unit disableConversation true; } else { //Sanity check to make sure we don't enable unconsious AI - if (_unit getVariable ["ace_isunconscious", false] && alive _unit) exitWith { + if (_unit getVariable ["ACE_isUnconscious", false] && alive _unit) exitWith { ERROR("Enabling AI for unconsious unit"); }; diff --git a/addons/common/functions/fnc_disableAiUAV.sqf b/addons/common/functions/fnc_disableAiUAV.sqf new file mode 100644 index 0000000000..195e3ed2dc --- /dev/null +++ b/addons/common/functions/fnc_disableAiUAV.sqf @@ -0,0 +1,45 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Disables/Enables UAV AI crew members, can be run on any machine and is applied globally. + * + * Arguments: + * 0: Unit + * 1: Disable AI + * + * Return Value: + * None + * + * Example: + * [cursorObject, true] call ace_common_fnc_disableAiUAV + * + * Public: No + */ + +params [["_unit", objNull, [objNull]], ["_disable", true, [false]]]; + +// Allow disabling of Zeus remote controlled units +if (!alive _unit || {isPlayer _unit} || {!unitIsUAV _unit}) exitWith {}; + +if (_disable) then { + // Ignore if already disabled + if (!isNil "_jipID") exitWith {}; + + // Disable shooting and targeting on every machine + // Give predefined JIP ID, in case of simultaneous executions on different machines + private _jipID = [QGVAR(disableAiUAV), [_unit, _disable], QGVAR(disableAiUAV_) + hashValue _unit] call CBA_fnc_globalEventJIP; + [_jipID, _unit] call CBA_fnc_removeGlobalEventJIP; + + _unit setVariable [QGVAR(disableAiUavJipID), _jipID, true]; +} else { + // Restore shooting and targeting to each client's individual state prior to disabling + private _jipID = _unit getVariable QGVAR(disableAiUavJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _unit setVariable [QGVAR(disableAiUavJipID), nil, true]; + + [QGVAR(disableAiUAV), [_unit, _disable]] call CBA_fnc_globalEvent; +}; diff --git a/addons/common/functions/fnc_disableUserInput.sqf b/addons/common/functions/fnc_disableUserInput.sqf index 4037a168b7..b89750e656 100644 --- a/addons/common/functions/fnc_disableUserInput.sqf +++ b/addons/common/functions/fnc_disableUserInput.sqf @@ -1,7 +1,8 @@ #include "..\script_component.hpp" #include "\a3\ui_f_curator\ui\defineResinclDesign.inc" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" /* - * Author: commy2 + * Author: commy2, johnb43 * Disables key input. ESC can still be pressed to open the menu. * * Arguments: @@ -27,7 +28,7 @@ if (_state) then { if (!isNull (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull])) exitWith {}; if (!isNil QGVAR(disableInputPFH)) exitWith {}; - // end TFAR and ACRE2 radio transmissions + // End TFAR and ACRE2 radio transmissions call FUNC(endRadioTransmission); // Close map @@ -45,38 +46,116 @@ if (_state) then { private _map = _display displayCtrl 101; _map ctrlMapCursor ["", QGVAR(blank)]; + GVAR(keyboardInputMain) = createHashMap; + GVAR(keyboardInputCombo) = createHashMap; + _display displayAddEventHandler ["KeyDown", { + // If input is enabled again, ignore + if (isNil QGVAR(keyboardInputMain)) exitWith {}; + params ["", "_key"]; - if (_key == 1 && {alive player}) then { - createDialog (["RscDisplayInterrupt", "RscDisplayMPInterrupt"] select isMultiplayer); + // Get key info; Stored as [isPressed, pressedCount] + private _keyPressedInfo = GVAR(keyboardInputMain) getOrDefault [_key, [false, 0], true]; + _keyPressedInfo params ["_keyPressed", "_keyPressedCount"]; + // For regular keys: If pressed, set to release and remove one key press + if (!_keyPressed) then { + _keyPressedInfo set [0, true]; + _keyPressedInfo set [1, _keyPressedCount + 1]; + }; + + // For combo keys, register only if pushed or released (no keypress count) + if !(GVAR(keyboardInputCombo) getOrDefault [_key, false]) then { + GVAR(keyboardInputCombo) set [_key, true]; + }; + + // Look if keybinds of various actions have been pressed + private _action = ""; + private _comboDikPressed = false; + private _return = false; + + // This technique has a limitation: It can't process the Escape key properly (KeyUp EH does not fire) + (["TeamSwitch", "CuratorInterface", "ShowMap", "DefaultAction", "Throw", "Chat", "PrevChannel", "NextChannel"] apply { + _action = _x; + + { + _x params ["_mainKeyArray", "_comboKeyArray", "_isDoubleTap"]; + _mainKeyArray params ["_mainDik", "_mainDevice"]; + + // If keybind doesn't contain key combo, it returns empty array; Therefore, return true + _comboDikPressed = if (_comboKeyArray isEqualTo []) then { + true + } else { + _comboKeyArray params ["_comboDik", "_comboDevice"]; + + _comboDevice == "KEYBOARD" && {GVAR(keyboardInputCombo) getOrDefault [_comboDik, false]} + }; + + // Check if the necessary keys were pressed for a keybind + _return = _comboDikPressed && + {_mainDevice == "KEYBOARD"} && + {((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 { + TRACE_1("Action triggered: ",_action); + }; + } forEach (actionKeysEx _action); + + _return + }) params ["_teamSwitch", "_curatorInterface", "_showMap", "_defaultAction", "_throw", "_chat", "_prevChannel", "_nextChannel"]; + + // Handle Escape separately because of limitation mentioned above + if (_key == DIK_ESCAPE && {alive player}) then { disableSerialization; + private _isMultiplayer = isMultiplayer; + private _is3DENPreview = is3DENPreview; + + createDialog (["RscDisplayInterrupt", "RscDisplayMPInterrupt"] select _isMultiplayer); + private _dlg = findDisplay 49; for "_index" from 100 to 2000 do { (_dlg displayCtrl _index) ctrlEnable false; }; - private _ctrl = _dlg displayctrl 103; - _ctrl ctrlSetEventHandler ["buttonClick", QUOTE(while {!isNull (uiNamespace getVariable [ARR_2(QUOTE(QGVAR(dlgDisableMouse)),displayNull)])} do {closeDialog 0}; failMission 'LOSER'; [false] call DFUNC(disableUserInput))]; - _ctrl ctrlEnable true; - _ctrl ctrlSetText "ABORT"; - _ctrl ctrlSetTooltip "Abort."; + private _ctrl = _dlg displayCtrl 103; + _ctrl ctrlSetEventHandler ["ButtonClick", toString { + while {!isNull (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull])} do { + closeDialog 0 + }; - _ctrl = _dlg displayctrl ([104, 1010] select isMultiplayer); - if (["ace_medical"] call FUNC(isModLoaded)) then { - _ctrl ctrlSetEventHandler ["buttonClick", 'closeDialog 0; [player, "respawn_button"] call EFUNC(medical_status,setDead); [false] call DFUNC(disableUserInput);']; - } else { - _ctrl ctrlSetEventHandler ["buttonClick", QUOTE(closeDialog 0; player setDamage 1; [false] call DFUNC(disableUserInput))]; - }; - _ctrl ctrlEnable ((getMissionConfigValue ["respawnButton", -1]) != 0); // handles 3den attribute or description.ext - _ctrl ctrlSetText localize "$str_3den_multiplayer_attributecategory_respawn_displayname"; - _ctrl ctrlSetTooltip "Respawn."; + failMission "LOSER"; + + [false] call FUNC(disableUserInput); + }]; + _ctrl ctrlEnable true; + _ctrl ctrlSetText localize (["str_disp_int_abort", "STR_3DEN_RscDisplayInterrupt_ButtonAbort_3DEN_text"] select (_is3DENPreview && !_isMultiplayer)); + _ctrl ctrlSetTooltip localize ([ + "STR_TOOLTIP_MAIN_ABORT_CAMPAIGN", + "STR_3DEN_RscDisplayInterrupt_ButtonAbort_3DEN_tooltip", + "STR_TOOLTIP_MAIN_ABORT" + ] select (([_is3DENPreview, _isMultiplayer] call FUNC(toBitmask)) min 2)); + + _ctrl = _dlg displayCtrl ([104, 1010] select _isMultiplayer); + _ctrl ctrlSetEventHandler ["ButtonClick", toString { + closeDialog 0; + + [player, "respawn_button"] call FUNC(setDead); + + [false] call FUNC(disableUserInput); + }]; + + private _respawnEnabled = (getMissionConfigValue ["respawnButton", -1]) != 0; + + _ctrl ctrlEnable _respawnEnabled; // handles 3den attribute or description.ext + _ctrl ctrlSetText localize "str_disp_int_respawn"; + _ctrl ctrlSetTooltip localize (["str_3den_attributes_respawn_none_tooltip", "str_disp_int_respawn"] select _respawnEnabled); }; - if (_key in actionKeys "TeamSwitch" && {teamSwitchEnabled}) then { + if (_teamSwitch && teamSwitchEnabled) then { (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; private _acc = accTime; @@ -84,18 +163,20 @@ if (_state) then { setAccTime _acc; }; - if (_key in actionKeys "CuratorInterface" && {getAssignedCuratorLogic player in allCurators}) then { + if (_curatorInterface && {!isNull getAssignedCuratorLogic player}) then { (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; + openCuratorInterface; }; - if (_key in actionKeys "ShowMap" && {player getVariable ["ACE_canSwitchUnits", false]}) then { + if (_showMap && {player getVariable ["ACE_canSwitchUnits", false]}) then { (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; + openMap true; }; - if (isServer || {serverCommandAvailable "#kick"}) then { - if (!(_key in (actionKeys "DefaultAction" + actionKeys "Throw")) && {_key in (actionKeys "Chat" + actionKeys "PrevChannel" + actionKeys "NextChannel")}) then { + if (isMultiplayer && {isServer || {serverCommandAvailable "#kick"}}) then { + if (!(_defaultAction || _throw) && {_chat || _prevChannel || _nextChannel}) then { _key = 0; }; }; @@ -103,7 +184,41 @@ if (_state) then { _key > 0 }]; - _display displayAddEventHandler ["KeyUp", {true}]; + _display displayAddEventHandler ["KeyUp", { + // If input is enabled again, ignore + if (isNil QGVAR(keyboardInputMain)) exitWith {}; + + params ["", "_key"]; + + // For combo keys: If pressed, release + if (GVAR(keyboardInputCombo) getOrDefault [_key, false]) then { + GVAR(keyboardInputCombo) deleteAt _key; + }; + + private _keyPressedInfo = GVAR(keyboardInputMain) getOrDefault [_key, [false, 0]]; + + // If pressed, release it + if (_keyPressedInfo select 0) then { + _keyPressedInfo set [0, false]; + }; + + // Cache keystrokes of regular keys for a small amount of time + [{ + // If input is enabled again, ignore + if (isNil QGVAR(keyboardInputMain)) exitWith {}; + + params ["_key"]; + + private _keyPressedInfo = GVAR(keyboardInputMain) getOrDefault [_key, [false, 0]]; + + // Release it + _keyPressedInfo set [1, ((_keyPressedInfo select 1) - 1) max 0]; + + if (_keyPressedInfo isEqualTo [false, 0]) then { + GVAR(keyboardInputMain) deleteAt _key; + }; + }, _key, 0.5] call CBA_fnc_waitAndExecute; + }]; }; GVAR(disableInputPFH) = [{ @@ -133,4 +248,7 @@ if (_state) then { }; (uiNamespace getVariable [QGVAR(dlgDisableMouse), displayNull]) closeDisplay 0; + + GVAR(keyboardInputMain) = nil; + GVAR(keyboardInputCombo) = nil; }; diff --git a/addons/common/functions/fnc_displayIcon.sqf b/addons/common/functions/fnc_displayIcon.sqf index 1b307fdf33..da08fa832a 100644 --- a/addons/common/functions/fnc_displayIcon.sqf +++ b/addons/common/functions/fnc_displayIcon.sqf @@ -53,8 +53,7 @@ private _refresh = { { ctrlDelete _x; - false - } count _allControls; + } forEach _allControls; _allControls = []; @@ -80,7 +79,6 @@ private _refresh = { _ctrl ctrlSetTextColor _xcolor; _ctrl ctrlCommit 0; _allControls pushBack _ctrl; - false } forEach (missionNamespace getVariable [QGVAR(displayIconList),[]]); }; @@ -116,8 +114,7 @@ if (_show) then { if (_x select 0 != _iconId) then { _newList pushBack _x; }; - false - } count _list; + } forEach _list; missionNamespace setVariable [QGVAR(displayIconList), _newList]; call _refresh; diff --git a/addons/common/functions/fnc_dumpArray.sqf b/addons/common/functions/fnc_dumpArray.sqf index 754b811314..87437c37e2 100644 --- a/addons/common/functions/fnc_dumpArray.sqf +++ b/addons/common/functions/fnc_dumpArray.sqf @@ -34,8 +34,7 @@ if (IS_ARRAY(_var)) then { { [_x, _depth] call FUNC(dumpArray); - false - } count _var; + } forEach _var; diag_log text format ["%1],", _pad]; }; diff --git a/addons/common/functions/fnc_dumpPerformanceCounters.sqf b/addons/common/functions/fnc_dumpPerformanceCounters.sqf index fa0b4e4e6d..309b82c673 100644 --- a/addons/common/functions/fnc_dumpPerformanceCounters.sqf +++ b/addons/common/functions/fnc_dumpPerformanceCounters.sqf @@ -25,8 +25,7 @@ if (!isNil "ACE_PFH_COUNTER") then { private _isActive = ["ACTIVE", "REMOVED"] select isNil {CBA_common_PFHhandles select (_pfh select 0)}; diag_log text format ["Registered PFH: id=%1 [%2, delay %3], %4:%5", _pfh select 0, _isActive, _parameters select 1, _pfh select 1, _pfh select 2]; - false - } count ACE_PFH_COUNTER; + } forEach ACE_PFH_COUNTER; }; diag_log text format ["ACE COUNTER RESULTS"]; @@ -50,8 +49,7 @@ diag_log text format ["-------------------------------------------"]; }; _iter = _iter + 1; - false - } count _counterEntry; + } forEach _counterEntry; // results _averageResult = (_total / _count) * 1000; @@ -61,8 +59,7 @@ diag_log text format ["-------------------------------------------"]; } else { diag_log text format ["%1: No results", _counterEntry select 0]; }; - false -} count ACE_COUNTERS; +} forEach ACE_COUNTERS; /* // Dump PFH Trackers diff --git a/addons/common/functions/fnc_errorMessage.sqf b/addons/common/functions/fnc_errorMessage.sqf index 021fdba10c..e98a5baf8f 100644 --- a/addons/common/functions/fnc_errorMessage.sqf +++ b/addons/common/functions/fnc_errorMessage.sqf @@ -1,147 +1,141 @@ #include "..\script_component.hpp" +#include "\a3\ui_f\hpp\defineResincl.inc" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" /* - * Author: commy2, based on BIS_fnc_errorMsg and BIS_fnc_guiMessage by Karel Moricky (BI) - * Stops simulation and opens a textbox with error message. + * Author: commy2, johnb43, based on BIS_fnc_errorMsg and BIS_fnc_guiMessage by Karel Moricky (BI) + * Opens a textbox with an error message, used for PBO checking. * * Arguments: - * ? + * 0: Header + * 1: Text * * Return Value: * None * * Example: - * call ace_common_fnc_errorMessage + * ["[ACE] ERROR", "Test"] call ace_common_fnc_errorMessage * * Public: No */ -disableSerialization; +// Force stop any loading screens endLoadingScreen; -// no message without player possible +// No message without interface possible if (!hasInterface) exitWith {}; -// wait for display -if (isNull (call BIS_fnc_displayMission)) exitWith { - [{ - if (isNull (call BIS_fnc_displayMission)) exitWith {}; +[{ + !isNull (call BIS_fnc_displayMission) +}, { + params ["_textHeader", "_textMessage"]; - (_this select 0) call FUNC(errorMessage); - [_this select 1] call CBA_fnc_removePerFrameHandler; + disableSerialization; - }, 1, _this] call CBA_fnc_addPerFrameHandler; -}; + // Use curator display if present + private _curatorDisplay = findDisplay 312; -params ["_textHeader", "_textMessage", ["_onOK", {}], ["_onCancel", {}]]; + private _mainDisplay = if (!isNull _curatorDisplay) then { + _curatorDisplay + } else { + call BIS_fnc_displayMission + }; -if (_textMessage isEqualType "") then { - _textMessage = parseText _textMessage; -}; + if (_textMessage isEqualType "") then { + _textMessage = parseText _textMessage; + }; -ARR_SELECT(_this,4,call BIS_fnc_displayMission) createDisplay "RscDisplayCommonMessagePause"; + private _display = _mainDisplay createDisplay "RscDisplayCommonMessagePause"; -private _display = uiNamespace getVariable "RscDisplayCommonMessage_display"; -private _ctrlRscMessageBox = _display displayCtrl 2351; -private _ctrlBcgCommonTop = _display displayCtrl 235100; -private _ctrlBcgCommon = _display displayCtrl 235101; -private _ctrlText = _display displayCtrl 235102; -private _ctrlBackgroundButtonOK = _display displayCtrl 235103; -private _ctrlBackgroundButtonMiddle = _display displayCtrl 235104; -private _ctrlBackgroundButtonCancel = _display displayCtrl 235105; -private _ctrlButtonOK = _display displayCtrl 235106; -private _ctrlButtonCancel = _display displayCtrl 235107; + if (isNull _display) exitWith {}; -_ctrlBcgCommonTop ctrlSetText _textHeader; + private _ctrlRscMessageBox = _display displayCtrl 2351; + private _ctrlBcgCommonTop = _display displayCtrl 235100; + private _ctrlBcgCommon = _display displayCtrl 235101; + private _ctrlText = _display displayCtrl 235102; + private _ctrlBackgroundButtonOK = _display displayCtrl 235103; + private _ctrlBackgroundButtonMiddle = _display displayCtrl 235104; + private _ctrlBackgroundButtonCancel = _display displayCtrl 235105; + private _ctrlButtonOK = _display displayCtrl 235106; + private _ctrlButtonCancel = _display displayCtrl 235107; -private _ctrlButtonOKPos = ctrlPosition _ctrlButtonOK; -private _ctrlBcgCommonPos = ctrlPosition _ctrlBcgCommon; -private _bottomSpaceY = (_ctrlButtonOKPos select 1) - ((_ctrlBcgCommonPos select 1) + (_ctrlBcgCommonPos select 3)); + _ctrlBcgCommonTop ctrlSetText _textHeader; -private _ctrlTextPos = ctrlPosition _ctrlText; -private _marginX = (_ctrlTextPos select 0) - (_ctrlBcgCommonPos select 0); -private _marginY = (_ctrlTextPos select 1) - (_ctrlBcgCommonPos select 1); + private _ctrlButtonOKPos = ctrlPosition _ctrlButtonOK; + private _ctrlBcgCommonPos = ctrlPosition _ctrlBcgCommon; + private _bottomSpaceY = (_ctrlButtonOKPos select 1) - ((_ctrlBcgCommonPos select 1) + (_ctrlBcgCommonPos select 3)); -_ctrlText ctrlSetStructuredText _textMessage; -private _ctrlTextPosH = ctrlTextHeight _ctrlText; + private _ctrlTextPos = ctrlPosition _ctrlText; + private _marginX = (_ctrlTextPos select 0) - (_ctrlBcgCommonPos select 0); + private _marginY = (_ctrlTextPos select 1) - (_ctrlBcgCommonPos select 1); -_ctrlBcgCommon ctrlSetPosition [ - _ctrlBcgCommonPos select 0, - _ctrlBcgCommonPos select 1, - _ctrlBcgCommonPos select 2, - _ctrlTextPosH + _marginY * 2 -]; -_ctrlBcgCommon ctrlCommit 0; + _ctrlText ctrlSetStructuredText _textMessage; + private _ctrlTextPosH = ctrlTextHeight _ctrlText; -_ctrlText ctrlSetPosition [ - (_ctrlBcgCommonPos select 0) + _marginX, - (_ctrlBcgCommonPos select 1) + _marginY, - (_ctrlBcgCommonPos select 2) - _marginX * 2, - _ctrlTextPosH -]; -_ctrlText ctrlCommit 0; + _ctrlBcgCommon ctrlSetPosition [ + _ctrlBcgCommonPos select 0, + _ctrlBcgCommonPos select 1, + _ctrlBcgCommonPos select 2, + _ctrlTextPosH + _marginY * 2 + ]; + _ctrlBcgCommon ctrlCommit 0; -private _bottomPosY = (_ctrlBcgCommonPos select 1) + _ctrlTextPosH + (_marginY * 2) + _bottomSpaceY; + _ctrlText ctrlSetPosition [ + (_ctrlBcgCommonPos select 0) + _marginX, + (_ctrlBcgCommonPos select 1) + _marginY, + (_ctrlBcgCommonPos select 2) - _marginX * 2, + _ctrlTextPosH + ]; + _ctrlText ctrlCommit 0; -{ - private _xPos = ctrlPosition _x; + private _bottomPosY = (_ctrlBcgCommonPos select 1) + _ctrlTextPosH + (_marginY * 2) + _bottomSpaceY; - _xPos set [1, _bottomPosY]; - _x ctrlSetPosition _xPos; - _x ctrlCommit 0; -} forEach [ - _ctrlBackgroundButtonOK, - _ctrlBackgroundButtonMiddle, - _ctrlBackgroundButtonCancel, - _ctrlButtonOK, - _ctrlButtonCancel -]; + { + private _xPos = ctrlPosition _x; -private _ctrlRscMessageBoxPos = ctrlPosition _ctrlRscMessageBox; -private _ctrlRscMessageBoxPosH = _bottomPosY + (_ctrlButtonOKPos select 3); + _xPos set [1, _bottomPosY]; + _x ctrlSetPosition _xPos; + _x ctrlCommit 0; + } forEach [ + _ctrlBackgroundButtonOK, + _ctrlBackgroundButtonMiddle, + _ctrlBackgroundButtonCancel, + _ctrlButtonOK, + _ctrlButtonCancel + ]; -_ctrlRscMessageBox ctrlSetPosition [ - 0.5 - (_ctrlBcgCommonPos select 2) / 2, - 0.5 - _ctrlRscMessageBoxPosH / 2, - (_ctrlBcgCommonPos select 2) + 0.5, - _ctrlRscMessageBoxPosH -]; + private _ctrlRscMessageBoxPos = ctrlPosition _ctrlRscMessageBox; + private _ctrlRscMessageBoxPosH = _bottomPosY + (_ctrlButtonOKPos select 3); -_ctrlRscMessageBox ctrlEnable true; -_ctrlRscMessageBox ctrlCommit 0; + _ctrlRscMessageBox ctrlSetPosition [ + 0.5 - (_ctrlBcgCommonPos select 2) / 2, + 0.5 - _ctrlRscMessageBoxPosH / 2, + (_ctrlBcgCommonPos select 2) + 0.5, + _ctrlRscMessageBoxPosH + ]; -if (_onOK isEqualTo {}) then { - _ctrlButtonOK ctrlEnable false; - _ctrlButtonOK ctrlSetFade 0; - _ctrlButtonOK ctrlSetText ""; - _ctrlButtonOK ctrlCommit 0; -} else { + _ctrlRscMessageBox ctrlEnable true; + _ctrlRscMessageBox ctrlCommit 0; + + // Enable ok button _ctrlButtonOK ctrlEnable true; _ctrlButtonOK ctrlSetFade 0; _ctrlButtonOK ctrlSetText localize "STR_DISP_OK"; _ctrlButtonOK ctrlCommit 0; ctrlSetFocus _ctrlButtonOK; -}; -if (_onCancel isEqualTo {}) then { + // Disable cancel button _ctrlButtonCancel ctrlEnable false; _ctrlButtonCancel ctrlSetFade 0; _ctrlButtonCancel ctrlSetText ""; _ctrlButtonCancel ctrlCommit 0; -} else { - _ctrlButtonCancel ctrlEnable true; - _ctrlButtonCancel ctrlSetFade 0; - _ctrlButtonCancel ctrlSetText localize "STR_DISP_CANCEL"; - _ctrlButtonCancel ctrlCommit 0; - ctrlSetFocus _ctrlButtonCancel; -}; + _ctrlButtonOK ctrlAddEventHandler ["ButtonClick", {(ctrlParent (_this select 0)) closeDisplay IDC_OK; true}]; -_ctrlButtonOK ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 1; true}]; -_ctrlButtonCancel ctrlAddEventHandler ["buttonClick", {(ctrlParent (_this select 0)) closeDisplay 2; true}]; + // Intercept all keystrokes except the enter keys + _display displayAddEventHandler ["KeyDown", {!((_this select 1) in [DIK_RETURN, DIK_NUMPADENTER])}]; -GVAR(errorOnOK) = _onOK; -GVAR(errorOnCancel) = _onCancel; - -_display displayAddEventHandler ["unload", {call ([{}, GVAR(errorOnOK), GVAR(errorOnCancel)] select (_this select 1))}]; -_display displayAddEventHandler ["keyDown", {_this select 1 == 1}]; + // Close curator and mission displays (because of the message display, it doesn't quit the mission yet) + findDisplay 312 closeDisplay 0; + findDisplay 46 closeDisplay 0; +}, _this] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/common/functions/fnc_findUnloadPosition.sqf b/addons/common/functions/fnc_findUnloadPosition.sqf index 3e961b50d1..2047f7349d 100644 --- a/addons/common/functions/fnc_findUnloadPosition.sqf +++ b/addons/common/functions/fnc_findUnloadPosition.sqf @@ -2,138 +2,150 @@ /* * Author: PabstMirror, ViperMaul * Find a safe place near a vehicle to unload something. - * Handles Normal Terrain, In Water or On Buildings (Pier, StaticShip). + * Handles normal terrain, water or on buildings (Pier, StaticShip). * * Arguments: - * 0: Source Vehicle - * 1: Cargo or - * 2: Unloader (player) (default: objNull) - * 3: Max Distance (meters) (default: 10) - * 4: Check Vehicle is Stable (default: true) + * 0: Holder object (vehicle) + * 1: Item to be unloaded or + * 2: Unit doing the unloading (default: objNull) + * 3: Max distance (meters) (default: 10) + * 4: Check if holder object is stable (default: true) * * Return Value: - * Unload PositionAGL (can Be [] if no valid pos found) + * Unload PositionAGL ([] if no valid pos found) * * Example: - * [theCar, "CAManBase", player, 10, true] call ace_common_fnc_findUnloadPosition + * [cursorObject, "CAManBase", player, 10, true] call ace_common_fnc_findUnloadPosition * * Public: No */ -//Number of tests run (effects performance in worst case scenarior where nothing is found VERSUES reliably finding a pos): +// Number of tests run (effects performance in worst case scenario where nothing is found VERSUS reliably finding a pos) #define MAX_TESTS 75 -//Manual collision tests (count and radius): +// Manual collision tests (count and radius) #define COL_TEST_COUNT 12 -params ["_vehicle", "_cargo", ["_theUnloader", objNull], ["_maxDistance", 10], ["_checkVehicleIsStable", true]]; -TRACE_5("params",_vehicle,_cargo,_theUnloader,_maxDistance,_checkVehicleIsStable); +params ["_vehicle", "_item", ["_unloader", objNull], ["_maxDistance", 10], ["_checkVehicleIsStable", true]]; +TRACE_5("params",_vehicle,_item,_unloader,_maxDistance,_checkVehicleIsStable); scopeName "main"; if (_checkVehicleIsStable) then { if (((vectorMagnitude (velocity _vehicle)) > 1.5) || {(!(_vehicle isKindOf "Ship")) && {(!isTouchingGround _vehicle) && {((getPos _vehicle) select 2) > 1.5}}}) then { TRACE_4("bad vehicle state",_vehicle,velocity _vehicle,isTouchingGround _vehicle,getPos _vehicle); - [] breakOut "main"; + + [] breakOut "main" }; }; private _radiusOfItem = 1; -if (_cargo isKindOf "CAManBase") then { + +if (_item isKindOf "CAManBase") then { _radiusOfItem = 1.1; } else { - //`sizeOf` is unreliable, and does not work with object types that don't exist on map, so estimate size based on cargo size - private _configOfCargo = if (_cargo isEqualType objNull) then { - configOf _cargo - } else { - configFile >> "CfgVehicles" >> _cargo - }; - private _itemSize = if (isNumber (_configOfCargo >> QEGVAR(cargo,size)) && {getNumber (_configOfCargo >> QEGVAR(cargo,size)) != -1}) then { - getNumber (_configOfCargo >> QEGVAR(cargo,size)); - } else { - if (["ace_cargo"] call FUNC(isModLoaded)) then { - [_cargo] call EFUNC(cargo,getSizeItem); - } else { - _radiusOfItem; + // `sizeOf` is unreliable, and does not work with object types that don't exist on map, so estimate size based on cargo size + if (["ace_cargo"] call FUNC(isModLoaded)) then { + private _itemSize = _item call EFUNC(cargo,getSizeItem); + + if (_itemSize > 0) then { + _radiusOfItem = (_itemSize ^ 0.35) max 0.75; }; }; - if (_itemSize != -1) then { - _radiusOfItem = (_itemSize ^ 0.35) max 0.75; - }; }; -if (isNull _theUnloader) then {_theUnloader = _vehicle;}; +if (isNull _unloader || {_unloader in _vehicle}) then { + _unloader = _vehicle; +}; -//Ideal unload pos is halfway between unloader and vehicle (at the unloader's height) -private _originASL = ((getPosASL _theUnloader) vectorAdd (getPosASL _vehicle)) vectorMultiply 0.5; -_originASL set [2, (getPosASL _theUnloader) select 2]; +// Ideal unload pos is halfway between unloader and vehicle (at the unloader's height) +private _originASL = ((getPosASL _unloader) vectorAdd (getPosASL _vehicle)) vectorMultiply 0.5; +_originASL set [2, (getPosASL _unloader) select 2]; private _originAGL = ASLtoAGL _originASL; -//Do a manual search for empty pos (handles underwater, buildings or piers) +// Do a manual search for empty pos (handles underwater, buildings or piers) TRACE_2("Checking for unload",_originAGL,_radiusOfItem); private _rangeToCheck = 0; + while {_rangeToCheck < _maxDistance} do { private _roundDistance = random _rangeToCheck; private _roundAngle = random 360; private _roundAGL = _originAGL vectorAdd [(cos _roundAngle) * _roundDistance, (sin _roundAngle) * _roundDistance, 0]; private _roundPointIsValid = false; + if (((AGLtoASL _roundAGL) select 2) > 0) then { - //Shoot a ray down, and make sure we hit something solid like a building or the ground: - private _belowRoundArray = lineIntersectsSurfaces [(AGLtoASL _roundAGL) vectorAdd [0,0,0.5], (AGLtoASL _roundAGL) vectorAdd [0,0,-1]]; + // Shoot a ray down, and make sure we hit something solid like a building or the ground + private _belowRoundArray = lineIntersectsSurfaces [(AGLtoASL _roundAGL) vectorAdd [0, 0, 0.5], (AGLtoASL _roundAGL) vectorAdd [0, 0, -1]]; TRACE_4("Testing for solid",_roundDistance,_roundAngle,_roundAGL,_belowRoundArray); + if (_belowRoundArray isNotEqualTo []) then { private _aboveBuilding = (_belowRoundArray select 0) select 2; - //Point is above something: Terrain(null) or Building + + // Point is above something: Terrain (null) or Building if ((isNull _aboveBuilding) || {_aboveBuilding isKindOf "Building"}) then { - //Get the real intersection point: + // Get the real intersection point _roundAGL = ASLtoAGL ((_belowRoundArray select 0) select 0); + _roundPointIsValid = true; }; }; } else { - //Underwater, just unload anywhere + // Underwater, just unload anywhere TRACE_3("Under the sea",_roundDistance,_roundAngle,_roundAGL); + _roundPointIsValid = true; }; - //Make sure point is valid and do a fast check for people in the way (which sometimes aren't caught by line scaning) + // Make sure point is valid and do a fast check for people in the way (which sometimes aren't caught by line scanning) if (_roundPointIsValid && {(_roundAGL nearEntities ["Man", _radiusOfItem]) isEqualTo []}) then { for "_index" from 0 to (COL_TEST_COUNT -1) do { - //Scan for colisions with objects with lineIntersectsSurfaces + // Scan for collisions with objects with lineIntersectsSurfaces private _angle = _index * (360 / COL_TEST_COUNT); private _point1ASL = (AGLtoASL _roundAGL) vectorAdd [_radiusOfItem * cos _angle, _radiusOfItem * sin _angle, 0.1]; - private _point2ASL = (AGLtoASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, (_radiusOfItem + 0.5)]; + private _point2ASL = (AGLtoASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, _radiusOfItem + 0.5]; private _testIntersections = lineIntersectsSurfaces [_point1ASL, _point2ASL]; + if (((count _testIntersections) == 1) && {isNull ((_testIntersections select 0) select 2)}) then { private _hitGroundASL = (_testIntersections select 0) select 0; private _hitHeightOffset = ((AGLtoASL _roundAGL) select 2) - (_hitGroundASL select 2); private _hit2dOffset = _roundAGL distance2D _hitGroundASL; private _slope = _hitHeightOffset atan2 _hit2dOffset; - if (_slope < 25) then { //Ignore ground hit if slope is reasonable + + // Ignore ground hit if slope is reasonable + if (_slope < 25) then { _testIntersections = []; }; }; + if (_testIntersections isNotEqualTo []) exitWith { TRACE_2("collision low/high",_roundAGL,_testIntersections); + _roundPointIsValid = false; }; + _point1ASL = (AGLtoASL _roundAGL) vectorAdd [_radiusOfItem * cos _angle, _radiusOfItem * sin _angle, 0.5]; _point2ASL = (AGLtoASL _roundAGL) vectorAdd [-_radiusOfItem * cos _angle, -_radiusOfItem * sin _angle, 1]; _testIntersections = lineIntersectsSurfaces [_point1ASL, _point2ASL]; + if (_testIntersections isNotEqualTo []) exitWith { TRACE_2("collision mid",_roundAGL,_testIntersections); + _roundPointIsValid = false; }; }; + if (_roundPointIsValid) then { - TRACE_3("Valid point found", _rangeToCheck,_roundAGL, (_originAGL distance _roundAGL)); - //Raise it slightly so we don't sink through the floor: - (_roundAGL vectorAdd [0,0,0.05]) breakOut "main"; + TRACE_3("Valid point found",_rangeToCheck,_roundAGL,_originAGL distance _roundAGL); + + // Raise it slightly so we don't sink through the floor + (_roundAGL vectorAdd [0, 0, 0.05]) breakOut "main"; // return }; }; + _rangeToCheck = _rangeToCheck + (_maxDistance / MAX_TESTS); }; TRACE_1("no valid spots found",_rangeToCheck); -[] //return empty array + +[] // return diff --git a/addons/common/functions/fnc_firedEH.sqf b/addons/common/functions/fnc_firedEH.sqf index 9a4c8e50d6..2c0c32994d 100644 --- a/addons/common/functions/fnc_firedEH.sqf +++ b/addons/common/functions/fnc_firedEH.sqf @@ -24,7 +24,7 @@ BEGIN_COUNTER(firedEH); params ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; -TRACE_7("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); +TRACE_7("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); if (_unit isKindOf "CAManBase") then { // The unit it on foot @@ -50,8 +50,7 @@ if (_unit isKindOf "CAManBase") then { _gunner = _unit turretUnit _x; _turret = _x; }; - false - } count allTurrets [_unit, true]; + } forEach allTurrets [_unit, true]; // Ensure that at least the pilot is returned if there is no gunner if (isManualFire _unit && {isNull _gunner}) then { _gunner = effectiveCommander _unit; diff --git a/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf b/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf index 4e8aa1ec2a..8982d6bbad 100644 --- a/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf +++ b/addons/common/functions/fnc_fixLoweredRifleAnimation.sqf @@ -17,6 +17,6 @@ params ["_unit"]; -if (currentWeapon _unit != "" && {currentWeapon _unit == primaryWeapon _unit} && {weaponLowered _unit} && {stance _unit == "STAND"} && {vehicle _unit == _unit}) then { +if (currentWeapon _unit != "" && {currentWeapon _unit == primaryWeapon _unit} && {weaponLowered _unit} && {stance _unit == "STAND"} && {isNull objectParent _unit}) then { [_unit, "amovpercmstpsraswrfldnon", 0] call FUNC(doAnimation); }; diff --git a/addons/common/functions/fnc_getAllDefinedSetVariables.sqf b/addons/common/functions/fnc_getAllDefinedSetVariables.sqf index 6642a09789..081836c196 100644 --- a/addons/common/functions/fnc_getAllDefinedSetVariables.sqf +++ b/addons/common/functions/fnc_getAllDefinedSetVariables.sqf @@ -35,7 +35,6 @@ private _return = []; _return pushBack [_x select 0, typeName _val, _val, _x select 2, _x select 5]; }; }; - false -} count GVAR(OBJECT_VARIABLES_STORAGE); +} forEach GVAR(OBJECT_VARIABLES_STORAGE); _return 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_getDeathAnim.sqf b/addons/common/functions/fnc_getDeathAnim.sqf index 2b92e6ef10..18c6c93c07 100644 --- a/addons/common/functions/fnc_getDeathAnim.sqf +++ b/addons/common/functions/fnc_getDeathAnim.sqf @@ -27,9 +27,9 @@ if (getNumber (_unitAnimationCfg >> "terminal") == 1) exitWith {_animationState} private _unitActionsCfg = configFile >> "CfgMovesBasic" >> "Actions" >> getText (_unitAnimationCfg >> "actions"); -TRACE_2("Animation/Action", configName _unitAnimationCfg, configName _unitActionsCfg); +TRACE_2("Animation/Action",configName _unitAnimationCfg,configName _unitActionsCfg); -if (vehicle _unit != _unit) then { +if (!isNull objectParent _unit) then { private _interpolateArray = getArray (_unitAnimationCfg >> "interpolateTo"); for "_index" from 0 to (count _interpolateArray - 1) step 2 do { 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_getDoorTurrets.sqf b/addons/common/functions/fnc_getDoorTurrets.sqf index fb652cfd1a..1b6f22152a 100644 --- a/addons/common/functions/fnc_getDoorTurrets.sqf +++ b/addons/common/functions/fnc_getDoorTurrets.sqf @@ -29,7 +29,6 @@ private _doorTurrets = []; if (((getNumber (_config >> "isCopilot")) == 0) && {count getArray (_config >> "weapons") > 0}) then { _doorTurrets pushBack _x; }; - false -} count _turrets; +} forEach _turrets; _doorTurrets diff --git a/addons/common/functions/fnc_getGunner.sqf b/addons/common/functions/fnc_getGunner.sqf index ffa0334a26..376f18070e 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; @@ -28,8 +28,7 @@ private _gunner = objNull; if (_weapon in (_vehicle weaponsTurret _x)) exitWith { _gunner = _vehicle turretUnit _x; }; - false -} count allTurrets [_vehicle, true]; +} forEach allTurrets [_vehicle, true]; // ensure that at least the pilot is returned if there is no gunner if (isManualFire _vehicle && {isNull _gunner}) then { diff --git a/addons/common/functions/fnc_getInPosition.sqf b/addons/common/functions/fnc_getInPosition.sqf index fdbad3ee4a..076fd7a23c 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}; @@ -38,8 +38,7 @@ private _enemiesInVehicle = false; //Possible Side Restriction { if (side _unit getFriend side _x < 0.6) exitWith {_enemiesInVehicle = true}; - false -} count crew _vehicle; +} forEach crew _vehicle; switch (_position) do { case "driver" : { 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..daa4bd86cd 100644 --- a/addons/common/functions/fnc_getMapGridData.sqf +++ b/addons/common/functions/fnc_getMapGridData.sqf @@ -38,13 +38,12 @@ private _stepY = 1e10; _stepX = getNumber (_x >> "stepX"); _stepY = getNumber (_x >> "stepY"); }; - false -} count configProperties [_cfgGrid, "isClass _x", false]; +} forEach configProperties [_cfgGrid, "isClass _x", false]; 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_getNumberMagazinesIn.sqf b/addons/common/functions/fnc_getNumberMagazinesIn.sqf index fc2c3d0605..b71e6729dd 100644 --- a/addons/common/functions/fnc_getNumberMagazinesIn.sqf +++ b/addons/common/functions/fnc_getNumberMagazinesIn.sqf @@ -25,8 +25,7 @@ if (_unit isKindOf "CAManBase") then { } else { { _return = _return + ({_x == _magazine} count magazines _x); - false - } count crew _unit; + } forEach crew _unit; (getMagazineCargo _unit) params [["_magNames", []], ["_magCount", []]]; { diff --git a/addons/common/functions/fnc_getSettingData.sqf b/addons/common/functions/fnc_getSettingData.sqf index a2dceb746c..eeb8dff1d8 100644 --- a/addons/common/functions/fnc_getSettingData.sqf +++ b/addons/common/functions/fnc_getSettingData.sqf @@ -32,7 +32,6 @@ scopeName "main"; if (_x select 0 == _name) then { _x breakOut "main"; }; - false -} count GVAR(settings); +} forEach GVAR(settings); [] diff --git a/addons/common/functions/fnc_getTurretDirection.sqf b/addons/common/functions/fnc_getTurretDirection.sqf index 6f24b40f3e..7592bc8f33 100644 --- a/addons/common/functions/fnc_getTurretDirection.sqf +++ b/addons/common/functions/fnc_getTurretDirection.sqf @@ -25,7 +25,7 @@ private _pov = getText (_turret >> "memoryPointGunnerOptics"); private _gunBeg = getText (_turret >> "gunBeg"); private _gunEnd = getText (_turret >> "gunEnd"); -TRACE_3("", _pov, _gunBeg, _gunEnd); +TRACE_3("",_pov,_gunBeg,_gunEnd); // Pull the PIP pov or barrel direction, depending on how the model is set up private _povPos = _vehicle modelToWorldVisualWorld (_vehicle selectionPosition _pov); diff --git a/addons/common/functions/fnc_getTurretIndex.sqf b/addons/common/functions/fnc_getTurretIndex.sqf index dcbaafb3b2..75deced412 100644 --- a/addons/common/functions/fnc_getTurretIndex.sqf +++ b/addons/common/functions/fnc_getTurretIndex.sqf @@ -24,7 +24,6 @@ scopeName "main"; { if (_unit == (_vehicle turretUnit _x)) then {_x breakOut "main"}; - nil -} count allTurrets [_vehicle, true]; +} forEach allTurrets [_vehicle, true]; [] diff --git a/addons/common/functions/fnc_getVehicleCrew.sqf b/addons/common/functions/fnc_getVehicleCrew.sqf index 00a90b1ab2..a1bc06f6ab 100644 --- a/addons/common/functions/fnc_getVehicleCrew.sqf +++ b/addons/common/functions/fnc_getVehicleCrew.sqf @@ -29,11 +29,10 @@ 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); }; }; - false -} count fullCrew _vehicle; +} forEach fullCrew _vehicle; _crew 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_getVehicleUAVCrew.sqf b/addons/common/functions/fnc_getVehicleUAVCrew.sqf index 0ac91e644a..f991e08d57 100644 --- a/addons/common/functions/fnc_getVehicleUAVCrew.sqf +++ b/addons/common/functions/fnc_getVehicleUAVCrew.sqf @@ -17,4 +17,4 @@ params [["_vehicle", objNull, [objNull]]]; -crew _vehicle select {getText (configOf _x >> "simulation") == "UAVPilot"} // return +(crew _vehicle) select {unitIsUAV _x} // return diff --git a/addons/common/functions/fnc_getWeaponModes.sqf b/addons/common/functions/fnc_getWeaponModes.sqf index 55e260ef27..42a29681f2 100644 --- a/addons/common/functions/fnc_getWeaponModes.sqf +++ b/addons/common/functions/fnc_getWeaponModes.sqf @@ -1,35 +1,45 @@ #include "..\script_component.hpp" /* - * Author: commy2 + * Author: commy2, johnb43 * Get the available firing modes of a weapon. Will ignore the AI helper modes. * * Arguments: * 0: Weapon + * 1: Muzzle (default: weapon) * * Return Value: * Firing Modes * * Example: - * ["gun"] call ace_common_fnc_getWeaponModes + * "arifle_AK12_F" call ace_common_fnc_getWeaponModes * * Public: Yes */ -params [["_weapon", "", [""]]]; +params [["_weapon", "", [""]], ["_muzzle", nil, [""]]]; private _config = configFile >> "CfgWeapons" >> _weapon; +if (!isNil "_muzzle") then { + _config = _config >> _muzzle +}; + +if (!isClass _config) exitWith { + [] // return +}; + private _modes = []; { if (getNumber (_config >> _x >> "showToPlayer") == 1) then { - _modes pushBack _x; + if (_x == "this") then { + _modes pushBack (configName _config); + } else { + if (isClass (_config >> _x)) then { + _modes pushBack (configName (_config >> _x)); + }; + }; }; +} forEach getArray (_config >> "modes"); - if (_x == "this") then { - _modes pushBack _weapon; - }; - false -} count getArray (_config >> "modes"); - -_modes +_modes // return diff --git a/addons/common/functions/fnc_getWeaponState.sqf b/addons/common/functions/fnc_getWeaponState.sqf index 7ccb016c7a..2fadbd23ea 100644 --- a/addons/common/functions/fnc_getWeaponState.sqf +++ b/addons/common/functions/fnc_getWeaponState.sqf @@ -42,7 +42,6 @@ private _ammo = _muzzles apply {0}; _ammo set [_index, _x select 1]; }; }; - false -} count magazinesAmmoFull _unit; +} forEach magazinesAmmoFull _unit; [_attachments, _muzzles, _magazines, _ammo]; diff --git a/addons/common/functions/fnc_getWeight.sqf b/addons/common/functions/fnc_getWeight.sqf index fd50c62c14..300a74d382 100644 --- a/addons/common/functions/fnc_getWeight.sqf +++ b/addons/common/functions/fnc_getWeight.sqf @@ -5,10 +5,10 @@ * * Arguments: * 0: The Unit (usually the player) - * 1: Force a return type + * 1: Return imperial units * * Return Value: - * The return value + * Weight string * * Example: * [player] call ace_common_fnc_getWeight diff --git a/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf new file mode 100644 index 0000000000..2194c2aca0 --- /dev/null +++ b/addons/common/functions/fnc_getWheelHitPointsWithSelections.sqf @@ -0,0 +1,104 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Returns the wheel hitpoints and their selections. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * 0: Wheel hitpoints + * 1: Wheel hitpoint selections + * + * Example: + * cursorObject call ace_common_fnc_getWheelHitPointsWithSelections + * + * Public: No + */ + +params ["_vehicle"]; +TRACE_1("params",_vehicle); + +// TODO: Fix for GM vehicles +GVAR(wheelSelections) getOrDefaultCall [typeOf _vehicle, { + // Get the vehicles wheel config + private _wheels = configOf _vehicle >> "Wheels"; + + if (isClass _wheels) then { + // Get all hitpoints and selections + (getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; + + // Get all wheels and read selections from config + _wheels = "true" configClasses _wheels; + + private _wheelHitPoints = []; + private _wheelHitPointSelections = []; + + { + private _wheelName = configName _x; + private _wheelCenter = getText (_x >> "center"); + private _wheelBone = getText (_x >> "boneName"); + private _wheelBoneNameResized = _wheelBone select [0, 9]; // Count "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. + + TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); + + private _wheelHitPoint = ""; + private _wheelHitPointSelection = ""; + + // Commy's orginal method + { + if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. + _wheelHitPoint = _hitPoints select _forEachIndex; + _wheelHitPointSelection = _hitPointSelections select _forEachIndex; + TRACE_2("wheel found [Orginal]",_wheelName,_wheelHitPoint); + }; + } forEach _hitPointSelections; + + + if (_vehicle isKindOf "Car") then { + // Backup method, search for the closest hitpoint to the wheel's center selection pos. + // Ref #2742 - RHS's HMMWV + if (_wheelHitPoint == "") then { + private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; + if (_wheelCenterPos isEqualTo [0, 0, 0]) exitWith {TRACE_1("no center?",_wheelCenter);}; + + + private _bestDist = 99; + private _bestIndex = -1; + { + if (_x != "") then { + // Filter out things that definitly aren't wheeels (#3759) + if ((toLowerANSI (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; + private _xPos = _vehicle selectionPosition _x; + if (_xPos isEqualTo [0, 0, 0]) exitWith {}; + private _xDist = _wheelCenterPos distance _xPos; + if (_xDist < _bestDist) then { + _bestIndex = _forEachIndex; + _bestDist = _xDist; + }; + }; + } forEach _hitPointSelections; + + TRACE_2("closestPoint",_bestDist,_bestIndex); + if (_bestIndex != -1) then { + _wheelHitPoint = _hitPoints select _bestIndex; + _wheelHitPointSelection = _hitPointSelections select _bestIndex; + TRACE_2("wheel found [Backup]",_wheelName,_wheelHitPoint); + }; + }; + }; + + if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { + _wheelHitPoints pushBack _wheelHitPoint; + _wheelHitPointSelections pushBack _wheelHitPointSelection; + }; + } forEach _wheels; + + [_wheelHitPoints, _wheelHitPointSelections] + } else { + // Exit with nothing if the vehicle has no wheels class + TRACE_1("No Wheels",_wheels); + + [[], []] + } +}, true] // return diff --git a/addons/common/functions/fnc_goKneeling.sqf b/addons/common/functions/fnc_goKneeling.sqf index 881fad7669..303a413385 100644 --- a/addons/common/functions/fnc_goKneeling.sqf +++ b/addons/common/functions/fnc_goKneeling.sqf @@ -18,7 +18,7 @@ params ["_unit"]; // Animation changes even inside vehicle post-1.60 -if (stance _unit == "PRONE" || {vehicle _unit != _unit} || {_unit call EFUNC(common,isSwimming)}) exitWith {}; +if (stance _unit == "PRONE" || {!isNull objectParent _unit} || {_unit call EFUNC(common,isSwimming)}) exitWith {}; [ _unit, diff --git a/addons/common/functions/fnc_hasItem.sqf b/addons/common/functions/fnc_hasItem.sqf index f446c5dac0..ac0be8b10e 100644 --- a/addons/common/functions/fnc_hasItem.sqf +++ b/addons/common/functions/fnc_hasItem.sqf @@ -1,21 +1,21 @@ #include "..\script_component.hpp" /* * Author: Glowbal - * Check if unit has item. Note: case-sensitive. + * Check if given unit has an item of given classname. Note: Case sensitive. * * Arguments: * 0: Unit - * 1: Item Classname + * 1: Item classname * * Return Value: - * Unit has Item + * Unit has item * * Example: - * [bob, "item"] call ace_common_fnc_hasItem + * [player, "ACE_Banana"] call ace_common_fnc_hasItem * * Public: Yes */ params [["_unit", objNull, [objNull]], ["_item", "", [""]]]; -_item in (_unit call EFUNC(common,uniqueItems)) +_item in (_unit call FUNC(uniqueItems)) // return diff --git a/addons/common/functions/fnc_hasMagazine.sqf b/addons/common/functions/fnc_hasMagazine.sqf index 7874bcbd16..9f35aafdba 100644 --- a/addons/common/functions/fnc_hasMagazine.sqf +++ b/addons/common/functions/fnc_hasMagazine.sqf @@ -1,23 +1,21 @@ #include "..\script_component.hpp" /* * Author: Glowbal - * Check if given unit has a magazine of given classname + * Check if given unit has a magazine of given classname. Note: Case sensitive. * * Arguments: * 0: Unit - * 1: Magazine Classname + * 1: Magazine classname * * Return Value: - * has Magazine + * Unit has magazine * * Example: - * [bob, "magazine"] call ace_common_fnc_hasMagazine + * [player, "30Rnd_65x39_caseless_mag"] call ace_common_fnc_hasMagazine * * Public: yes - * - * Note: Case sensitive */ params [["_unit", objNull, [objNull]], ["_magazine", "", [""]]]; -_magazine in magazines _unit // return +_magazine in ([_unit, 2] call FUNC(uniqueItems)) // return diff --git a/addons/common/functions/fnc_isModLoaded.sqf b/addons/common/functions/fnc_isModLoaded.sqf index fb7b1807b6..b070b39b38 100644 --- a/addons/common/functions/fnc_isModLoaded.sqf +++ b/addons/common/functions/fnc_isModLoaded.sqf @@ -4,24 +4,17 @@ * Check in CfgPatches if modification is loaded * * Arguments: - * 0: Mod Name or Classname of the mod in CfgPatches + * 0: Classname of the mod in CfgPatches * * Return Value: - * if modification is loaded + * If modification is loaded * * Example: - * ["class"] call ace_common_fnc_isModLoaded + * "class" call ace_common_fnc_isModLoaded * * Public: Yes */ params [["_modName", "", [""]]]; -private _return = GVAR(isModLoadedCache) get _modName; - -if (isNil "_return") then { - _return = isClass (configFile >> "CfgPatches" >> _modName); - GVAR(isModLoadedCache) set [_modName, _return]; -}; - -_return +GVAR(isModLoadedCache) getOrDefaultCall [toLowerANSI _modName, {isClass (configFile >> "CfgPatches" >> _modName)}, true] diff --git a/addons/common/functions/fnc_moduleLSDVehicles.sqf b/addons/common/functions/fnc_moduleLSDVehicles.sqf index fde230b0ca..35e1f07eba 100644 --- a/addons/common/functions/fnc_moduleLSDVehicles.sqf +++ b/addons/common/functions/fnc_moduleLSDVehicles.sqf @@ -28,8 +28,7 @@ if (isNil QGVAR(LSD_Vehicles)) then { if (_hSCount > 0) then { GVAR(LSD_Vehicles) pushBack [_x, _hSCount]; }; - nil -} count _units; +} forEach _units; if (isNil QGVAR(LSD_Colors)) then { GVAR(LSD_Colors) = [ @@ -51,8 +50,7 @@ if (isNil QGVAR(LSD_PFH)) then { for "_i" from 0 to (_hSCount - 1) do { _vehicle setObjectTexture [_i, GVAR(LSD_Colors) select _index]; }; - nil - } count GVAR(LSD_Vehicles); + } forEach GVAR(LSD_Vehicles); _index = ((_index + 1) % 7) mod count GVAR(LSD_Colors); (_this select 0) set [0, _index]; diff --git a/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf index 71f62959b9..2108751066 100644 --- a/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf +++ b/addons/common/functions/fnc_nearestVehiclesFreeSeat.sqf @@ -22,7 +22,7 @@ params ["_unit", ["_distance", 10], ["_cargoOnly", false]]; private _nearVehicles = nearestObjects [_unit, ["Car", "Air", "Tank", "Ship_F", "Pod_Heli_Transport_04_crewed_base_F"], _distance]; _nearVehicles select { // Filter cargo seats that will eject unconscious units (e.g. quad bike) - private _canSitInCargo = (!(_unit getVariable ['ACE_isUnconscious', false])) || {(getNumber (configOf _x >> "ejectDeadCargo")) == 0}; + private _canSitInCargo = (_unit call EFUNC(common,isAwake)) || {(getNumber (configOf _x >> "ejectDeadCargo")) == 0}; ((fullCrew [_x, "", true]) findIf { _x params ["_body", "_role", "_cargoIndex"]; (isNull _body) // seat empty diff --git a/addons/common/functions/fnc_parseList.sqf b/addons/common/functions/fnc_parseList.sqf index 93ceccf17d..a559994bfa 100644 --- a/addons/common/functions/fnc_parseList.sqf +++ b/addons/common/functions/fnc_parseList.sqf @@ -32,8 +32,7 @@ private _whitespaceList = []; } else { _whitespaceList pushBack ([_x] call CBA_fnc_trim); }; - false -} count _list; +} forEach _list; _list = _whitespaceList; TRACE_1("Whitespace List",_list); @@ -46,8 +45,7 @@ if (_checkNil) then { if (!isNil _x) then { _nilCheckedList pushBack (missionNamespace getVariable _x); }; - false - } count _list; + } forEach _list; _list = _nilCheckedList; }; diff --git a/addons/common/functions/fnc_playConfigSound3D.sqf b/addons/common/functions/fnc_playConfigSound3D.sqf index c282199365..1069cf0f18 100644 --- a/addons/common/functions/fnc_playConfigSound3D.sqf +++ b/addons/common/functions/fnc_playConfigSound3D.sqf @@ -22,7 +22,7 @@ params ["_soundClass", "_posASL", "_volume", "_distance"]; private _sound = getArray (configFile >> "CfgSounds" >> _soundClass >> "sound"); if (_sound isEqualTo []) exitWith { - ERROR_1("CfgSounds class [%1] does not exist or contains empty sound array", _soundClass); + ERROR_1("CfgSounds class [%1] does not exist or contains empty sound array",_soundClass); }; TRACE_2("sound",_soundClass,_sound); @@ -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_progressBar.sqf b/addons/common/functions/fnc_progressBar.sqf index 20c1283da4..9b5519c232 100644 --- a/addons/common/functions/fnc_progressBar.sqf +++ b/addons/common/functions/fnc_progressBar.sqf @@ -1,4 +1,5 @@ #include "..\script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" /* * Author: commy2, Glowbal, PabstMirror * Draw progress bar and execute given function if succesful. @@ -9,9 +10,10 @@ * 1: Arguments, passed to condition, fail and finish * 2: On Finish: Code called or STRING raised as event. * 3: On Failure: Code called or STRING raised as event. - * 4: (Optional) Localized Title - * 5: Code to check each frame (Optional) - * 6: Exceptions for checking EFUNC(common,canInteractWith) (Optional) + * 4: Localized Title (default: "") + * 5: Code to check each frame (default: {true}) + * 6: Exceptions for checking ace_common_fnc_canInteractWith (default: []) + * 7: Create progress bar as dialog, this blocks user input (default: true) * * Return Value: * None @@ -22,13 +24,17 @@ * Public: Yes */ -params ["_totalTime", "_args", "_onFinish", "_onFail", ["_localizedTitle", ""], ["_condition", {true}], ["_exceptions", []]]; +params ["_totalTime", "_args", "_onFinish", "_onFail", ["_localizedTitle", ""], ["_condition", {true}], ["_exceptions", []], ["_dialog", true]]; private _player = ACE_player; //Open Dialog and set the title closeDialog 0; -createDialog QGVAR(ProgressBar_Dialog); +if (_dialog) then { + createDialog QGVAR(ProgressBar_Dialog); +} else { + QGVAR(progressBarDisplay) cutRsc [QGVAR(ProgressBar_Display), "PLAIN"]; +}; private _display = uiNamespace getVariable QGVAR(dlgProgress); @@ -36,8 +42,16 @@ private _display = uiNamespace getVariable QGVAR(dlgProgress); _display call (uiNamespace getVariable "CBA_events_fnc_initDisplayCurator"); // Hide cursor by using custom transparent cursor -private _map = _display displayCtrl 101; -_map ctrlMapCursor ["", QGVAR(blank)]; +if (_dialog) then { + private _map = _display displayCtrl 101; + _map ctrlMapCursor ["", QGVAR(blank)]; +} else { // Add key handler for ESC to cancel + [DIK_ESCAPE, [false, false, false], { + QGVAR(progressBarDisplay) cutText ["", "PLAIN"]; + [QGVAR(progressBarKeyHandler), "keydown"] call CBA_fnc_removeKeyHandler; + true + }, "keydown", QGVAR(progressBarKeyHandler)] call CBA_fnc_addKeyHandler; +}; (uiNamespace getVariable QGVAR(ctrlProgressBarTitle)) ctrlSetText _localizedTitle; @@ -53,7 +67,7 @@ _ctrlPos set [1, ((0 + 29 * GVAR(settingProgressBarLocation)) * ((((safezoneW / (uiNamespace getVariable QGVAR(ctrlProgressBarTitle)) ctrlCommit 0; [{ - (_this select 0) params ["_args", "_onFinish", "_onFail", "_condition", "_player", "_startTime", "_totalTime", "_exceptions", "_title"]; + (_this select 0) params ["_args", "_onFinish", "_onFail", "_condition", "_player", "_startTime", "_totalTime", "_exceptions", "_title", "_dialog"]; private _elapsedTime = CBA_missionTime - _startTime; private _errorCode = -1; @@ -71,8 +85,12 @@ _ctrlPos set [1, ((0 + 29 * GVAR(settingProgressBarLocation)) * ((((safezoneW / if !([_player, objNull, _exceptions] call EFUNC(common,canInteractWith)) then { _errorCode = 4; } else { - if (_elapsedTime >= _totalTime) then { - _errorCode = 0; + if (!_dialog && {dialog}) then { + _errorCode = 5; + } else { + if (_elapsedTime >= _totalTime) then { + _errorCode = 0; + }; }; }; }; @@ -84,7 +102,13 @@ _ctrlPos set [1, ((0 + 29 * GVAR(settingProgressBarLocation)) * ((((safezoneW / //Only close dialog if it's the progressBar: if (!isNull (uiNamespace getVariable [QGVAR(ctrlProgressBar), controlNull])) then { - closeDialog 0; + if (_dialog) then { + closeDialog 0; + } else { + QGVAR(progressBarDisplay) cutText ["", "PLAIN"]; + // Remove key handler for non-dialog bar + [QGVAR(progressBarKeyHandler), "keydown"] call CBA_fnc_removeKeyHandler; + }; }; [_this select 1] call CBA_fnc_removePerFrameHandler; @@ -116,4 +140,4 @@ _ctrlPos set [1, ((0 + 29 * GVAR(settingProgressBarLocation)) * ((((safezoneW / }; }; }; -}, 0, [_args, _onFinish, _onFail, _condition, _player, CBA_missionTime, _totalTime, _exceptions, _localizedTitle]] call CBA_fnc_addPerFrameHandler; +}, 0, [_args, _onFinish, _onFail, _condition, _player, CBA_missionTime, _totalTime, _exceptions, _localizedTitle, _dialog]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/common/functions/fnc_readSettingFromModule.sqf b/addons/common/functions/fnc_readSettingFromModule.sqf index dc9ead397f..5f9678f97b 100644 --- a/addons/common/functions/fnc_readSettingFromModule.sqf +++ b/addons/common/functions/fnc_readSettingFromModule.sqf @@ -23,7 +23,7 @@ params ["_logic", "_settingName", "_moduleVariable"]; // Check if the variable is already defined if (isNil _settingName) exitWith { - ERROR_1("readSettingFromModule - param [%1] is not an ace_setting", _settingName); + ERROR_1("readSettingFromModule - param [%1] is not an ace_setting",_settingName); }; // Check if the parameter is defined in the module diff --git a/addons/common/functions/fnc_readSettingsFromParamsArray.sqf b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf index 2abb5fa73e..7273fc61ca 100644 --- a/addons/common/functions/fnc_readSettingsFromParamsArray.sqf +++ b/addons/common/functions/fnc_readSettingsFromParamsArray.sqf @@ -32,7 +32,7 @@ TRACE_1("Reading missionConfigFile params",_paramsArray); // Check if the variable is already defined if (isNil _settingName) exitWith { - ERROR_1("readSettingsFromParamsArray - param [%1] is not an ace_setting", _settingName); + ERROR_1("readSettingsFromParamsArray - param [%1] is not an ace_setting",_settingName); }; // The setting is not forced, so update the value @@ -52,7 +52,7 @@ TRACE_1("Reading missionConfigFile params",_paramsArray); }; if (!_validValue) exitWith { - WARNING_3("readSettingsFromParamsArray - param [%1] type not valid [%2] - expected type [%3]", _settingName,_settingValue,_settingType); + WARNING_3("readSettingsFromParamsArray - param [%1] type not valid [%2] - expected type [%3]",_settingName,_settingValue,_settingType); }; if ([_settingName, "mission"] call CBA_settings_fnc_isForced) then { diff --git a/addons/common/functions/fnc_receiveRequest.sqf b/addons/common/functions/fnc_receiveRequest.sqf index 6c45fb8966..02a9379e6c 100644 --- a/addons/common/functions/fnc_receiveRequest.sqf +++ b/addons/common/functions/fnc_receiveRequest.sqf @@ -31,7 +31,7 @@ if (isLocalized _requestMessage) then { _requestMessage = format [_requestMessage, [_caller, false, true] call FUNC(getName)]; }; -hint format ["%1", _requestMessage]; // @todo ? +hint str _requestMessage; // @todo ? if (!isNil QGVAR(RECIEVE_REQUEST_TIME_OUT_SCRIPT)) then { terminate GVAR(RECIEVE_REQUEST_TIME_OUT_SCRIPT); diff --git a/addons/common/functions/fnc_registerItemReplacement.sqf b/addons/common/functions/fnc_registerItemReplacement.sqf index ce2fd7e393..f1e068c322 100644 --- a/addons/common/functions/fnc_registerItemReplacement.sqf +++ b/addons/common/functions/fnc_registerItemReplacement.sqf @@ -20,15 +20,23 @@ params [["_oldItem", "", [0,""]], ["_newItems", "", ["", []]], ["_replaceInherited", false, [false]]]; TRACE_3("registerItemReplacement",_oldItem,_newItems,_replaceInherited); - // Setup on first run if (isNil QGVAR(itemReplacements)) then { - GVAR(itemReplacements) = [] call CBA_fnc_createNamespace; + GVAR(itemReplacements) = createHashMap; GVAR(inheritedReplacements) = []; GVAR(oldItems) = []; ["loadout", LINKFUNC(replaceRegisteredItems)] call CBA_fnc_addPlayerEventHandler; }; +// Get config case - if item doesn't exist, "" is returned +if (_oldItem isEqualType "") then { + _oldItem = _oldItem call FUNC(getConfigName); +}; + +if (_oldItem isEqualTo "") exitWith { + ERROR("Item doesn't exist"); +}; + // Save item replacement // $ prefix is used for types (numbers) and replacements with inheritance if (_replaceInherited) then { @@ -42,9 +50,8 @@ if (_newItems isEqualType "") then { _newItems = [_newItems]; }; -private _oldReplacements = GVAR(itemReplacements) getVariable [_oldItem, []]; +private _oldReplacements = GVAR(itemReplacements) getOrDefault [_oldItem, [], true]; _oldReplacements append _newItems; -GVAR(itemReplacements) setVariable [_oldItem, _oldReplacements]; // Force item scan when new replacement was registered in PostInit if !(isNull ACE_player) then { 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_removeSyncedEventHandler.sqf b/addons/common/functions/fnc_removeSyncedEventHandler.sqf index 5aed6270f4..615f50ce49 100644 --- a/addons/common/functions/fnc_removeSyncedEventHandler.sqf +++ b/addons/common/functions/fnc_removeSyncedEventHandler.sqf @@ -18,7 +18,7 @@ params ["_name"]; if !(_name in GVAR(syncedEvents)) exitWith { - ERROR_1("Synced event key [%1] not found (removeSyncedEventHandler).", _name); + ERROR_1("Synced event key [%1] not found (removeSyncedEventHandler)",_name); false }; diff --git a/addons/common/functions/fnc_replaceRegisteredItems.sqf b/addons/common/functions/fnc_replaceRegisteredItems.sqf index bfe2e493e0..baa591c8d8 100644 --- a/addons/common/functions/fnc_replaceRegisteredItems.sqf +++ b/addons/common/functions/fnc_replaceRegisteredItems.sqf @@ -42,7 +42,7 @@ for "_i" from 0 to count _newItems - 1 do { private _replacements = []; // Determine replacement items: direct replacements, ... - private _directReplacements = GVAR(itemReplacements) getVariable _item; + private _directReplacements = GVAR(itemReplacements) get _item; if (!isNil "_directReplacements") then { _doReplace = true; _replacements append _directReplacements; @@ -50,7 +50,7 @@ for "_i" from 0 to count _newItems - 1 do { // ... item type replacements ... private _type = getNumber (_cfgWeapons >> _item >> "ItemInfo" >> "type"); - private _typeReplacements = GVAR(itemReplacements) getVariable ("$" + str _type); + private _typeReplacements = GVAR(itemReplacements) get ("$" + str _type); if (!isNil "_typeReplacements") then { _doReplace = true; _replacements append _typeReplacements; @@ -59,7 +59,7 @@ for "_i" from 0 to count _newItems - 1 do { // ... and inherited replacements { if (_item isKindOf [_x, _cfgWeapons]) then { - private _inheritedReplacements = GVAR(itemReplacements) getVariable _x; + private _inheritedReplacements = GVAR(itemReplacements) get _x; if (!isNil "_inheritedReplacements") then { _doReplace = true; _replacements append _inheritedReplacements; diff --git a/addons/common/functions/fnc_resetAllDefaults.sqf b/addons/common/functions/fnc_resetAllDefaults.sqf index 4d9f42a13b..ef74724183 100644 --- a/addons/common/functions/fnc_resetAllDefaults.sqf +++ b/addons/common/functions/fnc_resetAllDefaults.sqf @@ -27,8 +27,7 @@ if (isPlayer _unit) then { // clear all disable user input { [_x, false] call FUNC(setDisableUserInputStatus); - false - } count GVAR(DISABLE_USER_INPUT_COLLECTION); + } forEach GVAR(DISABLE_USER_INPUT_COLLECTION); }; }; @@ -36,5 +35,4 @@ if (isPlayer _unit) then { if !(_x select 4) then { _unit setVariable [_x select 0, nil, _x select 3]; }; - false -} count ([_unit] call FUNC(getAllDefinedSetVariables)); +} forEach ([_unit] call FUNC(getAllDefinedSetVariables)); diff --git a/addons/common/functions/fnc_restoreVariablesJIP.sqf b/addons/common/functions/fnc_restoreVariablesJIP.sqf index 905353d8ab..ac22cd3fa0 100644 --- a/addons/common/functions/fnc_restoreVariablesJIP.sqf +++ b/addons/common/functions/fnc_restoreVariablesJIP.sqf @@ -24,6 +24,4 @@ _respawnVariables pushBack "ACE_PersistentFunctions"; { _unit setVariable [_x, _unit getVariable _x, true]; - false -} count _respawnVariables; -nil +} forEach _respawnVariables; 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_runTests.sqf b/addons/common/functions/fnc_runTests.sqf index 946255c42f..4a449fb7eb 100644 --- a/addons/common/functions/fnc_runTests.sqf +++ b/addons/common/functions/fnc_runTests.sqf @@ -22,7 +22,7 @@ private _startTime = diag_tickTime; private _fails = []; private _total = 0; -INFO_1("ace_common_fnc_runTests starting for [%1]", _specificTest); +INFO_1("ace_common_fnc_runTests starting for [%1]",_specificTest); { private _testName = configName _x; @@ -41,8 +41,8 @@ INFO_1("ace_common_fnc_runTests starting for [%1]", _specificTest); }; } forEach (configProperties [configFile >> "ACE_Tests"]); -INFO_1("ace_common_fnc_runTests finished in %1 ms", (1000 * (diag_tickTime - _startTime)) toFixed 1); -INFO_2("[%1 / %2] Tests Passed", (_total - (count _fails)), _total); +INFO_1("ace_common_fnc_runTests finished in %1 ms",(1000 * (diag_tickTime - _startTime)) toFixed 1); +INFO_2("[%1 / %2] Tests Passed",(_total - (count _fails)),_total); if (_fails isNotEqualTo []) then { - INFO_1("Failed: %1", _fails); + INFO_1("Failed: %1",_fails); }; diff --git a/addons/common/functions/fnc_sanitizeString.sqf b/addons/common/functions/fnc_sanitizeString.sqf index c30cbe1292..7d0b2dd2f1 100644 --- a/addons/common/functions/fnc_sanitizeString.sqf +++ b/addons/common/functions/fnc_sanitizeString.sqf @@ -47,7 +47,6 @@ private _array = []; _array pushBack _x; }; }; - false -} count toArray _string; +} forEach toArray _string; toString _array // return diff --git a/addons/common/functions/fnc_setApproximateVariablePublic.sqf b/addons/common/functions/fnc_setApproximateVariablePublic.sqf index 3ef9595121..ebd4476de5 100644 --- a/addons/common/functions/fnc_setApproximateVariablePublic.sqf +++ b/addons/common/functions/fnc_setApproximateVariablePublic.sqf @@ -38,4 +38,4 @@ if (abs(_value - _oldValue) < _tolerance) exitWith {}; _object setVariable [_varName, _value, true]; _object setVariable [_oldVarName, _value]; -TRACE_2("Published variable:", _varName, _value); +TRACE_2("Published variable:",_varName,_value); diff --git a/addons/common/functions/fnc_setDead.sqf b/addons/common/functions/fnc_setDead.sqf new file mode 100644 index 0000000000..f6d62abd34 --- /dev/null +++ b/addons/common/functions/fnc_setDead.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Kills a unit without changing visual appearance. + * + * Arguments: + * 0: Unit + * 1: Reason for death (only used if ace_medical is loaded) (default: "") + * 2: Killer (vehicle that killed unit) (default: objNull) + * 3: Instigator (unit who pulled trigger) (default: objNull) + * + * Return Value: + * None + * + * Example: + * [cursorObject, "", player, player] call ace_common_fnc_setDead; + * + * Public: Yes + */ + +params [["_unit", objNull, [objNull]], ["_reason", "", [""]], ["_source", objNull, [objNull]], ["_instigator", objNull, [objNull]]]; + +if (!local _unit) exitWith { + WARNING_1("setDead executed on non-local unit - %1",_this); +}; + +if (GETEGVAR(medical,enabled,false)) then { + [_unit, _reason, _source, _instigator] call EFUNC(medical_status,setDead); +} else { + // From 'ace_medical_status_fnc_setDead': Kill the unit without changing visual appearance + + // (#8803) Reenable damage if disabled to prevent having live units in dead state + // Keep this after death event for compatibility with third party hooks + if (!isDamageAllowed _unit) then { + WARNING_1("setDead executed on unit with damage blocked - %1",_this); + _unit allowDamage true; + }; + + private _currentDamage = _unit getHitPointDamage "HitHead"; + + _unit setHitPointDamage ["HitHead", 1, true, _source, _instigator]; + + _unit setHitPointDamage ["HitHead", _currentDamage, true, _source, _instigator]; +}; diff --git a/addons/common/functions/fnc_setVariablePublic.sqf b/addons/common/functions/fnc_setVariablePublic.sqf index 8b583849be..678e2bc057 100644 --- a/addons/common/functions/fnc_setVariablePublic.sqf +++ b/addons/common/functions/fnc_setVariablePublic.sqf @@ -34,7 +34,7 @@ if (_object isEqualTo (_object getVariable [format ["ACE_onEmbargo_%1", _varName _object setVariable [_varName, _value, true]; _object setVariable [format ["ACE_onEmbargo_%1", _varName], _object]; -TRACE_2("Starting Embargo", _varName, _delay); +TRACE_2("Starting Embargo",_varName,_delay); [{ params ["_object", "_varName", "_value"]; @@ -43,7 +43,7 @@ TRACE_2("Starting Embargo", _varName, _delay); _object setVariable [format ["ACE_onEmbargo_%1", _varName], nil]; //Remove Embargo private _curValue = _object getVariable _varName; - TRACE_4("End of embargo", _object, _varName, _value, _curValue); + TRACE_4("End of embargo",_object,_varName,_value,_curValue); //If value at start of embargo doesn't equal current, then broadcast and start new embargo if (_value isNotEqualTo _curValue) then { diff --git a/addons/common/functions/fnc_showHud.sqf b/addons/common/functions/fnc_showHud.sqf index da6f2e0975..5bb0153772 100644 --- a/addons/common/functions/fnc_showHud.sqf +++ b/addons/common/functions/fnc_showHud.sqf @@ -41,11 +41,11 @@ if (isArray (missionConfigFile >> "showHUD")) then { if (_reason != "") then { _reason = toLower _reason; if (_mask isEqualTo []) then { - TRACE_2("Removing", _reason, _mask); + TRACE_2("Removing",_reason,_mask); GVAR(showHudHash) deleteAt _reason; } else { while {(count _mask) < 10} do { _mask pushBack true; }; - TRACE_2("Setting", _reason, _mask); + TRACE_2("Setting",_reason,_mask); GVAR(showHudHash) set [_reason, _mask]; }; }; @@ -56,14 +56,14 @@ private _resultMask = []; for "_index" from 0 to 9 do { private _set = true; //Default to true { - if (!(_x select _index)) exitWith { + if !(_x select _index) exitWith { _set = false; //Any false will make it false }; } forEach _masks; _resultMask pushBack _set; }; -TRACE_2("showHud", _resultMask, keys GVAR(showHudHash)); +TRACE_2("showHud",_resultMask,keys GVAR(showHudHash)); showHud _resultMask; _resultMask diff --git a/addons/common/functions/fnc_statusEffect_addType.sqf b/addons/common/functions/fnc_statusEffect_addType.sqf index 959ae8c2ef..5535b0d914 100644 --- a/addons/common/functions/fnc_statusEffect_addType.sqf +++ b/addons/common/functions/fnc_statusEffect_addType.sqf @@ -5,8 +5,9 @@ * * Arguments: * 0: Status Effect Name, this should match a corresponding event name - * 1: Send event globaly + * 1: Send event globally * 2: Common Effect Reaons to pre-seed durring init + * 3: Send event to JIP (requires sending event globally) * * Return Value: * None @@ -17,18 +18,20 @@ * Public: No */ -params [["_name", "", [""]], ["_isGlobal", false, [false]], ["_commonReasonsArray", [], [[]]]]; +params [["_name", "", [""]], ["_isGlobal", false, [false]], ["_commonReasonsArray", [], [[]]], ["_sendJIP", false, [false]]]; TRACE_3("params",_name,_isGlobal,_commonReasonsArray); -if (_name == "") exitWith {ERROR_1("addStatusEffect - Bad Name %1", _this)}; -if (_name in GVAR(statusEffect_Names)) exitWith {WARNING_1("addStatusEffect - Effect Already Added (note, will not update global bit) %1", _this)}; +if (_name == "") exitWith {ERROR_1("addStatusEffect - Bad Name %1",_this)}; +if (_name in GVAR(statusEffect_Names)) exitWith {WARNING_1("addStatusEffect - Effect Already Added (note, will not update global bit) %1",_this)}; +if (_sendJIP && !_isGlobal) exitWith {WARNING_1("addStatusEffect - Trying to add non-global JIP effect %1",_this)}; GVAR(statusEffect_Names) pushBack _name; GVAR(statusEffect_isGlobal) pushBack _isGlobal; +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_localEH.sqf b/addons/common/functions/fnc_statusEffect_localEH.sqf index f8ff93dba7..e60679350d 100644 --- a/addons/common/functions/fnc_statusEffect_localEH.sqf +++ b/addons/common/functions/fnc_statusEffect_localEH.sqf @@ -22,12 +22,12 @@ TRACE_2("params",_object,_isLocal); //Only run this after the settings are initialized //Need to wait for all EH to be installed (local event will happen between pre and post init) if !(GVAR(settingsInitFinished)) exitWith { - TRACE_1("pushing to runAtSettingsInitialized", _this); + TRACE_1("pushing to runAtSettingsInitialized",_this); GVAR(runAtSettingsInitialized) pushBack [FUNC(statusEffect_localEH), _this]; }; -if (!_isLocal) exitWith {TRACE_1("object no longer local", _this)}; -if (isNull _object) exitWith {TRACE_1("object null", _this)}; +if (!_isLocal) exitWith {TRACE_1("object no longer local",_this)}; +if (isNull _object) exitWith {TRACE_1("object null",_this)}; //Reset any variables because of respawn [_object, false] call FUNC(statusEffect_resetVariables); diff --git a/addons/common/functions/fnc_statusEffect_respawnEH.sqf b/addons/common/functions/fnc_statusEffect_respawnEH.sqf index 2c4a4840fe..edad032a9a 100644 --- a/addons/common/functions/fnc_statusEffect_respawnEH.sqf +++ b/addons/common/functions/fnc_statusEffect_respawnEH.sqf @@ -21,12 +21,12 @@ TRACE_1("params",_object); //Only run this after the settings are initialized //Need to wait for all EH to be installed (local event will happen between pre and post init) if !(GVAR(settingsInitFinished)) exitWith { - TRACE_1("pushing to runAtSettingsInitialized", _this); + TRACE_1("pushing to runAtSettingsInitialized",_this); GVAR(runAtSettingsInitialized) pushBack [FUNC(statusEffect_respawnEH), _this]; }; -if (!local _object) exitWith {TRACE_1("object no longer local", _this)}; -if (isNull _object) exitWith {TRACE_1("object null", _this)}; +if (!local _object) exitWith {TRACE_1("object no longer local",_this)}; +if (isNull _object) exitWith {TRACE_1("object null",_this)}; //Reset any variables on "real" respawn [_object, false] call FUNC(statusEffect_resetVariables); diff --git a/addons/common/functions/fnc_statusEffect_sendEffects.sqf b/addons/common/functions/fnc_statusEffect_sendEffects.sqf index 10f7ffb30c..a4e3f2d2a4 100644 --- a/addons/common/functions/fnc_statusEffect_sendEffects.sqf +++ b/addons/common/functions/fnc_statusEffect_sendEffects.sqf @@ -30,12 +30,21 @@ if (isNull _object) exitWith {}; TRACE_2("checking if event is nil",_x,_effectNumber); if (_effectNumber != -1) then { private _eventName = format [QGVAR(%1), _x]; - if (GVAR(statusEffect_isGlobal) select _forEachIndex) then { - TRACE_2("Sending Global Event", _object, _effectNumber); - [_eventName, [_object, _effectNumber]] call CBA_fnc_globalEvent; - } else { - TRACE_2("Sending Target Event", _object, _effectNumber); - [_eventName, [_object, _effectNumber], _object] call CBA_fnc_targetEvent; + switch (true) do { + case (GVAR(statusEffect_sendJIP) select _forEachIndex): { + TRACE_2("Sending Global JIP Event",_object,_effectNumber); + private _jipID = format [QGVAR(effect_%1_%2), _eventName, hashValue _object]; + [_eventName, [_object, _effectNumber], _jipID] call CBA_fnc_globalEventJIP; + [_jipID, _object] call CBA_fnc_removeGlobalEventJIP; + }; + case (GVAR(statusEffect_isGlobal) select _forEachIndex): { + TRACE_2("Sending Global Event",_object,_effectNumber); + [_eventName, [_object, _effectNumber]] call CBA_fnc_globalEvent; + }; + default { + TRACE_2("Sending Target Event",_object,_effectNumber); + [_eventName, [_object, _effectNumber], _object] call CBA_fnc_targetEvent; + }; }; }; }; diff --git a/addons/common/functions/fnc_statusEffect_set.sqf b/addons/common/functions/fnc_statusEffect_set.sqf index 48af4bf771..a4bf352a56 100644 --- a/addons/common/functions/fnc_statusEffect_set.sqf +++ b/addons/common/functions/fnc_statusEffect_set.sqf @@ -23,7 +23,7 @@ TRACE_4("params",_object,_effectName,_ID,_set); //Only run this after the settings are initialized if !(GVAR(settingsInitFinished)) exitWith { - TRACE_1("pushing to runAtSettingsInitialized", _this); + TRACE_1("pushing to runAtSettingsInitialized",_this); GVAR(runAtSettingsInitialized) pushBack [FUNC(statusEffect_set), _this]; }; @@ -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_stopGesture.sqf b/addons/common/functions/fnc_stopGesture.sqf new file mode 100644 index 0000000000..53e319b04b --- /dev/null +++ b/addons/common/functions/fnc_stopGesture.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: ACRE2Team + * Stops a unit's gesture. + * + * Arguments: + * 0: Target + * + * Return Value: + * None + * + * Example: + * [bob] call ace_common_fnc_stopGesture + * + * Public: Yes + */ + +params ["_unit"]; + +[QGVAR(playActionNow), [_unit, QGVAR(stop)], _unit] call CBA_fnc_targetEvent diff --git a/addons/common/functions/fnc_swayLoop.sqf b/addons/common/functions/fnc_swayLoop.sqf index 069d908d1a..adbc32053f 100644 --- a/addons/common/functions/fnc_swayLoop.sqf +++ b/addons/common/functions/fnc_swayLoop.sqf @@ -17,12 +17,12 @@ private _baseline = 1; if (GVAR(swayFactorsBaseline) isNotEqualTo []) then { - _baseline = 1 max ([missionNamespace, "ACE_setCustomAimCoef_baseline", "max"] call EFUNC(common,arithmeticGetResult)); + _baseline = 1 max ([missionNamespace, "ACE_setCustomAimCoef_baseline", "max"] call FUNC(arithmeticGetResult)); }; private _multiplier = 1; if (GVAR(swayFactorsMultiplier) isNotEqualTo []) then { - _multiplier = [missionNamespace, "ACE_setCustomAimCoef_multiplier", "product"] call EFUNC(common,arithmeticGetResult); + _multiplier = [missionNamespace, "ACE_setCustomAimCoef_multiplier", "product"] call FUNC(arithmeticGetResult); }; ACE_player setCustomAimCoef (_baseline * _multiplier); diff --git a/addons/common/functions/fnc_switchToGroupSide.sqf b/addons/common/functions/fnc_switchToGroupSide.sqf index 94d8c52701..1a3e588855 100644 --- a/addons/common/functions/fnc_switchToGroupSide.sqf +++ b/addons/common/functions/fnc_switchToGroupSide.sqf @@ -58,7 +58,7 @@ if (_switch) then { private _newGroup = createGroup (_x select 1); [_unit] joinSilent _newGroup; }; - if (count units _currentGroup == 0) then { + if (units _currentGroup isEqualTo []) then { deleteGroup _currentGroup; }; _previousGroupsList set [_forEachIndex, objNull]; diff --git a/addons/common/functions/fnc_syncedEvent.sqf b/addons/common/functions/fnc_syncedEvent.sqf index 5bcb678524..75170fe7d1 100644 --- a/addons/common/functions/fnc_syncedEvent.sqf +++ b/addons/common/functions/fnc_syncedEvent.sqf @@ -20,7 +20,7 @@ params ["_name", "_args", ["_ttl", 0]]; if !(_name in GVAR(syncedEvents)) exitWith { - ERROR_1("Synced event key [%1] not found (syncedEvent).", _name); + ERROR_1("Synced event key [%1] not found (syncedEvent)",_name); false }; diff --git a/addons/common/functions/fnc_throttledPublicVariable.sqf b/addons/common/functions/fnc_throttledPublicVariable.sqf index 3c1ed2761b..e6b1fdbaf6 100644 --- a/addons/common/functions/fnc_throttledPublicVariable.sqf +++ b/addons/common/functions/fnc_throttledPublicVariable.sqf @@ -29,8 +29,7 @@ if (isNil QGVAR(publishSchedId)) then { { _x params ["_unit", "_varName"]; _unit setVariable [_varName, _unit getVariable _varName, true]; - false - } count GVAR(publishVarNames); + } forEach GVAR(publishVarNames); GVAR(publishVarNames) = []; GVAR(publishNextTime) = 1e7; diff --git a/addons/common/functions/fnc_uniqueItems.sqf b/addons/common/functions/fnc_uniqueItems.sqf index dc783ebbea..5b2177a376 100644 --- a/addons/common/functions/fnc_uniqueItems.sqf +++ b/addons/common/functions/fnc_uniqueItems.sqf @@ -1,37 +1,86 @@ #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 = []; - _items arrayIntersect _items + private _inventoryItems = (getItemCargo uniformContainer _target) select 0; + _inventoryItems append ((getItemCargo vestContainer _target) select 0); + _inventoryItems append ((getItemCargo backpackContainer _target) select 0); + + private _magazines = magazines _target; + + _items set [0, _inventoryItems arrayIntersect _inventoryItems]; + _items set [1, _magazines arrayIntersect _magazines]; + + _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/functions/fnc_unloadPersonLocal.sqf b/addons/common/functions/fnc_unloadPersonLocal.sqf index d7a2f57db0..0378c6a4b8 100644 --- a/addons/common/functions/fnc_unloadPersonLocal.sqf +++ b/addons/common/functions/fnc_unloadPersonLocal.sqf @@ -35,7 +35,7 @@ if (_emptyPos isEqualTo []) then { }; if (count _emptyPos != 3) exitwith { - WARNING_4("Could not find unload pos %1-ASL: %2 isTouchingGround: %3 Speed: %4",_vehicle, getPosASL _vehicle, isTouchingGround _vehicle, speed _vehicle); + WARNING_4("Could not find unload pos %1-ASL: %2 isTouchingGround: %3 Speed: %4",_vehicle,getPosASL _vehicle,isTouchingGround _vehicle,speed _vehicle); if ((!isNull _unloader) && {[_unloader] call FUNC(isPlayer)}) then { //display text saying there are no safe places to exit the vehicle [QGVAR(displayTextStructured), [localize LSTRING(NoRoomToUnload)], [_unloader]] call CBA_fnc_targetEvent; diff --git a/addons/common/initSettings.sqf b/addons/common/initSettings.inc.sqf similarity index 68% rename from addons/common/initSettings.sqf rename to addons/common/initSettings.inc.sqf index e6b8b73248..a784ac64a9 100644 --- a/addons/common/initSettings.sqf +++ b/addons/common/initSettings.inc.sqf @@ -1,5 +1,6 @@ private _category = format ["ACE %1", LLSTRING(DisplayName)]; -private _categoryColors = [_category, format ["| %1 |", LLSTRING(subcategory_colors)]]; +private _categoryColors = [_category, LSTRING(subcategory_colors)]; +private _categorySway = [_category, LSTRING(subcategory_sway)]; [ QGVAR(checkPBOsAction), @@ -33,7 +34,7 @@ private _categoryColors = [_category, format ["| %1 |", LLSTRING(subcategory_col "LIST", [LSTRING(SettingFeedbackIconsName), LSTRING(SettingFeedbackIconsDesc)], _category, - [[0, 1, 2, 3, 4], [ELSTRING(optionsmenu,Hide), ELSTRING(optionsmenu,TopRightDown), ELSTRING(optionsmenu,TopRightLeft), ELSTRING(optionsmenu,TopLeftDown), ELSTRING(optionsmenu,TopLeftRight)], 1], + [[0, 1, 2, 3, 4], [LSTRING(Hide), LSTRING(TopRightDown), LSTRING(TopRightLeft), LSTRING(TopLeftDown), LSTRING(TopLeftRight)], 1], 0 ] call CBA_fnc_addSetting; @@ -42,7 +43,7 @@ private _categoryColors = [_category, format ["| %1 |", LLSTRING(subcategory_col "LIST", [LSTRING(SettingProgressBarLocationName), LSTRING(SettingProgressBarLocationDesc)], _category, - [[0, 1], [ELSTRING(optionsmenu,Top), ELSTRING(optionsmenu,Bottom)], 0], + [[0, 1], [LSTRING(Top), LSTRING(Bottom)], 0], 0 ] call CBA_fnc_addSetting; @@ -87,7 +88,7 @@ private _categoryColors = [_category, format ["| %1 |", LLSTRING(subcategory_col QGVAR(epilepsyFriendlyMode), "CHECKBOX", [LSTRING(EpilepsyFriendlyMode), LSTRING(EpilepsyFriendlyModeTooltip)], - format ["ACE %1", localize LSTRING(DisplayName)], + _category, false, 2 ] call CBA_fnc_addSetting; @@ -96,7 +97,45 @@ private _categoryColors = [_category, format ["| %1 |", LLSTRING(subcategory_col QGVAR(progressBarInfo), "LIST", [LSTRING(progressBarInfoName), LSTRING(progressBarInfoDesc)], - format ["ACE %1", localize LSTRING(DisplayName)], + _category, [[0, 1, 2], [LSTRING(None), LSTRING(progressBarInfoPercentage), LSTRING(progressBarInfoTime)], 2], 0 ] call CBA_fnc_addSetting; + +[ + QGVAR(enableSway), + "CHECKBOX", + [LSTRING(enableSway), LSTRING(enableSway_Description)], + _categorySway, + true, + 1, + {}, + true +] call CBA_fnc_addSetting; + +[ + QGVAR(swayFactor), + "SLIDER", + [LSTRING(SwayFactor), LSTRING(SwayFactor_Description)], + _categorySway, + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(restedSwayFactor), + "SLIDER", + [LSTRING(RestedSwayFactor), LSTRING(RestedSwayFactor_Description)], + _categorySway, + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(deployedSwayFactor), + "SLIDER", + [LSTRING(DeployedSwayFactor), LSTRING(DeployedSwayFactor_Description)], + _categorySway, + [0, 5, 1, 2], + 1 +] call CBA_fnc_addSetting; diff --git a/addons/common/scripts/checkVersionNumber.sqf b/addons/common/scripts/checkVersionNumber.sqf deleted file mode 100644 index 0f2c055500..0000000000 --- a/addons/common/scripts/checkVersionNumber.sqf +++ /dev/null @@ -1,160 +0,0 @@ -// by commy2 -#include "..\script_component.hpp" - -private _aceWhitelist = missionNamespace getVariable ["ACE_Version_Whitelist", []]; -private _files = CBA_common_addons select { - (_x select [0,3] != "a3_") && - {_x select [0,4] != "ace_"} && - {!((toLower _x) in _aceWhitelist)} -}; - -private _versions = []; -{ - getText (configFile >> "CfgPatches" >> _x >> "version") splitString "." params [["_major", "0"], ["_minor", "0"]]; - private _version = parseNumber _major + parseNumber _minor/100; - _versions set [_forEachIndex, _version]; -} forEach _files; - -if (isServer) then { - ACE_Version_ServerVersions = [_files, _versions]; - publicVariable "ACE_Version_ServerVersions"; -} else { - ACE_Version_ClientVersions = [_files, _versions]; -}; - -// Begin client version check -if (!isServer) then { - // Wait for server to send the servers files and version numbers - waitUntil { - sleep 1; - !isNil "ACE_Version_ClientVersions" && {!isNil "ACE_Version_ServerVersions"} - }; - - private _client = profileName; - - _files = ACE_Version_ClientVersions select 0; - _versions = ACE_Version_ClientVersions select 1; - - private _serverFiles = ACE_Version_ServerVersions select 0; - private _serverVersions = ACE_Version_ServerVersions select 1; - - // Compare client and server files and versions - private _missingAddons = []; - private _oldVersionsClient = []; - private _oldVersionsServer = []; - { - private _serverVersion = _serverVersions select _forEachIndex; - - private _index = _files find _x; - if (_index == -1) then { - if (_x != "ace_server") then {_missingAddons pushBack _x;}; - } else { - - private _clientVersion = _versions select _index; - - if (_clientVersion < _serverVersion) then { - _oldVersionsClient pushBack [_x, _clientVersion, _serverVersion]; - }; - - if (_clientVersion > _serverVersion) then { - _oldVersionsServer pushBack [_x, _clientVersion, _serverVersion]; - }; - }; - } forEach _serverFiles; - - // find client files which the server doesn't have - private _missingAddonsServer = []; - { - private _index = _serverFiles find _x; - if (_index == -1) then { - _missingAddonsServer pushBack _x; - } - } forEach _files; - - // display and log error messages - private _fnc_cutComma = { - private _string = _this; - _string = toArray _string; - - private _count = count _string; - _string set [_count - 2, toArray "." select 0]; - _string set [_count - 1, -1]; - _string = _string - [-1]; - - toString _string; - }; - - private _missingAddon = false; - if (count _missingAddons > 0) then { - _missingAddon = true; - - private _error = format ["[ACE] %1: ERROR client missing addon(s): ", _client]; - { - _error = _error + format ["%1, ", _x]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _missingAddons; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; - }; - - private _missingAddonServer = false; - if (count _missingAddonsServer > 0) then { - _missingAddonServer = true; - - private _error = format ["[ACE] %1: ERROR server missing addon(s): ", _client]; - { - _error = _error + format ["%1, ", _x]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _missingAddonsServer; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; - }; - - private _oldVersionClient = false; - if (count _oldVersionsClient > 0) then { - _oldVersionClient = true; - - private _error = format ["[ACE] %1: ERROR outdated client addon(s): ", _client]; - { - _error = _error + format ["%1 (client: %2, server: %3), ", _x select 0, _x select 1, _x select 2]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _oldVersionsClient; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; - }; - - private _oldVersionServer = false; - if (count _oldVersionsServer > 0) then { - _oldVersionServer = true; - - private _error = format ["[ACE] %1: ERROR outdated server addon(s): ", _client]; - { - _error = _error + format ["%1 (client: %2, server: %3), ", _x select 0, _x select 1, _x select 2]; - - if (_forEachIndex > 9) exitWith {}; - } forEach _oldVersionsServer; - - _error = _error call _fnc_cutComma; - - diag_log text _error; - [QGVAR(systemChatGlobal), _error] call CBA_fnc_globalEvent; - [QGVAR(serverLog), _error] call CBA_fnc_serverEvent; - }; - - ACE_Version_ClientErrors = [_missingAddon, _missingAddonServer, _oldVersionClient, _oldVersionServer]; -}; diff --git a/addons/common/stringtable.xml b/addons/common/stringtable.xml index 4662249745..8c59d06516 100644 --- a/addons/common/stringtable.xml +++ b/addons/common/stringtable.xml @@ -5,7 +5,7 @@ Common Allgemein Comune - 全般 + 一般 通用 通用 일반 @@ -334,7 +334,7 @@ ONO NyÉNy ONO - 北北西 + 西北西 서북서 西北西 西北偏西 @@ -385,7 +385,7 @@ Ação cancelada. Művelet megszakítva. Azione cancellata. - 動作を中止した。 + アクションを中断した。 행동 취소됨. 動作已被取消 动作已被取消 @@ -402,7 +402,7 @@ [ACE] Itens diversos [ACE] Egyéb tárgyak [ACE] Oggetti vari - [ACE] その他アイテム + [ACE] その他のアイテム [ACE] 기타 물품. [ACE] 雜項 [ACE] 杂项 @@ -482,7 +482,7 @@ Controlla Azioni PBO 檢查PBO動作 检查 PBO 动作 - PBO 検査の挙動 + PBO検査の挙動 PBO 검사 Sprawdź akcję PBO Действие при проверке PBO @@ -498,11 +498,13 @@ 设定当玩家有错误的 PBO 时要如何处理。 Nastavuje jakou akci provést pokud hráč nemá správné PBO. Określa akcję, która ma być podjęta, jeśli gracz nie ma właściwych PBO. - プレイヤーが不正規の PBO を所持している場合の動作を決定します。 + プレイヤーが不正規のPBOを所持している場合の動作を定義します。 Define la accion a tomar si un jugador no tiene el PBO correcto + Definisce l'azione che verrà presa se il giocatore non ha gli stessi PBO. Определяет, какое действие будет предпринято, если игрок не имеет корректные PBO. Definiert, was passieren soll, wenn ein Spieler nicht die korrekten PBOs nutzt. 플레이어가 같은 PBO를 가지고 있지 않을 시 취할 행동을 정합니다. + Define a ação a ser tomada se um jogador não tiver os PBOs corretos. Check PBO All @@ -510,7 +512,7 @@ Controlla Tutti i PBO 檢查所有PBO 检查所有 PBO - PBO 全てを検査 + 全てのPBOを検査 모든 PBO 검사 Sprawdź wszystkie PBO Проверять все PBO @@ -522,15 +524,17 @@ Check all addons, not only those of ACE. Vérifie tous les addons, même ceux qui ne sont pas liés à ACE. + Controlla tutti gli addon, non solo quelli ACE. 檢查全部的插件而非只有ACE。 检查全部插件而非只有 ACE。 Zkontrolovat všechny addony a ne jenom ACE. Sprawdź wszystkie dodatki, nie tylko ACE. - ACE のみならず、全てのアドオンを検査します。 + ACE だけでなく、全てのアドオンを検査します。 Comprueba todos los complementos, no sólo los de ACE Проверять все аддоны, а не только ACE. Überprüft alle Erweiterungen, nicht nur die von ACE. ACE 뿐만이 아닌 다른 PBO 모두 검사합니다. + Verifica todos os addons, não apenas os do ACE. Check PBO Whitelist @@ -538,7 +542,7 @@ Controlla Whitelist PBO 檢查PBO白名單 检查 PBO 白名单 - 許可リスト内の PBO を検査 + PBO 検査のホワイトリスト PBO 화이트리스트 확인 Sprawdź białą listę PBO Белый список для проверки PBO @@ -550,15 +554,17 @@ Define a list of regardless allowed addons. Permet de définir une liste d'addons autorisés systématiquement. + Definisce una lista di PBO permessi in ogni caso. 定義哪些插件是允許使用的。 定义哪些插件是允许使用的。 Nastavte seznam addonů, které jsou povolené. Zdefiniuj listę niezależnie od dozwolonych dodatków. - 許可するアドオンを定義します。 + 関係なく使用が許可されるアドオンのリストを定義します。 Comprueba la lista de PBOs permitidos Задать список непроверяемых аддонов. Ermöglicht das Erstellen einer Liste von immer erlaubten Erweiterungen. 허용된 애드온 목록을 정의합니다. + Define uma lista de addons permitidos. Feedback icons @@ -587,7 +593,7 @@ Nastavuje pozici nebo vypíná pomocné ikony. Tyto ikony ukazují extra informace ke stavu postavy a vykonávaných činností. Itt beállítható a visszajelző ikonok képernyőn lévő helyzete és jelenléte. Ezek az ikonok extra visszajelzést biztosítanak a karaktered állapotán és végrehajtott cselekvésein. Selecione a posição ou disabilite a posição dos ícones de feedback na sua tela. Esses ícones irão aparecer para mostrar feedback extra do status do seu personagem e ações realizadas. - 画面上に表示するフィードバック アイコンの位置や無効化を選択できます。このアイコンは自キャラクター状態や動作の状況をフィードバックするために表示されています。 + 画面上のフィードバック アイコンの位置を選択するか、無効にします。 これらのアイコンは、キャラクターのステータスと実行されたアクションに関する追加のフィードバックを提供するために表示されます。 피드백 아이콘의 위치를 설정하거나 비활성화합니다. 피드백 아이콘은 캐릭터의 상세정보와 행동을 보여줍니다. 選擇位置或取消回饋圖標顯示在螢幕上。這些圖標將顯示出你角色額外的狀態與行動等資訊 选择位置或取消回馈图标显示在屏幕上。这些图标将显示出你角色额外的状态与行动等信息。 @@ -667,7 +673,7 @@ Barva fontu nápovědy. Súgószöveg betűinek színe Cor do do texto da hint - ヒント文章の色 + ヒント文章の文字色 힌트 글씨색 提示文字的顏色 提示文字的颜色 @@ -683,7 +689,7 @@ Barva fontu ACE nápověd. Toto je standardní barva pro všechen text zobrazovaný ACE nápovědami, pokud nemá nápověda žádnou specifikanou barvu. Az ACE-súgók betűkészletének színek. Ez a szín alapértelmezett az összes szövegre az ACE-súgórendszerben, ha a súgószöveg maga nem ad meg más színt. A cor do texto das hints do ACE. Essa cor é a cor default para todos os texos exibidos pelo sistema de hints do ACE , caso o texto da hint não tem outra cor especificada. - ACE によるヒントの文章に色を設定できます。この色は ACE ヒント システムを介して表示される全文章の色と標準でなっており、特定の色を設定していても、標準色になります。 + ACE ヒント文章の文字色。 ヒント文章に他の色が指定されていない場合、この色は、ACE ヒント システムを通じて表示されるすべての文章の標準色になります。 ACE 힌트에 쓰이는 글씨 색입니다. 힌트 글씨의 색이 정해지지 않을경우 모든 힌트의 색은 기본으로 설정됩니다. 設定ACE提示文字的顏色。若提示字體並無指定其他顏色,將會自動選用ACE系統的預設顏色 设定 ACE 提示文字的颜色。若提示字体并无指定其他颜色,将会自动选用 ACE 的预设颜色。 @@ -705,8 +711,8 @@ Persistent weapon laserpointer/flashlight Автоматический ЛЦУ/тактический фонарь - 武器のレーザー ポインタ/フラッシュライトの永続 - Laser/torcia dell'arma costantemente accesi + 武器のレーザー ポインター/フラッシュライトの永続性 + Laser/torcia dell'arma rimangono accesi 무기 레이저 지시기/손전등 지속 Kontinuität des Laserpointers/Taktischen Lichts 保持武器雷射/手電筒的狀態 @@ -720,7 +726,7 @@ Enable gunlight after weapon switch or vehicle enter/exit if it was previously enabled. Включать ЛЦУ/тактический фонарь после смены оружия или входа/выхода из машины, если он был до этого включен. - 銃のライト等を点けていると武器を切り替えた後や車両を乗り降りしても、ライト等を点けたままにします。 + 銃のライトをつけていた場合、武器の切り替え後または車両の出入り後にライトを再度点灯します。 Abilita la torcia/laser dopo il cambio dell'arma o l'entrata/uscita del veicolo se precedentemente attiva. 이전에 무기의 손전등/레이저를 켠 경우 무기 전환이나 차량 승하차시 켠 상태를 유지합니다. Aktiviert Laserpointer/Taktisches Licht nach einem Waffenwechsel oder dem Auf-/Absitzen, falls es zuvor aktiv war. @@ -775,7 +781,7 @@ PBO-k ellenőrzése Проверка аддонов Controlla PBO - PBO を検査 + PBOを検査 PBO 검사 檢查PBO檔 检查 PBO @@ -790,7 +796,7 @@ Выполняет проверку версий аддонов ACE у подключаемых игроков /!\ Module obsolète /!\ - Vérifie l'intégrité des addons avec le serveur, et effectue l'action sélectionnée si un addon est manquant. Controlla l'integrità degli addon con il server ed esegui l'azione selezionata se un addon è mancante - サーバがアドオンの整合性を検査し、もし不備があれば実行する動作を選択できます。 + サーバーとのアドオンの整合性をチェックし、不備があった場合は選択したアクションを実行します。 서버 애드온의 무결성을 검사하고 사라진 애드온이 있을 경우 행동을 선택합니다. 檢查客戶端與伺服器端的模組清單是否一致且完整,並提供訊息表示遺失的模組 检查客户端与服务器端的模组清单是否一致且完整,并提供信息表示遗失的模组。 @@ -822,7 +828,7 @@ Mi legyen azokkal a személyekkel, akiknek nincsenek meg a helyes PBO-k? Что делать с игроками с неправильными аддонами? Cosa fare con giocatori che non hanno i PBO corretti? - プレイヤーが正しい PBO を持っていない場合は? + プレイヤーが正しいPBOを持っていない場合は? 올바르지 않은 PBO를 가진 사람을 어떻게 할까요? 若玩家沒有正確的PBO檔時,將採取何種動作? 若玩家没有正确的 PBO 档时,将采取何种动作? @@ -838,7 +844,7 @@ Egyszeri figyelmeztetés Предупредить один раз Avverti una volta - 一度の警告 + 一度警告 경고 한 번 警告 (一次) 警告(一次) @@ -855,7 +861,7 @@ Figyelmeztetés (tartós) Предупреждать (постоянно) Avverti (permanente) - 警告 (永久的) + 警告 (永続) 경고 (영구적) 警告 (持續) 警告(持续) @@ -905,7 +911,7 @@ Az összes bővítmény ellenőrzése, csak az ACE helyett? Проверять все аддоны, а не только ACE? Controlla tutti gli addon invece dei soli addon ACE? - ACE MOD の代わりに全アドオンを検査しますか? + ACE のアドオンだけではなく、すべてのアドオンをチェックしますか? ACE를 제외한 모든 모드를 검사할까요? 檢查包含ACE之外的其他模組? 检查包含 ACE 之外的其他模组? @@ -921,7 +927,7 @@ Fehérlista Вайтлист доп. аддонов Lista Bianca - 許可制 + ホワイトリスト 화이트리스트 白名單 白名单 @@ -970,7 +976,7 @@ LSD-effekt hozzáadása a szinkronizált járművekhez Добавляет эффект LSD (мигание всеми цветами радуги) синхронизированным транспортным средствам Aggiunge effetti LSD ai veicoli sincronizzati - 同期されたオブジェクトに LSD の効果を追加します + 同期された車両に LSD 効果を追加します 동기화된 차량에 LSD 효과를 추가합니다. 使被同步的載具產生瘋狂的迷幻效果。(後果自負) 使被同步的载具产生疯狂的迷幻效果。(后果自负) @@ -986,7 +992,7 @@ Kézi eszköz kapcsolása Включить портативное устройство Apri dispositivo palmare - デバイスを常に表示 + 携帯装置の表示を切り替え 휴대장치 토글 切換手持裝備 切换手持装备 @@ -1002,7 +1008,7 @@ Kézi eszköz bezárása Закрыть портативное устройство Chiudi dispositivo palmare - デバイスを閉じる + 携帯装置を閉じる 휴대장치 닫기 關閉手持裝備 关闭手持装备 @@ -1018,7 +1024,7 @@ Kézi eszköz váltása Следующее портативное устройство Cicla tra dispositivi palmari - 表示するデバイスを変える + 表示する携帯装置をサイクル 휴대장치 순환 循環切換手持裝備 循环切换手持装备 @@ -1246,7 +1252,7 @@ ACE Obecné ACE Comune ACE Commun - ACE 全般 + ACE 一般 ACE 일반 ACE 通用按鍵 ACE 通用 @@ -1320,11 +1326,13 @@ ACE 未分类 ACE 무분류 ACE Unkategorisiert + ACE Non-Categorizzati ACE Nieskategoryzowane - ACE 未区分 + ACE 未分類 ACE Без категории ACE Sin categoría ACE Non classé + ACE Sem Categoria No Room to unload @@ -1352,7 +1360,7 @@ Non hai più spazio Nincs több hely В инвентаре нет места - インベントリに空きがない + インベントリに空きがありません 넣을 공간이 없습니다 無可用空間 无可用空间 @@ -1398,7 +1406,7 @@ 음악 끄기 허용 允許調低音樂音量 允许调低音乐音量 - 音楽の音量低下を許可 + 音楽音量の低減を許可 Permesso di abbassare la musica Zezwól na przyciszanie muzyki Разрешить приглушение музыки @@ -1414,7 +1422,7 @@ ACE 스크립트가 음악을 끌 수 있습니다. 允許ACE腳本去控制音樂的音量 允许 ACE 脚本去控制音乐的音量。 - ACE スプリントへ音量低下を許可します。 + ACEのスクリプトに音楽音量の低減を許可します。 Permetti agli script di ACEdi abbassare la musica. Zezwól skrypty ACE na przyciszanie muzyki. Позволить скриптам ACE приглушать музыку @@ -1427,24 +1435,28 @@ Epilepsy friendly mode Epilepsiefreundlicher Modus - けいれん回避モード + てんかん対応モード Tryb dla epileptyków Mode adapté à l'épilepsie + Modalità per Epilettici 癫痫病友好模式 광과민 친화적 모드 Режим для эпилептиков Modo adaptado para epilepsia + Modo adaptado para epilepsia Disables some flashing light effects to reduce seizure risk. Deaktiviert einige Lichtflackereffekte um das Risiko von Epilepsieanfällen zu reduzieren. - 点滅する光エフェクトを無効化し、けいれんする恐れを低下させます。 + てんかん発作のリスクを軽減するために、一部の点滅する光の効果を無効にします。 Wyłącz część migających efektów w celu zredukowania ryzyka napadu epilepsji Désactive certains effets de lumière clignotante afin de réduire les risques de crise d'épilepsie. + Disattiva alcuni effetti di luci intermittenti per ridurre il rischio di crisi epilettiche. 禁用一些闪烁的灯光效果,以降低癫痫发作的风险。 반짝거리는 빛으로 인해 일어날 발작 상황을 줄여줍니다. Отключает некоторые вспышки во избежание риска приступа. Deshabilita algunos efectos de iluminación para reducir el riesgo de convulsiones. + Desabilita alguns efeitos de luz para reduzir o risco de convulsões. Flag (ACE - Black) @@ -1452,7 +1464,7 @@ 旗帜(ACE-黑色): 旗幟(ACE-黑色) Bandiera (ACE - Nera) - 旗 (ACE - 黒) + 旗 (ACE - 黒色) Flaga (ACE - Czarna) Флаг (ACE - Черный) Bandeira (ACE - Preto) @@ -1468,7 +1480,7 @@ 旗帜(ACE-白色): 旗幟(ACE-白色) Bandiera (ACE - Bianca) - 旗 (ACE - 白) + 旗 (ACE - 白色) Flaga (ACE - Biała) Флаг (ACE - Белый) Bandeira (ACE - Branco) @@ -1500,11 +1512,13 @@ Tylko dla AI 인공지능만 Nur KI + Solo IA 仅 AI AIのみ Только ИИ Sólo IA IA uniquement + Somente IA Players and AI @@ -1530,7 +1544,7 @@ 在自我互动菜单内显示动作 Pokaż akcje w menu interakcji własnej Mostra a ação no menu de auto-interação - セルフ インタラクションに動作を表示 + セルフ・インタラクションにアクションを表示します Mostra le azioni nel menu di interazione con se stessi Mostrar la acción en el menú de interacción propio Zobrazit akci v menu vlastních interakcí @@ -1546,32 +1560,38 @@ Les deux Оба Beide + Entrambi Oba 两方 둘 다 Ambos + Ambos Additional progress bar information - プログレス バー詳細情報 + プログレス バーの詳細情報 Infos supplémentaires de la barre de progression Доп. информация индикатора процесса Zusätzliche Informationen beim Fortschrittsbalken + Info aggiuntive sulla barra del progresso Dodatkowe informacje na pasku postępu 额外的进度条信息 추가 진행 막대 정보 Barra adicional de información de progreso + Informações adicionais na barra de progresso Controls extra information shown in progress bar. - プログレス バーへ表示される情報量を決定します。 + プログレス バーへ表示される情報量を制御します。 Définit quelles informations supplémentaires sont affichées dans la barre de progression. Устанавливает дополнительную информацию в индикаторе процесса. - Kontrolliert zusätzliche Informationen beim Fortschrittsbalkens + Kontrolliert zusätzliche Informationen beim Fortschrittsbalkens. + Mostra ulteriori informazioni nella barra di avanzamento. Kontroluje dodatkowe informacje na pasku postępu. 控制进度条中显示的额外信息。 진행 막대에 추가적인 정보를 보여주는걸 결정합니다. Controla la información extra mostrada en la barra de progreso. + Controla informações adicionais mostradas na barra de progresso. Percentage @@ -1579,10 +1599,12 @@ Pourcentage Процент выполнения Prozent + Percentuale Procent 百分比 백분율 Porcentaje + Porcentagem Time remaining @@ -1590,10 +1612,12 @@ Temps restant Времени осталось Zeit verbleibend + Tempo rimanente Pozostały czas 剩余时间 남은 시간 Tiempo restante + Tempo restante None @@ -1617,7 +1641,7 @@ Renommer Umbenennen Zmień nazwę - 改名 + 名前変更 Rinomina 이름 바꾸기 重新命名 @@ -1629,26 +1653,28 @@ Time left: %1s - 残り時間: %1 秒 + 残り時間: %1秒 Temps restant : %1 s Оставшееся время: %1s Zeit übrig %1s + Tempo rimanente: %1s Pozostały czas: %1s 剩余时间:%1秒 남은 시간: %1초 Tiempo restante: %1s + Tempo restante: %1s Locations Boost Training Zdravotnická místa zvyšují zdravotnickou úrovně - Sedi per potenziare la formazione + Luoghi che potenziano le abilità Örtliche Trainingssteigerung Ubicación mejora entrenamiento. Miejsca zwiększają wyszkolenie Localização melhora treinamento Le lieu améliore l'efficacité Места ускоренного обучения - 衛生能力の上昇位置 + 能力が向上する場所 교육 증가 지역 位置提升能力 受所在位置影響提升醫療能力 @@ -1663,7 +1689,9 @@ Разрядить оружие Descargar arma Waffe entladen + Scarica Arma Décharger l'arme + Descarregar arma Load @@ -1681,5 +1709,228 @@ 装载 Yükle + + Hide + Ukryj + Ocultar + Verstecken + Skrýt + Ocultar + Cacher + Elrejtés + Скрыть + Nascondi + 非表示 + 숨기기 + 隐藏 + 隱藏 + Gizle + + + Top right, downwards + Po prawej u góry, w dół + Arriba a la derecha, hacia abajo + Oben rechts, nach unten + Vpravo nahoře, dolů + Superior direito, para baixo + En haut à droite, vers le bas + Jobb felül, lefele + Справа — сверху вниз + In Alto a Destra, verso il Basso + 右上、下向 + 오른쪽 위에서 아래로 + 右上角,向下 + 右上角,向下 + Sağ üst, aşağı + + + Top right, to the left + Po prawej u góry, do lewej + Arriba a la derecha, hacia la izquierda + Von rechts nach links + Vpravo nahoře, do leva + Superior direito, à esquerda + En haut à droite, vers la gauche + Jobb felül, balra + Сверху — справа налево + In Alto a Destra, verso Sinistra + 右上、左向 + 오른쪽 위에서 왼쪽으로 + 右上角,向左 + 右上角,向左 + Sağ üstte, solda + + + Top left, downwards + Po lewej u góry, w dół + Arriba a la izquierda, hacia abajo + Von links, nach unten + Vlevo nahoře, dolů + Superior esquerdo, para baixo + En haut à gauche, vers le bas + Bal felül, lefele + Слева - сверху вниз + In Alto a Sinistra, verso il Basso + 左上、下向 + 왼쪽 위에서 아래로 + 左上角,向下 + 左上角,向下 + Sol üst, aşağı + + + Top left, to the right + Po lewej u góry, do prawej + Arriba a la izquierda, hacia la derecha + Oben links nach rechts + Vlevo nahoře, do prava + Superior esquerdo, para a direita + En haut à gauche, vers la droite + Bal felül, jobbra + Сверху — слева направо + In Alto a Sinistra, verso Destra + 右上、右向 + 왼쪽 위에서 오른쪽으로 + 左上角,向右 + 左上角,向右 + Sol üst, sağa + + + Top + Góra + Arriba + Oben + Nahoře + Acima + En haut + Fent + Сверху + Alto + 上側 + 상단 + 上方 + 上方 + Üst + + + Bottom + Dół + Abajo + Unten + Dole + Abaixo + En bas + Alul + Снизу + Basso + 下側 + 하단 + 下方 + 下方 + Alt + + + Weapon Sway + 手ぶれ + 무기 흔들림 + Oscillation de l'arme + Колебание оружия + Waffen schwanken + Oscilación del arma + Oscillazione arma + + + Enable Weapon Sway + 手ぶれを有効化 + 무기 흔들림 추가 + Activer l'oscillation de l'arme + Включить колебание оружия + Aktiviere Waffen schwanken + Habilitar oscilación del arma + Abilita oscillazione arma + + + Enables weapon sway influenced by sway factors, such as stance, fatigue and medical condition.\nDisabling this setting will defer sway to vanilla or other mods. + 姿勢、疲労、負傷状態などの手ぶれ要因に影響を受ける武器照準の揺れを有効にします。\nこの設定を無効にすると、手ぶれの揺れはバニラまたは他のMODの処理に任されます。 + 흔들림 계수, 자세, 피로도, 건강 상태 등의 요인에 영향을 받는 무기 흔들림을 활성화합니다.\n이 설정을 비활성화하면 바닐라 또는 다른 모드의 흔들림으로 대체됩니다. + Active l'oscillation de l'arme influencé par les facteurs d'oscillation, tels que la position, la fatigue et l'état de santé.\nLa désactivation de ce paramètre reportera l'oscillation à vanilla ou à d'autres mods. + Активируйте колебание оружия в зависимости от таких факторов, как стойка, усталость и состояние здоровья.\nОтключение этого параметра приведет к переносу раскачивания на vanilla или другие моды. + Ermöglicht die Beeinflussung des Waffen-Schwankens durch Beeinflussungsfaktoren wie Haltung, Müdigkeit und Gesundheitszustand.\nDie Deaktivierung dieser Einstellung erlaubt die Beeinflussung durch Vanilla oder andere Mods. + Habilita la oscilación del arma afectado por factores como la postura, la fatiga y la condición médica.\nDeshabilitar esta opción hará que el comportamiento de la oscilación venga definido por Vanilla o por otros mods. + Abilita l'oscillazione ACE, influenzata da fattori come postura, fatica e condizione medica.\nDisabilitare questa impostazione farà controllare l'oscillazione al gioco vanilla o altre mod. + + + Sway factor + Factor de balanceo de mira + Verwacklungsfaktor + 手ぶれ因数 + 抖动系数 + 抖動因素 + Facteur de tremblement + Fattore di Oscillazione + Czynnik kołysania + Фактор колебания прицела + Fator de Balanço de Mira + Faktor kývání + 손떨림 정도 + + + Influences the amount of weapon sway. Higher means more sway. + Afecta al la estabilidad de la mira. Más alto significa más balanceo + Beeinflusst, wie ruhig man eine Waffe halten kann. Ein höherer Wert bedeutet weniger Stabilisierung. + 武器の手ぶれの大きさに影響します。値が高いほど、手ぶれが強くなります。 + 影响手持武器的晃动程度,数值越高,抖动的越厉害。 + 影響手持武器晃動程度,數值越高抖動越厲害 + Influe sur l'amplitude du tremblement de l'arme. Une valeur plus élevée signifie plus de tremblement. + Influenza l'aumento di oscillazione dell'arma quando affaticato. Maggiore significa più oscillazione. + Wpływa na poziom kołysania broni. Większa ilość znaczy większe kołysanie. + Влияет на колебания прицела оружия. Чем выше - тем больше. + Influencia a quantidade de balanço da mira da arma. Quanto maior, mais balanço. + Ovlivňuje množství kývání zbraní. Vyšší znamená více kývání. + 손떨림의 정도를 정합니다. 높을 수록 많이 휘적입니다. + + + Rested sway factor + Facteur de balancement au repos + 휴식 시 손떨림 정도 + Fator de balanço de mira em repouso + Verwacklungsfaktor, wenn aufgelegt + Fattore di Oscillazione Appoggiato + 静止依託時の手ぶれ係数 + Коэф. колебания прицела в состоянии покоя + Factor de oscilación apoyado + + + Influences the amount of weapon sway while weapon is rested. + Influence le degré de balancement de l'arme au repos. + 무기가 아무런 행동도 하지 않는 동안 무기가 흔들리는 정도를 정합니다. + Influencia a quantidade de balanço de mira enquanto a arma está em repouso. + Beeinflusst, wie ruhig man die Waffe hält, während sie aufgelegt ist. + Determina la quantità di oscillazione dell'arma quando questa è appoggiata. + 静止し壁などに依託している時の武器の手ぶれの大きさに影響します。 + Влияет на величину колебания прицела оружия в состоянии покоя. + Afecta la cantidad de oscilación del arma cuando se está apoyado. + + + Deployed sway factor + Facteur de balancement déployé + 거치 시 손떨림 정도 + Fator de balanço de mira em posição de tiro + Verwacklungsfaktor, wenn Zweibein aufgestellt ist. + Fattore di Oscillazione su Bipode + 接地展開時の手ぶれ係数 + Коэф. колебания прицела при развертывании + Factor de oscilación desplegado + + + Influences the amount of weapon sway while weapon is deployed. + Influence le degré de balancement de l'arme déployée. + 무기를 거치하는 동안 무기를 흔드는 정도를 정합니다. + Influencia a quantidade de balanço de mira enquanto a arma está em posição de tiro. + 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. + 武器の接地展開時の武器の手ぶれの大きさに影響します。 + Влияет на величину колебания прицела оружия при его развертывании. + Afecta la cantidad de oscilación del arma cuando se está desplegado. + diff --git a/addons/compat_cup_terrains/$PBOPREFIX$ b/addons/compat_cup_terrains/$PBOPREFIX$ new file mode 100644 index 0000000000..f904236cf3 --- /dev/null +++ b/addons/compat_cup_terrains/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_cup_terrains diff --git a/addons/compat_cup_terrains/CfgEventHandlers.hpp b/addons/compat_cup_terrains/CfgEventHandlers.hpp new file mode 100644 index 0000000000..9cc1b0427b --- /dev/null +++ b/addons/compat_cup_terrains/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_terrains/CfgVehicles.hpp b/addons/compat_cup_terrains/CfgVehicles.hpp new file mode 100644 index 0000000000..3fbd69f291 --- /dev/null +++ b/addons/compat_cup_terrains/CfgVehicles.hpp @@ -0,0 +1,56 @@ +class CBA_Extended_EventHandlers; +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} + +class CfgVehicles { + class House; + class House_Small_F; + class Strategic; + class House_EP1: House {}; + + class Land_Benzina_schnell: House { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-1.5,-3.93,-1.25}, {2.35,-3.93,-1.25}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; + class ACE_Actions { + class ACE_MainActions { + displayName = ECSTRING(interaction,MainAction); + position = "[0,-3.93,-1.25]"; + distance = 5; + condition = "true"; + }; + }; + }; + class Land_A_FuelStation_Feed: Strategic { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; + }; + class Land_Ind_FuelStation_Feed_EP1: House_EP1 { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; + }; + class Land_FuelStation_Feed_PMC: Strategic { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-0.34,0,0}, {0.34,0,0}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; + }; + class FuelStation: House_Small_F { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{1.25, .2, -1.1}}; + EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; + class ACE_Actions { + class ACE_MainActions { + displayName = ECSTRING(interaction,MainAction); + position = "[1.25, .2, -1]"; + distance = 5; + condition = "true"; + }; + }; + }; + class WarfareBBaseStructure; + class Base_WarfareBVehicleServicePoint: WarfareBBaseStructure { + // "vehicle service point" (a conex /w barrels) - need hooks??? + XEH_INHERITED; + }; +}; diff --git a/addons/compat_cup_terrains/XEH_postInit.sqf b/addons/compat_cup_terrains/XEH_postInit.sqf new file mode 100644 index 0000000000..32b9393d98 --- /dev/null +++ b/addons/compat_cup_terrains/XEH_postInit.sqf @@ -0,0 +1,5 @@ +#include "script_component.hpp" + +if (["CUP_Terrains_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 - Terrains'"); +}; diff --git a/addons/compat_cup_terrains/config.cpp b/addons/compat_cup_terrains/config.cpp new file mode 100644 index 0000000000..a7020be4da --- /dev/null +++ b/addons/compat_cup_terrains/config.cpp @@ -0,0 +1,27 @@ +#include "script_component.hpp" +#include "\z\ace\addons\refuel\defines.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CABuildings", + "CAStructuresHouse_A_FuelStation", + "CAStructures_E_Ind_Ind_FuelStation", + "CAStructures_PMC_FuelStation", + "CUP_Buildings_Config", + "ace_refuel" // not a sub-component because it's all this compat does + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Community Upgrade Project", "Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" +#include "CfgEventHandlers.hpp" diff --git a/addons/compat_cup_terrains/script_component.hpp b/addons/compat_cup_terrains/script_component.hpp new file mode 100644 index 0000000000..633de5584b --- /dev/null +++ b/addons/compat_cup_terrains/script_component.hpp @@ -0,0 +1,5 @@ +#define COMPONENT compat_cup_terrains +#define COMPONENT_BEAUTIFIED CUP Terrains Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_cup_units/$PBOPREFIX$ b/addons/compat_cup_units/$PBOPREFIX$ new file mode 100644 index 0000000000..7a3dc51ddd --- /dev/null +++ b/addons/compat_cup_units/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_cup_units diff --git a/addons/compat_cup_units/CfgGlasses.hpp b/addons/compat_cup_units/CfgGlasses.hpp new file mode 100644 index 0000000000..1620f74212 --- /dev/null +++ b/addons/compat_cup_units/CfgGlasses.hpp @@ -0,0 +1,492 @@ +class CfgGlasses { + + #define ESS_OVERLAY \ + ace_overlay = QPATHTOEF(goggles,textures\hud\combatgoggles.paa); \ + ace_overlayCracked = QPATHTOEF(goggles,textures\hud\combatgogglescracked.paa) + + class None; + class CUP_G_PMC_RadioHeadset_Glasses; + + // ESS Goggles - Dark + class CUP_G_ESS_BLK_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Blk_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Blk: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Dark: None { + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + + // ESS Goggles - Ember + class CUP_G_ESS_BLK_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Ember: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Facewrap_White: None { + ace_color[] = {1, 0, 0}; + ace_protection = 1; + ace_resistance = 1; + ace_tintAmount = 8; + ESS_OVERLAY; + }; + + // ESS Goggles - Clear + class CUP_G_ESS_BLK: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Facewrap_Black: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Facewrap_Black_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Grn: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Grn_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_White: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Face_White_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Grn_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_Red_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_BLK_Scarf_White_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_CBR_Facewrap_Red: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Facewrap_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Face_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Face_Tan_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_KHK_Scarf_Tan_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Ranger: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Skull: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + class CUP_G_ESS_RGR_Facewrap_Tropical: None { + ace_protection = 1; + ace_resistance = 1; + ESS_OVERLAY; + }; + + // Oakleys - Dark + class CUP_G_Oakleys_Drk: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Dark: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Dark: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Dark_Headset: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_RadioHeadset_Glasses_Dark: CUP_G_PMC_RadioHeadset_Glasses { + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Oakleys - Ember + class CUP_G_Oakleys_Embr: None { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Black_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tan_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Tropical_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_Facewrap_Winter_Glasses_Ember: CUP_G_PMC_Facewrap_Black_Glasses_Dark { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_PMC_RadioHeadset_Glasses_Ember: CUP_G_PMC_RadioHeadset_Glasses { + ace_color[] = {1, 0, 0}; + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Shades - Dark + class CUP_G_Beard_Shades_Black: None { + ace_resistance = 1; + ace_tintAmount = 8; + }; + class CUP_G_Beard_Shades_Blonde: CUP_G_Beard_Shades_Black { + ace_resistance = 1; + ace_tintAmount = 8; + }; + + // Shades - Clear + class CUP_G_Grn_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Grn_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_Tan_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPS_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo_Beard: None { + ace_protection = 1; + ace_resistance = 1; + }; + class CUP_G_White_Scarf_Shades_GPSCombo_Beard_Blonde: None { + ace_protection = 1; + ace_resistance = 1; + }; + + // Thug - Dark + class CUP_PMC_G_thug: None { + ace_tintAmount = 8; + }; +}; diff --git a/addons/compat_cup_units/CfgWeapons.hpp b/addons/compat_cup_units/CfgWeapons.hpp new file mode 100644 index 0000000000..37a210db9d --- /dev/null +++ b/addons/compat_cup_units/CfgWeapons.hpp @@ -0,0 +1,87 @@ +#define HEARING(CLASSNAME) \ + class CLASSNAME: ItemCore { \ + ace_hearing_protection = 0.75; \ + ace_hearing_lowerVolume = 0; \ + } + +#define HEARING_PARENT(CLASSNAME,PARENT) \ + class CLASSNAME: PARENT { \ + ace_hearing_protection = 0.75; \ + ace_hearing_lowerVolume = 0; \ + } + +class CfgWeapons { + class ItemCore; + class CUP_H_PMC_Beanie_Khaki; + + HEARING(CUP_H_BAF_DDPM_Mk6_CREW_PRR); + HEARING(CUP_H_BAF_DPM_Mk6_CREW_PRR); + HEARING(CUP_H_BAF_MTP_Mk6_CREW_PRR); + HEARING(CUP_H_CZ_Cap_Headphones); + HEARING(CUP_H_CZ_Cap_Headphones_des); + HEARING(CUP_H_CZ_Helmet05); + HEARING(CUP_H_CZ_Helmet07); + HEARING(CUP_H_CZ_Helmet08); + HEARING(CUP_H_CZ_Helmet09); + HEARING(CUP_H_CZ_Helmet10); + HEARING(CUP_H_FR_ECH); + HEARING(CUP_H_Ger_Beret_TankCommander_Blk); + HEARING(CUP_H_Ger_Beret_TankCommander_Grn); + HEARING(CUP_H_Ger_Cap_EP_Grn1); + HEARING(CUP_H_Ger_Cap_EP_Grn2); + HEARING(CUP_H_Ger_Cap_EP_Tan1); + HEARING(CUP_H_Ger_Cap_EP_Tan2); + HEARING(CUP_H_OpsCore_Black); + HEARING(CUP_H_OpsCore_Black_SF); + HEARING(CUP_H_OpsCore_Covered_AAF); + HEARING(CUP_H_OpsCore_Covered_AAF_SF); + HEARING(CUP_H_OpsCore_Covered_Fleck); + HEARING(CUP_H_OpsCore_Covered_Fleck_SF); + HEARING(CUP_H_OpsCore_Covered_MCAM); + HEARING(CUP_H_OpsCore_Covered_MCAM_SF); + HEARING(CUP_H_OpsCore_Covered_MCAM_US); + HEARING(CUP_H_OpsCore_Covered_MCAM_US_SF); + HEARING(CUP_H_OpsCore_Covered_MTP); + HEARING(CUP_H_OpsCore_Covered_MTP_SF); + HEARING(CUP_H_OpsCore_Covered_Tigerstripe); + HEARING(CUP_H_OpsCore_Covered_Tigerstripe_SF); + HEARING(CUP_H_OpsCore_Covered_Tropen); + HEARING(CUP_H_OpsCore_Covered_Tropen_SF); + HEARING(CUP_H_OpsCore_Covered_UCP); + HEARING(CUP_H_OpsCore_Covered_UCP_SF); + HEARING(CUP_H_OpsCore_Green); + HEARING(CUP_H_OpsCore_Green_SF); + HEARING(CUP_H_OpsCore_Grey); + HEARING(CUP_H_OpsCore_Grey_SF); + HEARING(CUP_H_OpsCore_Spray); + HEARING(CUP_H_OpsCore_Spray_SF); + HEARING(CUP_H_OpsCore_Spray_US); + HEARING(CUP_H_OpsCore_Spray_US_SF); + HEARING(CUP_H_OpsCore_Tan); + HEARING(CUP_H_OpsCore_Tan_SF); + HEARING_PARENT(CUP_H_PMC_Beanie_Headphones_Khaki,CUP_H_PMC_Beanie_Khaki); + HEARING_PARENT(CUP_H_PMC_Beanie_Headphones_Black,CUP_H_PMC_Beanie_Headphones_Khaki); + HEARING_PARENT(CUP_H_PMC_Beanie_Headphones_Winter,CUP_H_PMC_Beanie_Headphones_Khaki); + HEARING(CUP_H_PMC_Cap_Back_EP_Grey); + HEARING(CUP_H_PMC_Cap_Back_EP_Tan); + HEARING(CUP_H_PMC_Cap_EP_Grey); + HEARING(CUP_H_PMC_Cap_EP_Tan); + HEARING(CUP_H_PMC_EP_Headset); + HEARING(CUP_H_USArmy_HelmetMICH_earpro); + HEARING(CUP_H_USArmy_HelmetMICH_earpro_DCU); + HEARING(CUP_H_USArmy_HelmetMICH_earpro_ess); + HEARING(CUP_H_USArmy_HelmetMICH_earpro_ess_DCU); + HEARING(CUP_H_USArmy_HelmetMICH_earpro_ess_wdl); + HEARING(CUP_H_USArmy_HelmetMICH_earpro_wdl); + HEARING(CUP_H_USArmy_Helmet_ECH1_Black); + HEARING(CUP_H_USArmy_Helmet_ECH1_Green); + HEARING(CUP_H_USArmy_Helmet_ECH1_Sand); + HEARING(CUP_H_USArmy_Helmet_ECH2_Black); + HEARING(CUP_H_USArmy_Helmet_ECH2_GREEN); + HEARING(CUP_H_USArmy_Helmet_ECH2_Sand); + HEARING(CUP_H_USMC_Crew_Helmet); + HEARING(CUP_H_USMC_MICH2000_DEF_DES); + HEARING(CUP_H_USMC_MICH2000_DEF_ESS_DES); + HEARING(CUP_H_USMC_MICH2000_DEF_ESS_WDL); + HEARING(CUP_H_USMC_MICH2000_DEF_WDL); +}; diff --git a/addons/compat_cup_units/compat_cup_nouniformrestrictions/CfgVehicles.hpp b/addons/compat_cup_units/compat_cup_nouniformrestrictions/CfgVehicles.hpp new file mode 100644 index 0000000000..386cc7df0b --- /dev/null +++ b/addons/compat_cup_units/compat_cup_nouniformrestrictions/CfgVehicles.hpp @@ -0,0 +1,86 @@ +class CfgVehicles { + class SoldierWB; + class Civilian_F; + + class CUP_BAF_Soldier_DPM_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_BAF_Soldier_DDPM_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_BAF_Soldier_MTP_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_GER_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_NAPA_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_PMC_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_PMC_Soldier_Winter_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_RUS_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_TK_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_TKI_Insurgent_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_TKG_Guerrilla_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_USMC_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_FR_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Civil_Chernarus_Base: Civilian_F { + modelSides[] = {6}; + }; + class CUP_Creatures_Civil_Takistan_Base: Civilian_F { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_ACR_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_CDF_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_UNO_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_OPFINS_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_RACS_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_SLA_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_USA_Soldier_ACU_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_USA_Soldier_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_HIL_Reservist_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_HIL_Recon_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_HIL_Man_Base: SoldierWB { + modelSides[] = {6}; + }; + class CUP_Creatures_Military_HIL_SF_Base: SoldierWB { + modelSides[] = {6}; + }; +}; diff --git a/addons/compat_cup_units/compat_cup_nouniformrestrictions/config.cpp b/addons/compat_cup_units/compat_cup_nouniformrestrictions/config.cpp new file mode 100644 index 0000000000..826f796226 --- /dev/null +++ b/addons/compat_cup_units/compat_cup_nouniformrestrictions/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "CUP_Creatures_People_LoadOrder", + "ace_nouniformrestrictions" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike", "Jonpas"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_cup_units/compat_cup_nouniformrestrictions/script_component.hpp b/addons/compat_cup_units/compat_cup_nouniformrestrictions/script_component.hpp new file mode 100644 index 0000000000..0b98185fa0 --- /dev/null +++ b/addons/compat_cup_units/compat_cup_nouniformrestrictions/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nouniformrestrictions +#define SUBCOMPONENT_BEAUTIFIED No Uniform Restrictions +#include "..\script_component.hpp" diff --git a/addons/compat_cup_units/config.cpp b/addons/compat_cup_units/config.cpp new file mode 100644 index 0000000000..c3ba110e74 --- /dev/null +++ b/addons/compat_cup_units/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"CUP_Creatures_People_LoadOrder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike", "Jonpas"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgGlasses.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_cup_units/script_component.hpp b/addons/compat_cup_units/script_component.hpp new file mode 100644 index 0000000000..46e1542b50 --- /dev/null +++ b/addons/compat_cup_units/script_component.hpp @@ -0,0 +1,5 @@ +#define COMPONENT compat_cup_units +#define COMPONENT_BEAUTIFIED CUP Units Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" +#include "\z\ace\addons\main\script_macros.hpp" 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..5334987fff --- /dev/null +++ b/addons/compat_cup_vehicles/CfgVehicles.hpp @@ -0,0 +1,288 @@ +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"}; + }; + }; + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l1", "hitera_l2", "hitera_l3", "hitera_l4", "hitera_l5", + "hitera_l6", "hitera_l7", "hitera_l8", "hitera_r1", "hitera_r2", + "hitera_r3", "hitera_r4", "hitera_r5", "hitera_r6", "hitera_r7", + "hitera_r8", "hitera_t1", "hitera_t2", "hitera_t3", "hitera_t4", + "hitera_t5", "hitera_t6", "hitera_t7", "hitera_t8", "hitera_fr1", + "hitera_fr2", "hitera_fr3", "hitera_fr4", "hitera_fr5", "hitera_fr6", + "hitera_fr7", "hitera_fr8", "hitera_fr9", "hitera_fl1", "hitera_fl2", + "hitera_fl3", "hitera_fl4", "hitera_fl5" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = {}; + }; + class CUP_T90_Base: Tank_F { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l1", "hitera_l2", "hitera_l3", "hitera_r1", "hitera_r2", + "hitera_r3", "hitera_1_t_l", "hitera_1_t_r", "hitera_2_t_l", + "hitera_2_t_r" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = {}; + }; + class CUP_T90M_Base: Tank_F { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_t1", "hitera_t2", "hitera_t3", "hitera_t4", "hitera_t5", + "hitera_t6", "hitera_t7", "hitera_t8", "hitera_t9", "hitera_t10", + "hitera_t11", "hitera_t12", "hitera_t13", "hitera_t14", "hitera_t15", + "hitera_t16", "hitera_t17", "hitera_t18", "hitera_t19", "hitera_t20", + "hitera_t21", "hitera_f1", "hitera_f2", "hitera_f3", "hitera_f4", + "hitera_f5", "hitera_f6", "hitera_f7", "hitera_s1", "hitera_s2", + "hitera_s3", "hitera_s4", "hitera_s5", "hitera_s6", "hitera_s7", + "hitera_s8", "hitera_s9", "hitera_s10", "hitera_s11", "hitera_s12", + "hitera_t22", "hitera_t23", "hitera_t24", "hitera_t25", "hitera_t26", + "hitera_t27", "hitera_t28", "hitera_t29", "hitera_t30", "hitera_t31", + "hitera_t32", "hitera_t33" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "hitslat_left", "hitslat_right", "hitslat_turret_rear", + "hitslat_turret_left", "hitslat_rear" + }; + }; + + class CUP_T72_ACR_Base; + class CUP_B_T72_CZ: CUP_T72_ACR_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_top_l1", "hitera_top_l2", "hitera_top_l3", "hitera_top_l4", + "hitera_top_r1", "hitera_top_r2", "hitera_top_r3", "hitera_top_r4", + "hitera_front_r1", "hitera_front_r2", "hitera_front_l1", + "hitera_front_l2", "hitera_top_rear" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = {}; + }; + + class CUP_Leopard2_Base; + class CUP_Leopard2_ERA_Base: CUP_Leopard2_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_1", "hitera_2", "hitera_3", "hitera_4", "hitera_5", "hitera_6", + "hitera_7", "hitera_8", "hitera_9", "hitera_10", "hitera_11", "hitera_12", + "hitera_13", "hitera_14", "hitera_15", "hitera_16", "hitera_17", "hitera_18", + "hitera_19", "hitera_20", "hitera_21", "hitera_22", "hitera_23", "hitera_24", + "hitera_25", "hitera_26", "hitera_27", "hitera_28", "hitera_29", "hitera_30", + "hitera_31", "hitera_32", "hitera_33", "hitera_34", "hitera_35", "hitera_36", + "hitera_37", "hitera_38", "hitera_39", "hitera_40", "hitera_41", "hitera_42", + "hitera_43", "hitera_44", "hitera_45", "hitera_46", "hitera_47" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = {}; + }; + + class CUP_M1_Abrams_base; + class CUP_M1A2_TUSK_base: CUP_M1_Abrams_base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l1", "hitera_l2", "hitera_l3", "hitera_l4", "hitera_r1", + "hitera_r2", "hitera_r3", "hitera_r4" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "hitslat_rear" + }; + }; + + class CUP_M1Abrams_Base; + class CUP_M1Abrams_TUSK_Base: CUP_M1Abrams_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l01", "hitera_l02", "hitera_l03", "hitera_l04", "hitera_l05", + "hitera_l06", "hitera_l07", "hitera_l08", "hitera_l09", "hitera_l10", + "hitera_l11", "hitera_l12", "hitera_l13", "hitera_l14", "hitera_l15", + "hitera_l16", "hitera_r01", "hitera_r02", "hitera_r03", "hitera_r04", + "hitera_r05", "hitera_r06", "hitera_r07", "hitera_r08", "hitera_r09", + "hitera_r10", "hitera_r11", "hitera_r12", "hitera_r13", "hitera_r14", + "hitera_r15", "hitera_r16" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "hitslat_rear" + }; + }; + + class CUP_M1Abrams_A2_Base; + class CUP_M1Abrams_A2_TUSK_Base: CUP_M1Abrams_A2_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l01", "hitera_l02", "hitera_l03", "hitera_l04", "hitera_l05", + "hitera_l06", "hitera_l07", "hitera_l08", "hitera_l09", "hitera_l10", + "hitera_l11", "hitera_l12", "hitera_l13", "hitera_l14", "hitera_l15", + "hitera_l16", "hitera_l17", "hitera_l18", "hitera_l19", "hitera_l20", + "hitera_r01", "hitera_r02", "hitera_r03", "hitera_r04", "hitera_r05", + "hitera_r06", "hitera_r07", "hitera_r08", "hitera_r09", "hitera_r10", + "hitera_r11", "hitera_r12", "hitera_r13", "hitera_r14", "hitera_r15", + "hitera_r16", "hitera_r17", "hitera_r18", "hitera_r19", "hitera_r20" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "hitslat_rear" + }; + }; + + class CUP_M1A2Abrams_Base; + class CUP_M1A2Abrams_TUSK_Base: CUP_M1A2Abrams_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l01", "hitera_l02", "hitera_l03", "hitera_l04", "hitera_l05", + "hitera_l06", "hitera_l07", "hitera_l08", "hitera_l09", "hitera_l10", + "hitera_l11", "hitera_l12", "hitera_l13", "hitera_l14", "hitera_l15", + "hitera_l16", "hitera_r01", "hitera_r02", "hitera_r03", "hitera_r04", + "hitera_r05", "hitera_r06", "hitera_r07", "hitera_r08", "hitera_r09", + "hitera_r10", "hitera_r11", "hitera_r12", "hitera_r13", "hitera_r14", + "hitera_r15", "hitera_r16" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "hitslat_rear" + }; + }; + class CUP_M1A2Abrams_TUSK_II_Base: CUP_M1A2Abrams_TUSK_Base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "hitera_l01", "hitera_l02", "hitera_l03", "hitera_l04", "hitera_l05", + "hitera_l06", "hitera_l07", "hitera_l08", "hitera_l09", "hitera_l10", + "hitera_l11", "hitera_l12", "hitera_l13", "hitera_l14", "hitera_l15", + "hitera_l16", "hitera_l17", "hitera_l18", "hitera_l19", "hitera_l20", + "hitera_r01", "hitera_r02", "hitera_r03", "hitera_r04", "hitera_r05", + "hitera_r06", "hitera_r07", "hitera_r08", "hitera_r09", "hitera_r10", + "hitera_r11", "hitera_r12", "hitera_r13", "hitera_r14", "hitera_r15", + "hitera_r16", "hitera_r17", "hitera_r18", "hitera_r19", "hitera_r20" + }; + }; +}; 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/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..1042c0eacf --- /dev/null +++ b/addons/compat_cup_vehicles/compat_cup_vehicles_refuel/CfgVehicles.hpp @@ -0,0 +1,31 @@ +class CfgVehicles { + class CUP_T810_Unarmed_Base; + class CUP_T810_Refuel_Base: CUP_T810_Unarmed_Base { + 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 { + 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 { + 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 { + 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 { + 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..513993ef57 --- /dev/null +++ b/addons/compat_cup_vehicles/config.cpp @@ -0,0 +1,22 @@ +#include "script_component.hpp" + +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" 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/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..9ff8519ce1 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/CfgWeapons.hpp @@ -0,0 +1,289 @@ +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_I_2b14_82mm_AAF"; + }; + }; + 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_I_M252_AAF"; + }; + }; + }; + + 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_I_L16A2_AAF"; + }; + }; + }; + + 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_I_M2StaticMG_AAF"; + ace_csw_m3TripodLow = "CUP_I_M2StaticMG_MiniTripod_AAF"; + }; + }; + 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_I_DSHKM_AAF"; + ace_csw_kordTripodLow = "CUP_I_DSHKM_MiniTriPod_AAF"; + }; + }; + 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_I_KORD_high_AAF"; + ace_csw_kordTripodLow = "CUP_I_KORD_AAF"; + }; + }; + 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_I_AGS_AAF"; + }; + }; + 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_I_MK19_TriPod_AAF"; + }; + }; + 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_I_Metis_AAF"; + }; + 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_I_TOW_TriPod_AAF"; + }; + }; + 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_I_TOW2_TriPod_AAF"; + }; + }; + }; + + 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_I_SPG9_AAF"; + }; + }; + 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..ea16be2905 --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_csw/stringtable.xml @@ -0,0 +1,169 @@ + + + + + [CSW] AGS30 Belt + [CSW] AGS30 ベルト + [CSW] Лента AGS 30 + [CSW] AGS-30 벨트 + [CSW] AGS30 Gurt + [CSW] Cinta de AGS30 + [CSW] Nastro AGS30 + + + [CSW] MK19 Belt + [CSW] Mk19 ベルト + [CSW] Лента Mk19 + [CSW] Mk.19 벨트 + [CSW] MK19 Gurt + [CSW] Cinta de MK19 + [CSW] Nastro MK19 + + + [CSW] TOW Tube + [CSW] TOW チューブ + [CSW] Туба TOW + [CSW] TOW 튜브 + [CSW] TOW Rohr + [CSW] Tubo de TOW + [CSW] Tubo TOW + + + [CSW] TOW2 Tube + [CSW] TOW2 チューブ + [CSW] Туба TOW-2 + [CSW] TOW2 튜브 + [CSW] TOW2 Rohr + [CSW] Tubo de TOW2 + [CSW] Tubo TOW2 + + + [CSW] PG-9 Round + [CSW] PG-9 砲弾 + [CSW] Снаряд ПГ-9 + [CSW] PG-9 대전차고폭탄 + [CSW] PG-9 Rakete + [CSW] Carga de PG-9 + [CSW] Razzo PG-9 + + + [CSW] OG-9 Round + [CSW] OG-9 砲弾 + [CSW] Снаряд OГ-9 + [CSW] OG-9 고폭파편탄 + [CSW] OG-9 Rakete + [CSW] Carga de OG-9 + [CSW] Razzo OG-9 + + + [CSW] M1 HE + [CSW] M1 榴弾 + [CSW] M1 HE + [CSW] M1 고폭탄 + [CSW] M1 HE + [CSW] M1 HE + [CSW] HE de M1 + [CSW] M1 HE + + + [CSW] M84 Smoke + [CSW] M84 白煙弾 + [CSW] M84 Дымовая + [CSW] M84 연막탄 + [CSW] M84 Fumigène + [CSW] M84 Rauch + [CSW] Humo M84 + [CSW] M84 Fumogeno + + + [CSW] M60A2 WP + [CSW] M60A2 白リン弾 + [CSW] M60A2 WP + [CSW] M60A2 백린연막탄 + [CSW] M60A2 WP + [CSW] M60A2 WP + [CSW] M60A2 WP + [CSW] M60A2 WP + + + [CSW] M67 AT Laser Guided + [CSW] M67 対戦車レーザー誘導弾 + [CSW] M67 AT Laser Guided + [CSW] M67 레이저유도 대전차탄 + [CSW] M67 AT Guidé laser + [CSW] M67 AT Lasergelenkt + [CSW] AT Guiado por Láser M67 + [CSW] M67 AT Laserguidato + + + [CSW] M314 Illumination + [CSW] M314 照明弾 + [CSW] M314 Осветительная + [CSW] M314 조명탄 + [CSW] M314 Illumination + [CSW] M314 Beleuchtung + [CSW] Iluminación M314 + [CSW] M314 Illuminante + + + [CSW] 3OF56 HE + [CSW] 3OF56 榴弾 + [CSW] 3OF56 HE + [CSW] 3OF56 고폭탄 + [CSW] 3OF56 HE + [CSW] 3OF56 HE + [CSW] HE de 3OF56 + [CSW] 3OF56 HE + + + [CSW] 3OF69M Laser Guided + [CSW] 3OF69M レーザー誘導弾 + [CSW] 3OF69M Laser Guided + [CSW] 3OF69M 레이저유도탄 + [CSW] 3OF69M Guidé laser + [CSW] 3OF69M Lasergelenkt + [CSW] 3OF69M Guiado por Láser + [CSW] 3OF69M Laserguidato + + + [CSW] 122mm WP + [CSW] 122mm 白リン弾 + [CSW] 122mm WP + [CSW] 122mm 백린탄 + [CSW] 122mm WP + [CSW] 122mm WP + [CSW] WP de 122mm + [CSW] 122mm WP + + + [CSW] D-462 Smoke + [CSW] D-462 白煙弾 + [CSW] D-462 Дымовая + [CSW] D-462 연막탄 + [CSW] D-462 Fumigène + [CSW] D-462 Rauch + [CSW] Humo D-462 + [CSW] D-462 Fumogeno + + + [CSW] S-463 Illumination + [CSW] S-463 照明弾 + [CSW] S-463 Осветительная + [CSW] S-463 조명탄 + [CSW] S-463 Eclairante + [CSW] S-463 Beleuchtung + [CSW] Iluminación S-463 + [CSW] S-463 Illuminante + + + [CSW] BK-6M HEAT + [CSW] BK-6M HEAT弾 + [CSW] BK-6M HEAT + [CSW] BK-6M 대전차고폭탄 + [CSW] BK-6M HEAT + [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..5e31f93caf --- /dev/null +++ b/addons/compat_cup_weapons/compat_cup_weapons_nightvision/stringtable.xml @@ -0,0 +1,102 @@ + + + + + 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-14 (WP) + + + AN/PVS-15 (Black, 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 (Negras, WP) + + + AN/PVS-15 (Green, 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 (Verdes, WP) + + + AN/PVS-15 (Tan, WP) + AN/PVS-15 (タン, 白色蛍光) + AN/PVS-15 (Marroncino, 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 (Marrones, WP) + + + AN/PVS-15 (Winter, WP) + AN/PVS-15 (冬季迷彩, WP) + AN/PVS-15 (Invernale, FB) + AN/PVS-15 (설상, 백색광) + AN/PVS-15 (Белый, БФ) + AN/PVS-15 (Blanc, WP) + AN/PVS-15 (Winter, WP) + AN/PVS-15 (Blancas, WP) + + + GPNVG (Black, WP) + GPNVG (ブラック、白色蛍光) + GPNVG (Nero, FB) + GPNVG (Czarne, WP) + GPNVG (Schwarz, WP) + GPNVG (검정, 백색광) + GPNVG (Noires, WP) + GPNVG (Чёрный, БФ) + GPNVG (Negras, WP) + + + GPNVG (Tan, WP) + GPNVG (タン, 白色蛍光) + GPNVG (Marroncino, FB) + GPNVG (Jasnobrązowa, WP) + GPNVG (Hellbraun, WP) + GPNVG (황갈색, 백색광) + GPNVG (Marron clair, WP) + GPNVG (Желтовато-коричневый, БФ) + GPNVG (Marrones, WP) + + + GPNVG (Green, WP) + GPNVG (グリーン, 白色蛍光) + GPNVG (Verde, FB) + GPNVG (Zielone, WP) + GPNVG (Grün, WP) + GPNVG (녹색, 백색광) + GPNVG (Vertes, WP) + GPNVG (Зелёный, БФ) + GPNVG (Verdes, WP) + + + GPNVG (Winter, WP) + GPNVG (冬季迷彩, WP) + GPNVG (Invernale, FB) + GPNVG (설상, 백색광) + AN/PVS-15 (Белый, БФ) + GPNVG (Blanc, WP) + GPNVG (Winter, WP) + GPNVG (Blancas, WP) + + + diff --git a/addons/compat_cup_weapons/config.cpp b/addons/compat_cup_weapons/config.cpp new file mode 100644 index 0000000000..54dd0271cc --- /dev/null +++ b/addons/compat_cup_weapons/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +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 "CfgEventHandlers.hpp" +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" 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_gm/compat_gm_refuel/CfgVehicles.hpp b/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp deleted file mode 100644 index 46a4deeefd..0000000000 --- a/addons/compat_gm/compat_gm_refuel/CfgVehicles.hpp +++ /dev/null @@ -1,6 +0,0 @@ -class CfgVehicles { - class gm_ural4320_base; - class gm_ural4320_refuel_base: gm_ural4320_base { - transportFuel = 0; - }; -}; diff --git a/addons/compat_gm/compat_gm_refuel/config.cpp b/addons/compat_gm/compat_gm_refuel/config.cpp index 6becabe70a..05688eff70 100644 --- a/addons/compat_gm/compat_gm_refuel/config.cpp +++ b/addons/compat_gm/compat_gm_refuel/config.cpp @@ -21,4 +21,3 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" -#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/$PBOPREFIX$ b/addons/compat_rf/$PBOPREFIX$ new file mode 100644 index 0000000000..78e6f45daf --- /dev/null +++ b/addons/compat_rf/$PBOPREFIX$ @@ -0,0 +1 @@ +z\ace\addons\compat_rf diff --git a/addons/compat_rf/CfgWeapons.hpp b/addons/compat_rf/CfgWeapons.hpp new file mode 100644 index 0000000000..d1daa7c710 --- /dev/null +++ b/addons/compat_rf/CfgWeapons.hpp @@ -0,0 +1,42 @@ +class CfgWeapons { + // Ballistics + class Pistol_Base_F; + class hgun_Glock19_RF: Pistol_Base_F { + ace_barrelTwist = 254; + ace_barrelLength = 102; + ace_twistDirection = 1; + }; + + class hgun_DEagle_RF: Pistol_Base_F { + ace_barrelTwist = 482; + ace_barrelLength = 127; + ace_twistDirection = 1; + }; + + class Rifle_Long_Base_F; + class srifle_h6_base_rf: Rifle_Long_Base_F { + ace_barrelTwist = 228.6; + ace_barrelLength = 460; + ace_twistDirection = 1; + }; + + class Rifle_Base_F; + class arifle_ash12_base_RF: Rifle_Base_F { + ace_barrelTwist = 228.6; + ace_barrelLength = 400; + ace_twistDirection = 1; + }; + + class arifle_ash12_LR_base_RF: arifle_ash12_base_RF { + ace_barrelLength = 450; + }; + + // Hearing + class H_HelmetIA; + class H_HelmetIA_sb_arid_RF: H_HelmetIA { + ace_hearing_protection = 0.75; + }; + class H_HelmetIA_sb_digital_RF: H_HelmetIA { + ace_hearing_protection = 0.75; + }; +}; diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp b/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp new file mode 100644 index 0000000000..553c199ee6 --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/CfgVehicles.hpp @@ -0,0 +1,12 @@ +// Generated using ace_nouniformrestrictions_fnc_exportConfig +class CfgVehicles { + class B_Helipilot_F; + class C_Helipilot_Green_UniformHolder_RF; + + class C_Helipilot_Rescue_UniformHolder_RF: B_Helipilot_F { + modelSides[] = {6}; + }; + class B_Helipilot_Green_UniformHolder_RF: C_Helipilot_Green_UniformHolder_RF { + modelSides[] = {6}; + }; +}; diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp b/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp new file mode 100644 index 0000000000..2de1cf9673 --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/config.cpp @@ -0,0 +1,21 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "RF_Data_Loadorder", + "ace_nouniformrestrictions" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp b/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp new file mode 100644 index 0000000000..0b98185fa0 --- /dev/null +++ b/addons/compat_rf/compat_rf_nouniformrestrictions/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT nouniformrestrictions +#define SUBCOMPONENT_BEAUTIFIED No Uniform Restrictions +#include "..\script_component.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp b/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp new file mode 100644 index 0000000000..9915ad1d44 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/Attachments.hpp @@ -0,0 +1,41 @@ +class optic_MRD; +class optic_MRD_khk_RF: optic_MRD { + displayName = SUBCSTRING(optic_mrd_khk_Name); +}; +class optic_MRD_tan_RF: optic_MRD { + displayName = SUBCSTRING(optic_mrd_tan_Name); +}; + +class optic_ACO_grn; +class optic_ACO_grn_desert_RF: optic_ACO_grn { + displayName = SUBCSTRING(optic_aco_grn_desert_Name); +}; +class optic_ACO_grn_wood_RF: optic_ACO_grn { + displayName = SUBCSTRING(optic_aco_grn_wood_Name); +}; + +class optic_Aco; +class optic_ACO_desert_RF: optic_Aco { + displayName = SUBCSTRING(optic_aco_desert_Name); +}; +class optic_ACO_wood_RF: optic_Aco { + displayName = SUBCSTRING(optic_aco_wood_Name); +}; + +class ItemCore; +class optic_rds_RF: ItemCore { + displayName = SUBCSTRING(optic_rds_Name); +}; + +class optic_VRCO_RF: ItemCore { + displayName = SUBCSTRING(optic_vrco_Name); +}; +class optic_VRCO_tan_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_tan_Name); +}; +class optic_VRCO_khk_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_khk_Name); +}; +class optic_VRCO_pistol_RF: optic_VRCO_RF { + displayName = SUBCSTRING(optic_vrco_pistol_Name); +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp new file mode 100644 index 0000000000..52231bcf07 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgMagazines.hpp @@ -0,0 +1,24 @@ +class CfgMagazines { + class CA_Magazine; + class 1Rnd_RC40_shell_RF: CA_Magazine { + displayName = SUBCSTRING(rc40_Name); + }; + class 1Rnd_RC40_HE_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_he_Name); + }; + class 1Rnd_RC40_SmokeWhite_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_white_Name); + }; + class 1Rnd_RC40_SmokeBlue_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_blue_Name); + }; + class 1Rnd_RC40_SmokeRed_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_red_Name); + }; + class 1Rnd_RC40_SmokeGreen_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_green_Name); + }; + class 1Rnd_RC40_SmokeOrange_shell_RF: 1Rnd_RC40_shell_RF { + displayName = SUBCSTRING(rc40_orange_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp new file mode 100644 index 0000000000..2983525ec8 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgVehicles.hpp @@ -0,0 +1,152 @@ +class CfgVehicles { + class Heli_light_03_dynamicLoadout_base_F; + class B_Heli_light_03_dynamicLoadout_RF: Heli_light_03_dynamicLoadout_base_F { + displayName = SUBCSTRING(heli_light_03_Name); + }; + + class Heli_light_03_unarmed_base_F; + class B_Heli_light_03_unarmed_RF: Heli_light_03_unarmed_base_F { + displayName = SUBCSTRING(heli_light_03_unarmed_Name); + }; + + class I_Heli_light_03_dynamicLoadout_RF; + class I_E_Heli_light_03_dynamicLoadout_RF: I_Heli_light_03_dynamicLoadout_RF { + displayName = SUBCSTRING(heli_light_03_Name); + }; + + class I_Heli_light_03_unarmed_RF; + class I_E_Heli_light_03_unarmed_RF: I_Heli_light_03_unarmed_RF { + displayName = SUBCSTRING(heli_light_03_unarmed_Name); + }; + + // H240 Transport, Gendarmerie/ION Transport + class Helicopter_Base_H; + class Heli_EC_01_base_RF: Helicopter_Base_H { + displayName = SUBCSTRING(ec_01_base_Name); + }; + // H240C Transport, CIV Transport + class Heli_EC_01_civ_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_01_civ_base_Name); + }; + // H235 Transport, CIV Transport Float-less (not used) + class Heli_EC_01A_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_01a_base_Name); + }; + // H235C Transport, CIV Transport Float-less + class Heli_EC_01A_civ_base_RF: Heli_EC_01A_base_RF { + displayName = SUBCSTRING(ec_01a_civ_base_Name); + }; + // RAI-350M Cougar (Unarmed), IND/UNA Transport Float-less + class Heli_EC_01A_military_base_RF: Heli_EC_01A_base_RF { + displayName = SUBCSTRING(ec_01a_military_base_Name); + }; + // RAI-360M Cougar, IND/OPF SOCAT Float-less + class Heli_EC_02_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_02_base_Name); + }; + // MH-360M Cougar, NATO SOCAT (not used) Float-less + class B_Heli_EC_02_RF: Heli_EC_02_base_RF { + displayName = SUBCSTRING(ec_02_nato_Name); + }; + // MH-245 Cougar, NATO Combat Type + class Heli_EC_03_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_03_base_Name); + }; + // H245 SAR, CIV SAR Type + class Heli_EC_04_base_RF: Heli_EC_01_base_RF { + displayName = SUBCSTRING(ec_04_base_Name); + }; + // MH-245 Cougar (Unarmed), NATO Transport Type (Maybe SAR?) + class Heli_EC_04_military_base_RF: Heli_EC_04_base_RF { + displayName = SUBCSTRING(ec_04_military_base_Name); + }; + + // HEMTT + class B_Truck_01_fuel_F; + class C_Truck_01_water_rf: B_Truck_01_fuel_F { + displayName = SUBCSTRING(truck_01_water_Name); + }; + + // Typhoon + class O_Truck_03_fuel_F; + class C_Truck_03_water_rf: O_Truck_03_fuel_F { + displayName = SUBCSTRING(truck_03_water_Name); + }; + + // RAM 1500 (Pickup) + class Offroad_01_unarmed_base_F; + class Pickup_01_base_rf: Offroad_01_unarmed_base_F { + displayName = SUBCSTRING(pickup_01_Name); + }; + class Pickup_fuel_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_fuel_Name); + }; + class Pickup_service_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_service_Name); + }; + class Pickup_repair_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_repair_Name); + }; + class Pickup_comms_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_comms_Name); + }; + class Pickup_repair_ig_base_rf: Pickup_repair_base_rf { + displayName = SUBCSTRING(pickup_01_repair_Name); + }; + class Pickup_01_hmg_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_hmg_Name); + }; + class Pickup_01_mmg_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_mmg_Name); + }; + class Pickup_01_mrl_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_mrl_Name); + }; + class Pickup_01_aat_base_rf: Pickup_01_base_rf { + displayName = SUBCSTRING(pickup_01_aa_Name); + }; + class Pickup_covered_base_rf: Pickup_service_base_rf { + displayName = SUBCSTRING(pickup_01_covered_Name); + }; + + class C_IDAP_Pickup_rf; + class C_IDAP_Pickup_water_rf: C_IDAP_Pickup_rf { + displayName = SUBCSTRING(pickup_01_water_Name); + }; + + class StaticMortar; + class CommandoMortar_base_RF: StaticMortar { + displayName = SUBCSTRING(commando_Name); + }; + + class StaticMGWeapon; + class TwinMortar_base_RF: StaticMGWeapon { + displayName = SUBCSTRING(twinmortar_Name); + }; + + class Helicopter_Base_F; + class UAV_RC40_Base_RF: Helicopter_Base_F { + displayName = SUBCSTRING(rc40_base_Name); + }; + class UAV_RC40_Base_Sensor_RF: UAV_RC40_Base_RF { + displayName = SUBCSTRING(rc40_Name); + }; + class UAV_RC40_Base_HE_RF: UAV_RC40_Base_RF { + displayName = SUBCSTRING(rc40_he_Name); + }; + class UAV_RC40_Base_SmokeWhite_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_white_Name); + }; + class UAV_RC40_Base_SmokeBlue_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_blue_Name); + }; + class UAV_RC40_Base_SmokeRed_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_red_Name); + }; + class UAV_RC40_Base_SmokeGreen_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_green_Name); + }; + class UAV_RC40_Base_SmokeOrange_RF: UAV_RC40_Base_HE_RF { + displayName = SUBCSTRING(rc40_orange_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp b/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp new file mode 100644 index 0000000000..c2d9003f11 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/CfgWeapons.hpp @@ -0,0 +1,111 @@ +class CfgWeapons { + #include "Attachments.hpp" + + class Pistol_Base_F; + class hgun_Glock19_RF: Pistol_Base_F { + displayName = SUBCSTRING(glock19_Name); + }; + class hgun_Glock19_khk_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_khk_Name); + }; + class hgun_Glock19_Tan_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_tan_Name); + }; + class hgun_Glock19_auto_RF: hgun_Glock19_RF { + displayName = SUBCSTRING(glock19_auto_Name); + }; + class hgun_Glock19_auto_khk_RF: hgun_Glock19_auto_RF { + displayName = SUBCSTRING(glock19_auto_khk_Name); + }; + class hgun_Glock19_auto_Tan_RF: hgun_Glock19_auto_RF { + displayName = SUBCSTRING(glock19_auto_tan_Name); + }; + + class hgun_DEagle_RF: Pistol_Base_F { + displayName = SUBCSTRING(deagle_Name); + }; + class hgun_DEagle_classic_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_classic_Name); + }; + class hgun_DEagle_bronze_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_bronze_Name); + }; + class hgun_DEagle_copper_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_copper_Name); + }; + class hgun_DEagle_gold_RF: hgun_DEagle_RF { + displayName = SUBCSTRING(deagle_gold_Name); + }; + + class srifle_h6_base_rf; + class srifle_h6_tan_rf: srifle_h6_base_rf { + displayName = SUBCSTRING(h6_tan_Name); + }; + class srifle_h6_oli_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_oli_Name); + }; + class srifle_h6_blk_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_blk_Name); + }; + class srifle_h6_digi_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_digi_Name); + }; + class srifle_h6_gold_rf: srifle_h6_tan_rf { + displayName = SUBCSTRING(h6_gold_Name); + }; + + class srifle_DMR_01_F; + class srifle_DMR_01_black_RF: srifle_DMR_01_F { + displayName = SUBCSTRING(dmr_01_black_Name); + }; + class srifle_DMR_01_tan_RF: srifle_DMR_01_black_RF { + displayName = SUBCSTRING(dmr_01_tan_Name); + }; + + class SMG_01_F; + class SMG_01_black_RF: SMG_01_F { + displayName = SUBCSTRING(smg_01_black_Name); + }; + + class arifle_ash12_base_RF; + class arifle_ash12_blk_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_blk_Name); + }; + class arifle_ash12_desert_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_desert_Name); + }; + class arifle_ash12_urban_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_urban_Name); + }; + class arifle_ash12_wood_RF: arifle_ash12_base_RF { + displayName = SUBCSTRING(ash12_wood_Name); + }; + + class arifle_ash12_GL_base_RF; + class arifle_ash12_GL_blk_RF: arifle_ash12_GL_base_RF { + displayName = SUBCSTRING(ash12_gl_blk_Name); + }; + class arifle_ash12_GL_desert_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_desert_Name); + }; + class arifle_ash12_GL_urban_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_urban_Name); + }; + class arifle_ash12_GL_wood_RF: arifle_ash12_GL_blk_RF { + displayName = SUBCSTRING(ash12_gl_wood_Name); + }; + + class arifle_ash12_LR_base_RF; + class arifle_ash12_LR_blk_RF: arifle_ash12_LR_base_RF { + displayName = SUBCSTRING(ash12_lr_blk_Name); + }; + class arifle_ash12_LR_desert_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_desert_Name); + }; + class arifle_ash12_LR_urban_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_urban_Name); + }; + class arifle_ash12_LR_wood_RF: arifle_ash12_LR_blk_RF { + displayName = SUBCSTRING(ash12_lr_wood_Name); + }; +}; diff --git a/addons/compat_rf/compat_rf_realisticnames/config.cpp b/addons/compat_rf/compat_rf_realisticnames/config.cpp new file mode 100644 index 0000000000..47003c4a42 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/config.cpp @@ -0,0 +1,23 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "RF_Data_Loadorder", + "ace_realisticnames" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike", "Marc"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgMagazines.hpp" +#include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/script_component.hpp b/addons/compat_rf/compat_rf_realisticnames/script_component.hpp new file mode 100644 index 0000000000..b8d0682fa4 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT realisticnames +#define SUBCOMPONENT_BEAUTIFIED Realistic Names +#include "..\script_component.hpp" diff --git a/addons/compat_rf/compat_rf_realisticnames/stringtable.xml b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml new file mode 100644 index 0000000000..03d5003a62 --- /dev/null +++ b/addons/compat_rf/compat_rf_realisticnames/stringtable.xml @@ -0,0 +1,550 @@ + + + + + EOTech MRDS (Khaki) + EOTech MRDS (カーキ) + 이오텍 MRDS (카키) + EOTech MRDS (Khaki) + EOTech MRDS (Cachi) + + + EOTech MRDS (Tan) + EOTech MRDS (タン) + 이오텍 MRDS (황갈) + EOTech MRDS (Hellbraun) + EOTech MRDS (Marroncino) + + + C-More Railway (Green, Desert) + C-More レイルウェイ (グリーン、砂漠迷彩) + 씨모어 레일웨이 (녹색, 사막) + C-More Railway (Grün, Wüste) + C-More Railway (Verde, Deserto) + + + C-More Railway (Green, Woodland) + C-More レイルウェイ (グリーン、森林迷彩) + 씨모어 레일웨이 (녹색, 수풀 위장) + C-More Railway (Grün, Grünes Tarnmuster) + C-More Railway (Verde, Boschivo) + + + C-More Railway (Red, Desert) + C-More レイルウェイ (グリーン、砂漠迷彩) + 씨모어 레일웨이 (빨강, 사막) + C-More Railway (Rot, Wüste) + C-More Railway (Rosso, Desert) + + + C-More Railway (Red, Woodland) + C-More レイルウェイ (グリーン、森林迷彩) + 씨모어 레일웨이 (빨강, 수풀) + C-More Railway (Rot, Grünes Tarnmuster) + C-More Railway (Rosso, Boschivo) + + + Aimpoint Micro R-1 + Aimpoint マイクロ R-1 + 에임포인트 마이크로 R-1 + Aimpoint Micro R-1 + Aimpoint Micro R-1 + + + Vortex Spitfire Prism + Vortex スピットファイア プリズム + 버텍스 스핏파이어 프리즘 + Vortex Spitfire Prism + Vortex Spitfire Prism + + + Vortex Spitfire Prism (Tan) + Vortex スピットファイア プリズム (タン) + 버텍스 스핏파이어 프리즘 (황갈) + Vortex Spitfire Prism (Hellbraun) + Vortex Spitfire Prism (Marroncino) + + + Vortex Spitfire Prism (Khaki) + Vortex スピットファイア プリズム (カーキ) + 버텍스 스핏파이어 프리즘 (카키) + Vortex Spitfire Prism (Khaki) + Vortex Spitfire Prism (Cachi) + + + Vortex Spitfire Prism (Pistol) + Vortex スピットファイア プリズム (ピストル用) + 버텍스 스핏파이어 프리즘 (권총용) + Vortex Spitfire Prism (Pistole) + Vortex Spitfire Prism (Pistola) + + + Glock 19X + グロック 19X + 글록 19X + Glock 19X + Glock 19X + + + Glock 19X (Khaki) + グロック 19X (カーキ) + 글록 19X (카키) + Glock 19X (Khaki) + Glock 19X (Cachi) + + + Glock 19X (Tan) + グロック 19X (タン) + 글록 19X (황갈) + Glock 19X (Hellbraun) + Glock 19X (Marroncino) + + + Glock 19X Auto + グロック 19X オート + 글록 19X 기관권총 + Glock 19X Auto + Glock 19X Auto + + + Glock 19X Auto (Khaki) + グロック 19X オート (カーキ) + 글록 19X 기관권총 (카키) + Glock 19X Auto (Khaki) + Glock 19X Auto (Cachi) + + + Glock 19X Auto (Tan) + グロック 19X オート (タン) + 글록 19X 기관권총 (황갈) + Glock 19X Auto (Hellbraun) + Glock 19X Auto (Marroncino) + + + Desert Eagle Mark XIX L5 + デザートイーグル Mark XIX L5 + 데저트 이글 마크 XIX L5 + Desert Eagle Mark XIX L5 + Desert Eagle Mark XIX L5 + + + Desert Eagle Mark XIX L5 (Classic) + デザートイーグル Mark XIX L5 (クラシック) + 데저트 이글 마크 XIX L5 (클래식) + Desert Eagle Mark XIX L5 (Klassisch) + Desert Eagle Mark XIX L5 (Classico) + + + Desert Eagle Mark XIX L5 (Bronze) + デザートイーグル Mark XIX L5 (ブロンズ) + 데저트 이글 마크 XIX L5 (브론즈) + Desert Eagle Mark XIX L5 (Bronze) + Desert Eagle Mark XIX L5 (Bronzo) + + + Desert Eagle Mark XIX L5 (Copper) + デザートイーグル Mark XIX L5 (カッパー) + 데저트 이글 마크 XIX L5 (구리) + Desert Eagle Mark XIX L5 (Kupfer) + Desert Eagle Mark XIX L5 (Rame) + + + Desert Eagle Mark XIX L5 (Gold) + デザートイーグル Mark XIX L5 (ゴールド) + 데저트 이글 마크 XIX L5 (금색) + Desert Eagle Mark XIX L5 (Gold) + Desert Eagle Mark XIX L5 (Oro) + + + HERA H6 (Tan) + HERA H6 (タン) + 헤라 H6 (황갈) + HERA H6 (Hellbraun) + HERA H6 (Marroncino) + + + HERA H6 (Olive) + HERA H6 (オリーブ) + 헤라 H6 (올리브) + HERA H6 (Olivgrün) + HERA H6 (Oliva) + + + HERA H6 (Black) + HERA H6 (ブラック) + 헤라 H6 (검정) + HERA H6 (Schwarz) + HERA H6 (Nero) + + + HERA H6 (Digital) + HERA H6 (AAF迷彩) + 헤라 H6 (AAF 디지털) + HERA H6 (Digital) + HERA H6 (Digitale) + + + HERA H6 (Gold) + HERA H6 (ゴールド) + 헤라 H6 (금색) + HERA H6 (Gold) + HERA H6 (Oro) + + + VS-121 (Black) + VS-121 (ブラック) + VS-121 (검정) + VS-121 (Schwarz) + VS-121 (Nero) + + + VS-121 (Tan) + VS-121 (タン) + VS-121 (황갈) + VS-121 (Hellbraun) + VS-121 (Marroncino) + + + Vector SMG (Black) + ベクター SMG (ブラック) + 벡터 SMG (검정) + Vector SMG (Schwarz) + Vector SMG (Nero) + + + ASh-12 (Black) + ASh-12 (ブラック) + ASh-12 (검정) + ASh-12 (Schwarz) + ASh-12 (Nero) + + + ASh-12 (Desert) + ASh-12 (砂漠迷彩) + ASh-12 (사막) + ASh-12 (Wüste) + ASh-12 (Deserto) + + + ASh-12 (Urban) + ASh-12 (市街地迷彩) + ASh-12 (도심) + ASh-12 (Urban) + ASh-12 (Urbano) + + + ASh-12 (Woodland) + ASh-12 (森林迷彩) + ASh-12 (수풀) + ASh-12 (Grünes Tarnmuster) + ASh-12 (Boschivo) + + + ASh-12 GL (Black) + ASh-12 GL (ブラック) + ASh-12 GL (검정) + ASh-12 GL (Schwarz) + ASh-12 GL (Nero) + + + ASh-12 GL (Desert) + ASh-12 GL (砂漠迷彩) + ASh-12 GL (사막) + ASh-12 GL (Wüste) + ASh-12 GL (Deserto) + + + ASh-12 GL (Urban) + ASh-12 GL (市街地迷彩) + ASh-12 GL (도심) + ASh-12 GL (Urban) + ASh-12 GL (Urbano) + + + ASh-12 GL (Woodland) + ASh-12 GL (森林迷彩) + ASh-12 GL (수풀) + ASh-12 GL (Grünes Tarnmuster) + ASh-12 GL (Boschivo) + + + ASh-12 LR (Black) + ASh-12 LR (ブラック) + ASh-12 LR (검정) + ASh-12 LR (Schwarz) + ASh-12 LR (Nero) + + + ASh-12 LR (Desert) + ASh-12 LR (砂漠迷彩) + ASh-12 LR (사막) + ASh-12 LR (Wüste) + ASh-12 LR (Deserto) + + + ASh-12 LR (Urban) + ASh-12 LR (市街地迷彩) + ASh-12 LR (도심) + ASh-12 LR (Urban) + ASh-12 LR (Urbano) + + + ASh-12 LR (Woodland) + ASh-12 LR (森林迷彩) + ASh-12 LR (수풀) + ASh-12 LR (Grünes Tarnmuster) + ASh-12 LR (Boschivo) + + + AW159 Wildcat ASW + AW159 ワイルドキャット ASW + AW159 와일드캣 ASW + AW159 Wildcat ASW + AW159 Wildcat ASW + + + AW159 Wildcat ASW (Unarmed) + AW159 ワイルドキャット ASW (非武装) + AW159 와일드캣 ASW (비무장) + AW159 Wildcat ASW (Unbewaffnet) + AW159 Wildcat ASW (Disarmato) + + + H225 Super Puma (Transport) + H225 シュペル ピューマ (輸送型) + H225 슈퍼 퓨마 (비무장) + H225 Super Puma (Transport) + H225 Super Puma (Trasporto) + + + H225 Super Puma (Civilian) + H225 シュペル ピューマ (民生型) + H225 슈퍼 퓨마 (비무장) + H225 Super Puma (Zivil) + H225 Super Puma (Civile) + + + H215 Super Puma (Transport) + H215 シュペル ピューマ (輸送型) + H215 슈퍼 퓨마 (비무장) + H215 Super Puma (Transport) + H215 Super Puma (Trasporto) + + + H215 Super Puma (Civilian) + H215 シュペル ピューマ (民生型) + H215 슈퍼 퓨마 (비무장) + H215 Super Puma (Zivil) + H215 Super Puma (Civile) + + + H215 Super Puma (Unarmed) + H215 シュペル ピューマ (非武装) + H215 슈퍼 퓨마 (비무장) + H215 Super Puma (Unbewaffnet) + H215 Super Puma (Disarmato) + + + H225M Super Cougar SOCAT + H225M シュペル クーガー SOCAT + H225M 슈퍼 쿠거 SOCAT + H225M Super Cougar SOCAT + H225M Super Cougar SOCAT + + + H225M Super Cougar SOCAT + H225M シュペル クーガー SOCAT + H225M 슈퍼 쿠거 SOCAT + H225M Super Cougar SOCAT + H225M Super Cougar SOCAT + + + H225M Super Cougar + H225M シュペル クーガー + H225M 슈퍼 쿠거 + H225M Super Cougar + H225M Super Cougar + + + H225 Super Puma SAR + H225 シュペル ピューマ 捜索救難型 + H225 슈퍼 퓨마 SAR + H225 Super Puma SAR + H225 Super Puma SAR + + + H225M Super Cougar (Unarmed) + H225M シュペル クーガー (非武装) + H225M Super Cougar (Unbewaffnet) + H225M Super Cougar (Disarmato) + H225M 슈퍼 쿠거 (비무장) + + + HEMTT Fire Truck + HEMTT anti-incendie + HEMTT (wersja pożarnicza) + HEMTT-Löschfahrzeug + HEMTT (camión de bomberos) + Пожарная машина HEMTT + HEMTT 消防卡车 + HEMTT contra incêndio + HEMTT 消防車 + HEMTT Autobotte + HEMTT 소방트럭 + + + Typhoon Water + タイフーン 給水 + 타이푼 급수 + Typhoon Water + Typhoon Acqua + + + Ram 1500 + ラム 1500 + 램 1500 + Ram 1500 + Ram 1500 + + + Ram 1500 (Fuel) + ラム 1500 (燃料) + 램 1500 (연료) + Ram 1500 (Treibstoff) + Ram 1500 (Carburante) + + + Ram 1500 (Services) + ラム 1500 (サービス) + 램 1500 (서비스) + Ram 1500 (Pannenhilfe) + Ram 1500 (Servizi) + + + Ram 1500 (Repair) + ラム 1500 (修理) + 램 1500 (정비) + Ram 1500 (Instandsetzung) + Ram 1500 (Riparazioni) + + + Ram 1500 (Comms) + ラム 1500 (通信) + 램 1500 (통신) + Ram 1500 (Kommunikation) + Ram 1500 (Comunicazioni) + + + Ram 1500 (HMG) + ラム 1500 (HMG) + 램 1500 (중기관총) + Ram 1500 (HMG) + Ram 1500 (HMG) + + + Ram 1500 (MMG) + ラム 1500 (MMG) + 램 1500 (중형기관총) + Ram 1500 (MMG) + Ram 1500 (MMG) + + + Ram 1500 (MRL) + ラム 1500 (MRL) + 램 1500 (다연장로켓) + Ram 1500 (MRL) + Ram 1500 (MRL) + + + Ram 1500 (AA) + ラム 1500 (対空) + 램 1500 (대공) + Ram 1500 (AA) + Ram 1500 (AA) + + + Ram 1500 (Covered) + ラム 1500 (カバー) + 램 1500 (커버) + Ram 1500 (Abgedeckt) + Ram 1500 (Coperto) + + + Ram 1500 (Water) + ラム 1500 (給水) + 램 1500 (급수) + Ram 1500 (Wasser) + Ram 1500 (Acqua) + + + RSG60 + RSG60 + RSG60 + RSG60 + RSG60 + + + AMOS Container + AMOS コンテナ + AMOS 컨테이너 + AMOS Container + AMOS Container + + + Drone40 + ドローン40 + 드론40 + Drone40 + Drone40 + + + Drone40 Scout + ドローン40 偵察型 + 드론40 정찰 + Drone40 Scout + Drone40 Scout + + + Drone40 HE + ドローン40 榴弾 + 드론40 고폭 + Drone40 HE + Drone40 HE + + + Drone40 Smoke (White) + ドローン40 発煙弾 (白) + 드론40 연막 (백색) + Drone40 Smoke (Weiß) + Drone40 Smoke (Bianco) + + + Drone40 Smoke (Blue) + ドローン40 発煙弾 (青) + 드론40 연막 (청색) + Drone40 Smoke (Blau) + Drone40 Smoke (Blu) + + + Drone40 Smoke (Red) + ドローン40 発煙弾 (赤) + 드론40 연막 (적색) + Drone40 Smoke (Rot) + Drone40 Smoke (Rosso) + + + Drone40 Smoke (Green) + ドローン40 発煙弾 (緑) + 드론40 연막 (녹색) + Drone40 Smoke (Grün) + Drone40 Smoke (Verde) + + + Drone40 Smoke (Orange) + ドローン40 発煙弾 (橙) + 드론40 연막 (주황색) + Drone40 Smoke (Orange) + Drone40 Smoke (Arancione) + + + diff --git a/addons/compat_rf/config.cpp b/addons/compat_rf/config.cpp new file mode 100644 index 0000000000..ab6fb94275 --- /dev/null +++ b/addons/compat_rf/config.cpp @@ -0,0 +1,18 @@ +#include "script_component.hpp" + +class CfgPatches { + class ADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"RF_Data_Loadorder"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {"Mike"}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rf/script_component.hpp b/addons/compat_rf/script_component.hpp new file mode 100644 index 0000000000..2cc45da490 --- /dev/null +++ b/addons/compat_rf/script_component.hpp @@ -0,0 +1,6 @@ +#define COMPONENT compat_rf +#define COMPONENT_BEAUTIFIED Reaction Forces Compatibility + +#include "\z\ace\addons\main\script_mod.hpp" + +#include "\z\ace\addons\main\script_macros.hpp" diff --git a/addons/compat_rhs_afrf3/CfgAmmo.hpp b/addons/compat_rhs_afrf3/CfgAmmo.hpp index 54ff3bd2c2..11aee03d79 100644 --- a/addons/compat_rhs_afrf3/CfgAmmo.hpp +++ b/addons/compat_rhs_afrf3/CfgAmmo.hpp @@ -219,6 +219,10 @@ class CfgAmmo { EGVAR(frag,force) = 0; }; + class SmokeShell; + class rhs_ammo_rdg2_white: SmokeShell { + EGVAR(grenades,rollVectorDirAndUp)[] = {{0, 1, 0}, {0, 0, 1}}; + }; class Sh_125mm_APFSDS; class Sh_125mm_HE; diff --git a/addons/compat_rhs_afrf3/CfgVehicles.hpp b/addons/compat_rhs_afrf3/CfgVehicles.hpp index 622d764ad2..1cf5029bc3 100644 --- a/addons/compat_rhs_afrf3/CfgVehicles.hpp +++ b/addons/compat_rhs_afrf3/CfgVehicles.hpp @@ -434,7 +434,11 @@ class CfgVehicles { "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", - "era_31_hitpoint", "era_32_hitpoint" + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint", + "era_37_hitpoint", "era_38_hitpoint", "era_39_hitpoint", "era_40_hitpoint", "era_41_hitpoint", "era_42_hitpoint", + "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", + "era_49_hitpoint", "era_50_hitpoint", "era_58_hitpoint", "era_59_hitpoint", "era_60_hitpoint", "era_61_hitpoint", + "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", "era_66_hitpoint", "era_67_hitpoint" }; EGVAR(vehicle_damage,slatHitpoints)[] = { "SLAT_51_hitpoint", "SLAT_52_hitpoint", "SLAT_53_hitpoint", @@ -470,6 +474,9 @@ class CfgVehicles { "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", "era_49_hitpoint", "era_50_hitpoint" }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "slat_51_hitpoint", "slat_52_hitpoint", "slat_53_hitpoint", "slat_54_hitpoint" + }; }; class rhs_t90am_tv: rhs_t90_tv { EGVAR(vehicle_damage,eraHitpoints)[] = { @@ -483,7 +490,7 @@ class CfgVehicles { "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", "era_47_hitpoint", "era_48_hitpoint", "era_49_hitpoint", "era_50_hitpoint", "era_51_hitpoint", "era_52_hitpoint", "era_53_hitpoint", "era_54_hitpoint", "era_55_hitpoint", "era_56_hitpoint", "era_57_hitpoint", "era_58_hitpoint", "era_59_hitpoint", "era_60_hitpoint", - "era_51_hitpoint", "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", "era_66_hitpoint" + "era_61_hitpoint", "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", "era_66_hitpoint" }; EGVAR(vehicle_damage,slatHitpoints)[] = { "SLAT_18_hitpoint", "SLAT_19_hitpoint", "SLAT_20_hitpoint", "SLAT_21_hitpoint", @@ -492,10 +499,31 @@ class CfgVehicles { }; }; class rhs_t90sm_tv: rhs_t90am_tv { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", + "era_5_hitpoint", "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", + "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", + "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_24_hitpoint", "era_25_hitpoint", + "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", + "era_35_hitpoint", "era_36_hitpoint", "era_37_hitpoint", "era_38_hitpoint", + "era_39_hitpoint", "era_40_hitpoint", "era_41_hitpoint", "era_42_hitpoint", + "era_43_hitpoint", "era_44_hitpoint", "era_45_hitpoint", "era_46_hitpoint", + "era_47_hitpoint", "era_48_hitpoint", "era_49_hitpoint", "era_50_hitpoint", + "era_26_hitpoint", "era_55_hitpoint", "era_56_hitpoint", "era_57_hitpoint", + "era_58_hitpoint", "era_59_hitpoint", "era_60_hitpoint", "era_61_hitpoint", + "era_62_hitpoint", "era_63_hitpoint", "era_64_hitpoint", "era_65_hitpoint", + "era_66_hitpoint", "era_23_hitpoint" + }; EGVAR(vehicle_damage,slatHitpoints)[] = { - "SLAT_23_hitpoint", "SLAT_26_hitpoint", "SLAT_51_hitpoint", "SLAT_52_hitpoint", - "SLAT_53_hitpoint", "SLAT_54_hitpoint", "SLAT_55_hitpoint", "SLAT_56_hitpoint", - "SLAT_57_hitpoint" + "slat_23_hitpoint", "slat_26_hitpoint", "slat_51_hitpoint", + "slat_52_hitpoint", "slat_53_hitpoint", "slat_54_hitpoint", + "slat_55_hitpoint", "slat_56_hitpoint", "slat_57_hitpoint", + "slat_18_hitpoint", "slat_19_hitpoint", "slat_20_hitpoint", + "slat_21_hitpoint", "slat_22_hitpoint", "slat_24_hitpoint", + "slat_25_hitpoint" }; }; @@ -539,6 +567,35 @@ class CfgVehicles { "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint" }; }; + class rhs_t80um: rhs_t80u { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", "era_5_hitpoint", "era_6_hitpoint", + "era_7_hitpoint", "era_8_hitpoint", "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", "era_17_hitpoint", "era_18_hitpoint", + "era_19_hitpoint", "era_20_hitpoint", "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", "era_29_hitpoint", "era_30_hitpoint", + "era_31_hitpoint", "era_32_hitpoint", "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint" + }; + }; + + class rhs_t15_base; + class rhs_t15_tv: rhs_t15_base { + EGVAR(vehicle_damage,eraHitpoints)[] = { + "era_1_hitpoint", "era_2_hitpoint", "era_3_hitpoint", "era_4_hitpoint", + "era_5_hitpoint", "era_6_hitpoint", "era_7_hitpoint", "era_8_hitpoint", + "era_9_hitpoint", "era_10_hitpoint", "era_11_hitpoint", "era_12_hitpoint", + "era_13_hitpoint", "era_14_hitpoint", "era_15_hitpoint", "era_16_hitpoint", + "era_17_hitpoint", "era_18_hitpoint", "era_19_hitpoint", "era_20_hitpoint", + "era_21_hitpoint", "era_22_hitpoint", "era_23_hitpoint", "era_24_hitpoint", + "era_25_hitpoint", "era_26_hitpoint", "era_27_hitpoint", "era_28_hitpoint", + "era_29_hitpoint", "era_30_hitpoint", "era_31_hitpoint", "era_32_hitpoint", + "era_33_hitpoint", "era_34_hitpoint", "era_35_hitpoint", "era_36_hitpoint", + "era_37_hitpoint" + }; + EGVAR(vehicle_damage,slatHitpoints)[] = { + "slat_38_hitpoint", "slat_39_hitpoint", "slat_40_hitpoint", "slat_41_hitpoint" + }; + }; // Wirecutter Backpacks class rhs_assault_umbts; diff --git a/addons/compat_rhs_afrf3/CfgWeapons.hpp b/addons/compat_rhs_afrf3/CfgWeapons.hpp index a6def44c40..a25d1f7cd0 100644 --- a/addons/compat_rhs_afrf3/CfgWeapons.hpp +++ b/addons/compat_rhs_afrf3/CfgWeapons.hpp @@ -108,19 +108,7 @@ class CfgWeapons { EGVAR(overpressure,offset) = 1.65; }; - class H_HelmetB; - class rhs_tsh4: H_HelmetB { - HEARING_PROTECTION_VICCREW; - }; - - class rhs_6b47_bare; - class rhs_6b48: rhs_6b47_bare { - HEARING_PROTECTION_VICCREW; - }; - - class rhs_zsh7a: H_HelmetB { - HEARING_PROTECTION_VICCREW; - }; + class rhs_zsh7a; class rhs_zsh7a_alt: rhs_zsh7a { ACE_Protection = 1; }; @@ -133,22 +121,6 @@ class CfgWeapons { ACE_Protection = 1; }; - class rhs_gssh18: H_HelmetB { - HEARING_PROTECTION_EARMUFF; - }; - - class rhs_6b47; - class rhs_6b47_6m2: rhs_6b47 { - HEARING_PROTECTION_PELTOR; - }; - class rhs_6b47_6m2_1: rhs_6b47 { - HEARING_PROTECTION_PELTOR; - }; - - class rhs_6m2: H_HelmetB { - HEARING_PROTECTION_PELTOR; - }; - class rhs_weap_d81; class rhs_weap_2a70: rhs_weap_d81 { // "Low pressure" 100mm cannon EGVAR(overpressure,range) = 15; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/CfgWeapons.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/CfgWeapons.hpp index 994af4f667..4fda436d18 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/CfgWeapons.hpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/CfgWeapons.hpp @@ -1,7 +1,14 @@ class CfgWeapons { // Last update: RHSAFRF 0.5.6 - class rhs_acc_perst3; - class rhs_acc_perst3_2dp: rhs_acc_perst3 { - baseWeapon = "rhs_acc_perst3_2dp"; + class rhs_acc_perst3_2dp_light; + class rhs_acc_perst3_2dp_light_h: rhs_acc_perst3_2dp_light { + baseWeapon = "rhs_acc_perst3_2dp_h"; + }; + + class acc_pointer_IR; + class rhs_acc_perst1ik: acc_pointer_IR { + MRT_SwitchItemHintText = ""; // prevent false info for illuminator stat + MRT_SwitchItemNextClass = ""; + MRT_SwitchItemPrevClass = ""; }; }; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/config.cpp index bb2e1bf3a2..b544accac3 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/config.cpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_arsenal/config.cpp @@ -15,4 +15,4 @@ class CfgPatches { }; }; -//#include "CfgWeapons.hpp" +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp index fd889cd096..6a3bb0a083 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_csw/CfgVehicles.hpp @@ -5,7 +5,6 @@ class CfgVehicles { class StaticGrenadeLauncher; class rhs_SPG9_base: AT_01_base_F { - // ENABLE_CSW_ATTRIBUTE; class ACE_CSW { enabled = 1; proxyWeapon = QGVAR(rhs_weap_SPG9); @@ -26,7 +25,6 @@ class CfgVehicles { }; class rhs_Kornet_Base: AT_01_base_F { - // ENABLE_CSW_ATTRIBUTE; class ACE_CSW { enabled = 1; proxyWeapon = QGVAR(rhs_weap_9K133_launcher); @@ -40,7 +38,6 @@ class CfgVehicles { }; class rhs_Metis_Base: AT_01_base_F { - // ENABLE_CSW_ATTRIBUTE; class ACE_CSW { enabled = 1; proxyWeapon = QGVAR(rhs_weap_9K115_2_launcher); @@ -54,7 +51,6 @@ class CfgVehicles { }; class rhs_2b14_82mm_Base: StaticMortar { - // ENABLE_CSW_ATTRIBUTE; class ACE_CSW { enabled = 1; magazineLocation = ""; @@ -99,7 +95,6 @@ class CfgVehicles { }; class RHS_AGS30_TriPod_base: StaticGrenadeLauncher { - // ENABLE_CSW_ATTRIBUTE; class ACE_CSW { enabled = 1; proxyWeapon = QGVAR(rhs_weap_AGS30); diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/CfgWeapons.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/CfgWeapons.hpp new file mode 100644 index 0000000000..04edf4d754 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/CfgWeapons.hpp @@ -0,0 +1,28 @@ +class CfgWeapons { + class H_HelmetB; + class rhs_tsh4: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; + class rhs_zsh7a: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; + class rhs_gssh18: H_HelmetB { + HEARING_PROTECTION_EARMUFF; + }; + class rhs_6m2: H_HelmetB { + HEARING_PROTECTION_PELTOR; + }; + + class rhs_6b47; + class rhs_6b47_6m2: rhs_6b47 { + HEARING_PROTECTION_PELTOR; + }; + class rhs_6b47_6m2_1: rhs_6b47 { + HEARING_PROTECTION_PELTOR; + }; + + class rhs_6b47_bare; + class rhs_6b48: rhs_6b47_bare { + HEARING_PROTECTION_VICCREW; + }; +}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/config.cpp new file mode 100644 index 0000000000..4a8056bf0c --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + +class CfgPatches { + class SUBADDON { + addonRootClass = QUOTE(COMPONENT); + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhs_main_loadorder", + "ace_hearing" + }; + skipWhenMissingDependencies = 1; + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/script_component.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/script_component.hpp new file mode 100644 index 0000000000..8edb825af3 --- /dev/null +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_hearing/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT hearing +#define SUBCOMPONENT_BEAUTIFIED Hearing +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp deleted file mode 100644 index 047e264c6e..0000000000 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/CfgVehicles.hpp +++ /dev/null @@ -1,10 +0,0 @@ -class CfgVehicles { - class RHS_Ural_Support_MSV_Base_01; - class RHS_Ural_Fuel_MSV_01: RHS_Ural_Support_MSV_Base_01 { - transportFuel = 0; - }; - class rhs_kraz255b1_base; - class rhs_kraz255b1_fuel_base: rhs_kraz255b1_base { - transportFuel = 0; - }; -}; diff --git a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp index 5101a383a3..8e1986b65f 100644 --- a/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp +++ b/addons/compat_rhs_afrf3/compat_rhs_afrf3_refuel/config.cpp @@ -18,4 +18,4 @@ class CfgPatches { }; }; -#include "CfgVehicles.hpp" +// ADDON kept for backward compatiblity diff --git a/addons/compat_rhs_afrf3/config.cpp b/addons/compat_rhs_afrf3/config.cpp index 44fcd30fcb..8bf5668485 100644 --- a/addons/compat_rhs_afrf3/config.cpp +++ b/addons/compat_rhs_afrf3/config.cpp @@ -1,5 +1,4 @@ #include "script_component.hpp" -#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" class CfgPatches { class ADDON { @@ -7,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhs_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhs_main_loadorder"}; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "commy2", "Skengman2"}; url = ECSTRING(main,URL); diff --git a/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp index 220aec4c24..7e58387dab 100644 --- a/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp +++ b/addons/compat_rhs_gref3/compat_rhs_gref3_csw/CfgVehicles.hpp @@ -1,7 +1,6 @@ class CfgVehicles { class StaticMGWeapon; class rhs_DSHKM_base: StaticMGWeapon { - // ENABLE_CSW_ATTRIBUTE; class ACE_CSW { enabled = 1; proxyWeapon = QGVAR(rhs_weap_DSHKM); diff --git a/addons/compat_rhs_gref3/config.cpp b/addons/compat_rhs_gref3/config.cpp index f2e7aeacde..84717435be 100644 --- a/addons/compat_rhs_gref3/config.cpp +++ b/addons/compat_rhs_gref3/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhsgref_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhsgref_main_loadorder"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {"PabstMirror", "Ruthberg", "Anton"}; diff --git a/addons/compat_rhs_saf3/config.cpp b/addons/compat_rhs_saf3/config.cpp index 75ee4f5530..71340640ce 100644 --- a/addons/compat_rhs_saf3/config.cpp +++ b/addons/compat_rhs_saf3/config.cpp @@ -6,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhssaf_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhssaf_main_loadorder"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {}; diff --git a/addons/compat_rhs_usf3/CfgMagazineWells.hpp b/addons/compat_rhs_usf3/CfgMagazineWells.hpp deleted file mode 100644 index 01223ec141..0000000000 --- a/addons/compat_rhs_usf3/CfgMagazineWells.hpp +++ /dev/null @@ -1,11 +0,0 @@ -class CfgMagazineWells { - class ace_hellfire_K { - ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_k)}; - }; - class ace_hellfire_N { - ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_n)}; - }; - class ace_hellfire_L { - ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_l)}; - }; -}; diff --git a/addons/compat_rhs_usf3/CfgMagazines.hpp b/addons/compat_rhs_usf3/CfgMagazines.hpp index f11dad081c..471b345dcd 100644 --- a/addons/compat_rhs_usf3/CfgMagazines.hpp +++ b/addons/compat_rhs_usf3/CfgMagazines.hpp @@ -38,21 +38,4 @@ class cfgMagazines { EGVAR(overpressure,range) = 0; EGVAR(overpressure,damage) = 0; }; - - class rhs_mag_AGM114K_2; - class GVAR(pylon_mag_2rnd_hellfire_k): rhs_mag_AGM114K_2 { - displayName = "2x AGM-114K [ACE]"; - pylonWeapon = "ace_hellfire_launcher"; - ammo = "ACE_Hellfire_AGM114K"; - }; - class GVAR(pylon_mag_2rnd_hellfire_n): rhs_mag_AGM114K_2 { - displayName = "2x AGM-114N [ACE]"; - pylonWeapon = "ace_hellfire_launcher_N"; - ammo = "ACE_Hellfire_AGM114N"; - }; - class GVAR(pylon_mag_2rnd_hellfire_l): rhs_mag_AGM114K_2 { - displayName = "2x AGM-114L [ACE]"; - pylonWeapon = "ace_hellfire_launcher_L"; - ammo = "ACE_Hellfire_AGM114L"; - }; }; diff --git a/addons/compat_rhs_usf3/CfgWeapons.hpp b/addons/compat_rhs_usf3/CfgWeapons.hpp index 46ac7e56ba..50b09c760f 100644 --- a/addons/compat_rhs_usf3/CfgWeapons.hpp +++ b/addons/compat_rhs_usf3/CfgWeapons.hpp @@ -206,170 +206,7 @@ class CfgWeapons { EGVAR(overpressure,offset) = 0.9; }; - // Fast Helmets - class rhsusf_opscore_01; - class rhsusf_opscore_ut_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor1_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor1_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_bk_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_fg_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_fg_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_fg_pelt_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_paint_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_paint_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_paint_pelt_nsw_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor2_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_aor2_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_ut_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_ut_pelt_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_ut_pelt_nsw_cam: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_pelt: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_pelt_nsw: rhsusf_opscore_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_cover; - class rhsusf_opscore_mc_cover_pelt_nsw: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_cover_pelt: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mc_cover_pelt_cam: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_rg_cover_pelt: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_coy_cover_pelt: rhsusf_opscore_cover { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mar_01; - class rhsusf_opscore_mar_ut_pelt: rhsusf_opscore_mar_01 { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_opscore_mar_fg_pelt: rhsusf_opscore_mar_01 { - HEARING_PROTECTION_PELTOR; - }; - - // ACH Helmets - class rhsusf_ach_helmet_ocp; - class rhsusf_ach_bare_des_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_des_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_semi_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_semi_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_tan_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_tan_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_wood_headset: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_bare_wood_headset_ess: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_helmet_headset_ocp: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_ach_helmet_headset_ess_ocp: rhsusf_ach_helmet_ocp { - HEARING_PROTECTION_PELTOR; - }; - - // ACVC Helmets - class rhsusf_cvc_helmet: rhsusf_opscore_01 { - HEARING_PROTECTION_VICCREW; - }; - - // MICH Helmets - class rhsusf_mich_bare; - class rhsusf_mich_bare_alt: rhsusf_mich_bare { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos; - class rhsusf_mich_bare_norotos_alt: rhsusf_mich_bare_norotos { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_arc; - class rhsusf_mich_bare_norotos_arc_alt: rhsusf_mich_bare_norotos_arc { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_semi; - class rhsusf_mich_bare_alt_semi: rhsusf_mich_bare_semi { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_semi; - class rhsusf_mich_bare_norotos_alt_semi: rhsusf_mich_bare_norotos_semi { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_arc_semi: rhsusf_mich_bare_norotos_alt_semi { - HEARING_PROTECTION_OPEN; - }; - class rhsusf_mich_bare_norotos_arc_alt_semi: rhsusf_mich_bare_norotos_arc_semi { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_tan; - class rhsusf_mich_bare_alt_tan: rhsusf_mich_bare_tan { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_tan; - class rhsusf_mich_bare_norotos_alt_tan: rhsusf_mich_bare_norotos_tan { - HEARING_PROTECTION_PELTOR; - }; - class rhsusf_mich_bare_norotos_arc_tan; - class rhsusf_mich_bare_norotos_arc_alt_tan: rhsusf_mich_bare_norotos_arc_tan { - HEARING_PROTECTION_PELTOR; - }; - - class rhsusf_hgu56p: rhsusf_opscore_01 { - HEARING_PROTECTION_VICCREW; - }; + class rhsusf_hgu56p; class rhsusf_hgu56p_visor: rhsusf_hgu56p { ACE_Protection = 1; }; @@ -420,13 +257,9 @@ class CfgWeapons { class rhsusf_hgu56p_mask_black_skull: rhsusf_hgu56p_visor_mask_black_skull { ACE_Protection = 0; }; - class rhsusf_ihadss: rhsusf_opscore_01 { - HEARING_PROTECTION_VICCREW; - }; class H_HelmetB; class RHS_jetpilot_usaf: H_HelmetB { ACE_Protection = 1; - HEARING_PROTECTION_VICCREW; }; }; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/CfgWeapons.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/CfgWeapons.hpp index 7888e52393..b87223ae27 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/CfgWeapons.hpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_arsenal/CfgWeapons.hpp @@ -3,6 +3,9 @@ class CfgWeapons { class acc_pointer_IR; class rhsusf_acc_anpeq15: acc_pointer_IR { baseWeapon = "rhsusf_acc_anpeq15"; + MRT_SwitchItemHintText = ""; // prevent false info for illuminator stat + MRT_SwitchItemNextClass = ""; + MRT_SwitchItemPrevClass = ""; }; class rhsusf_acc_anpeq15_bk: rhsusf_acc_anpeq15 { baseWeapon = "rhsusf_acc_anpeq15_bk"; @@ -18,6 +21,8 @@ class CfgWeapons { baseWeapon = "rhsusf_acc_anpeq15_wmx"; }; class rhsusf_acc_M952V: rhsusf_acc_anpeq15_light { + rhs_acc_combo = ""; // prevent materializing a PEQ-15 if RHS's attachment switch is called + rhs_anpeq15_base = ""; // same deal baseWeapon = "rhsusf_acc_M952V"; }; class rhsusf_acc_wmx: rhsusf_acc_M952V { @@ -26,11 +31,25 @@ class CfgWeapons { class rhsusf_acc_wmx_bk: rhsusf_acc_M952V { baseWeapon = "rhsusf_acc_wmx_bk"; }; + class rhsusf_acc_anpeq15A: acc_pointer_IR { baseWeapon = "rhsusf_acc_anpeq15A"; + MRT_SwitchItemHintText = ""; // prevent false info for illuminator stat + MRT_SwitchItemNextClass = ""; + MRT_SwitchItemPrevClass = ""; }; + class rhsusf_acc_anpeq15_top: rhsusf_acc_anpeq15A { + baseWeapon = "rhsusf_acc_anpeq15_top"; + }; + class rhsusf_acc_anpeq15_bk_top: rhsusf_acc_anpeq15_top { + baseWeapon = "rhsusf_acc_anpeq15_bk_top"; + }; + class rhsusf_acc_anpeq15side: acc_pointer_IR { baseWeapon = "rhsusf_acc_anpeq15side"; + MRT_SwitchItemHintText = ""; // prevent false info for illuminator stat + MRT_SwitchItemNextClass = ""; + MRT_SwitchItemPrevClass = ""; }; class rhsusf_acc_anpeq15side_bk: rhsusf_acc_anpeq15side { baseWeapon = "rhsusf_acc_anpeq15side_bk"; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml index 2b909ffacf..bc2413a2ca 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_csw/stringtable.xml @@ -9,6 +9,8 @@ [CSW] BGM-71A TOW [CSW] BGM-71A TOW [CSW] BGM-71A TOW + [CSW] BGM-71A TOW + [CSW] BGM-71A TOW [CSW] BGM-71B TOW @@ -18,6 +20,8 @@ [CSW] BGM-71B TOW [CSW] BGM-71B TOW [CSW] BGM-71B TOW + [CSW] BGM-71B TOW + [CSW] BGM-71B TOW [CSW] BGM-71C ITOW @@ -27,6 +31,8 @@ [CSW] BGM-71C ITOW [CSW] BGM-71C ITOW [CSW] BGM-71C ITOW + [CSW] BGM-71C ITOW + [CSW] BGM-71C ITOW [CSW] BGM-71D TOW-2 @@ -36,6 +42,8 @@ [CSW] BGM-71D TOW-2 [CSW] BGM-71D TOW-2 [CSW] BGM-71D TOW-2 + [CSW] BGM-71D TOW-2 + [CSW] BGM-71D TOW-2 [CSW] BGM-71E TOW-2A @@ -45,6 +53,8 @@ [CSW] BGM-71E TOW-2A [CSW] BGM-71E TOW-2A [CSW] BGM-71E TOW-2A + [CSW] BGM-71E TOW-2A + [CSW] BGM-71E TOW-2A [CSW] BGM-71F TOW-2B @@ -54,6 +64,8 @@ [CSW] BGM-71F TOW-2B [CSW] BGM-71F TOW-2B [CSW] BGM-71F TOW-2B + [CSW] BGM-71F TOW-2B + [CSW] BGM-71F TOW-2B [CSW] BGM-71F-3 TOW-2B AERO @@ -63,15 +75,19 @@ [CSW] BGM-71F-3 TOW-2B AERO [CSW] BGM-71F-3 TOW-2B AERO [CSW] BGM-71F-3 TOW-2B AERO + [CSW] BGM-71F-3 TOW-2B AERO + [CSW] BGM-71F-3 TOW-2B AERO [CSW] BGM-71H Bunker Buster [CSW] BGM-71H 벙커버스터 - [CSW] BGM-71H Bunker Buster + [CSW] BGM-71H バンカーバスター [班组] BGM-71H “碉堡克星” [CSW] BGM-71H Bunker Buster [CSW] BGM-71H Anti-Búnquer [CSW] BGM-71H Bunker Buster + [CSW] BGM-71H Anti-Bunker + [CSW] BGM-71H Bunker Buster [CSW] Mk. 19 40mm M384 HE @@ -81,6 +97,8 @@ [CSW] Mk. 19 40 мм M384 HE [CSW] Mk. 19 40mm M384 HE [CSW] Mk. 19 40mm M384 HE + [CSW] Mk. 19 40mm M384 HE + [CSW] Mk. 19 40mm M384 HE [CSW] Mk. 19 40mm M430I HEDP @@ -90,6 +108,8 @@ [CSW] Mk. 19 40 мм M430I HEDP [CSW] Mk. 19 40mm M430I HEDP [CSW] Mk. 19 40mm M430I HEDP + [CSW] Mk. 19 40mm M430I HEDP + [CSW] Mk. 19 40mm M430I HEDP [CSW] Mk. 19 40mm M430A1 HEDP @@ -99,6 +119,8 @@ [CSW] Mk. 19 40 мм M430A1 HEDP [CSW] Mk. 19 40mm M430A1 HEDP [CSW] Mk. 19 40mm M430A1 HEDP + [CSW] Mk. 19 40mm M430A1 HEDP + [CSW] Mk. 19 40mm M430A1 HEDP [CSW] Mk. 19 40mm M1001 Canister @@ -108,6 +130,8 @@ [CSW] Mk. 19 40 мм M1001 Канистровый [CSW] Mk. 19 40mm M1001 Bote de metralla [CSW] Mk. 19 40mm M1001 Kanister + [CSW] Mk. 19 40mm M1001 Pallettoni + [CSW] Mk. 19 40 mm M1001 Chevrotine diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/CfgWeapons.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/CfgWeapons.hpp new file mode 100644 index 0000000000..f0571e876f --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/CfgWeapons.hpp @@ -0,0 +1,174 @@ +class CfgWeapons { + // Fast Helmets + class rhsusf_opscore_01; + class rhsusf_opscore_ut_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor1_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor1_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_bk_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_fg_pelt_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_paint_pelt_nsw_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor2_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_aor2_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_ut_pelt_nsw_cam: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_pelt: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_pelt_nsw: rhsusf_opscore_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_cover; + class rhsusf_opscore_mc_cover_pelt_nsw: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mc_cover_pelt_cam: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_rg_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_coy_cover_pelt: rhsusf_opscore_cover { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mar_01; + class rhsusf_opscore_mar_ut_pelt: rhsusf_opscore_mar_01 { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_opscore_mar_fg_pelt: rhsusf_opscore_mar_01 { + HEARING_PROTECTION_PELTOR; + }; + + // ACH Helmets + class rhsusf_ach_helmet_ocp; + class rhsusf_ach_bare_des_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_des_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_semi_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_semi_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_tan_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_tan_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_wood_headset: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_bare_wood_headset_ess: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_helmet_headset_ocp: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_ach_helmet_headset_ess_ocp: rhsusf_ach_helmet_ocp { + HEARING_PROTECTION_PELTOR; + }; + + // ACVC Helmets + class rhsusf_cvc_helmet: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + + // MICH Helmets + class rhsusf_mich_bare; + class rhsusf_mich_bare_alt: rhsusf_mich_bare { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos; + class rhsusf_mich_bare_norotos_alt: rhsusf_mich_bare_norotos { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc; + class rhsusf_mich_bare_norotos_arc_alt: rhsusf_mich_bare_norotos_arc { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_semi; + class rhsusf_mich_bare_alt_semi: rhsusf_mich_bare_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_semi; + class rhsusf_mich_bare_norotos_alt_semi: rhsusf_mich_bare_norotos_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc_semi: rhsusf_mich_bare_norotos_alt_semi { + HEARING_PROTECTION_OPEN; + }; + class rhsusf_mich_bare_norotos_arc_alt_semi: rhsusf_mich_bare_norotos_arc_semi { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_tan; + class rhsusf_mich_bare_alt_tan: rhsusf_mich_bare_tan { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_tan; + class rhsusf_mich_bare_norotos_alt_tan: rhsusf_mich_bare_norotos_tan { + HEARING_PROTECTION_PELTOR; + }; + class rhsusf_mich_bare_norotos_arc_tan; + class rhsusf_mich_bare_norotos_arc_alt_tan: rhsusf_mich_bare_norotos_arc_tan { + HEARING_PROTECTION_PELTOR; + }; + + class rhsusf_hgu56p: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + class rhsusf_ihadss: rhsusf_opscore_01 { + HEARING_PROTECTION_VICCREW; + }; + + class H_HelmetB; + class RHS_jetpilot_usaf: H_HelmetB { + HEARING_PROTECTION_VICCREW; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/config.cpp new file mode 100644 index 0000000000..e52454b184 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/config.cpp @@ -0,0 +1,19 @@ +#include "script_component.hpp" +#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" + +class CfgPatches { + class SUBADDON { + addonRootClass = QUOTE(COMPONENT); + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_hearing" + }; + skipWhenMissingDependencies = 1; + VERSION_CONFIG; + }; +}; + +#include "CfgWeapons.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/script_component.hpp new file mode 100644 index 0000000000..8edb825af3 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hearing/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT hearing +#define SUBCOMPONENT_BEAUTIFIED Hearing +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgAmmo.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgAmmo.hpp new file mode 100644 index 0000000000..16a0628d1f --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgAmmo.hpp @@ -0,0 +1,8 @@ +class CfgAmmo { + // Use RHS Hellfire 3D Model on ACE Hellfires + class M_Scalpel_AT; + class ACE_Hellfire_AGM114K: M_Scalpel_AT { + model = "\rhsusf\addons\rhsusf_airweapons\proxyammo\rhsusf_m_AGM114K_fly"; + proxyShape = "\rhsusf\addons\rhsusf_airweapons\proxyammo\rhsusf_m_AGM114K"; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazineWells.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazineWells.hpp new file mode 100644 index 0000000000..e574b123a2 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazineWells.hpp @@ -0,0 +1,11 @@ +class CfgMagazineWells { + class ace_hellfire_K { + ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_k), QGVAR(pylon_mag_4rnd_hellfire_k)}; + }; + class ace_hellfire_N { + ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_n), QGVAR(pylon_mag_4rnd_hellfire_n)}; + }; + class ace_hellfire_L { + ADDON[] = {QGVAR(pylon_mag_2rnd_hellfire_l), QGVAR(pylon_mag_4rnd_hellfire_l)}; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazines.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazines.hpp new file mode 100644 index 0000000000..9d96974ab8 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/CfgMagazines.hpp @@ -0,0 +1,37 @@ +class CfgMagazines { + // 2x ACE Hellfire racks + class rhs_mag_AGM114K_2; + class GVAR(pylon_mag_2rnd_hellfire_k): rhs_mag_AGM114K_2 { + displayName = "2x AGM-114K [ACE]"; + pylonWeapon = "ace_hellfire_launcher"; + ammo = "ACE_Hellfire_AGM114K"; + }; + class GVAR(pylon_mag_2rnd_hellfire_n): rhs_mag_AGM114K_2 { + displayName = "2x AGM-114N [ACE]"; + pylonWeapon = "ace_hellfire_launcher_N"; + ammo = "ACE_Hellfire_AGM114N"; + }; + class GVAR(pylon_mag_2rnd_hellfire_l): rhs_mag_AGM114K_2 { + displayName = "2x AGM-114L [ACE]"; + pylonWeapon = "ace_hellfire_launcher_L"; + ammo = "ACE_Hellfire_AGM114L"; + }; + + // 4x ACE Hellfire racks that align better on RHS Apaches and Blackhawks than the standard ACE 4x racks + class rhs_mag_AGM114K_4; + class GVAR(pylon_mag_4rnd_hellfire_k): rhs_mag_AGM114K_4 { + displayName = "4x AGM-114K [ACE]"; + pylonWeapon = "ace_hellfire_launcher"; + ammo = "ACE_Hellfire_AGM114K"; + }; + class GVAR(pylon_mag_4rnd_hellfire_n): rhs_mag_AGM114K_4 { + displayName = "4x AGM-114N [ACE]"; + pylonWeapon = "ace_hellfire_launcher_N"; + ammo = "ACE_Hellfire_AGM114N"; + }; + class GVAR(pylon_mag_4rnd_hellfire_l): rhs_mag_AGM114K_4 { + displayName = "4x AGM-114L [ACE]"; + pylonWeapon = "ace_hellfire_launcher_L"; + ammo = "ACE_Hellfire_AGM114L"; + }; +}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/config.cpp new file mode 100644 index 0000000000..f460508a18 --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/config.cpp @@ -0,0 +1,25 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = { + "rhsusf_main_loadorder", + "ace_hellfire" + }; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "CfgAmmo.hpp" +#include "CfgMagazines.hpp" +#include "CfgMagazineWells.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/script_component.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/script_component.hpp new file mode 100644 index 0000000000..387de2d3ad --- /dev/null +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_hellfire/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT hellfire +#define SUBCOMPONENT_BEAUTIFIED Hellfire +#include "..\script_component.hpp" diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp deleted file mode 100644 index 5aaf6b4e22..0000000000 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/CfgVehicles.hpp +++ /dev/null @@ -1,15 +0,0 @@ -class CfgVehicles { - class rhsusf_M1078A1P2_B_M2_fmtv_usarmy; - class rhsusf_M1078A1R_SOV_M2_D_fmtv_socom: rhsusf_M1078A1P2_B_M2_fmtv_usarmy { - transportFuel = 0; - }; - - class rhsusf_M977A4_usarmy_wd; - class rhsusf_M978A4_usarmy_wd: rhsusf_M977A4_usarmy_wd { - transportFuel = 0; - }; - - class rhsusf_M978A4_BKIT_usarmy_wd: rhsusf_M977A4_usarmy_wd { - transportFuel = 0; - }; -}; diff --git a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp index 391e22d95e..bf600d5d5a 100644 --- a/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp +++ b/addons/compat_rhs_usf3/compat_rhs_usf3_refuel/config.cpp @@ -21,4 +21,3 @@ class CfgPatches { }; #include "CfgEventHandlers.hpp" -#include "CfgVehicles.hpp" diff --git a/addons/compat_rhs_usf3/config.cpp b/addons/compat_rhs_usf3/config.cpp index 1e67b1e007..b28a08b22e 100644 --- a/addons/compat_rhs_usf3/config.cpp +++ b/addons/compat_rhs_usf3/config.cpp @@ -1,5 +1,4 @@ #include "script_component.hpp" -#include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" class CfgPatches { class ADDON { @@ -7,7 +6,7 @@ class CfgPatches { units[] = {}; weapons[] = {}; requiredVersion = REQUIRED_VERSION; - requiredAddons[] = {"rhsusf_main_loadorder"}; + requiredAddons[] = {"ace_common", "rhsusf_main_loadorder"}; skipWhenMissingDependencies = 1; author = ECSTRING(common,ACETeam); authors[] = {"Ruthberg", "GitHawk", "BaerMitUmlaut", "Fyuran"}; @@ -19,7 +18,6 @@ class CfgPatches { #include "CfgAmmo.hpp" #include "CfgEventHandlers.hpp" #include "CfgMagazines.hpp" -#include "CfgMagazineWells.hpp" #include "CfgWeapons.hpp" #include "CfgVehicles.hpp" #include "CfgGlasses.hpp" diff --git a/addons/compat_sog/CfgAmmo/grenades.hpp b/addons/compat_sog/CfgAmmo/grenades.hpp index d280443b6e..6395756f64 100644 --- a/addons/compat_sog/CfgAmmo/grenades.hpp +++ b/addons/compat_sog/CfgAmmo/grenades.hpp @@ -4,6 +4,13 @@ class vn_molotov_grenade_ammo: vn_grenadehand { EGVAR(frag,enabled) = 0; }; +class vn_t67_grenade_ammo: vn_grenadehand { + EGVAR(grenades,rollVectorDirAndUp)[] = {{-1, 0, 0}, {0, 0, 1}}; +}; +class vn_chicom_grenade_ammo: vn_grenadehand { + EGVAR(grenades,rollVectorDirAndUp)[] = {{1, 0, 0}, {0, 0, 1}}; +}; + class SmokeShell; class vn_m14_grenade_ammo: SmokeShell { EGVAR(grenades,incendiary) = 1; diff --git a/addons/compat_sog/CfgEventHandlers.hpp b/addons/compat_sog/CfgEventHandlers.hpp index fc6d80fc5f..d28b79fb99 100644 --- a/addons/compat_sog/CfgEventHandlers.hpp +++ b/addons/compat_sog/CfgEventHandlers.hpp @@ -32,6 +32,16 @@ class Extended_InitPost_EventHandlers { init = QUOTE((_this select 0) setMass 1e-12); }; }; + class Land_vn_canisterfuel_f { + class ADDON { + init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})])); + }; + }; + class Land_vn_fuelcan { + class ADDON { + init = QUOTE(call (missionNamespace getVariable [ARR_2(QQEFUNC(refuel,makeJerryCan),{})])); + }; + }; class vn_bicycle_base { class ADDON { init = QUOTE(call FUNC(disableCookoff)); diff --git a/addons/compat_sog/CfgVehicles/land.hpp b/addons/compat_sog/CfgVehicles/land.hpp index c939026590..70b305a31d 100644 --- a/addons/compat_sog/CfgVehicles/land.hpp +++ b/addons/compat_sog/CfgVehicles/land.hpp @@ -1,18 +1,19 @@ +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} // fuel pumps class Land_vn_commercial_base; class Land_vn_fuelstation_01_pump_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_vn_fuelstation_02_pump_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_vn_fuelstation_feed_f: Land_vn_commercial_base { - transportFuel = 0; + XEH_INHERITED; EGVAR(refuel,hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; EGVAR(refuel,fuelCargo) = REFUEL_INFINITE_FUEL; }; @@ -20,13 +21,47 @@ class Land_vn_fuelstation_feed_f: Land_vn_commercial_base { // fuel objects class Land_vn_building_b_base; class Land_vn_usaf_fueltank_75_01: Land_vn_building_b_base { - transportFuel = 0; - EGVAR(refuel,hooks)[] = {{0, -0.4, -0.5}}; + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{-2.52, -2.2, -2.05}, {2.5, 0, -1.3}}; EGVAR(refuel,fuelCargo) = 2840; // 750 * 3.785 }; +class Land_vn_b_prop_fuelbladder_01: Land_vn_usaf_fueltank_75_01 { + EGVAR(refuel,hooks)[] = {{-1.75, -6.7, -1}}; + EGVAR(refuel,fuelCargo) = 3785; // 1000 * 3.785 +}; +class Land_vn_b_prop_fuelbladder_03: Land_vn_b_prop_fuelbladder_01 { + EGVAR(refuel,hooks)[] = {{-1.55, -6.5, -1}}; +}; +class Land_vn_building_industrial_base; +class Land_vn_fuel_tank_stairs: Land_vn_building_industrial_base { + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0.4, -1.3}, {0, -0.4, -1.3}}; + EGVAR(refuel,fuelCargo) = 10000; // reference is B_Slingload_01_Fuel_F +}; class Land_vn_object_b_base; class Land_vn_b_prop_fueldrum_01: Land_vn_object_b_base { - transportFuel = 0; - EGVAR(refuel,hooks)[] = {{0, 0, 0.5}}; // reference is Land_FlexibleTank_01_F + XEH_INHERITED; + EGVAR(refuel,hooks)[] = {{0, 0, 0}}; EGVAR(refuel,fuelCargo) = 300; // reference is Land_FlexibleTank_01_F }; +class Land_vn_b_prop_fueldrum_02: Land_vn_b_prop_fueldrum_01 { + EGVAR(refuel,hooks)[] = {{0, -1.3, -0.15}, {2.3, 1.25, -0.15}}; + EGVAR(refuel,fuelCargo) = 14100; // (23 + 24) * 300 +}; +class vn_b_ammobox_supply_07; +class vn_b_ammobox_supply_09: vn_b_ammobox_supply_07 { // just a pallet + XEH_INHERITED; +}; +class vn_object_c_base_02; +class Land_vn_canisterfuel_f: vn_object_c_base_02 { + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; +}; +class Land_vn_object_c_base; +class Land_vn_fuelcan: Land_vn_object_c_base { + XEH_INHERITED; + EGVAR(cargo,size) = 1; + EGVAR(cargo,canLoad) = 1; + EGVAR(cargo,noRename) = 1; +}; diff --git a/addons/compat_sog/CfgVehicles/wheeled.hpp b/addons/compat_sog/CfgVehicles/wheeled.hpp index 3525328d3f..3a898519dd 100644 --- a/addons/compat_sog/CfgVehicles/wheeled.hpp +++ b/addons/compat_sog/CfgVehicles/wheeled.hpp @@ -5,7 +5,6 @@ class vn_wheeled_m54_base: vn_wheeled_truck_base { }; class vn_wheeled_m54_cab_base; class vn_wheeled_m54_fuel_base: vn_wheeled_m54_cab_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.15, -2.3, 0.28}}; EGVAR(refuel,fuelCargo) = 4542; }; @@ -25,7 +24,6 @@ class vn_wheeled_z157_base: vn_wheeled_truck_base { EGVAR(refuel,fuelCapacity) = 150; }; class vn_wheeled_z157_fuel_base: vn_wheeled_z157_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-1.36, -3.575, -0.4}}; EGVAR(refuel,fuelCargo) = 4000; }; diff --git a/addons/compat_sog/config.cpp b/addons/compat_sog/config.cpp index 62b235773b..04db68293c 100644 --- a/addons/compat_sog/config.cpp +++ b/addons/compat_sog/config.cpp @@ -1,5 +1,4 @@ #include "script_component.hpp" -// ToDo: move refuel to subconfig #include "\z\ace\addons\refuel\defines.hpp" #include "\z\ace\addons\hearing\script_macros_hearingProtection.hpp" @@ -47,6 +46,8 @@ class CfgPatches { }; }; +class CBA_Extended_EventHandlers; + #include "ACE_CSW_Groups.hpp" #include "ACE_Medical_Injuries.hpp" #include "ACE_Triggers.hpp" diff --git a/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf b/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf index 17ed92a172..7cac6829c5 100644 --- a/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf +++ b/addons/compat_sog/functions/fnc_handlePunjiTrapTrigger.sqf @@ -14,8 +14,10 @@ * * Public: No */ + params ["_trap"]; -if (!(["ACE_Medical"] call EFUNC(common,isModLoaded))) exitWith {}; + +if !(GETEGVAR(medical,enabled,false)) exitWith {}; private _radius = getNumber (configOf _trap >> "indirectHitRange"); private _affectedUnits = _trap nearEntities ["CAManBase", _radius]; diff --git a/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf b/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf index 75ee243f08..6d3b7a8678 100644 --- a/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf +++ b/addons/compat_sog/functions/fnc_woundsHandlerIncendiary.sqf @@ -18,8 +18,6 @@ * Public: No */ -#define BURN_THRESHOLD 1 - params ["_unit", "_damages"]; TRACE_2("woundsHandlerIncendiary",_unit,_damages); @@ -32,9 +30,7 @@ private _fireDamage = 0; private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true]; TRACE_2("",_intensity,_fireDamage); -if (_intensity > BURN_THRESHOLD) then { - TRACE_2("Setting unit ablaze",_intensity,BURN_THRESHOLD); - ["ace_fire_burn", [_unit, _intensity]] call CBA_fnc_globalEvent; -}; +// Let fire handle if unit is set ablaze or not +[QEGVAR(fire,burn), [_unit, _intensity]] call CBA_fnc_localEvent; _this // return diff --git a/addons/compat_sog/stringtable.xml b/addons/compat_sog/stringtable.xml index 57e4106b78..fc64aef97c 100644 --- a/addons/compat_sog/stringtable.xml +++ b/addons/compat_sog/stringtable.xml @@ -5,381 +5,495 @@ Dig in Zakop Eingraben + Trincerati 掘る 땅파기 挖掘 Закопать Enterrarse + Escavar + Creuser M49A2 60mm HE M49A2 60mm HE - M49A2 60mm りゅう弾 + M49A2 60mm HE + M49A2 60mm 榴弾 M49A2 60mm HE M49A2 60mm 고폭 M49A2 60 mm 高爆弹 M49A2 60 мм ОФ M49A2 60mm HE + M49A2 60mm HE + M49A2 60mm HE M302 60mm WP M302 60mm Weißer Phosphor + M302 60mm Fosforo Bianco M302 60mm 白リン弾 M302 60mm WP M302 60mm 백린 M302 60 mm 白磷弹 M302 60 мм Фосфорная M302 60mm WP + M302 60mm WP + M302 60mm Phosphore Blanc M83 60mm Lume M83 60mm Leuchtpatrone + M83 60mm Illuminante M83 60mm 照明弾 M83 60mm ILUM M83 60mm 조명 M83 60 mm 照明弹 M83 60 мм Осветительная M83 60mm Iluminación + M83 60mm Iluminação + M83 60 mm Eclairant M374 81mm HE M374 81mm HE - M374 81mm りゅう弾 + M374 81mm HE + M374 81mm 榴弾 M374 81mm HE M374 81mm 고폭 M374 81 mm 高爆弹 M374 81 мм ОФ M374 81mm HE + M374 81mm HE + M374 81mm HE M375 81mm WP M375 81mm Weißer Phosphor + M375 81mm Fosforo Bianco M375 81mm 白リン弾 M375 81mm WP M375 81mm 백린 M375 81 mm 白磷弹 M375 81 мм Фосфорная M375 81mm WP + M375 81mm WP + M375 81mm Phosphore Blanc M301A3 81mm Lume M301A3 81mm Leuchtpatrone + M301A3 81mm Illuminante M301A3 81mm 照明弾 M301A3 81mm ILUM M301A3 81mm 조명 M301A3 81 mm 照明弹 M301A3 81 мм Осветительная M301A3 81mm Iluminación + M301A3 81mm Iluminação + M301A3 81mm Eclairant M57 81mm Smoke M57 81mm Nebelpatrone + M57 81mm Fumogeno M57 81mm 発煙弾 M57 81mm Dymny M57 81mm 연막 M57 81 mm 烟雾弹 M57 81 мм Дымовая M57 81mm Smoke + M57 81mm Fumígena + M57 81mm Fumigène O-832D 82mm HE O-832D 82mm HE - O-832D 82mm りゅう弾 + O-832D 82mm HE + O-832D 82mm 榴弾 O-832D 82mm HE O-832D 82mm 고폭 O-832D 82 mm 高爆弹 О-832Д 82 мм ОФ O-832D 82mm HE + O-832D 82mm HE + O-832D 82mm HE D-832 82mm WP D-832 82mm Weißer Phosphor + D-832 82mm Fosforo Bianco D-832 82mm 白リン弾 D-832 82mm WP D-832 82mm 백린 D-832 82 mm 白磷弹 Д-832 82 мм Фосфорная D-832 82mm WP + D-832 82mm WP + D-832 82mm Phosphore Blanc S-832S 82mm Lume S-832S 82mm Leuchtpatrone + S-832S 82mm Illuminante S-832S 82mm 照明弾 S-832S 82mm ILUM S-832S 82mm 조명 S-832S 82 mm 照明弹 С-832С 82 мм Осветительная S-832S 82mm Iluminación + S-832S 82mm Iluminação + S-832S 82mm Eclairant [ACE] M49A2 60mm HE Box [ACE] M49A2 60mm HE Box - [ACE] M49A2 60mm りゅう弾入り弾薬箱 + [ACE] Scatola M49A2 60mm HE + [ACE] M49A2 60mm 榴弾入り弾薬箱 [ACE] Skrzynia M49A2 60mm HE [ACE] M49A2 60mm 고폭 상자 [ACE] M49A2 60 mm 高爆弹弹药箱 [ACE] Коробка M49A2 60 мм ОФ [ACE] M49A2 60mm Caja de HE + [ACE] M49A2 60mm Caixa de HE + [ACE] Scatola M49A2 60mm HE [ACE] M302 60mm WP Box [ACE] M302 60mm Weißer Phosphor Box + [ACE] Scatola M302 60mm Fosforo Bianco [ACE] M302 60mm 白リン弾入り弾薬箱 [ACE] Skrzynia M302 60mm WP [ACE] M302 60mm 백린 상자 [ACE] M302 60 mm 白磷弹弹药箱 [ACE] Коробка M302 60 мм Фосфорных [ACE] M302 60mm Caja de WP + [ACE] M302 60mm Caixa de WP + [ACE] M302 60mm Phosphore Blanc Box [ACE] M83 60mm Lume Box [ACE] M83 60mm Leuchtpatrone Box + [ACE] Scatola M83 60mm Illuminanti [ACE] M83 60mm 照明弾弾入り弾薬箱 [ACE] Skrzynia ILUM M83 60mm [ACE] M83 60mm 조명 상자 [ACE] M83 60 mm 照明弹弹药箱 [ACE] Коробка M83 60 мм Осветительных [ACE] M83 60mm Caja de Iluminación + [ACE] M83 60mm Caixa de Iluminação + [ACE] M83 60mm Eclairant Box [ACE] M374 81mm HE Box [ACE] M374 81mm HE Box - [ACE] M374 81mm りゅう弾入り弾薬箱 + [ACE] Scatola M374 81mm HE + [ACE] M374 81mm 榴弾入り弾薬箱 [ACE] Skrzynia M374 81mm HE [ACE] M374 81mm 고폭 상자 [ACE] M374 81 mm 高爆弹弹药箱 [ACE] Коробка M374 81 мм ОФ [ACE] M374 81mm Caja de HE + [ACE] M374 81mm Caixa de HE + [ACE] Scatola M374 81mm HE [ACE] M375 81mm WP Box [ACE] M375 81mm Weißer Phosphor Box + [ACE] Scatola M375 81mm Fosforo Bianco [ACE] M375 81mm 白リン弾入り弾薬箱 [ACE] Skrzynia M375 81mm WP [ACE] M375 81mm 백린 상자 [ACE] M375 81 mm 白磷弹弹药箱 [ACE] Коробка M375 81 мм Фосфорных [ACE] M375 81mm Caja de WP + [ACE] M375 81mm Caixa de WP + [ACE] M375 81mm Phosphore Blanc Box [ACE] M301A3 81mm Lume Box [ACE] M301A3 81mm Leuchtpatrone Box + [ACE] Scatola M301A3 81mm Illuminanti [ACE] M301A1 81mm 照明弾入り弾薬箱 [ACE] Skrzynia M301A3 81mm ILUM [ACE] M301A3 81mm 조명 상자 [ACE] M301A3 81 mm 照明弹弹药箱 [ACE] Коробка M301A3 81 мм Осветительных [ACE] M301A3 81mm Caja de Iluminación + [ACE] M301A3 81mm Caixa de Iluminação + [ACE] M301A3 81mm Eclairant Box [ACE] M57 81mm Smoke Box [ACE] M57 81mm Nebelpatrone Box + [ACE] Scatola M57 81mm Fumogeni [ACE] M57 81mm 煙幕弾入り弾薬箱 [ACE] Skrzynia M57 81mm Dymny [ACE] M57 81mm 연막 상자 [ACE] M57 81 mm 烟雾弹弹药箱 [ACE] Коробка M57 81 мм Дымовых [ACE] M57 81mm Caja de Humo + [ACE] M57 81mm Caixa de Fumígena + [ACE] M57 81mm Fumigène Box [ACE] O-832D 82mm HE Box [ACE] O-832D 82mm HE Box - [ACE] O-832D 82mm りゅう弾入り弾薬箱 + [ACE] Scatola O-832D 82mm HE + [ACE] O-832D 82mm 榴弾入り弾薬箱 [ACE] Skrzynia O-832D 82mm HE [ACE] O-832D 82mm 고폭 상자 [ACE] O-832D 82 mm 高爆弹弹药箱 [ACE] Коробка О-832Д 82 мм ОФ [ACE] O-832D 82mm Caja de HE + [ACE] O-832D 82mm Caixa de HE + [ACE] Scatola O-832D 82mm HE [ACE] D-832 82mm WP Box [ACE] D-832 82mm Weißer Phosphor Box + [ACE] Scatola D-832 82mm Fosforo Bianco [ACE] D-832 82mm 白リン弾入り弾薬箱 [ACE] Skrzynia D-832 82mm WP [ACE] D-832 82mm 백린 상자 [ACE] D-832 82 mm 白磷弹弹药箱 [ACE] Коробка Д-832 82 мм Фосфорных [ACE] D-832 82mm Caja de WP + [ACE] D-832 82mm Caixa de WP + [ACE] D-832 82mm Phosphore Blanc Box [ACE] S-832S 82mm Lume Box [ACE] S-832S 82mm Leuchtpatrone Box + [ACE] Scatola S-832S 82mm Illuminanti [ACE] S-832S 82mm 照明弾入り弾薬箱 [ACE] Skrzynia S-832S 82mm ILUM [ACE] S-832S 82mm 조명 상자 [ACE] S-832S 82 mm 照明弹弹药箱 [ACE] Коробка С-832С 82 мм Осветительных [ACE] S-832S 82mm Caja de Iluminación + [ACE] S-832S 82mm Caixa de Iluminação + [ACE] S-832S 82mm Eclairant Box Dig Spiderhole Schützenloch graben + Scava buco di ragno 蛸壺壕を掘る Wykop Lisią Norę 개인호 파기 挖掘散兵坑 Выкопать паучью дыру Excavar Agujero de araña + Escavar buraco de aranha + Creuser un trou d'araignée Dig Spiderhole (Angled Cover) Schützenloch graben (Abgeschrägte Abdeckung) + Scava buco di ragno (Coperchio Angolato) 蛸壺壕 (屋根) を掘る Wykop Lisią Norę (z dachem) 개인호 파기 (각진 엄폐) 挖掘带斜盖散兵坑 Выкопать крытую паучью дыру Excavar Agujero de araña (Cubierta inclinada) + Escavar buraco de aranha (Cobertura inclinada) + Creuser un trou d'araignée (couverture d'angle) Dig Spiderhole (Dual) Großes Schützenloch graben + Scava buco di ragno (Doppio) 蛸壺壕 (2人用) を掘る Wykop Lisią Norę (podwójną) 개인호 파기 (2인용) 挖掘双人散兵坑 Выкопать двойную паучью дыру Excavar Agujero de araña (Doble) + Escavar buraco de aranha (Duplo) + Creuser un trou d'araignée (double) [CSW] M1919A4 Gun Bag [CSW] M1919A4 Waffentasche + [CSW] Borsa per Mitra M1919A4 [CSW] M1919A4 ガン バッグ [CSW] Torba na M1919A4 [CSW] M1919A4 총가방 [班组] M1919A4 枪袋 [CSW] Сумка с M1919A4 [CSW] M1919A4 Bolsa para arma + [CSW] Bolsa para M1919A4 + [CSW] M1919A4 Gun Bag [CSW] M1919A6 Gun Bag [CSW] M1919A6 Waffentasche + [CSW] Borsa per Mitra M1919A6 [CSW] M1919A6 ガン バッグ [CSW] Torba na M1919A6 [CSW] M1919A6 총가방 [班组] M1919A6 枪袋 [CSW] Сумка с M1919A6 [CSW] M1919A6 Bolsa para arma + [CSW] Bolsa para M1919A6 + [CSW] M1919A6 Gun Bag [CSW] M60 Gun Bag [CSW] M60 Waffentasche + [CSW] Borsa per Mitra M60 [CSW] M60 ガン バッグ [CSW] Torba na M60 [CSW] M60 총가방 [班组] M60 枪袋 [CSW] Сумка с M60 [CSW] M60 Bolsa para arma + [CSW] Bolsa para M60 + [CSW] M60 Gun Bag [CSW] DShK (Shield) Gun Bag [CSW] DShK (Schutzschild) Waffentasche + [CSW] Borsa per Mitra DShK (con scudo) [CSW] DShK (防盾) ガン バッグ [CSW] Torba na DShK (z tarczą) [CSW] DShK (방패) 총가방 [班组] DShK(防盾)枪袋 [CSW] Сумка с ДШК (со щитом) [CSW] DShK (Apantallada) Bolsa para arma + [CSW] Bolsa para DShK (Escudo) + [CSW] DShK (Shield) Gun Bag [CSW] DShK (AA) Gun Bag [CSW] DShK (AA) Waffentasche + [CSW] Borsa per Mitra DShK (AA) [CSW] DShK (対空) ガン バッグ [CSW] Torba na DShK (AA) [CSW] DShK (대공) 총가방 [班组] DShK(高)枪袋 [CSW] Сумка с ДШК (зенитный) [CSW] DShK (AA) Bolsa para arma + [CSW] Bolsa para DShK (AA) + [CSW] DShK (AA) Gun Bag [CSW] RPD Gun Bag [CSW] RPD Waffentasche + [CSW] Borsa per Mitra RPD [CSW] RPD ガン バッグ [CSW] Torba na RPD [CSW] RPD 총가방 [班组] RPD 枪袋 [CSW] Сумка с РПД [CSW] RPD Bolsa para arma + [CSW] Bolsa para RPD + [CSW] RPD Gun Bag [CSW] PK Gun Bag [CSW] PK Waffentasche + [CSW] Borsa per Mitra PK [CSW] PK ガン バッグ [CSW] Torba na PK [CSW] PK 총가방 [班组] PK 枪袋 [CSW] Сумка с ПК [CSW] PK Bolsa para arma + [CSW] Bolsa para PK + [CSW] PK Sac d'armes [CSW] MG42 Gun Bag [CSW] MG42 Waffentasche + [CSW] Borsa per Mitra MG42 [CSW] MG42 ガン バッグ [CSW] Torba na MG42 [CSW] MG42 총가방 [班组] MG42 枪袋 [CSW] Сумка с MG42 [CSW] MG42 Bolsa para arma + [CSW] Bolsa para MG42 + [CSW] MG42 Sac d'armes [CSW] SGM Gun Bag [CSW] SGM Waffentasche + [CSW] Borsa per Mitra SGM [CSW] SGM ガン バッグ [CSW] Torba na SGM [CSW] SGM 총가방 [班组] SGM 枪袋 [CSW] Сумка с СГМ [CSW] SGM Bolsa para arma + [CSW] Bolsa para SGM + [CSW] SGM Sac d'armes [CSW] SGM (Shield) Gun Bag [CSW] SGM (Schutzschild) Waffentasche + [CSW] Borsa per Mitra SGM (con scudo) [CSW] SGM (防盾) ガン バッグ [CSW] Torba na SGM (z tarczą) [CSW] SGM (방패) 총가방 [班组] SGM(防盾)枪袋 [CSW] Сумка с СГМ (со щитом) [CSW] SGM (Apantallada) Bolsa para arma + [CSW] Bolsa para SGM (Escudo) + [CSW] SGM Sac d'armes (avec bouclier) [CSW] Mk18 Gun Bag [CSW] Mk18 Waffentasche + [CSW] Borsa per GMG Mk18 [CSW] Mk18 ガン バッグ [CSW] Torba na Mk18 [CSW] Mk18 총가방 [班组] Mk18 枪袋 [CSW] Сумка с Mk18 [CSW] Mk18 Bolsa para arma + [CSW] Bolsa para Mk18 + [CSW] Mk18 Sac d'armes [CSW] M29 Mortar Tube [CSW] M29 Mörserrohr + [CSW] Tubo di Mortaio M29 [CSW] M29 発射筒 [CSW] M29 Rura od moździerza [CSW] M29 박격포 포신 [班组] M29 迫击炮炮管 [CSW] Сумка с миномётом M29 [CSW] M29 Tubo de Mortero + [CSW] M29 Tubo de Morteiro + [CSW] Tube de mortier M29 [CSW] M2 Mortar Tube [CSW] M2 Mörserrohr + [CSW] Tubo di Mortaio M2 [CSW] M2 底盤 [CSW] M2 Rura od moździerza [CSW] M2 박격포 포신 [班组] M2 迫击炮炮管 [CSW] Сумка с миномётом M2 [CSW] M2 Tubo de mortero + [CSW] M2 Tubo de Morteiro + [CSW] Tube de mortier M2 [CSW] Type 53 Mortar Tube [CSW] Typ 53 Mörserrohr + [CSW] Tubo di Mortaio Type 53 [CSW] 53 式 発射筒 [CSW] Type 53 Rura od moździerza [CSW] 53식 박격포 포신 [班组] 53式迫击炮炮管 [CSW] Сумка с миномётом Type 53 [CSW] Type 53 Tubo de mortero + [CSW] Type 53 Tubo de Morteiro + [CSW] Tube de mortier Type 53 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_spe/compat_spe_refuel/CfgVehicles.hpp b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp index f47d6877f7..fc1ebc9b4e 100644 --- a/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp +++ b/addons/compat_spe/compat_spe_refuel/CfgVehicles.hpp @@ -1,13 +1,11 @@ class CfgVehicles { class SPE_Halftrack_base; class SPE_US_M3_Halftrack_Fuel: SPE_Halftrack_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; EGVAR(refuel,fuelCargo) = 2000; }; class SPE_OpelBlitz_base; class SPE_OpelBlitz_Fuel: SPE_OpelBlitz_base { - transportFuel = 0; EGVAR(refuel,hooks)[] = {{-0.23,-2.58,-0.59}}; EGVAR(refuel,fuelCargo) = 2000; }; diff --git a/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf b/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf index aa282e9be8..d2b0cb165c 100644 --- a/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf +++ b/addons/compat_spe/functions/fnc_woundsHandlerIncendiary.sqf @@ -18,8 +18,6 @@ * Public: No */ -#define BURN_THRESHOLD 1 - params ["_unit", "_damages"]; TRACE_2("woundsHandlerIncendiary",_unit,_damages); @@ -32,9 +30,7 @@ private _fireDamage = 0; private _intensity = linearConversion [0, 20, _fireDamage, 0, 10, true]; TRACE_2("",_intensity,_fireDamage); -if (_intensity > BURN_THRESHOLD) then { - TRACE_2("Setting unit ablaze",_intensity,BURN_THRESHOLD); - ["ace_fire_burn", [_unit, _intensity]] call CBA_fnc_globalEvent; -}; +// Let fire handle if unit is set ablaze or not +[QEGVAR(fire,burn), [_unit, _intensity]] call CBA_fnc_localEvent; _this // return diff --git a/addons/compat_ws/CfgWeapons.hpp b/addons/compat_ws/CfgWeapons.hpp index 10e4b68eb2..a8b27fb1f3 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 @@ -35,6 +37,11 @@ class CfgWeapons { ACE_twistDirection = 1; }; + class arifle_SLR_V_lxWS; + class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS { + ACE_barrelLength = 266.7; + }; + // Velko R4/R5 class arifle_Velko_base_lxWS: arifle_Galat_base_lxWS { ACE_barrelLength = 460; diff --git a/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp b/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp new file mode 100644 index 0000000000..95801e04e9 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/Attachments.hpp @@ -0,0 +1,75 @@ +class optic_Arco; +class optic_arco_hex_lxWS: optic_Arco { + displayName = SUBCSTRING(arco_hex_Name); +}; + +class optic_Holosight; +class optic_Holosight_snake_lxWS: optic_Holosight { + displayName = SUBCSTRING(holosight_snake_Name); +}; + +class optic_Holosight_smg; +class optic_Holosight_smg_snake_lxWS: optic_Holosight_smg { + displayName = SUBCSTRING(holosight_snake_smg_Name); +}; + +class optic_Hamr; +class optic_Hamr_arid_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_arid_Name); +}; +class optic_Hamr_lush_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_lush_Name); +}; +class optic_Hamr_sand_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_sand_Name); +}; +class optic_Hamr_snake_lxWS: optic_Hamr { + displayName = SUBCSTRING(hamr_snake_Name); +}; + +class ItemCore; +class optic_r1_high_lxWS: ItemCore { + displayName = SUBCSTRING(r1_high_black_Name); +}; +class optic_r1_high_khaki_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_khaki_Name); +}; +class optic_r1_high_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_sand_Name); +}; +class optic_r1_high_snake_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_snake_Name); +}; +class optic_r1_high_arid_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_arid_Name); +}; +class optic_r1_high_lush_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_lush_Name); +}; +class optic_r1_high_black_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_high_black_sand_Name); +}; + +class optic_r1_low_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_black_Name); +}; +class optic_r1_low_khaki_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_khaki_Name); +}; +class optic_r1_low_sand_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_sand_Name); +}; +class optic_r1_low_snake_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_snake_Name); +}; +class optic_r1_low_arid_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_arid_Name); +}; +class optic_r1_low_lush_lxWS: optic_r1_high_lxWS { + displayName = SUBCSTRING(r1_low_lush_Name); +}; + +class optic_DMS; +class optic_DMS_snake_lxWS: optic_DMS { + displayName = SUBCSTRING(dms_snake_Name); +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp new file mode 100644 index 0000000000..fe1aed7e17 --- /dev/null +++ b/addons/compat_ws/compat_ws_realisticnames/CfgVehicles.hpp @@ -0,0 +1,60 @@ +class CfgVehicles { + class APC_Wheeled_01_base_F; + class APC_Wheeled_01_atgm_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_atgm_Name); + }; + class APC_Wheeled_01_command_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_command_Name); + }; + class APC_Wheeled_01_mortar_base_lxWS: APC_Wheeled_01_base_F { + displayName = SUBCSTRING(apc_wheeled_01_mortar_Name); + }; + + class Truck_02_base_F; + class Truck_02_aa_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_aa_Name); + }; + class Truck_02_cargo_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_cargo_Name); + }; + class Truck_02_box_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_repair_Name); + }; + class C_Truck_02_racing_lxWS: Truck_02_box_base_lxWS { + displayName = SUBCSTRING(truck_02_racing_Name); + }; + class Truck_02_Ammo_base_lxWS: Truck_02_base_F { + displayName = SUBCSTRING(truck_02_ammo_Name); + }; + class Truck_02_flatbed_base_lxWS: Truck_02_cargo_base_lxWS { + displayName = SUBCSTRING(truck_02_flatbed_Name); + }; + + class Heli_Transport_02_base_F; + class B_UN_Heli_Transport_02_lxWS: Heli_Transport_02_base_F { + displayName = SUBCSTRING(heli_transport_02_Name); + }; + + class O_APC_Tracked_02_cannon_F; + class O_APC_Tracked_02_30mm_lxWS: O_APC_Tracked_02_cannon_F { + displayName = SUBCSTRING(apc_tracked_02_Name); + }; + + class APC_Wheeled_02_base_v2_F; + class APC_Wheeled_02_hmg_base_lxws: APC_Wheeled_02_base_v2_F { + displayName = SUBCSTRING(apc_wheeled_02_hmg_Name); + }; + class APC_Wheeled_02_unarmed_base_lxws: APC_Wheeled_02_base_v2_F { + displayName = SUBCSTRING(apc_wheeled_02_unarmed_Name); + }; + + class O_Heli_Light_02_dynamicLoadout_F; + class B_ION_Heli_Light_02_dynamicLoadout_lxWS: O_Heli_Light_02_dynamicLoadout_F { + displayName = SUBCSTRING(heli_light_02_armed_Name); + }; + + class O_Heli_Light_02_unarmed_F; + class B_ION_Heli_Light_02_unarmed_lxWS: O_Heli_Light_02_unarmed_F { + displayName = SUBCSTRING(heli_light_02_unarmed_Name); + }; +}; diff --git a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp index c09400a03c..e9cf3c6934 100644 --- a/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp +++ b/addons/compat_ws/compat_ws_realisticnames/CfgWeapons.hpp @@ -1,4 +1,6 @@ class CfgWeapons { + #include "Attachments.hpp" + // AA12 class sgun_aa40_base_lxWS; class sgun_aa40_lxWS: sgun_aa40_base_lxWS { @@ -99,6 +101,12 @@ class CfgWeapons { class arifle_SLR_V_camo_lxWS: arifle_SLR_V_lxWS { displayName = SUBCSTRING(SLR_Camo_Name); }; + class arifle_SLR_Para_lxWS: arifle_SLR_V_lxWS { + displayName = SUBCSTRING(SLR_Para_Name); + }; + class arifle_SLR_Para_snake_lxWS: arifle_SLR_Para_lxWS { + displayName = SUBCSTRING(SLR_Para_Snake_Name); + }; // Vektor R4/R5 class arifle_Velko_base_lxWS; @@ -156,4 +164,16 @@ class CfgWeapons { class arifle_XMS_M_Sand_lxWS: arifle_XMS_M_lxWS { displayName = SUBCSTRING(XMS_SW_Sand_Name); }; + + // GM6 Lynx + class srifle_GM6_F; + class srifle_GM6_snake_lxWS: srifle_GM6_F { + displayName = SUBCSTRING(gm6_snake_Name); + }; + + // RPG-32 + class launch_RPG32_F; + class launch_RPG32_tan_lxWS: launch_RPG32_F { + displayName = SUBCSTRING(rpg32_tan_Name); + }; }; diff --git a/addons/compat_ws/compat_ws_realisticnames/config.cpp b/addons/compat_ws/compat_ws_realisticnames/config.cpp index 5c8e166e00..0eb75926a8 100644 --- a/addons/compat_ws/compat_ws_realisticnames/config.cpp +++ b/addons/compat_ws/compat_ws_realisticnames/config.cpp @@ -19,3 +19,4 @@ class CfgPatches { }; #include "CfgWeapons.hpp" +#include "CfgVehicles.hpp" diff --git a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml index c2ed8ec9a1..606bbb7932 100644 --- a/addons/compat_ws/compat_ws_realisticnames/stringtable.xml +++ b/addons/compat_ws/compat_ws_realisticnames/stringtable.xml @@ -5,156 +5,318 @@ AA12 AA-12 AA12 + AA12 + AA12 + AA12 + AA12 + AA12 AA12 (Sand) AA-12 (모래) AA12 (Sand) + AA12 (Sabbia) + AA12 (サンド) + AA12 (Песочный) + AA12 (Sable) + AA12 (Arena) AA12 (Snake) AA-12 (뱀 위장) AA12 (Schlange) + AA12 (Serpe) + AA12 (ヘビ柄迷彩) + AA12 (Змея) + AA12 (Serpiente) Galil ARM 갈릴 ARM Galil ARM + Galil ARM + ガリル ARM + Galil ARM + Galil ARM + Galil ARM Galil ARM (Old) 갈릴 ARM (낡음) Galil ARM (Alt) + Galil ARM (Vecchio) + ガリル ARM (古びた) + Galil ARM (Старый) + Galil ARM (Ancien) + Galil ARM (Vieja) GLX 160 GLX-160 GLX 160 + GLX-160 + GLX 160 + GLX 160 + GLX 160 + GLX 160 GLX 160 (Snake) GLX-160 (뱀 위장) GLX 160 (Schlange) + GLX-160 (Serpe) + GLX 160 (ヘビ柄迷彩) + GLX 160 (Змея) + GLX 160 (Serpiente) GLX 160 (Hex) GLX-160 (육각) GLX 160 (Hex) + GLX-160 (Hex) + GLX 160 (六角形迷彩) + GLX 160 (Гекс) + GLX 160 (Hex) + GLX 160 (Hex) GLX 160 (Green Hex) GLX-160 (초록육각) GLX 160 (Grün Hex) + GLX-160 (Hex Verde) + GLX 160 (緑六角形迷彩) + GLX 160 (Зеленый Гекс) + GLX 160 (Vert Hex) + GLX 160 (Hex Verde) GLX 160 (Camo) GLX-160 (위장) GLX 160 (Tarn) + GLX-160 (Mimetica) + GLX 160 (AAF迷彩) + GLX 160 (Камуфляж) + GLX 160 (Camo) + GLX 160 (Camo) GLX 160 (Sand) GLX-160 (모래) GLX 160 (Sand) + GLX-160 (Sabbia) + GLX 160 (サンド) + GLX 160 (Песочный) + GLX 160 (Sable) + GLX 160 (Arena) Mk14 Mod 1 EBR (Black) Mk.14 Mod 1 EBR (검정) Mk14 Mod 1 EBR (Schwarz) + Mk14 Mod 1 EBR (Nero) + Mk14 Mod 1 EBR (ブラック) + Mk14 Mod 1 EBR (Черный) + Mk14 Mod 1 EBR (Noir) + Mk14 Mod 1 EBR (Negra) Mk14 Mod 1 EBR (Snake) Mk.14 Mod 1 EBR (뱀 위장) Mk14 Mod 1 EBR (Schlange) + Mk14 Mod 1 EBR (Serpe) + Mk14 Mod 1 EBR (ヘビ柄迷彩) + Mk14 Mod 1 EBR (Змея) + Mk14 Mod 1 EBR (Serpiente) Vektor SS-77 벡터 SS-77 Vektor SS-77 + ヴェクター SS-77 + Vektor SS-77 + Vektor SS-77 + Vektor SS-77 Vektor SS-77 (Camo) 벡터 SS-77 (위장) Vektor SS-77 (Tarn) + Vektor SS-77 (Mimetica) + ヴェクター SS-77 (AAF迷彩) + Vektor SS-77 (Камуфляж) + Vektor SS-77 (Camo) + Vektor SS-77 (Camo) Vektor SS-77 (Hex) 벡터 SS-77 (육각) Vektor SS-77 (Hex) + Vektor SS-77 (Hex) + ヴェクター SS-77 (六角形迷彩) + Vektor SS-77 (гекс) + Vektor SS-77 (Hex) + Vektor SS-77 (Hex) Vektor SS-77 (Green Hex) 벡터 SS-77 (초록육각) Vektor SS-77 (Grün Hex) + Vektor SS-77 (Hex Verde) + ヴェクター SS-77 (緑六角形迷彩) + Vektor SS-77 (зеленый гекс) + Vektor SS-77 (VertHex) + Vektor SS-77 (Hex Verde) Vektor SS-77 (Desert) 벡터 SS-77 (사막) - Vektor SS-77 (Wüstet) + Vektor SS-77 (Wüste) + Vektor SS-77 (Deserto) + ヴェクター SS-77 (砂漠迷彩) + Vektor SS-77 (песочныйt) + Vektor SS-77 (Désert) + Vektor SS-77 (Desierto) Vektor SS-77 Compact 벡터 SS-77 단축형 Vektor SS-77 Kompakt + Vektor SS-77 Compatto + ヴェクター SS-77 コンパクト + Vektor SS-77 Compact + Vektor SS-77 Compacte + Vektor SS-77 Compacta Vektor SS-77 Compact (Snake) 벡터 SS-77 단축형 (뱀 위장) Vektor SS-77 Compact (Schlange) + Vektor SS-77 Compatto (Serpe) + ヴェクター SS-77 コンパクト (ヘビ柄迷彩) + Vektor SS-77 Compact (змея) + Vektor SS-77 Compacta (Serpiente) FN FAL 50.00 (Wood) FN FAL 50.00 (목재) FN FAL 50.00 (Holz) + FN FAL 50.00 (Legno) + FN FAL 50.00 (木製) + FN FAL 50.00 (лесной) + FN FAL 50.00 (Bois) + FN FAL 50.00 (Madera) FN FAL 50.00 GL (Wood) FN FAL 50.00 GL (목재) 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 GL (Bois) + FN FAL 50.00 GL (Madera) FN FAL 50.00 FN FAL 50.00 FN FAL 50.00 + FN FAL 50.00 + FN FAL 50.00 + FN FAL 50.00 + FN FAL 50.00 + FN FAL 50.00 FN FAL 50.00 GL FN FAL 50.00 GL FN FAL 50.00 GL + FN FAL 50.00 GL + 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) FN FAL 50.00 (사막) FN FAL 50.00 (Wüstet) + FN FAL 50.00 (Deserto) + FN FAL 50.00 (砂漠迷彩) + FN FAL 50.00 (песочный) + FN FAL 50.00 (Désert) + FN FAL 50.00 (Desierto) FN FAL 50.00 (Jungle) FN FAL 50.00 (정글) FN FAL 50,00 (Dschungel) + FN FAL 50,00 (Giungla) + FN FAL 50.00 (熱帯迷彩) + FN FAL 50.00 (джунгли) + FN FAL 50.00 (Jungle) + FN FAL 50.00 (Jungla) + + + FN FAL OSW Para + FN FAL OSW パラ + FN FAL OSW 파라 + FN FAL OSW Fallschirmjäger + FN FAL OSW Para + + + FN FAL OSW Para (Snake) + FN FAL OSW パラ (ヘビ柄迷彩) + FN FAL OSW 파라 (뱀 위장) + FN FAL OSW Fallschirmjäger (Schlange) + FN FAL OSW Para (Serpe) Vektor R4 벡터 R4 Vektor R4 + Vektor R4 + ヴェクター R4 + Vektor R4 + Vektor R4 + Vektor R4 Vektor R5 Carbine 벡터 R5 카빈 Vektor R5 Carbine + Vektor R5 Carabina + ヴェクター R5 カービン + Vektor R5 Carbine + Vektor R5 Carbine + Vektor R5 Carabina Vektor R5 Carbine GL 벡터 R5 카빈 GL Vektor R5 Carbine GL + Vektor R5 Carabina GL + ヴェクター R5 カービン GL + Vektor R5 Carbine GL + Vektor R5 Carbine GL + Vektor R5 Carabina GL Vektor R5 Carbine (Snake) 벡터 R5 카빈 (뱀 위장) Vektor R5 Carbine (Schlange) + Vektor R5 Carabina (Serpe) + ヴェクター R5 カービン (ヘビ柄迷彩) + Vektor R5 Carbine (Змея) + Vektor R5 Carabina (Serpiente) Vektor R5 Carbine GL (Snake) 벡터 R5 카빈 GL (뱀 위장) Vektor R5 Carbine GL (Schlange) + Vektor R5 Carabina GL (Serpe) + ヴェクター R5 カービン GL (ヘビ柄迷彩) + Vektor R5 Carbine GL (Змея) + Vektor R5 Carabina GL (Serpiente) XMS @@ -166,28 +328,31 @@ XMS XMS XMS + XMS XMS (Khaki) XMS (kaki) XMS (khaki) - XMS (kaki) + XMS (Cachi) XMS (Cáqui) XMS (caqui) XMS(卡其色) XMS (хаки) XMS (카키) + XMS (カーキ) XMS (Sand) XMS (sable) XMS (Sand) - XMS (sabbia) + XMS (Sabbia) XMS (Areia) XMS (arena) XMS(沙色) XMS (песочный) XMS (모래) + XMS (サンド) XMS GL @@ -199,28 +364,31 @@ XMS GL XMS GL XMS GL + XMS GL XMS GL (Khaki) XMS GL (kaki) XMS GL (khaki) - XMS GL (kaki) + XMS GL (Cachi) XMS GL (Cáqui) XMS GL (caqui) XMS GL(卡其色) XMS GL (хаки) XMS GL (카키) + XMS GL (カーキ) XMS GL (Sand) XMS GL (sable) XMS GL (Sand) - XMS GL (sabbia) + XMS GL (Sabbia) XMS GL (Areia) XMS GL (arena) XMS GL(沙色) XMS GL (песочный) XMS GL (모래) + XMS GL (サンド) XMS SG @@ -232,28 +400,31 @@ XMS SG XMS SG XMS SG + XMS SG XMS SG (Khaki) XMS SG (kaki) XMS SG (khaki) - XMS SG (kaki) + XMS SG (Cachi) XMS SG (Cáqui) XMS SG (caqui) XMS SG(卡其色) XMS SG (хаки) XMS SG (카키) + XMS SG (カーキ) XMS SG (Sand) XMS SG (sable) XMS SG (Sand) - XMS SG (sabbia) + XMS SG (Sabbia) XMS SG (Areia) XMS SG (arena) XMS SG(沙色) XMS SG (песочный) XMS SG (모래) + XMS SG (サンド) XMS SW @@ -265,28 +436,297 @@ XMS SW XMS SW XMS SW + XMS SW XMS SW (Khaki) XMS SW (kaki) XMS SW (khaki) - XMS SW (kaki) + XMS SW (Cachi) XMS SW (Cáqui) XMS SW (caqui) XMS SW(卡其色) XMS SW (хаки) XMS SW (카키) + XMS SW (カーキ) XMS SW (Sand) XMS SW (sable) XMS SW (Sand) - XMS SW (sabbia) + XMS SW (Sabbia) XMS SW (Areia) XMS SW (arena) XMS SW(沙色) XMS SW (песочный) XMS SW (모래) + XMS SW (サンド) + + + GM6 Lynx (Snake) + GM6 リンクス (ヘビ柄迷彩) + GM6 링스 (뱀 위장) + GM6 Lynx (Schlange) + GM6 Lynx (Serpe) + + + RPG-32 (Sand) + RPG-32 (サンド) + RPG-32 (모래) + RPG-32 (Sand) + RPG-32 (Sabbia) + + + ELCAN SpecterOS (Hex) + ELCAN SpecterOS (六角形迷彩) + 엘칸 스펙터OS (육각) + ELCAN SpecterOS (Hex) + ELCAN SpecterOS (Hex) + + + EOTech XPS3 (Snake) + EOTech XPS3 (ヘビ柄迷彩) + 이오텍 XPS3 (뱀 위장) + EOTech XPS3 (Schlange) + EOTech XPS3 (Serpe) + + + EOTech XPS3 SMG (Snake) + EOTech XPS3 SMG (ヘビ柄迷彩) + 이오텍 XPS3 SMG (뱀 위장) + EOTech XPS3 SMG (Schlange) + EOTech XPS3 SMG (Serpe) + + + Leupold Mark 4 HAMR (Arid) + Leupold Mark 4 HAMR (乾燥地帯迷彩) + 류폴드 마크 4 HAMR (건조) + Leupold Mark 4 HAMR (Trocken) + Leupold Mark 4 HAMR (Arido) + + + Leupold Mark 4 HAMR (Lush) + Leupold Mark 4 HAMR (緑地迷彩) + 류폴드 마크 4 HAMR (초목) + Leupold Mark 4 HAMR (Grün) + Leupold Mark 4 HAMR (Verdeggiante) + + + Leupold Mark 4 HAMR (Sand) + Leupold Mark 4 HAMR (サンド) + 류폴드 마크 4 HAMR (모래) + Leupold Mark 4 HAMR (Sand) + Leupold Mark 4 HAMR (Sabbia) + + + Leupold Mark 4 HAMR (Snake) + Leupold Mark 4 HAMR (ヘビ柄迷彩) + 류폴드 마크 4 HAMR (뱀 위장) + Leupold Mark 4 HAMR (Schlange) + Leupold Mark 4 HAMR (Serpe) + + + Aimpoint Micro R-1 (High, Black) + Aimpoint マイクロ R-1 (ハイマウント、ブラック) + 에임포인트 마이크로 R-1 (높음, 검정) + Aimpoint Micro R-1 (Hoch, Schwarz) + Aimpoint Micro R-1 (Alto, Nero) + + + Aimpoint Micro R-1 (High, Khaki) + Aimpoint マイクロ R-1 (ハイマウント、カーキ) + 에임포인트 마이크로 R-1 (높음, 카키) + Aimpoint Micro R-1 (Hoch, Khaki) + Aimpoint Micro R-1 (Alto, Cachi) + + + Aimpoint Micro R-1 (High, Sand) + Aimpoint マイクロ R-1 (ハイマウント、サンド) + 에임포인트 마이크로 R-1 (높음, 모래) + Aimpoint Micro R-1 (Hoch, Sand) + Aimpoint Micro R-1 (Alto, Sabbia) + + + Aimpoint Micro R-1 (High, Snake) + Aimpoint マイクロ R-1 (ハイマウント、ヘビ柄迷彩) + 에임포인트 마이크로 R-1 (높음, 뱀 위장) + Aimpoint Micro R-1 (Hoch, Schlange) + Aimpoint Micro R-1 (Alto, Serpe) + + + Aimpoint Micro R-1 (High, Arid) + Aimpoint マイクロ R-1 (ハイマウント、乾燥地帯迷彩) + 에임포인트 마이크로 R-1 (높음, 건조) + Aimpoint Micro R-1 (Hoch, Trocken) + Aimpoint Micro R-1 (Alto, Arido) + + + Aimpoint Micro R-1 (High, Lush) + Aimpoint マイクロ R-1 (ハイマウント、緑地迷彩) + 에임포인트 마이크로 R-1 (높음, 초목) + Aimpoint Micro R-1 (Hoch, Grün) + Aimpoint Micro R-1 (Alto, Verdeggiante) + + + Aimpoint Micro R-1 (High, Black/Sand) + Aimpoint マイクロ R-1 (ハイマウント、ブラック/サンド) + 에임포인트 마이크로 R-1 (높음, 검정/모래) + Aimpoint Micro R-1 (Hoch, Schwarz/Sand) + Aimpoint Micro R-1 (Alto, Nero/Sabbia) + + + Aimpoint Micro R-1 (Low, Black) + Aimpoint マイクロ R-1 (ローマウント、ブラック) + 에임포인트 마이크로 R-1 (낮음, 검정) + Aimpoint Micro R-1 (Tief, Schwarz) + Aimpoint Micro R-1 (Basso, Nero) + + + Aimpoint Micro R-1 (Low, Khaki) + Aimpoint マイクロ R-1 (ローマウント、カーキ) + 에임포인트 마이크로 R-1 (낮음, 카키) + Aimpoint Micro R-1 (Tief, Khaki) + Aimpoint Micro R-1 (Basso, Cachi) + + + Aimpoint Micro R-1 (Low, Sand) + Aimpoint マイクロ R-1 (ローマウント、サンド) + 에임포인트 마이크로 R-1 (낮음, 모래) + Aimpoint Micro R-1 (Tief, Sand) + Aimpoint Micro R-1 (Basso, Sabbia) + + + Aimpoint Micro R-1 (Low, Snake) + Aimpoint マイクロ R-1 (ローマウント、ヘビ柄迷彩) + 에임포인트 마이크로 R-1 (낮음, 뱀 위장) + Aimpoint Micro R-1 (Tief, Schlange) + Aimpoint Micro R-1 (Basso, Serpe) + + + Aimpoint Micro R-1 (Low, Arid) + Aimpoint マイクロ R-1 (ローマウント、乾燥地帯迷彩) + 에임포인트 마이크로 R-1 (낮음, 건조) + Aimpoint Micro R-1 (Tief, Trocken) + Aimpoint Micro R-1 (Basso, Arido) + + + Aimpoint Micro R-1 (Low, Lush) + Aimpoint マイクロ R-1 (ローマウント、緑地迷彩) + 에임포인트 마이크로 R-1 (낮음, 초목) + Aimpoint Micro R-1 (Tief, Grün) + Aimpoint Micro R-1 (Basso, Verdeggiante) + + + Burris XTR II (Snake) + Burris XTR II (ヘビ柄迷彩) + 버리스 XTR II (뱀 위장) + Burris XTR II (Schlange) + Burris XTR II (Serpe) + + + Badger IFV (ATGM) + バジャー IFV (ATGM) + 뱃져 보병전투차 (대전차미사일) + Badger IFV (PzAbw) + Badger IFV (ATGM) + + + Badger IFV (Command) + バジャー IFV (指揮) + 뱃져 보병전투차 (지휘) + Badger IFV (Kommando) + Badger IFV (Comando) + + + Badger IFV (Mortar) + バジャー IFV (迫撃砲) + 뱃져 보병전투차 (자주박격포) + Badger IFV (Mörser) + Badger IFV (Mortaio) + + + KamAZ (Zu-23-2) + KamAZ (Zu-23-2) + 카마즈 (ZU-23-2) + KamAZ (Zu-23-2) + KamAZ (Zu-23-2) + + + KamAZ Cargo + KamAZ 貨物 + 카마즈 화물 + KamAZ Fracht + KamAZ Carico + + + KamAZ Repair + KamAZ 修理 + 카마즈 정비 + KamAZ Instandsetzung + KamAZ Riparazione + + + KamAZ Racing + KamAZ レース仕様 + 카마즈 경주용 + KamAZ Rennlaster + KamAZ da corsa + + + KamAZ Ammo + KamAZ 弾薬 + 카마즈 탄약 + KamAZ Munition + KamAZ Munizioni + + + KamAZ Flatbed + KamAZ フラットベッド + 카마즈 플랫베드 + KamAZ Flachbett + KamAZ Pianale + + + AW101 Merlin + AW101 マーリン + AW101 멀린 + AW101 Merlin + AW101 Merlin + + + BM-2T Stalker (Bumerang-BM) + BM-2T ストーカー (ブーメランク-BM) + BM-2T 스토커 (부메랑-BM) + BM-2T Stalker (Bumerang-BM) + BM-2T Stalker (Bumerang-BM) + + + Otokar ARMA (HMG) + オトカ アルマ (HMG) + 오토카르 아르마 APC (중기관총) + Otokar ARMA (HMG) + Otokar ARMA (HMG) + + + Otokar ARMA (Unarmed) + オトカ アルマ (非武装) + 오토카르 아르마 APC (비무장) + Otokar ARMA (Unbewaffnet) + Otokar ARMA (Disarmato) + + + Ka-60 Kasatka (UP) + Ka-60 カサートカ (UP) + Ka-60 카사트카 (UP) + Ka-60 Kasatka (UP) + Ka-60 Kasatka (UP) + + + Ka-60 Kasatka (UP, Unarmed) + Ka-60 カサートカ (UP、非武装) + Ka-60 카사트카 (UP, 비무장)) + Ka-60 Kasatka (UP, Unbewaffnet) + Ka-60 Kasatka (UP, Disarmato) diff --git a/addons/concertina_wire/XEH_postInit.sqf b/addons/concertina_wire/XEH_postInit.sqf index 7cb8909c81..bb3f022534 100644 --- a/addons/concertina_wire/XEH_postInit.sqf +++ b/addons/concertina_wire/XEH_postInit.sqf @@ -10,4 +10,4 @@ GVAR(deployPFH) = -1; }; }] call CBA_fnc_addEventHandler; -[QGVAR(vehicleDamage), {_this call FUNC(vehicleDamage)}] call CBA_fnc_addEventHandler; +[QGVAR(vehicleDamage), LINKFUNC(vehicleDamage)] call CBA_fnc_addEventHandler; diff --git a/addons/concertina_wire/functions/fnc_deploy.sqf b/addons/concertina_wire/functions/fnc_deploy.sqf index 579bc73f97..c915109e1b 100644 --- a/addons/concertina_wire/functions/fnc_deploy.sqf +++ b/addons/concertina_wire/functions/fnc_deploy.sqf @@ -22,7 +22,7 @@ params ["_wirecoil", "_unit"]; private _wireNoGeo = "ACE_ConcertinaWireNoGeo" createVehicle [0,0,0]; { _wireNoGeo animate [_x, 1]; -} count WIRE_FAST; +} forEach WIRE_FAST; GVAR(placer) = _unit; private _dir = getDir _unit; @@ -51,7 +51,7 @@ GVAR(deployPFH) = [{ private _wire = "ACE_ConcertinaWire" createvehicle [0, 0, 0]; { _wire animate [_x, _anim]; - } count WIRE_FAST; + } forEach WIRE_FAST; [{ params ["_args", "_idPFH"]; @@ -74,7 +74,7 @@ GVAR(deployPFH) = [{ _wireNoGeo setDir _dir; { _wireNoGeo animate [_x, _anim]; - } count WIRE_FAST; + } forEach WIRE_FAST; }, 0, [_wireNoGeo, _wireNoGeoPos, _unit]] call CBA_fnc_addPerFrameHandler; [LLSTRING(RollWire), "", ""] call EFUNC(interaction,showMouseHint); diff --git a/addons/concertina_wire/functions/fnc_dismountSuccess.sqf b/addons/concertina_wire/functions/fnc_dismountSuccess.sqf index 3a90b62a91..86aac9e8bf 100644 --- a/addons/concertina_wire/functions/fnc_dismountSuccess.sqf +++ b/addons/concertina_wire/functions/fnc_dismountSuccess.sqf @@ -20,7 +20,7 @@ params ["_wire"]; { _wire animate [_x, 1]; -} count WIRE_FAST; +} forEach WIRE_FAST; [{ params ["_args", "_idPFH"]; diff --git a/addons/concertina_wire/functions/fnc_handleDamage.sqf b/addons/concertina_wire/functions/fnc_handleDamage.sqf index 02092044ef..f5f1177df5 100644 --- a/addons/concertina_wire/functions/fnc_handleDamage.sqf +++ b/addons/concertina_wire/functions/fnc_handleDamage.sqf @@ -22,7 +22,7 @@ params ["_wire", "", "_damage", "_source", ""]; if (_damage < 0.5) exitWith { 0 }; -if (!(isNull _source)) then { +if (!isNull _source) then { _wire setVariable [QGVAR(lastDamager), _source]; }; diff --git a/addons/concertina_wire/stringtable.xml b/addons/concertina_wire/stringtable.xml index e0fd904086..603cc5a7a8 100644 --- a/addons/concertina_wire/stringtable.xml +++ b/addons/concertina_wire/stringtable.xml @@ -9,7 +9,7 @@ Alambre de espino Fil barbelé Ostnatý drát - Filo a concertina + Filo spinato NATO Concertina wire Arame farpado 鉄条網 @@ -26,11 +26,11 @@ Bobina de alambre de espino Bobine de fil barbelé Svitek ostnatého drátu - Bobina di filo a concertina + Bobina di filo spinato NATO Concertina wire coil Bobina de arame farpado 鉄条網コイル - 코일형 철조망 + 윤형철조망 鐵絲網捲 铁丝网卷 Bıçaklı Tel Rulo @@ -43,7 +43,7 @@ Desmontar alambre de espino Démontage du fil barbelé... Svinout ostnatý drát - Smonta il filo a concertina + Smonta il filo spinato NATO Dismount Concertina wire Desmontar arame farpado 鉄条網をほどく @@ -60,7 +60,7 @@ Desplegar alambre de espino Mettre en place le fil barbelé Rozvinout ostnatý drát - Piazza il filo a concertina + Piazza il filo spinato NATO Deploy Concertina wire Colocar arame farpado 鉄条網を置く diff --git a/addons/cookoff/ACE_Settings.hpp b/addons/cookoff/ACE_Settings.hpp index ba4447dba9..37594bed51 100644 --- a/addons/cookoff/ACE_Settings.hpp +++ b/addons/cookoff/ACE_Settings.hpp @@ -1,12 +1,8 @@ - class ACE_Settings { - class GVAR(enable) { - movedToSqf = 1; - }; class GVAR(enableAmmobox) { movedToSQF = 1; }; - class GVAR(enableAmmoCookoff) { // For CBA Setting Switch: we can eliminate and just use (ammoCookoffDuration == 0) + class GVAR(enableAmmoCookoff) { movedToSQF = 1; }; class GVAR(ammoCookoffDuration) { diff --git a/addons/cookoff/CfgCloudlets.hpp b/addons/cookoff/CfgCloudlets.hpp index c167177705..a328451a7b 100644 --- a/addons/cookoff/CfgCloudlets.hpp +++ b/addons/cookoff/CfgCloudlets.hpp @@ -1,4 +1,3 @@ - class CfgCloudlets { class GVAR(CookOff) { interval = 0.004; diff --git a/addons/cookoff/CfgEden.hpp b/addons/cookoff/CfgEden.hpp index 2b58daa304..f973ef4026 100644 --- a/addons/cookoff/CfgEden.hpp +++ b/addons/cookoff/CfgEden.hpp @@ -1,28 +1,27 @@ - class Cfg3DEN { class Object { class AttributeCategories { class ace_attributes { class Attributes { - class GVAR(enable) { - property = QGVAR(enable); + class GVAR(enable) { // setting was previously GVAR(enable), so maintain for backwards compatiblity with missions + property = QGVAR(enable); // same as above control = "Checkbox"; - displayName = CSTRING(enable_hd_name); - tooltip = CSTRING(enable_hd_tooltip); - expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + displayName = CSTRING(enableFire_name); + tooltip = CSTRING(enableFire_tooltip); + expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]}); typeName = "BOOL"; condition = "objectVehicle"; - defaultValue = QUOTE((GETMVAR(QGVAR(enable),0)) in [ARR_2(1,2)]); + defaultValue = QUOTE(GETMVAR(QGVAR(enableFire),true)); }; class GVAR(enableAmmoCookoff) { property = QGVAR(enableAmmoCookoff); control = "Checkbox"; displayName = CSTRING(enableAmmoCookoff_name); tooltip = CSTRING(enableAmmoCookoff_tooltip); - expression = QUOTE(if !(_value) then {_this setVariable [ARR_3('%s',_value,true)];};); + expression = QUOTE(if (!_value) then {_this setVariable [ARR_3('%s',_value,true)]}); typeName = "BOOL"; condition = "objectHasInventoryCargo"; - defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then { GETMVAR(QGVAR(enableAmmobox),true) } else { GETMVAR(QGVAR(enableAmmoCookoff),true) };); + defaultValue = QUOTE(if (_this isKindOf 'ReammoBox_F') then {GETMVAR(QGVAR(enableAmmobox),true)} else {GETMVAR(QGVAR(enableAmmoCookoff),true)}); }; }; }; diff --git a/addons/cookoff/CfgEventHandlers.hpp b/addons/cookoff/CfgEventHandlers.hpp index 6c29240403..f6503c2479 100644 --- a/addons/cookoff/CfgEventHandlers.hpp +++ b/addons/cookoff/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/cookoff/CfgSFX.hpp b/addons/cookoff/CfgSFX.hpp index 0d670ead86..24329862fc 100644 --- a/addons/cookoff/CfgSFX.hpp +++ b/addons/cookoff/CfgSFX.hpp @@ -1,4 +1,3 @@ - class CfgSFX { class GVAR(CookOff_low) { name = QGVAR(cookoff_low); diff --git a/addons/cookoff/CfgSounds.hpp b/addons/cookoff/CfgSounds.hpp new file mode 100644 index 0000000000..70d752d613 --- /dev/null +++ b/addons/cookoff/CfgSounds.hpp @@ -0,0 +1,66 @@ +#define VOLUME 2 +#define PITCH 1 + +#define SHOTSOUND(type,dist,N,maxDistance)\ +class GVAR(TRIPLES(type,dist,N)) {\ + sound[] = {QPATHTOF(sounds\type\DOUBLES(dist,N).wss), VOLUME, PITCH, maxDistance};\ + titles[] = {};\ +} + +#define SHOTSOUNDCLASS(type,dist,maxDistance)\ +SHOTSOUND(type,dist,1,maxDistance);\ +SHOTSOUND(type,dist,2,maxDistance);\ +SHOTSOUND(type,dist,3,maxDistance) + +#define SHOTSOUNDCLASSTYPE(type,maxDistance)\ +SHOTSOUNDCLASS(type,close,maxDistance);\ +SHOTSOUNDCLASS(type,mid,maxDistance);\ +SHOTSOUNDCLASS(type,far,maxDistance) + +// Allows other mods to change sounds for cook-off +class CfgSounds { + // These macros set up the sounds for the various classes + SHOTSOUNDCLASSTYPE(shotbullet,1250); + SHOTSOUNDCLASSTYPE(shotrocket,1600); + SHOTSOUNDCLASSTYPE(shotshell,1300); + + // Missiles use the same sounds as rockets + class GVAR(shotmissile_close_1): GVAR(shotrocket_close_1) {}; + class GVAR(shotmissile_close_2): GVAR(shotrocket_close_2) {}; + class GVAR(shotmissile_close_3): GVAR(shotrocket_close_3) {}; + class GVAR(shotmissile_mid_1): GVAR(shotrocket_mid_1) {}; + class GVAR(shotmissile_mid_2): GVAR(shotrocket_mid_2) {}; + class GVAR(shotmissile_mid_3): GVAR(shotrocket_mid_3) {}; + class GVAR(shotmissile_far_1): GVAR(shotrocket_far_1) {}; + class GVAR(shotmissile_far_2): GVAR(shotrocket_far_2) {}; + class GVAR(shotmissile_far_3): GVAR(shotrocket_far_3) {}; + + // Submunitions have the same sound as bullets, but a higher maxDistance + class GVAR(shotsubmunitions_close_1): GVAR(shotbullet_close_1) { + sound[] = {QPATHTOF(sounds\shotbullet\close_1.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_close_2): GVAR(shotbullet_close_2) { + sound[] = {QPATHTOF(sounds\shotbullet\close_2.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_close_3): GVAR(shotbullet_close_3) { + sound[] = {QPATHTOF(sounds\shotbullet\close_3.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_mid_1): GVAR(shotbullet_mid_1) { + sound[] = {QPATHTOF(sounds\shotbullet\mid_1.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_mid_2): GVAR(shotbullet_mid_2) { + sound[] = {QPATHTOF(sounds\shotbullet\mid_2.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_mid_3): GVAR(shotbullet_mid_3) { + sound[] = {QPATHTOF(sounds\shotbullet\mid_3.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_far_1): GVAR(shotbullet_far_1) { + sound[] = {QPATHTOF(sounds\shotbullet\far_1.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_far_2): GVAR(shotbullet_far_2) { + sound[] = {QPATHTOF(sounds\shotbullet\far_2.wss), VOLUME, PITCH, 1600}; + }; + class GVAR(shotsubmunitions_far_3): GVAR(shotbullet_far_3) { + sound[] = {QPATHTOF(sounds\shotbullet\far_3.wss), VOLUME, PITCH, 1600}; + }; +}; diff --git a/addons/cookoff/CfgVehicles.hpp b/addons/cookoff/CfgVehicles.hpp index 78cbd0c623..4451d12080 100644 --- a/addons/cookoff/CfgVehicles.hpp +++ b/addons/cookoff/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class Sound; class GVAR(Sound_low): Sound { @@ -7,7 +6,6 @@ class CfgVehicles { scope = 1; sound = QGVAR(CookOff_low); }; - class GVAR(Sound_mid): GVAR(Sound_low) { sound = QGVAR(CookOff_mid); }; @@ -17,47 +15,14 @@ class CfgVehicles { class Tank; class Tank_F: Tank { - GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; - GVAR(probability) = 0.5; - }; - class MBT_02_base_F: Tank_F { - GVAR(ammoLocation) = "HitTurret"; }; class Car_F; class Wheeled_APC_F: Car_F { - GVAR(ammoLocation) = "HitHull"; GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"}; - GVAR(probability) = 0.8; - // big explosions for wheeled APCs (same as for tanks) + // Big explosions for wheeled APCs (same as for tanks) explosionEffect = "FuelExplosionBig"; }; - - - class MRAP_01_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class MRAP_02_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class MRAP_03_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,-2,0}; - }; - - class Quadbike_01_base_F: Car_F { - GVAR(engineSmokeOffset)[] = {0,1,0}; - }; - - class Truck_F; - class Truck_02_base_F: Truck_F { - GVAR(engineSmokeOffset)[] = {0,-2.6,-0.1}; - }; - - class Truck_02_MRL_base_F: Truck_02_base_F { - GVAR(engineSmokeOffset)[] = {0,0.3,-0.1}; - }; }; diff --git a/addons/cookoff/XEH_PREP.hpp b/addons/cookoff/XEH_PREP.hpp index 2cd87efaa7..9405908953 100644 --- a/addons/cookoff/XEH_PREP.hpp +++ b/addons/cookoff/XEH_PREP.hpp @@ -1,10 +1,12 @@ - -PREP(handleDamageBox); -PREP(engineFire); -PREP(cookOff); -PREP(smoke); -PREP(cookOffEffect); -PREP(cookOffBox); -PREP(detonateAmmunition); +PREP(cookOffBoxLocal); +PREP(cookOffBoxServer); +PREP(cookOffLocal); +PREP(cookOffServer); +PREP(detonateAmmunitionServer); +PREP(detonateAmmunitionServerLoop); +PREP(engineFireLocal); +PREP(engineFireServer); PREP(getVehicleAmmo); +PREP(handleDamageBox); PREP(isMagazineFlare); +PREP(smoke); diff --git a/addons/cookoff/XEH_postInit.sqf b/addons/cookoff/XEH_postInit.sqf index b9c8101595..63e1486c82 100644 --- a/addons/cookoff/XEH_postInit.sqf +++ b/addons/cookoff/XEH_postInit.sqf @@ -1,60 +1,100 @@ #include "script_component.hpp" -[QGVAR(engineFire), FUNC(engineFire)] call CBA_fnc_addEventHandler; -[QGVAR(cookOff), { - params ["_vehicle"]; - if (local _vehicle) then { - _this call FUNC(cookOff); - }; -}] call CBA_fnc_addEventHandler; -[QGVAR(cookOffEffect), FUNC(cookOffEffect)] call CBA_fnc_addEventHandler; -[QGVAR(smoke), FUNC(smoke)] call CBA_fnc_addEventHandler; -[QGVAR(cookOffBox), FUNC(cookOffBox)] call CBA_fnc_addEventHandler; +[QGVAR(cookOffBoxLocal), LINKFUNC(cookOffBoxLocal)] call CBA_fnc_addEventHandler; +[QGVAR(cookOffLocal), LINKFUNC(cookOffLocal)] call CBA_fnc_addEventHandler; +[QGVAR(engineFireLocal), LINKFUNC(engineFireLocal)] call CBA_fnc_addEventHandler; +[QGVAR(smoke), LINKFUNC(smoke)] call CBA_fnc_addEventHandler; -// handle cleaning up effects when vehicle is deleted mid-cookoff -[QGVAR(addCleanupHandlers), { - params ["_vehicle"]; - - // Don't add a new EH if cookoff is run multiple times - if ((_vehicle getVariable [QGVAR(deletedEH), -1]) == -1) then { - private _deletedEH = _vehicle addEventHandler ["Deleted", { - params ["_vehicle"]; - - [QGVAR(cleanupEffects), [_vehicle]] call CBA_fnc_localEvent; - }]; - - _vehicle setVariable [QGVAR(deletedEH), _deletedEH]; - }; -}] call CBA_fnc_addEventHandler; +if (isServer) then { + [QGVAR(cookOffBoxServer), LINKFUNC(cookOffBoxServer)] call CBA_fnc_addEventHandler; + [QGVAR(cookOffServer), LINKFUNC(cookOffServer)] call CBA_fnc_addEventHandler; + [QGVAR(detonateAmmunitionServer), LINKFUNC(detonateAmmunitionServer)] call CBA_fnc_addEventHandler; + [QGVAR(engineFireServer), LINKFUNC(engineFireServer)] call CBA_fnc_addEventHandler; +}; +// Handle cleaning up effects when objects are deleted mid cook-off +["AllVehicles", "Deleted", { + { + deleteVehicle _x; + } forEach ((_this select 0) getVariable [QGVAR(effects), []]); +}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler; + +["ReammoBox_F", "Deleted", { + { + deleteVehicle _x; + } forEach ((_this select 0) getVariable [QGVAR(effects), []]); +}, true, [], true] call CBA_fnc_addClassEventHandler; + +// Raised when the flames have subsided or after the ammo of a box has finished cooking off [QGVAR(cleanupEffects), { - params ["_vehicle", ["_effects", []]]; + params ["_object"]; - _effects = _effects + (_vehicle getVariable [QGVAR(effects), []]); - if (_effects isNotEqualTo []) then { - { deleteVehicle _x } count _effects; - }; + { + deleteVehicle _x; + } forEach (_object getVariable [QGVAR(effects), []]); + + _object setVariable [QGVAR(effects), nil]; }] call CBA_fnc_addEventHandler; +// Ammo box damage handling ["ReammoBox_F", "init", { - (_this select 0) addEventHandler ["HandleDamage", { - if ((_this select 0) getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmobox)]) then { - _this call FUNC(handleDamageBox); - }; - }]; -}, nil, nil, true] call CBA_fnc_addClassEventHandler; + // Calling this function inside curly brackets allows the usage of "exitWith", which would be broken with "HandleDamage" otherwise + (_this select 0) addEventHandler ["HandleDamage", {_this call FUNC(handleDamageBox)}]; +}, true, [], true] call CBA_fnc_addClassEventHandler; + +// Vehicle ammo cook-off (secondary explosions) +["AllVehicles", "Killed", { + if (!GVAR(enableAmmoCookoff) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; -// secondary explosions -["AllVehicles", "killed", { params ["_vehicle", "", "", "_useEffects"]; - if ( - _useEffects && - _vehicle getVariable [QGVAR(enableAmmoCookoff), GVAR(enableAmmoCookoff)] - ) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_vehicle] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - private _delay = (random MAX_AMMO_DETONATION_START_DELAY) max MIN_AMMO_DETONATION_START_DELAY; - [FUNC(detonateAmmunition), [_vehicle, _mags, _total], _delay] call CBA_fnc_waitAndExecute; + if (_useEffects && {_vehicle getVariable [QGVAR(enableAmmoCookoff), true]}) then { + // We don't need to pass source and instigator, as vehicle is already dead + [QGVAR(detonateAmmunitionServer), [ + _vehicle, + false, + objNull, + objNull, + random [MIN_AMMO_DETONATION_START_DELAY, (MIN_AMMO_DETONATION_START_DELAY + MAX_AMMO_DETONATION_START_DELAY) / 2, MAX_AMMO_DETONATION_START_DELAY] + ]] call CBA_fnc_serverEvent; }; -}, nil, ["Man","StaticWeapon"]] call CBA_fnc_addClassEventHandler; +}, true, ["CAManBase", "StaticWeapon"], true] call CBA_fnc_addClassEventHandler; + +if (hasInterface) then { + // Plays a sound locally, so that different sounds can be used for various distances + [QGVAR(playCookoffSound), { + params ["_object", "_sound"]; + + if (isNull _object) exitWith {}; + + private _distance = _object distance (positionCameraToWorld [0, 0, 0]); + + TRACE_2("",_object,_sound); + + // 3 classes of distances: close, mid and far, each having different sound files + private _classDistance = switch (true) do { + case (_distance < DISTANCE_CLOSE): {"close"}; + case (_distance < DISTANCE_MID): {"mid"}; + default {"far"}; + }; + + _sound = format [QGVAR(%1_%2_%3), _sound, _classDistance, floor (random 3) + 1]; + + TRACE_1("",_sound); + + // Allows other mods to change sounds for cook-off + _sound = getArray (configFile >> "CfgSounds" >> _sound >> "sound"); + + if (_sound isEqualTo []) exitWith {}; + + _sound params ["_sound", "_volume", "_pitch", "_maxDistance"]; + + if (_distance > _maxDistance) exitWith {}; + + // Make sure file exists, so RPT isn't spammed with non-existent entry errors + if (!fileExists _sound) exitWith {}; + + // Obeys speed of sound and takes doppler effects into account + playSound3D [_sound, objNull, false, getPosASL _object, _volume, _pitch + (random 0.2) - 0.1, _maxDistance, 0, true]; + }] call CBA_fnc_addEventHandler; +}; diff --git a/addons/cookoff/XEH_preInit.sqf b/addons/cookoff/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/cookoff/XEH_preInit.sqf +++ b/addons/cookoff/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/cookoff/config.cpp b/addons/cookoff/config.cpp index 4fba15f5e1..dc7a472855 100644 --- a/addons/cookoff/config.cpp +++ b/addons/cookoff/config.cpp @@ -21,4 +21,5 @@ class CfgPatches { #include "CfgAmmo.hpp" #include "CfgCloudlets.hpp" #include "CfgSFX.hpp" +#include "CfgSounds.hpp" #include "CfgVehicles.hpp" diff --git a/addons/cookoff/functions/fnc_cookOff.sqf b/addons/cookoff/functions/fnc_cookOff.sqf deleted file mode 100644 index 1d598cdb96..0000000000 --- a/addons/cookoff/functions/fnc_cookOff.sqf +++ /dev/null @@ -1,129 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Start a cook-off in the given vehicle. - * - * Arguments: - * 0: Vehicle - * 1: Intensity of fire - * - * Return Value: - * None - * - * Example: - * [(vehicle player), 3] call ace_cookoff_fnc_cookOff - * - * Public: No - */ - -params ["_vehicle", "_intensity", ["_instigator", objNull], ["_smokeDelayEnabled", true], ["_ammoDetonationChance", 0], ["_detonateAfterCookoff", false], ["_fireSource", ""], ["_canRing", true], ["_maxIntensity", MAX_COOKOFF_INTENSITY, [0]], ["_canJet", true, [true]]]; - -if (GVAR(enable) == 0) exitWith {}; -if !(GVAR(enableFire)) exitWith {}; -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith {}; -// exit if cook-off enabled only for players and no players in vehicle crew found -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] isEqualTo 1 && {fullCrew [_vehicle, "", false] findIf {isPlayer (_x select 0)} == -1}) exitWith {}; - - -TRACE_2("cooking off",_vehicle,_intensity); -TRACE_8("",_instigator,_smokeDelayEnabled,_ammoDetonationChance,_detonateAfterCookoff,_fireSource,_canRing,_maxIntensity,_canJet); - -if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; -_vehicle setVariable [QGVAR(isCookingOff), true, true]; - -[QGVAR(addCleanupHandlers), [_vehicle]] call CBA_fnc_globalEvent; - -// limit maximum value of intensity to prevent very long cook-off times -_intensity = _intensity min _maxIntensity; - -private _config = _vehicle call CBA_fnc_getObjectConfig; -private _positions = getArray (_config >> QGVAR(cookoffSelections)) select {(_vehicle selectionPosition _x) isNotEqualTo [0,0,0]}; - -if (_positions isEqualTo []) then { - WARNING_1("no valid selection for cookoff found. %1",typeOf _vehicle); - { - private _pos = _vehicle selectionPosition _x; - if (_pos isEqualTo [0, 0, 0]) exitWith {}; - _positions pushBack _x; - } forEach DEFAULT_COMMANDER_HATCHES; - - if (_positions isEqualTo []) then { - _positions pushBack "#noselection"; - }; -}; - -private _delay = 0; -if (_smokeDelayEnabled) then { - _delay = SMOKE_TIME + random SMOKE_TIME; -}; -[QGVAR(smoke), [_vehicle, _positions]] call CBA_fnc_globalEvent; - -[{ - params ["_vehicle", "_positions", "_intensity", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet"]; - _vehicle setVariable [QGVAR(intensity), _intensity]; - private _smokeEffects = _vehicle getVariable [QGVAR(effects), []]; - - [{ - params ["_args", "_pfh"]; - _args params ["_vehicle", "_positions", "_ammoDetonationChance", "_detonateAfterCookoff", "_instigator", "_fireSource", "_canRing", "_canJet", "_smokeEffects"]; - private _intensity = _vehicle getVariable [QGVAR(intensity), 0]; - if (isNull _vehicle || {_intensity <= 1}) exitWith { - [QGVAR(cleanupEffects), [_vehicle, _smokeEffects]] call CBA_fnc_globalEvent; - _vehicle setVariable [QGVAR(isCookingOff), false, true]; - [_pfh] call CBA_fnc_removePerFrameHandler; - - if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) then { - _vehicle setDamage [1, true]; - }; - }; - - private _lastFlameTime = _vehicle getVariable [QGVAR(lastFlame), 0]; - private _nextFlameTime = _vehicle getVariable [QGVAR(nextFlame), 0]; - - // Wait until we are ready for the next flame - // dt = Tcurrent - Tlast - // dt >= Tnext - if ((CBA_missionTime - _lastFlameTime) >= _nextFlameTime) then { - private _ring = (0.2 > random 1); - if (!_ring && _intensity >= 2) then { - _ring = (0.7 > random 1); - }; - - if !(_canRing) then { - _ring = false; - }; - - private _time = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME; - - if (_fireSource isEqualTo "") then { - _fireSource = selectRandom _positions; - }; - - [QGVAR(cookOffEffect), [_vehicle, _canJet, _ring, _time, _fireSource, _intensity]] call CBA_fnc_globalEvent; - - _intensity = _intensity - (0.5 max random 1); - _vehicle setVariable [QGVAR(intensity), _intensity]; - _vehicle setVariable [QGVAR(lastFlame), CBA_missionTime]; - _vehicle setVariable [QGVAR(nextFlame), _time + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)]; - - { - [QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator]] call CBA_fnc_globalEvent; - } forEach crew _vehicle - }; - - if (_ammoDetonationChance > random 1) then { - private _lastExplosiveDetonationTime = _vehicle getVariable [QGVAR(lastExplosiveDetonation), 0]; - private _nextExplosiveDetonation = _vehicle getVariable [QGVAR(nextExplosiveDetonation), 0]; - - if ((CBA_missionTime - _lastExplosiveDetonationTime) > _nextExplosiveDetonation) then { - if (_fireSource isEqualTo "") then { - _fireSource = selectRandom _positions; - }; - createVehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld (_vehicle selectionPosition _fireSource)), [], 0 , "CAN_COLLIDE"]; - - _vehicle setVariable [QGVAR(lastExplosiveDetonation), CBA_missionTime]; - _vehicle setVariable [QGVAR(nextExplosiveDetonation), random 60]; - }; - }; - }, 0.25, [_vehicle, _positions, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet, _smokeEffects]] call CBA_fnc_addPerFrameHandler -}, [_vehicle, _positions, _intensity, _ammoDetonationChance, _detonateAfterCookoff, _instigator, _fireSource, _canRing, _canJet], _delay] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBox.sqf b/addons/cookoff/functions/fnc_cookOffBox.sqf deleted file mode 100644 index 8b8e60891c..0000000000 --- a/addons/cookoff/functions/fnc_cookOffBox.sqf +++ /dev/null @@ -1,74 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: KoffeinFlummi, commy2, kymckay - * Start a cook-off in the given ammo box. - * - * Arguments: - * 0: Ammo box - * - * Return Value: - * None - * - * Example: - * [_box] call ace_cookoff_fnc_cookOffBox - * - * Public: No - */ - -params ["_box"]; - -if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; -_box setVariable [QGVAR(isCookingOff), true]; - -if (local _box) then { - [QGVAR(cookOffBox), _box] call CBA_fnc_globalEvent; -}; - -[{ - params ["_box"]; - - // Box will start smoking - private _smoke = "#particlesource" createVehicleLocal [0,0,0]; - _smoke setParticleClass "AmmoSmokeParticles2"; - _smoke attachTo [_box, [0,0,0]]; - - private _effects = [_smoke]; - - if (isServer) then { - private _sound = createSoundSource ["Sound_Fire", position _box, [], 0]; - _effects pushBack _sound; - }; - - [{ - params ["_box", "_effects"]; - - // These functions are smart and do all the cooking off work - if (local _box) then { - if (GVAR(ammoCookoffDuration) == 0) exitWith {}; - ([_box] call FUNC(getVehicleAmmo)) params ["_mags", "_total"]; - [_box, _mags, _total] call FUNC(detonateAmmunition); - - // This shit is busy being on fire, magazines aren't accessible/usable - clearMagazineCargoGlobal _box; - }; - - // Light the fire (also handles lighting) - private _fire = "#particlesource" createVehicleLocal [0,0,0]; - _fire setParticleClass "AmmoBulletCore"; - _fire attachTo [_box, [0,0,0]]; - - _effects pushBack _fire; - - [{ - params ["_box", "_effects"]; - - { - deleteVehicle _x; - } forEach _effects; - - if (local _box) then { - _box setDamage 1; - }; - }, [_box, _effects], COOKOFF_TIME_BOX] call CBA_fnc_waitAndExecute; // TODO: Change so that box is alive until no ammo left, with locality in mind - }, [_box, _effects], SMOKE_TIME] call CBA_fnc_waitAndExecute; -}, _box, IGNITE_TIME] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf new file mode 100644 index 0000000000..8285104daf --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffBoxLocal.sqf @@ -0,0 +1,52 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, kymckay, johnb43 + * Spawns local cook-off effects for ammo boxes. + * + * Arguments: + * 0: Box + * 1: Source + * 2: Instigator + * 3: Start time of the cook-off + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player, CBA_missionTime + 10] call ace_cookoff_fnc_cookOffBoxLocal + * + * Public: No + */ + +params ["", "", "", "_startTime"]; + +[{ + params ["_box", "_source", "_instigator"]; + + // If box was deleted before smoke could be spawned, just exit + if (isNull _box) exitWith {}; + + private _boxPos = ASLToAGL getPosASL _box; + private _effects = []; + + // Box will start smoking + if (hasInterface) then { + private _smoke = createVehicleLocal ["#particlesource", _boxPos, [], 0, "CAN_COLLIDE"]; + _smoke setParticleClass "AmmoSmokeParticles2"; + _smoke attachTo [_box]; + + _effects pushBack _smoke; + }; + + if (isServer) then { + private _sound = createSoundSource ["Sound_Fire", _boxPos, [], 0]; + _sound attachTo [_box]; + + _effects pushBack _sound; + + // Detonate the ammunition + [QGVAR(detonateAmmunitionServer), [_box, true, _source, _instigator, random [DETONATION_DELAY / 2, DETONATION_DELAY, DETONATION_DELAY / 2 * 3]]] call CBA_fnc_localEvent; + }; + + _box setVariable [QGVAR(effects), _effects]; +}, _this, (_startTime - CBA_missionTime) max 0] call CBA_fnc_waitAndExecute; // This delay allows for synchronisation for JIP players diff --git a/addons/cookoff/functions/fnc_cookOffBoxServer.sqf b/addons/cookoff/functions/fnc_cookOffBoxServer.sqf new file mode 100644 index 0000000000..10d57876a7 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffBoxServer.sqf @@ -0,0 +1,50 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, kymckay, johnb43 + * Start an ammo cook-off in the given ammo box. + * + * Arguments: + * 0: Ammo box + * 1: Source (default: objNull) + * 2: Instigator (default: objNull) + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_cookoff_fnc_cookOffBoxServer + * + * Public: No + */ + +if (!isServer) exitWith {}; +if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; + +params ["_box", ["_source", objNull], ["_instigator", objNull]]; + +// Make sure it's a box (important, because deleted EH is assigned to ReammoBox_F only in postInit) +if !(_box isKindOf "ReammoBox_F") exitWith {}; + +if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {}; + +// Allow only 1 cook-off per box at a time +if (_box getVariable [QGVAR(isCookingOff), false]) exitWith {}; + +_box setVariable [QGVAR(isCookingOff), true, true]; + +private _delay = random [SMOKE_DELAY / 2, SMOKE_DELAY, SMOKE_DELAY / 2 * 3]; + +// Spawn cook-off effects on all connected machines and JIP +private _jipID = [QGVAR(cookOffBoxLocal), [ + _box, + _source, + _instigator, + CBA_missionTime + _delay // Generate a globally synced timestamp +]] call CBA_fnc_globalEventJIP; + +[_jipID, _box] call CBA_fnc_removeGlobalEventJIP; + +_box setVariable [QGVAR(cookoffBoxJipID), _jipID]; + +// API +[QGVAR(cookOffBox), [_box, _source, _instigator, _delay]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_cookOffEffect.sqf b/addons/cookoff/functions/fnc_cookOffEffect.sqf deleted file mode 100644 index a907f67606..0000000000 --- a/addons/cookoff/functions/fnc_cookOffEffect.sqf +++ /dev/null @@ -1,201 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Spawn cook-off effects - * - * Arguments: - * 0: Vehicle - * 1: Spawn fire jet - * 2: Spawn fire ring - * 3: How long effect will last (Max 20 seconds) - * 4: What selection will fire originate from - * 5: Cookoff intensity value - * - * Return Value: - * None - * - * Example: - * [vehicle player, true, false, 15, "commander_turret"] call ace_cookoff_fnc_cookOffEffect - * - * Public: No - */ - -params ["_obj", "_jet", "_ring", "_time", "_fireSelection", "_intensity"]; -private _light = "#lightpoint" createVehicleLocal [0,0,0]; -_light setLightBrightness 5; -_light setLightAmbient [0.8, 0.6, 0.2]; -_light setLightColor [1, 0.5, 0.2]; -_light lightAttachObject [_obj, [0,0,0]]; -_time = 0 max (_time min 20); - -private _sound = objNull; -if (isServer) then { - // ironically biggest performance hit is this. Creating a new sound source takes up aprox 400 milliseconds. - // I dont think there is an alternative that takes into effect distance and whatever, but if you find one please fix! - if (_jet || _ring) then { - private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65]; - _sound = createSoundSource [_soundName, position _obj, [], 0]; - }; - - if (_ring) then { - private _intensity = 6; - private _radius = 1.5 * ((boundingBoxReal _obj) select 2); - [QEGVAR(fire,addFireSource), [_obj, _radius, _intensity, _obj]] call CBA_fnc_localEvent; - }; -}; - -[{ - params ["_args", "_pfh"]; - _args params ["_obj", "_jet", "_ring", "_time", "_startTime", "_light", "_fireSelection", "_sound", "_intensity"]; - private _elapsedTime = CBA_missionTime - _startTime; - if (_elapsedTime >= _time) exitWith { - deleteVehicle _light; - deleteVehicle _sound; - if (isServer) then { - [QEGVAR(fire,removeFireSource), [_obj]] call CBA_fnc_localEvent; - }; - [_pfh] call CBA_fnc_removePerFrameHandler; - }; - private _factor = (1 + (_elapsedTime / 2) min 2); - private _flameSize = 1.5; - - if (_elapsedTime > (_time * (3 / 4))) then { - _factor = _factor * linearConversion [_time * (3 / 4), _time, _elapsedTime, 1, 0.5]; - }; - - _light setLightBrightness 5 * (_factor / 5); - - if (_jet) then { - private _particlePosition = (_obj selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, 0]; - - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", - "Billboard", - 1, - (0.1 + (random 0.2)) * _factor, - _particlePosition, - [0, 0, 15 * (_factor / 2)], - 0, - 10, - 7.9, - 0.075, - [1.25 * _factor, 2.5 * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], - 1, - 0, - "", - "", - _obj - ]; - - // make flame push object into ground to make effect seem more "alive" - if (!isGamePaused && { local _obj }) then { - private _force = [0, 0, _factor * -(0.5 min random 1.5) * (0.3 min random 1)] vectorMultiply getMass _obj; - _obj addForce [_force, vectorUpVisual _obj]; - }; - }; - - if (_ring) then { - private _ringOrigin = (_obj selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, -1]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [0, 20 * (_factor / 2), 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [0, -20 * (_factor / 2), 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [20 * (_factor / 2), 0, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - [-0.1 + random 0.2, -0.1 + random 0.2, -1], - [-20 * (_factor / 2), 0, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - private _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = -20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [_dir, -_dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - - _dir = 20 * (_factor / 2); - drop [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], - "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, - _ringOrigin, - [-_dir, _dir, 0], - 0, 10, 7.9, 0.075, - [1.25 * _factor, _flameSize * _factor], - [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], - [2 + random 1], 1, 0, "", "", _obj - ]; - }; - - (getVehicleTIPars _obj) params ["_tiEngine", "_tiWheels", "_tiWeapon"]; - _obj setVehicleTIPars [ - // formula is designed to have the temperature ramp up quickly and then level out - (_tiEngine + (_intensity * 0.01))/1.005, - (_tiWheels + (_intensity * 0.004))/1.002, // wheels//tracks are further away from burning parts - (_tiWeapon + (_intensity * 0.01))/1.005 - ]; - -}, 0, [_obj, _jet, _ring, _time, CBA_missionTime, _light, _fireSelection, _sound, _intensity]] call CBA_fnc_addPerFrameHandler; - diff --git a/addons/cookoff/functions/fnc_cookOffLocal.sqf b/addons/cookoff/functions/fnc_cookOffLocal.sqf new file mode 100644 index 0000000000..cbd160bba1 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffLocal.sqf @@ -0,0 +1,229 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Spawn cook-off fire effects. + * + * Arguments: + * 0: Vehicle + * 1: Spawn fire jet + * 2: Spawn fire ring + * 3: What selection fire will originate from + * 4: Cookoff intensity value + * 5: Start time + * 6: Duration of effect (max 20 seconds) + * + * Return Value: + * None + * + * Example: + * [cursorObject, true, false, "commander_turret", 6, CBA_missionTime, 15] call ace_cookoff_fnc_cookOffLocal + * + * Public: No + */ + +#define FLAME_SIZE 1.5 +#define FIRE_INTENSITY 20 + +params ["_vehicle", "_jet", "_ring", "_fireSelection", "_intensity", "_startTime", "_duration"]; + +// Check if still valid for JIP players +if (isNull _vehicle || {CBA_missionTime - _startTime >= _duration}) exitWith {}; + +// Spawn light +private _light = objNull; + +if (hasInterface) then { + _light = "#lightpoint" createVehicleLocal [0, 0, 0]; + _light setLightBrightness 5; + _light setLightAmbient [0.8, 0.6, 0.2]; + _light setLightColor [1, 0.5, 0.2]; + _light lightAttachObject [_vehicle, [0, 0, 0]]; +}; + +_duration = 0 max _duration min 20; + +private _sound = objNull; +private _fireKey = ""; + +if (isServer) then { + // Spawn sound effect + if (_jet || _ring) then { + private _soundName = selectRandomWeighted [QGVAR(Sound_low), 0.1, QGVAR(Sound_mid), 0.25, QGVAR(Sound_high), 0.65]; + _sound = createSoundSource [_soundName, ASLToAGL getPosASL _vehicle, [], 0]; + _sound attachTo [_vehicle]; + }; + + // Make the ring a source of fire + if (_ring && {["ace_fire"] call EFUNC(common,isModLoaded)}) then { + _fireKey = format [QGVAR(cookoffFire_%1), hashValue _vehicle]; + + [QEGVAR(fire,addFireSource), [_vehicle, FLAME_SIZE * ((boundingBoxReal _vehicle) select 2), FIRE_INTENSITY, _fireKey]] call CBA_fnc_localEvent; + }; +}; + +[{ + (_this select 0) params ["_vehicle", "_jet", "_ring", "_startTime", "_duration", "_light", "_fireSelection", "_sound", "_intensity", "_fireKey"]; + + private _elapsedTime = CBA_missionTime - _startTime; + + // Clean up effects once effects have finished or vehicle has been deleted + if (isNull _vehicle || {_elapsedTime >= _duration}) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + + deleteVehicle _light; + + if (isServer) then { + deleteVehicle _sound; + + if (["ace_fire"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(fire,removeFireSource), _fireKey] call CBA_fnc_localEvent; + }; + }; + }; + + private _factor = 1 + (_elapsedTime / 2) min 2; + + if (_elapsedTime > _duration * 3 / 4) then { + _factor = _factor * linearConversion [_duration * 3 / 4, _duration, _elapsedTime, 1, 0.5]; + }; + + // Make flame push object into ground to make effect seem more "alive" + if (_jet && !isGamePaused && {local _vehicle} && {_vehicle getVariable [QGVAR(nextForceTime), 0] <= CBA_missionTime}) then { + private _force = [0, 0, _factor * -(0.5 min random 1.5) * (0.3 min random 1)] vectorMultiply getMass _vehicle; + _vehicle addForce [_force, vectorUpVisual _vehicle]; + _vehicle setVariable [QGVAR(nextForceTime), CBA_missionTime + 0.01]; // This prevents bad behaviour when setAccTime is small + }; + + // Don't spawn visual effects on machines without interfaces + if (!hasInterface) exitWith {}; + + _light setLightBrightness _factor; + + if (_jet) then { + private _particlePosition = (_vehicle selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, 0]; + + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", + "Billboard", + 1, + (0.1 + random 0.2) * _factor, + _particlePosition, + [0, 0, 15 * (_factor / 2)], + 0, + 10, + 7.9, + 0.075, + [1.25 * _factor, 2.5 * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], + 1, + 0, + "", + "", + _vehicle + ]; + }; + + if (_ring) then { + private _ringOrigin = (_vehicle selectionPosition _fireSelection) vectorAdd [-0.1 + random 0.2, -0.1 + random 0.2, -1]; + + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [0, 20 * (_factor / 2), 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [0, -20 * (_factor / 2), 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [20 * (_factor / 2), 0, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + [-0.1 + random 0.2, -0.1 + random 0.2, -1], + [-20 * (_factor / 2), 0, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + private _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = -20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, + _ringOrigin, + [_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2],[1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal",16,2,32], + "", "Billboard", 1, (0.1 + (random 0.2)) * _factor, + _ringOrigin, + [_dir, -_dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + + _dir = 20 * (_factor / 2); + drop [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 2, 32], + "", "Billboard", 1, (0.1 + random 0.2) * _factor, + _ringOrigin, + [-_dir, _dir, 0], + 0, 10, 7.9, 0.075, + [1.25 * _factor, FLAME_SIZE * _factor], + [[1, 1, 1, -2], [1, 1, 1, -2], [1, 1, 1, -1], [1, 1, 1, -0]], + [2 + random 1], 1, 0, "", "", _vehicle + ]; + }; + + (getVehicleTIPars _vehicle) params ["_tiEngine", "_tiWheels", "_tiWeapon"]; + + // Formula is designed to have the temperature ramp up quickly and then level out + _vehicle setVehicleTIPars [ + (_tiEngine + _intensity * 0.01) / 1.005, + (_tiWheels + _intensity * 0.004) / 1.002, // Wheels/tracks are further away from burning parts + (_tiWeapon + _intensity * 0.01) / 1.005 + ]; +}, 0, [_vehicle, _jet, _ring, _startTime, _duration, _light, _fireSelection, _sound, _intensity, _fireKey]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_cookOffServer.sqf b/addons/cookoff/functions/fnc_cookOffServer.sqf new file mode 100644 index 0000000000..05111d7e69 --- /dev/null +++ b/addons/cookoff/functions/fnc_cookOffServer.sqf @@ -0,0 +1,202 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Start a cook-off in the given vehicle. + * Spews flames in multiple directions at the same time (ring) or from the turret towards the sky (jet). + * + * Arguments: + * 0: Vehicle + * 1: Intensity of fire + * 2: Source (default: objNull) + * 3: Instigator (default: objNull) + * 4: Delay between smoke and fire enabled (default: true) + * 5: Ammo detonation chance (default: 0) + * 6: Detonate after cook-off (default: false) + * 7: Selection for fire source (default: "") + * 8: Can spawn fire ring (default: true) + * 9: Can spawn fire jet (default: true) + * 10: Maximum intensity (default: MAX_COOKOFF_INTENSITY) + * + * Return Value: + * None + * + * Example: + * [cursorObject, 3] call ace_cookoff_fnc_cookOffServer + * + * Public: No + */ + +if (!isServer) exitWith {}; +if (!GVAR(enableFire) || {GVAR(cookoffDuration) == 0}) exitWith {}; + +params [ + "_vehicle", + "_intensity", + ["_source", objNull], + ["_instigator", objNull], + ["_delayBetweenSmokeAndFire", true], + ["_ammoDetonationChance", 0], + ["_detonateAfterCookoff", false], + ["_fireSelection", ""], + ["_canRing", true], + ["_canJet", true], + ["_maxIntensity", MAX_COOKOFF_INTENSITY] +]; + +// Make sure it's a vehicle (important, because deleted EH is assigned to AllVehicles only in postInit) +if !(_vehicle isKindOf "AllVehicles") exitWith {}; + +if (_vehicle isKindOf "CAManBase" || {_vehicle isKindOf "StaticWeapon"}) exitWith {}; + +// If under water, ignore +// underwater is not very reliable, so use model center instead +if (underwater _vehicle || {private _posASL = getPosWorld _vehicle; surfaceIsWater _posASL && {(_posASL select 2) < 0}}) exitWith {}; + +// Check if cook-off is disabled on vehicle specifically +if !(_vehicle getVariable [QGVAR(enable), true]) exitWith {}; // QGVAR(enable) is API + +TRACE_3("cooking off",_vehicle,_intensity,_maxIntensity); +TRACE_8("",_source,_instigator,_delayBetweenSmokeAndFire,_ammoDetonationChance,_detonateAfterCookoff,_fireSelection,_canRing,_canJet); + +if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {}; + +_vehicle setVariable [QGVAR(isCookingOff), true, true]; + +// Limit maximum value of intensity to prevent very long cook-off times +_intensity = _intensity min _maxIntensity; + +private _selections = getArray (configOf _vehicle >> QGVAR(cookoffSelections)) select {(_vehicle selectionPosition _x) isNotEqualTo [0, 0, 0]}; + +if (_selections isEqualTo []) then { + WARNING_1("no valid selection for cookoff found. %1",typeOf _vehicle); + + { + if ((_vehicle selectionPosition _x) isNotEqualTo [0, 0, 0]) then { + _selections pushBack _x; + }; + } forEach DEFAULT_COMMANDER_HATCHES; + + if (_selections isEqualTo []) then { + _selections pushBack "#noselection"; + }; +}; + +// Not guaranteed to be active/used, but reserve it nonetheless +private _fireJipID = format [QGVAR(cookOffLocal_%1), hashValue _vehicle]; +[_fireJipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +// Spawn smoke +private _smokeJipID = [QGVAR(smoke), [_vehicle, _selections]] call CBA_fnc_globalEventJIP; +[_smokeJipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +// Save intensity for looping purposes +_vehicle setVariable [QGVAR(intensity), _intensity]; + +private _delay = 0; + +if (_delayBetweenSmokeAndFire) then { + _delay = random [SMOKE_DELAY, 1.5 * SMOKE_DELAY, 2 * SMOKE_DELAY]; +}; + +[{ + [{ + (_this select 0) params ["_vehicle", "_selections", "_ammoDetonationChance", "_detonateAfterCookoff", "_source", "_instigator", "_fireSelection", "_canRing", "_canJet", "_smokeJipID", "_fireJipID"]; + + if ( + isNull _vehicle || + !GVAR(enableFire) || + {!(_vehicle getVariable [QGVAR(enable), true])} || // QGVAR(enable) is API + {GVAR(cookoffDuration) == 0} || + {underwater _vehicle} || + {private _posASL = getPosWorld _vehicle; surfaceIsWater _posASL && {(_posASL select 2) < 0}} // Underwater is not very reliable, so use model center instead + ) exitWith { + // Effects are deleted when vehicle is deleted + (_this select 1) call CBA_fnc_removePerFrameHandler; + }; + + private _intensity = _vehicle getVariable [QGVAR(intensity), 0]; + + if (_intensity <= 1) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + + // Wait until the previous flame has finished + private _nextFlameTime = (_vehicle getVariable [QGVAR(endCurrentFlame), CBA_missionTime]) - CBA_missionTime + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES); + + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + [{ + params ["_vehicle", "_source", "_instigator", "_detonateAfterCookoff", "_fireSelection", "_smokeJipID", "_fireJipID"]; + + // Effects are deleted when vehicle is deleted + if (isNull _vehicle) exitWith {}; + + // Remove effects from JIP + _smokeJipID call CBA_fnc_removeGlobalEventJIP; + _fireJipID call CBA_fnc_removeGlobalEventJIP; + + // Remove effects + [QGVAR(cleanupEffects), _vehicle] call CBA_fnc_globalEvent; + + // Reset variable, so it can cook-off again + _vehicle setVariable [QGVAR(isCookingOff), nil, true]; + + if (GVAR(destroyVehicleAfterCookoff) || _detonateAfterCookoff) then { + createVehicle ["ACE_ammoExplosionLarge", _vehicle modelToWorld (_vehicle selectionPosition _fireSelection), [], 0 , "CAN_COLLIDE"]; + + _vehicle setDamage [1, true, _source, _instigator]; // Because it's running on the server, source and instigator can be set + }; + }, [_vehicle, _source, _instigator, _detonateAfterCookoff, _fireSelection, _smokeJipID, _fireJipID], _nextFlameTime] call CBA_fnc_waitAndExecute; + }; + + // Wait until we are ready for the next flame + if ((_vehicle getVariable [QGVAR(nextFlame), 0]) <= CBA_missionTime) then { + private _ring = false; + + if (_canRing) then { + _ring = 0.2 > random 1; + + if (!_ring && {_intensity >= 2}) then { + _ring = 0.7 > random 1; + }; + }; + + private _duration = linearConversion [0, 10, _intensity, 3, 20] + random COOKOFF_TIME; + + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + // Sync for JIP players + [QGVAR(cookOffLocal), [_vehicle, _canJet, _ring, _fireSelection, _intensity, CBA_missionTime, _duration], _fireJipID] call CBA_fnc_globalEventJIP; + + // If there are any crew, burn them + if (["ace_fire"] call EFUNC(common,isModLoaded)) then { + // Use current intensity, in case GVAR(cookoffDuration) is very large and only 1 flameout stage happens + { + [QEGVAR(fire,burn), [_x, _intensity * 1.5, _instigator], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); + }; + + _intensity = (_intensity - (0.5 max random 1) / GVAR(cookoffDuration)) max 0; + + _vehicle setVariable [QGVAR(intensity), _intensity]; + _vehicle setVariable [QGVAR(endCurrentFlame), CBA_missionTime + _duration]; + _vehicle setVariable [QGVAR(nextFlame), CBA_missionTime + _duration + (MIN_TIME_BETWEEN_FLAMES max random MAX_TIME_BETWEEN_FLAMES)]; + }; + + if (_ammoDetonationChance > random 1 && {_vehicle getVariable [QGVAR(nextExplosiveDetonation), 0] <= CBA_missionTime}) then { + if (_fireSelection isEqualTo "") then { + _fireSelection = selectRandom _selections; + }; + + createVehicle ["ACE_ammoExplosionLarge", _vehicle modelToWorld (_vehicle selectionPosition _fireSelection), [], 0 , "CAN_COLLIDE"]; + + _vehicle setVariable [QGVAR(nextExplosiveDetonation), CBA_missionTime + random 60]; + }; + }, 0.25, _this] call CBA_fnc_addPerFrameHandler; +}, [_vehicle, _selections, _ammoDetonationChance, _detonateAfterCookoff, _source, _instigator, _fireSelection, _canRing, _canJet, _smokeJipID, _fireJipID], _delay] call CBA_fnc_waitAndExecute; + +// API +[QGVAR(cookoff), [_vehicle, _intensity, _instigator, _smokeDelayEnabled, _ammoDetonationChance, _detonateAfterCookoff, _fireSelection, _canRing, _maxIntensity, _canJet]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_detonateAmmunition.sqf b/addons/cookoff/functions/fnc_detonateAmmunition.sqf deleted file mode 100644 index b4d48f3120..0000000000 --- a/addons/cookoff/functions/fnc_detonateAmmunition.sqf +++ /dev/null @@ -1,135 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: Glowbal - * Detonates ammunition from a vehicle until no ammo left - * - * Arguments: - * 0: vehicle - * 1: Ammo Array - * - 0: Magazine Classname - * - 1: Ammo Count - * 2: Total Ammo Count - * - * Return Value: - * None - * - * Example: - * [_vehicle, magazinesAmmo _vehicle] call ace_cookoff_fnc_detonateAmmunition - * - * Public: No - */ - -params ["_vehicle", "_magazines", "_totalAmmo"]; - -if (GVAR(enable) == 0) exitWith {}; -if !(GVAR(enableAmmoCookoff)) exitWith {}; - -if (isNull _vehicle) exitWith {}; // vehicle got deleted -if (_magazines isEqualTo []) exitWith {}; // nothing to detonate anymore -if (underwater _vehicle) exitWith {}; - -private _magazineIndex = floor random(count _magazines); -private _magazine = _magazines select _magazineIndex; -_magazine params ["_magazineClassname", "_amountOfMagazines"]; - -if (_amountOfMagazines > 0) exitWith { - private _removed = _amountOfMagazines min floor(1 + random(6 / GVAR(ammoCookoffDuration))); - - _amountOfMagazines = _amountOfMagazines - _removed; - if (_amountOfMagazines <= 0) then { - _magazines deleteAt _magazineIndex; - } else { - _magazine set [1, _amountOfMagazines]; // clear out the magazine - }; - private _timeBetweenAmmoDetonation = (((random 10) / (sqrt _totalAmmo)) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1; - TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation); - _totalAmmo = _totalAmmo - _removed; - - private _ammo = getText (configFile >> "CfgMagazines" >> _magazineClassname >> "ammo"); - private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; - - private _speedOfAmmo = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "initSpeed"); - private _simType = getText (_ammoCfg >> "simulation"); - - private _effect2pos = _vehicle selectionPosition "destructionEffect2"; - - private _spawnProjectile = { - params ["_vehicle", "_ammo", "_speed", "_flyAway"]; - - private _spawnPos = _vehicle modelToWorld [-0.2 + (random 0.4), -0.2 + (random 0.4), random 3]; - if (_spawnPos select 2 < 0) then { - _spawnPos set [2, 0]; - }; - - private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"]; - if (_flyAway) then { - private _vectorAmmo = [(-1 + (random 2)), (-1 + (random 2)), -0.2 + (random 1)]; - private _velVec = _vectorAmmo vectorMultiply _speed; - _projectile setVectorDir _velVec; - _projectile setVelocity _velVec; - } else { - _projectile setDamage 1; - }; - - _projectile; - }; - - private _speed = random (_speedOfAmmo / 10) max 1; - - if (toLower _simType == "shotbullet") then { - private _sound = selectRandom [QUOTE(PATHTO_R(sounds\light_crack_close.wss)), QUOTE(PATHTO_R(sounds\light_crack_close_filtered.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close_filtered.wss))]; - playSound3D [_sound, objNull, false, (getPosASL _vehicle), 2, 1, 1250]; - - if (random 1 < 0.6) then { - [_vehicle, _ammo, _speed, true] call _spawnProjectile; - }; - }; - if (toLower _simType == "shotshell") then { - private _sound = selectRandom [QUOTE(PATHTO_R(sounds\heavy_crack_close.wss)), QUOTE(PATHTO_R(sounds\heavy_crack_close_filtered.wss))]; - playSound3D [_sound, objNull, false, (getPosASL _vehicle), 2, 1, 1300]; - - if (random 1 < 0.15) then { - [_vehicle, _ammo, _speed, true] call _spawnProjectile; - }; - }; - if (toLower _simType == "shotgrenade") then { - if (random 1 < 0.9) then { - _speed = 0; - }; - [_vehicle, _ammo, _speed, random 1 < 0.5] call _spawnProjectile; - }; - if (toLower _simType in ["shotrocket", "shotmissile", "shotsubmunitions"]) then { - if (random 1 < 0.1) then { - private _sound = selectRandom [QUOTE(PATHTO_R(sounds\cannon_crack_close.wss)), QUOTE(PATHTO_R(sounds\cannon_crack_close_filtered.wss))]; - playSound3D [_sound, objNull, false, (getPosASL _vehicle), 3, 1, 1600]; - - [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; - } else { - createvehicle ["ACE_ammoExplosionLarge", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; - }; - }; - if (toLower _simType in ["shotdirectionalbomb", "shotmine"]) then { - if (random 1 < 0.5) then { - // Not all explosives detonate on destruction, some have scripted alternatives - private _scripted = getNumber (_ammoCfg >> "triggerWhenDestroyed") == 1; - if !(_scripted) then { - _ammo = getText (_ammoCfg >> "ace_explosives_Explosive"); - }; - - // If a scripted alternative doesn't exist use generic explosion - if (_ammo != "") then { - [_vehicle, _ammo, 0, false] call _spawnProjectile; - } else { - createvehicle ["SmallSecondary", (_vehicle modelToWorld _effect2pos), [], 0 , "CAN_COLLIDE"]; - }; - }; - }; - if (toLower _simType == "shotilluminating") then { - if (random 1 < 0.15) then { - [_vehicle, _ammo, _speed, random 1 < 0.3] call _spawnProjectile; - }; - }; - - [FUNC(detonateAmmunition), [_vehicle, _magazines, _totalAmmo], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute; -}; -ERROR_1("mag with no ammo - %1", _magazine); diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf new file mode 100644 index 0000000000..43ac730e09 --- /dev/null +++ b/addons/cookoff/functions/fnc_detonateAmmunitionServer.sqf @@ -0,0 +1,54 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Starts detonating ammunition from an object (e.g. vehicle or crate). + * + * Arguments: + * 0: Object + * 1: Destroy when finished (default: false) + * 2: Source (default: objNull) + * 3: Instigator (default: objNull) + * 4: Initial delay (default: 0) + * + * Return Value: + * None + * + * Example: + * [cursorObject] call ace_cookoff_fnc_detonateAmmunitionServer + * + * Public: No + */ + +if (!isServer) exitWith {}; + +params ["_object", ["_destroyWhenFinished", false], ["_source", objNull], ["_instigator", objNull], ["_initialDelay", 0]]; + +if (isNull _object) exitWith {}; + +// Check if the object can cook its ammo off +if ( + underwater _object || + {private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead + {GVAR(ammoCookoffDuration) == 0} || + {!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} || + {!(_object getVariable [QGVAR(enableAmmoCookoff), true])} +) exitWith {}; + +// Don't have an object detonate its ammo twice +if (_object getVariable [QGVAR(isAmmoDetonating), false]) exitWith {}; + +_object setVariable [QGVAR(isAmmoDetonating), true, true]; + +_object setVariable [QGVAR(cookoffMagazines), _object call FUNC(getVehicleAmmo)]; + +// TODO: When setMagazineTurretAmmo and magazineTurretAmmo are fixed (https://feedback.bistudio.com/T79689), +// we can add gradual ammo removal during cook-off +if (GVAR(removeAmmoDuringCookoff)) then { + clearMagazineCargoGlobal _object; + + { + [QEGVAR(common,removeMagazinesTurret), [_object, _x select 0, _x select 1], _object, _x select 1] call CBA_fnc_turretEvent; + } forEach (magazinesAllTurrets _object); +}; + +[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _initialDelay] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf new file mode 100644 index 0000000000..7fdcedda51 --- /dev/null +++ b/addons/cookoff/functions/fnc_detonateAmmunitionServerLoop.sqf @@ -0,0 +1,181 @@ +#include "..\script_component.hpp" +/* + * Author: Glowbal, johnb43 + * Detonates ammunition from an object (e.g. vehicle or crate) until no ammo is left. + * + * Arguments: + * 0: Object + * 1: Destroy when finished + * 2: Source + * 3: Instigator + * + * Return Value: + * None + * + * Example: + * [cursorObject, true, player, player] call ace_cookoff_fnc_detonateAmmunitionServerLoop + * + * Public: No + */ + +params ["_object", "_destroyWhenFinished", "_source", "_instigator"]; + +if (isNull _object) exitWith {}; + +(_object getVariable QGVAR(cookoffMagazines)) params ["_magazines", "_totalAmmo"]; + +private _hasFinished = _totalAmmo <= 0 || {_magazines isEqualTo []}; + +// If the cook-off has finished or been interrupted, clean up the effects for boxes (no vehicle effects) +if ( + _hasFinished || + {underwater _object} || + {private _posASL = getPosWorld _object; surfaceIsWater _posASL && {(_posASL select 2) < 0}} || // Underwater is not very reliable, so use model center instead + {GVAR(ammoCookoffDuration) == 0} || + {!([GVAR(enableAmmoCookoff), GVAR(enableAmmobox)] select (_object isKindOf "ReammoBox_F"))} || + {!(_object getVariable [QGVAR(enableAmmoCookoff), true])} +) exitWith { + // Box cook-off fire ends after the ammo has detonated (vehicle cook-off fire does not depend on the ammo detonation) + if (_object isKindOf "ReammoBox_F") then { + [QGVAR(cleanupEffects), _object] call CBA_fnc_globalEvent; + + // Reset variable, so the box can cook-off again + _object setVariable [QGVAR(isCookingOff), nil, true]; + + // Remove cook-off effects from box + private _jipID = _object getVariable QGVAR(cookoffBoxJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _object setVariable [QGVAR(cookoffBoxJipID), nil]; + }; + + // Reset variables, so the object can detonate its ammo again + _object setVariable [QGVAR(cookoffMagazines), nil]; + _object setVariable [QGVAR(isAmmoDetonating), nil, true]; + + // If done, destroy the object if necessary + if (_hasFinished && _destroyWhenFinished) then { + _object setDamage [1, true, _source, _instigator]; + }; +}; + +private _magazineIndex = floor random (count _magazines); +private _magazine = _magazines select _magazineIndex; +_magazine params ["_magazineClassname", "_ammoCount", "_spawnProjectile"]; + +// Make sure ammo is at least 0 +_ammoCount = _ammoCount max 0; + +// Remove some ammo, which will be detonated +private _removed = _ammoCount min floor (1 + random (6 / GVAR(ammoCookoffDuration))); + +_ammoCount = _ammoCount - _removed; + +if (_ammoCount <= 0) then { + _magazines deleteAt _magazineIndex; +} else { + _magazine set [1, _ammoCount]; // remove ammo that was detonated +}; + +private _timeBetweenAmmoDetonation = ((random 10 / sqrt _totalAmmo) min MAX_TIME_BETWEEN_AMMO_DET) max 0.1; +TRACE_2("",_totalAmmo,_timeBetweenAmmoDetonation); +_totalAmmo = _totalAmmo - _removed; + +_object setVariable [QGVAR(cookoffMagazines), [_magazines, _totalAmmo]]; + +// Get magazine info, which is used to spawn projectiles +private _configMagazine = configFile >> "CfgMagazines" >> _magazineClassname; +private _ammo = getText (_configMagazine >> "ammo"); +private _configAmmo = configFile >> "CfgAmmo" >> _ammo; + +private _simType = toLower getText (_configAmmo >> "simulation"); +private _speed = linearConversion [0, 1, random 1, 1, 20, true]; +private _effect2pos = _object selectionPosition "destructionEffect2"; + +// Spawns the projectiles, making them either fly in random directions or explode +private _fnc_spawnProjectile = { + // If the magazines are inside of the cargo (inventory), don't let their projectiles escape the interior of the vehicle + if (!_spawnProjectile) exitWith {}; + + params ["_object", "_ammo", "_speed", "_flyAway"]; + + private _spawnPos = _object modelToWorld [-0.2 + random 0.4, -0.2 + random 0.4, random 3]; + + if (_spawnPos select 2 < 0) then { + _spawnPos set [2, 0]; + }; + + private _projectile = createVehicle [_ammo, _spawnPos, [], 0, "CAN_COLLIDE"]; + + if (_flyAway) then { + private _vectorAmmo = [-1 + random 2, -1 + random 2, -0.2 + random 1]; + private _vectorVelocity = _vectorAmmo vectorMultiply _speed; + + _projectile setVectorDir _vectorVelocity; + _projectile setVelocity _vectorVelocity; + } else { + _projectile setDamage 1; + }; +}; + +switch (_simType) do { + case "shotbullet": { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + if (random 1 < 0.6) then { + [_object, _ammo, _speed, true] call _fnc_spawnProjectile; + }; + }; + case "shotshell": { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + if (random 1 < 0.15) then { + [_object, _ammo, _speed, true] call _fnc_spawnProjectile; + }; + }; + case "shotgrenade": { + if (random 1 < 0.9) then { + _speed = 0; + }; + + [_object, _ammo, _speed, random 1 < 0.5] call _fnc_spawnProjectile; + }; + case "shotrocket"; + case "shotmissile"; + case "shotsubmunitions": { + if (random 1 < 0.1) then { + [QGVAR(playCookoffSound), [_object, _simType]] call CBA_fnc_globalEvent; + + [_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile; + } else { + createVehicle ["ACE_ammoExplosionLarge", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"]; + }; + }; + case "shotdirectionalbomb"; + case "shotmine": { + if (random 1 < 0.5) then { + // Not all explosives detonate on destruction, some have scripted alternatives + if (getNumber (_configAmmo >> "triggerWhenDestroyed") != 1) then { + _ammo = getText (_configAmmo >> QEGVAR(explosives,explosive)); + }; + + // If a scripted alternative doesn't exist use generic explosion + if (_ammo != "") then { + [_object, _ammo, 0, false] call _fnc_spawnProjectile; + } else { + createVehicle ["SmallSecondary", _object modelToWorld _effect2pos, [], 0 , "CAN_COLLIDE"]; + }; + }; + }; + case "shotilluminating": { + if (random 1 < 0.15) then { + [_object, _ammo, _speed, random 1 < 0.3] call _fnc_spawnProjectile; + }; + }; +}; + +// Detonate the remaining ammo after a delay +[LINKFUNC(detonateAmmunitionServerLoop), [_object, _destroyWhenFinished, _source, _instigator], _timeBetweenAmmoDetonation] call CBA_fnc_waitAndExecute; diff --git a/addons/cookoff/functions/fnc_engineFire.sqf b/addons/cookoff/functions/fnc_engineFire.sqf deleted file mode 100644 index 118537b30a..0000000000 --- a/addons/cookoff/functions/fnc_engineFire.sqf +++ /dev/null @@ -1,51 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: KoffeinFlummi, commy2 - * Start fire in engine block of a car. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * None - * - * Example: - * (vehicle player) call ace_cookoff_fnc_engineFire - * - * Public: No - */ - -params ["_vehicle"]; - -if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {}; -_vehicle setVariable [QGVAR(isEngineSmoking), true]; - -if (local _vehicle) then { - [QGVAR(engineFire), _vehicle] call CBA_fnc_globalEvent; -}; - -private _offset = getArray (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(engineSmokeOffset)); - -if (_offset isEqualTo []) then { - _offset = [0,0,0]; -}; - -private _position = [ - 0, - (boundingBoxReal _vehicle select 1 select 1) - 2, - (boundingBoxReal _vehicle select 0 select 2) + 2 -] vectorAdd _offset; - -private _smoke = "#particlesource" createVehicleLocal [0,0,0]; -_smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; -_smoke attachTo [_vehicle, _position]; - -[{ - (_this select 0) params ["_vehicle", "_smoke", "_time"]; - - if (isNull _vehicle || {!alive _vehicle} || {_vehicle getHitPointDamage "HitEngine" < 0.9} || {CBA_missionTime > _time}) then { - deleteVehicle _smoke; - _vehicle setVariable [QGVAR(isEngineSmoking), false]; - [_this select 1] call CBA_fnc_removePerFrameHandler; - }; -}, 5, [_vehicle, _smoke, CBA_missionTime + 240]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_engineFireLocal.sqf b/addons/cookoff/functions/fnc_engineFireLocal.sqf new file mode 100644 index 0000000000..afd6827d6b --- /dev/null +++ b/addons/cookoff/functions/fnc_engineFireLocal.sqf @@ -0,0 +1,81 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Start fire in engine block of a car. + * + * Arguments: + * 0: Vehicle + * 1: End time + * + * Return Value: + * None + * + * Example: + * [cursorObject, CBA_missionTime + 10] call ace_cookoff_fnc_engineFireLocal + * + * Public: No + */ + +params ["_vehicle", "_endTime"]; + +// For JIP players and if the time wasn't set properly +if (_endTime < CBA_missionTime) exitWith {}; + +private _smoke = objNull; + +if (hasInterface) then { + private _hitPoints = getAllHitPointsDamage _vehicle; + + // Get hitpoint for engine + private _index = (_hitPoints select 0) findIf {_x == "hitengine"}; + + // Get corresponding selection + private _position = if (_index != -1) then { + _vehicle selectionPosition [(_hitPoints select 1) select _index, "HitPoints", "AveragePoint"] + } else { + [0, 0, 0] + }; + + if (_position isEqualTo [0, 0, 0]) then { + // Get offset for engine smoke if there is one + private _offset = getArray (configOf _vehicle >> QGVAR(engineSmokeOffset)); + + if (_offset isEqualTo []) then { + _offset = [0, 0, 0]; + }; + + _position = [ + 0, + (boundingBoxReal _vehicle select 1 select 1) - 2, + (boundingBoxReal _vehicle select 0 select 2) + 2 + ] vectorAdd _offset; + }; + + // Spawn smoke + _smoke = createVehicleLocal ["#particlesource", ASLToAGL getPosASL _vehicle, [], 0, "CAN_COLLIDE"];; + _smoke setParticleClass "ObjectDestructionSmoke1_2Smallx"; + _smoke attachTo [_vehicle, _position]; +}; + +[{ + (_this select 0) params ["_vehicle", "_smoke", "_endTime"]; + + if (alive _vehicle && {_vehicle getHitPointDamage "HitEngine" >= 0.9} && {CBA_missionTime < _endTime}) exitWith {}; + + (_this select 1) call CBA_fnc_removePerFrameHandler; + + deleteVehicle _smoke; + + if (!isServer || {isNull _vehicle}) exitWith {}; + + // Reset variable, so engine can smoke again in the future + _vehicle setVariable [QGVAR(isEngineSmoking), nil, true]; + + private _jipID = _vehicle getVariable QGVAR(engineFireJipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _vehicle setVariable [QGVAR(engineFireJipID), nil]; +}, 5, [_vehicle, _smoke, _endTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/cookoff/functions/fnc_engineFireServer.sqf b/addons/cookoff/functions/fnc_engineFireServer.sqf new file mode 100644 index 0000000000..0d435029b8 --- /dev/null +++ b/addons/cookoff/functions/fnc_engineFireServer.sqf @@ -0,0 +1,34 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Start fire in engine block of a car. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_cookoff_fnc_engineFireServer + * + * Public: No + */ + +if (!isServer) exitWith {}; + +params ["_vehicle"]; + +// If already smoking, stop +if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {}; + +_vehicle setVariable [QGVAR(isEngineSmoking), true, true]; + +// Spawn engine fire effects on all connected machines +private _jipID = [QGVAR(engineFireLocal), [_vehicle, CBA_missionTime + random [ENGINE_FIRE_TIME / 2, ENGINE_FIRE_TIME, ENGINE_FIRE_TIME / 2 * 3]]] call CBA_fnc_globalEventJIP; +[_jipID, _vehicle] call CBA_fnc_removeGlobalEventJIP; + +_vehicle setVariable [QGVAR(engineFireJipID), _jipID]; + +// API +[QGVAR(engineFire), [_vehicle]] call CBA_fnc_globalEvent; diff --git a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf index f6be84c1f9..df4385d30d 100644 --- a/addons/cookoff/functions/fnc_getVehicleAmmo.sqf +++ b/addons/cookoff/functions/fnc_getVehicleAmmo.sqf @@ -1,65 +1,76 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Gets all magazines inside of a vehicle. + * Gets all magazines inside of an object. * * Arguments: - * 0: Vehicle + * 0: Object * * Return Value: - * 0: Ammo Array - * - 0: Magazine Classname - * - 1: Ammo Count - * 1: Total Ammo Count + * 0: Ammo array + * - 0: Magazine classname + * - 1: Ammo count + * - 2: If a projectile should be spawned upon detonation + * 1: Total ammo count * * Example: - * [vehicle player] call ace_cookoff_fnc_getVehicleAmmo + * cursorObject call ace_cookoff_fnc_getVehicleAmmo * * Public: No */ -params ["_vehicle"]; -TRACE_1("getVehicleAmmo",_vehicle); +params ["_object"]; +TRACE_1("getVehicleAmmo",_object); private _ammoToDetonate = []; private _totalAmmo = 0; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _ammo = ""; // Get ammo from turrets { - _x params ["_mag", "_turret", "_count"]; - // if the turret is an FFV seat, it takes magazines from the soldier - if (_count > 0) then { - if (_mag call FUNC(isMagazineFlare)) then {continue}; - private _ammo = getText (configFile >> "CfgMagazines" >> _mag >> "ammo"); - private _model = getText (configFile >> "CfgAmmo" >> _ammo >> "model"); - if (_model == "\A3\weapons_f\empty") exitWith {TRACE_3("skipping",_mag,_ammo,_model);}; - _ammoToDetonate pushBack [_mag, _count]; + // If the turret is an FFV seat, it takes magazines from the soldier + _x params ["_magazine", "", "_count"]; + + if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then { + _ammo = getText (_cfgMagazines >> _magazine >> "ammo"); + + if (getText (_cfgAmmo >> _ammo >> "model") == "\A3\weapons_f\empty") then { + TRACE_2("skipping",_magazine,_ammo); + + continue; + }; + + _ammoToDetonate pushBack [_magazine, _count, true]; _totalAmmo = _totalAmmo + _count; }; -} forEach (magazinesAllTurrets [_vehicle, true]); +} forEach (magazinesAllTurrets [_object, true]); // Get ammo from cargo space { - _x params ["_mag", "_count"]; - if (_count > 0) then { - if (_mag call FUNC(isMagazineFlare)) then {continue}; - _ammoToDetonate pushBack [_mag, _count]; + _x params ["_magazine", "_count"]; + + if (_count > 0 && {!(_magazine call FUNC(isMagazineFlare))}) then { + _ammoToDetonate pushBack [_magazine, _count, false]; _totalAmmo = _totalAmmo + _count; }; -} forEach (magazinesAmmoCargo _vehicle); +} forEach (magazinesAmmoCargo _object); // Get ammo from transportAmmo / ace_rearm -private _vehCfg = configOf _vehicle; +private _configVehicle = configOf _object; +private _configSupply = (getNumber (_configVehicle >> "transportAmmo")) max (getNumber (_configVehicle >> QEGVAR(rearm,defaultSupply))); -private _configSupply = (getNumber (_vehCfg >> "transportAmmo")) max (getNumber (_vehCfg >> QEGVAR(rearm,defaultSupply))); -if (_vehicle getVariable [QEGVAR(rearm,isSupplyVehicle), (_configSupply > 0)]) then { - TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _vehicle); +if (_object getVariable [QEGVAR(rearm,isSupplyVehicle), _configSupply > 0]) then { + TRACE_1("transportAmmo vehicle - adding virtual ammo",typeOf _object); - _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000]; + _ammoToDetonate pushBack ["2000Rnd_65x39_belt", 2000, false]; _totalAmmo = _totalAmmo + 2000; - _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100]; + + _ammoToDetonate pushBack ["20Rnd_105mm_HEAT_MP", 100, true]; _totalAmmo = _totalAmmo + 100; - _ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10]; + + _ammoToDetonate pushBack ["SatchelCharge_Remote_Mag", 10, true]; _totalAmmo = _totalAmmo + 10; }; diff --git a/addons/cookoff/functions/fnc_handleDamageBox.sqf b/addons/cookoff/functions/fnc_handleDamageBox.sqf index dfc5cb7267..2d55db0fd0 100644 --- a/addons/cookoff/functions/fnc_handleDamageBox.sqf +++ b/addons/cookoff/functions/fnc_handleDamageBox.sqf @@ -1,13 +1,13 @@ #include "..\script_component.hpp" /* - * Author: KoffeinFlummi, commy2 - * Handles all incoming damage for boxi + * Author: KoffeinFlummi, commy2, johnb43 + * Handles all incoming damage for boxes. * * Arguments: * HandleDamage EH * * Return Value: - * Damage to be inflicted. + * Damage to be inflicted (can be nil) * * Example: * _this call ace_cookoff_fnc_handleDamageBox @@ -15,58 +15,48 @@ * Public: No */ -params ["_vehicle", "", "_damage", "_source", "_ammo", "_hitIndex", "_shooter"]; +// If cookoff for boxes is disabled, exit +if (!GVAR(enableAmmobox) || {GVAR(ammoCookoffDuration) == 0}) exitWith {}; -// it's already dead, who cares? -if (damage _vehicle >= 1) exitWith {}; +params ["_box", "", "_damage", "_source", "_ammo", "", "_instigator", "_hitPoint"]; -// If cookoff is disabled exit -if (_vehicle getVariable [QGVAR(enable), GVAR(enable)] in [0, false]) exitWith {}; +if (!local _box) exitWith {}; -// get hitpoint name -private _hitpoint = "#structural"; +// If it's already dead, ignore +if (!alive _box) exitWith {}; -if (_hitIndex != -1) then { - _hitpoint = toLower ((getAllHitPointsDamage _vehicle param [0, []]) select _hitIndex); -}; +if !(_box getVariable [QGVAR(enableAmmoCookoff), true]) exitWith {}; -// get change in damage -private _oldDamage = 0; +if !(_hitPoint == "" && {_damage > 0.5}) exitWith {}; // "" means structural damage -if (_hitpoint isEqualTo "#structural") then { - _oldDamage = damage _vehicle; +private _ammoConfig = _ammo call CBA_fnc_getObjectConfig; + +// Catch fire when hit by an explosive or incendiary round +if ((getNumber (_ammoConfig >> "explosive") >= 0.5) || {getNumber (_ammoConfig >> QEGVAR(vehicle_damage,incendiary)) > random 1}) then { + [QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent; } else { - _oldDamage = _vehicle getHitIndex _hitIndex; -}; + // There is a small chance of cooking a box off if it's shot by tracer ammo + if (random 1 >= _damage * 0.05) exitWith {}; -if (_hitpoint == "#structural" && _damage > 0.5) then { - // Almost always catch fire when hit by an explosive - if (IS_EXPLOSIVE_AMMO(_ammo)) then { - _vehicle call FUNC(cookOffBox); + // Need magazine to check for tracers + private _magazine = if (_source == _instigator) then { + currentMagazine _source } else { - // Need magazine to check for tracers - private _mag = ""; - if (_source == _shooter) then { - _mag = currentMagazine _source; - } else { - _mag = _source currentMagazineTurret ([_shooter] call CBA_fnc_turretPath); - }; - private _magCfg = configFile >> "CfgMagazines" >> _mag; - - // Magazine could have changed during flight time (just ignore if so) - if (getText (_magCfg >> "ammo") == _ammo) then { - // If magazine's tracer density is high enough then low chance for cook off - private _tracers = getNumber (_magCfg >> "tracersEvery"); - if (_tracers >= 1 && {_tracers <= 4}) then { - if (random 1 < _oldDamage*0.05) then { - _vehicle call FUNC(cookOffBox); - }; - }; - }; + _source currentMagazineTurret (_source unitTurret _instigator) }; - // prevent destruction, let cook-off handle it if necessary - _damage min 0.89 -} else { - _damage + private _configMagazine = configFile >> "CfgMagazines" >> _magazine; + + // Magazine could have changed during flight time (just ignore if so) + if (getText (_configMagazine >> "ammo") == _ammo) then { + // If magazine's tracer density is high enough then low chance for cook off + private _tracers = getNumber (_configMagazine >> "tracersEvery"); + + if (_tracers >= 1 && {_tracers <= 4}) then { + [QGVAR(cookOffBoxServer), [_box, _source, _instigator]] call CBA_fnc_serverEvent; + }; + }; }; + +// Prevent destruction, let cook-off handle it if necessary +_damage min 0.89 diff --git a/addons/cookoff/functions/fnc_isMagazineFlare.sqf b/addons/cookoff/functions/fnc_isMagazineFlare.sqf index b6c8a604be..f856b21a9a 100644 --- a/addons/cookoff/functions/fnc_isMagazineFlare.sqf +++ b/addons/cookoff/functions/fnc_isMagazineFlare.sqf @@ -1,24 +1,22 @@ #include "..\script_component.hpp" /* * Author: Cyruz - * Checks if the magazine has ammo which is a flare + * Checks if the magazine's ammo are flares. * * Arguments: * 0: Magazine * * Return Value: - * 0: If magazine is type of flare + * If magazine is type of flare * * Example: - * ["3Rnd_UGL_FlareWhite_F"] call ace_cookoff_fnc_isMagazineFlare + * "3Rnd_UGL_FlareWhite_F" call ace_cookoff_fnc_isMagazineFlare * * Public: No */ params ["_magazine"]; -private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -private _intensity = getNumber (configFile >> "CfgAmmo" >> _ammo >> "intensity"); -private _flare = getNumber (configFile >> "CfgAmmo" >> _ammo >> QEGVAR(grenades,flare)); +private _configAmmo = configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -_intensity != 0 || _flare == 1 +getNumber (_configAmmo >> "intensity") != 0 || {getNumber (_configAmmo >> QEGVAR(grenades,flare)) == 1} diff --git a/addons/cookoff/functions/fnc_smoke.sqf b/addons/cookoff/functions/fnc_smoke.sqf index ce50043413..94055041de 100644 --- a/addons/cookoff/functions/fnc_smoke.sqf +++ b/addons/cookoff/functions/fnc_smoke.sqf @@ -5,7 +5,7 @@ * * Arguments: * 0: Vehicle - * 1. Selections for smoke to come out of (default: []) + * 1: Selections for smoke to come out of * * Return Value: * None @@ -16,12 +16,11 @@ * Public: No */ -params ["_vehicle", ["_positions", []]]; +params ["_vehicle", "_selections"]; -private _turretConfig = [_vehicle, [0]] call CBA_fnc_getTurret; -private _positionBarrelEnd = getText (_turretConfig >> "gunBeg"); +private _positionBarrelEnd = getText ([_vehicle, [0]] call CBA_fnc_getTurret >> "gunBeg"); -// smoke out of cannon and hatches +// Smoke out of cannon and hatches private _smokeBarrel = "#particlesource" createVehicleLocal [0, 0, 0]; _smokeBarrel setParticleClass "MediumDestructionSmoke"; _smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd]; @@ -29,10 +28,10 @@ _smokeBarrel attachTo [_vehicle, [0, 0, 0], _positionBarrelEnd]; private _effects = [_smokeBarrel]; { - private _position = [0, -2, 0]; - - if (_x isNotEqualTo "#noselection") then { - _position = _vehicle selectionPosition _x; + private _position = if (_x != "#noselection") then { + _vehicle selectionPosition _x + } else { + [0, -2, 0] }; private _smoke = "#particlesource" createVehicleLocal [0, 0, 0]; @@ -40,6 +39,6 @@ private _effects = [_smokeBarrel]; _smoke attachTo [_vehicle, _position]; _effects pushBack _smoke; -} forEach _positions; +} forEach _selections; _vehicle setVariable [QGVAR(effects), _effects]; diff --git a/addons/cookoff/initSettings.inc.sqf b/addons/cookoff/initSettings.inc.sqf new file mode 100644 index 0000000000..c7f1be8ffd --- /dev/null +++ b/addons/cookoff/initSettings.inc.sqf @@ -0,0 +1,71 @@ +[ + QGVAR(enableFire), + "CHECKBOX", + [LSTRING(enableFire_name), LSTRING(enableFire_tooltip)], + LSTRING(category_displayName), + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(cookoffDuration), + "SLIDER", + [LSTRING(cookoffDuration_name), LSTRING(cookoffDuration_tooltip)], + LSTRING(category_displayName), + [0, 10, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(probabilityCoef), + "SLIDER", + [LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)], + LSTRING(category_displayName), + [0, 10, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(destroyVehicleAfterCookoff), + "CHECKBOX", + [LSTRING(destroyVehicleAfterCookoff_name), LSTRING(destroyVehicleAfterCookoff_tooltip)], + LSTRING(category_displayName), + false, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(enableAmmoCookoff), + "CHECKBOX", + [LSTRING(enableAmmoCookoff_name), LSTRING(enableAmmoCookoff_tooltip)], + LSTRING(category_displayName), + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(enableAmmobox), + "CHECKBOX", + [LSTRING(enableBoxCookoff_name), LSTRING(enableBoxCookoff_tooltip)], + LSTRING(category_displayName), + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(ammoCookoffDuration), + "SLIDER", + [LSTRING(ammoCookoffDuration_name), LSTRING(ammoCookoffDuration_tooltip)], + LSTRING(category_displayName), + [0, 10, 1, 2], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(removeAmmoDuringCookoff), + "CHECKBOX", + [LSTRING(removeAmmoDuringCookoff_name), LSTRING(removeAmmoDuringCookoff_tooltip)], + LSTRING(category_displayName), + true, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/cookoff/initSettings.sqf b/addons/cookoff/initSettings.sqf deleted file mode 100644 index 8912636fd6..0000000000 --- a/addons/cookoff/initSettings.sqf +++ /dev/null @@ -1,69 +0,0 @@ -[ - QGVAR(enable), "LIST", - [LSTRING(enable_hd_name), LSTRING(enable_hd_tooltip)], - LSTRING(category_displayName), - [[0, 1, 2], ["STR_A3_OPTIONS_DISABLED", ELSTRING(common,playerOnly), ELSTRING(common,playersAndAI)], 2], - true, // isGlobal - {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_fnc_addSetting; - -[ - QGVAR(enableFire), "CHECKBOX", - [LSTRING(enableFire_name), LSTRING(enableFire_tooltip)], - LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableFire), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart -] call CBA_fnc_addSetting; - -[ - QGVAR(destroyVehicleAfterCookoff), "CHECKBOX", - [LSTRING(destroyVehicleAfterCookoff_name), LSTRING(destroyVehicleAfterCookoff_tooltip)], - LSTRING(category_displayName), - false, // default value - true, // isGlobal - {[QGVAR(destroyVehicleAfterCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart -] call CBA_fnc_addSetting; - -[ - QGVAR(enableAmmoCookoff), "CHECKBOX", - [LSTRING(enableAmmoCookoff_name), LSTRING(enableAmmoCookoff_tooltip)], - LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableAmmoCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart -] call CBA_fnc_addSetting; - -[ - QGVAR(enableAmmobox), "CHECKBOX", - [LSTRING(enableBoxCookoff_name), LSTRING(enableBoxCookoff_tooltip)], - LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(enableAmmobox), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_fnc_addSetting; - -[ - QGVAR(ammoCookoffDuration), "SLIDER", - [LSTRING(ammoCookoffDuration_name), LSTRING(ammoCookoffDuration_tooltip)], - LSTRING(category_displayName), - [0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(ammoCookoffDuration), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_fnc_addSetting; - -[ - QGVAR(probabilityCoef), "SLIDER", - [LSTRING(probabilityCoef_name), LSTRING(probabilityCoef_tooltip)], - LSTRING(category_displayName), - [0,5,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(probabilityCoef), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart -] call CBA_fnc_addSetting; diff --git a/addons/cookoff/script_component.hpp b/addons/cookoff/script_component.hpp index 03b3e5c5f5..bf8fd62dd5 100644 --- a/addons/cookoff/script_component.hpp +++ b/addons/cookoff/script_component.hpp @@ -16,14 +16,12 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define IS_EXPLOSIVE_AMMO(ammo) (getNumber (ammo call CBA_fnc_getObjectConfig >> "explosive") > 0.5) - // Stages of cookoff in order (in seconds) -// Should be no un-synced randomness in these as the effects must be ran on each client -#define IGNITE_TIME 3 -#define SMOKE_TIME 10.5 +// Should be no un-synced randomness in these as the effects must be run on each client +#define SMOKE_DELAY 10.5 +#define DETONATION_DELAY 3 #define COOKOFF_TIME 14 // Cook off time should be 20s at most due to length of sound files -#define COOKOFF_TIME_BOX 82.5 // Cook off time for boxes should be significant to allow time for ammo to burn +#define ENGINE_FIRE_TIME 240 #define MIN_TIME_BETWEEN_FLAMES 5 #define MAX_TIME_BETWEEN_FLAMES 15 #define MAX_TIME_BETWEEN_AMMO_DET 25 @@ -32,8 +30,8 @@ #define MIN_AMMO_DETONATION_START_DELAY 1 // Min time to wait before a vehicle's ammo starts to cookoff #define MAX_AMMO_DETONATION_START_DELAY 6 // Max time to wait before a vehicle's ammo starts to cookoff -// Delay between flame effect for players in a cooking off vehicle -#define FLAME_EFFECT_DELAY 0.4 - // Common commander hatch defines for default vehicles #define DEFAULT_COMMANDER_HATCHES ["osa_poklop_commander", "hatch_commander_axis"] + +#define DISTANCE_CLOSE 235 +#define DISTANCE_MID 952 diff --git a/addons/cookoff/sounds/cannon_crack_close.wss b/addons/cookoff/sounds/cannon_crack_close.wss deleted file mode 100644 index b45ea96ab0..0000000000 Binary files a/addons/cookoff/sounds/cannon_crack_close.wss and /dev/null differ diff --git a/addons/cookoff/sounds/cannon_crack_close_filtered.wss b/addons/cookoff/sounds/cannon_crack_close_filtered.wss deleted file mode 100644 index 4ddb18539b..0000000000 Binary files a/addons/cookoff/sounds/cannon_crack_close_filtered.wss and /dev/null differ diff --git a/addons/cookoff/sounds/heavy_crack_close.wss b/addons/cookoff/sounds/heavy_crack_close.wss deleted file mode 100644 index 95cc68d90e..0000000000 Binary files a/addons/cookoff/sounds/heavy_crack_close.wss and /dev/null differ diff --git a/addons/cookoff/sounds/heavy_crack_close_filtered.wss b/addons/cookoff/sounds/heavy_crack_close_filtered.wss deleted file mode 100644 index 1b4520cd4a..0000000000 Binary files a/addons/cookoff/sounds/heavy_crack_close_filtered.wss and /dev/null differ diff --git a/addons/cookoff/sounds/light_crack_close.wss b/addons/cookoff/sounds/light_crack_close.wss deleted file mode 100644 index ef284f24ef..0000000000 Binary files a/addons/cookoff/sounds/light_crack_close.wss and /dev/null differ diff --git a/addons/cookoff/sounds/light_crack_close_filtered.wss b/addons/cookoff/sounds/light_crack_close_filtered.wss deleted file mode 100644 index b1c76fa8ed..0000000000 Binary files a/addons/cookoff/sounds/light_crack_close_filtered.wss and /dev/null differ diff --git a/addons/cookoff/sounds/shotbullet/close_1.wss b/addons/cookoff/sounds/shotbullet/close_1.wss new file mode 100644 index 0000000000..19f07503bf Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/close_1.wss differ diff --git a/addons/cookoff/sounds/shotbullet/close_2.wss b/addons/cookoff/sounds/shotbullet/close_2.wss new file mode 100644 index 0000000000..bf83c29599 Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/close_2.wss differ diff --git a/addons/cookoff/sounds/shotbullet/close_3.wss b/addons/cookoff/sounds/shotbullet/close_3.wss new file mode 100644 index 0000000000..dcf4198acd Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/close_3.wss differ diff --git a/addons/cookoff/sounds/shotbullet/far_1.wss b/addons/cookoff/sounds/shotbullet/far_1.wss new file mode 100644 index 0000000000..07cd30e15b Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/far_1.wss differ diff --git a/addons/cookoff/sounds/shotbullet/far_2.wss b/addons/cookoff/sounds/shotbullet/far_2.wss new file mode 100644 index 0000000000..795581517a Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/far_2.wss differ diff --git a/addons/cookoff/sounds/shotbullet/far_3.wss b/addons/cookoff/sounds/shotbullet/far_3.wss new file mode 100644 index 0000000000..d7e5538150 Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/far_3.wss differ diff --git a/addons/cookoff/sounds/shotbullet/mid_1.wss b/addons/cookoff/sounds/shotbullet/mid_1.wss new file mode 100644 index 0000000000..b02a481b42 Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/mid_1.wss differ diff --git a/addons/cookoff/sounds/shotbullet/mid_2.wss b/addons/cookoff/sounds/shotbullet/mid_2.wss new file mode 100644 index 0000000000..1e184cc1ef Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/mid_2.wss differ diff --git a/addons/cookoff/sounds/shotbullet/mid_3.wss b/addons/cookoff/sounds/shotbullet/mid_3.wss new file mode 100644 index 0000000000..10606bf138 Binary files /dev/null and b/addons/cookoff/sounds/shotbullet/mid_3.wss differ diff --git a/addons/cookoff/sounds/shotrocket/close_1.wss b/addons/cookoff/sounds/shotrocket/close_1.wss new file mode 100644 index 0000000000..31ff1cbe38 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/close_1.wss differ diff --git a/addons/cookoff/sounds/shotrocket/close_2.wss b/addons/cookoff/sounds/shotrocket/close_2.wss new file mode 100644 index 0000000000..8ef09dcf04 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/close_2.wss differ diff --git a/addons/cookoff/sounds/shotrocket/close_3.wss b/addons/cookoff/sounds/shotrocket/close_3.wss new file mode 100644 index 0000000000..5410c359e4 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/close_3.wss differ diff --git a/addons/cookoff/sounds/shotrocket/far_1.wss b/addons/cookoff/sounds/shotrocket/far_1.wss new file mode 100644 index 0000000000..e71990476b Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/far_1.wss differ diff --git a/addons/cookoff/sounds/shotrocket/far_2.wss b/addons/cookoff/sounds/shotrocket/far_2.wss new file mode 100644 index 0000000000..bae24fa78e Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/far_2.wss differ diff --git a/addons/cookoff/sounds/shotrocket/far_3.wss b/addons/cookoff/sounds/shotrocket/far_3.wss new file mode 100644 index 0000000000..093e841277 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/far_3.wss differ diff --git a/addons/cookoff/sounds/shotrocket/mid_1.wss b/addons/cookoff/sounds/shotrocket/mid_1.wss new file mode 100644 index 0000000000..f927d7f174 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/mid_1.wss differ diff --git a/addons/cookoff/sounds/shotrocket/mid_2.wss b/addons/cookoff/sounds/shotrocket/mid_2.wss new file mode 100644 index 0000000000..785dd5b603 Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/mid_2.wss differ diff --git a/addons/cookoff/sounds/shotrocket/mid_3.wss b/addons/cookoff/sounds/shotrocket/mid_3.wss new file mode 100644 index 0000000000..7fb384421d Binary files /dev/null and b/addons/cookoff/sounds/shotrocket/mid_3.wss differ diff --git a/addons/cookoff/sounds/shotshell/close_1.wss b/addons/cookoff/sounds/shotshell/close_1.wss new file mode 100644 index 0000000000..aa9a0bc718 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/close_1.wss differ diff --git a/addons/cookoff/sounds/shotshell/close_2.wss b/addons/cookoff/sounds/shotshell/close_2.wss new file mode 100644 index 0000000000..355d061d01 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/close_2.wss differ diff --git a/addons/cookoff/sounds/shotshell/close_3.wss b/addons/cookoff/sounds/shotshell/close_3.wss new file mode 100644 index 0000000000..3847fa870f Binary files /dev/null and b/addons/cookoff/sounds/shotshell/close_3.wss differ diff --git a/addons/cookoff/sounds/shotshell/far_1.wss b/addons/cookoff/sounds/shotshell/far_1.wss new file mode 100644 index 0000000000..262b037c12 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/far_1.wss differ diff --git a/addons/cookoff/sounds/shotshell/far_2.wss b/addons/cookoff/sounds/shotshell/far_2.wss new file mode 100644 index 0000000000..38e0e1eb81 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/far_2.wss differ diff --git a/addons/cookoff/sounds/shotshell/far_3.wss b/addons/cookoff/sounds/shotshell/far_3.wss new file mode 100644 index 0000000000..781f86e4b8 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/far_3.wss differ diff --git a/addons/cookoff/sounds/shotshell/mid_1.wss b/addons/cookoff/sounds/shotshell/mid_1.wss new file mode 100644 index 0000000000..76c68cdee1 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/mid_1.wss differ diff --git a/addons/cookoff/sounds/shotshell/mid_2.wss b/addons/cookoff/sounds/shotshell/mid_2.wss new file mode 100644 index 0000000000..f84b579bc4 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/mid_2.wss differ diff --git a/addons/cookoff/sounds/shotshell/mid_3.wss b/addons/cookoff/sounds/shotshell/mid_3.wss new file mode 100644 index 0000000000..990a583a04 Binary files /dev/null and b/addons/cookoff/sounds/shotshell/mid_3.wss differ diff --git a/addons/cookoff/stringtable.xml b/addons/cookoff/stringtable.xml index 8dbe37937b..15d2d2adec 100644 --- a/addons/cookoff/stringtable.xml +++ b/addons/cookoff/stringtable.xml @@ -2,13 +2,13 @@ - ACE Cook off + ACE Cook-off ACE Detonación inducida por calor - ACE Esplosione + ACE Esplosioni di Munizioni ACE 殉爆效果 ACE 殉爆效果 ACE 誘爆 - ACE 쿡오프 + ACE 유폭 ACE Durchzündung ACE Auto-inflammation ACE Samozapłon @@ -16,45 +16,104 @@ ACE Cook off ACE Vznícení munice - - Damage handling and turret effects - Daño y efectos de torreta - Schadensberechnung und Geschützturmeffekte - 損傷処理と砲塔の効果 - Обработка урона и эффектов срыва башни - Manipulação de dano e efeitos de torre - Dégâts et effets de tourelle - 傷害控制及炮塔效果 - 损坏处理和炮塔效果 - Manovrabilità danneggiata ed effetti torretta - Poškodit ovládání a efekty věže - Obsługa obrażeń i efekty wieży - 피해량 조절 및 포탑에 효과 부여 + + Enable vehicle cook-off fire + 車両の誘爆火災を有効化 + Вкл. возгорание техники + 차량 유폭 화재를 활성화합니다 + Abilita incendio dei veicoli + Aktiviert Fahrzeug Munitionsbrand - - Changes damage handling for cook off and turret explosion effects - Cambia el daño de la detonación inducida por calor y los efectos de la explosión de la torreta - Ändert die Schadensberechnung für die Durchzündung und die Explosionseffekte des Geschützturmes - 誘爆の損傷処理と砲塔の爆発効果を変更します。 - Изменяет обработку урона для возгорания и эффекта срыва башни - Modifica a manipulação de dano para o cozinhamento de munição e efeitos de explosão da torre - Modifie la gestion des dégâts pour l'auto-inflammation et les effets d'explosion de tourelle. - 更改殉爆以及炮塔爆炸之傷害控制 - 改变殉爆和炮塔爆炸的损坏处理效果 - Modifica la gestione dei danni per gli effetti di esplosione della torretta e danneggiamenti - Změní poškození ovládání a efekty výbuchu veže - Zmienia obsługę obrażeń podczas samozapłonu i eksplozji wieży - 쿡오프로 인해 피해량의 변화와 포탑 터짐현상을 결정합니다. + + Enables vehicle cook-off fire effects.\nThis doesn't include ammunition detonations. + 車両の誘爆火災エフェクトを有効化します。\nこれには弾薬の爆発は含まれません。 + Вкл. эффект горения техники. \nНе включает детонацию боекомплекта + 차량 유폭 효과를 활성화합니다.\n여기엔 탄약 유폭이 포함되지 않습니다. + Abilita effetti di incendio del veicolo dovuto all'esplosione delle munizioni.\nQuesto non include gli effetti di esplosione. + Aktiviert Fahrzeug Brandeffekte durch Durchzündung.\nExplosionseffekte sind nicht mit einbegriffen. + + + Vehicle cook-off fire duration multiplier + 車両の誘爆火災の持続時間倍率 + Увел. продолжительности горения техники + 차량 유폭 화재 지속 시간 계수 + Coefficiente di durata incendio dei veicoli + Fahrzeugbrand Dauer-Multiplikator + + + Multiplier for how long vehicle cook-off fire lasts.\nSetting to 0 will disable vehicle cook-off fire. + 車両の誘爆火災の持続時間をどのくらいの長さにするかの倍率。\n0に設定すると車両の誘爆火災が無効化されます。 + Увел. продолжительности горения техники. \nУстановка значения на 0 выключает возгорание техники. + 차량 유폭 화재가 지속되는 시간에 대한 계수입니다.\n0으로 설정하면 차량 쿸오프 화재가 비활성화됩니다. + Coefficiente di durata degli incendi dei veicoli.\nImpostarlo su 0 disabilita incendi dei veicoli. + Multiplikator der Fahrzeugbrand Dauer.\nIhn auf 0 zu setzen wird Munitionsbrände deaktivieren. + + + Vehicle cook-off fire probability multiplier + 車両の誘爆火災の可能性倍率 + Возможность усиления пожара при детонации техники + 차량 유폭 화재 확률 계수 + Probabilità di incendio dei veicoli + Fahrzeug Munitionsbrand Wahrscheinlichkeit-Multiplikator + + + Multiplier for vehicle cook-off fire probability. Higher value results in higher cook-off probability.\nSetting to 0 will disable vehicle cook-off fire. + 車両の誘爆火災がどのくらいの可能性で発生するかの倍率。高い数値は高い誘爆の可能性につながります。\n0に設定すると車両の誘爆火災が無効化されます。 + Увел. вероятности возникновения возгорания техники. Большое значение указывает на высокую вероятность детонации. \nУстановка значения 0 предотвращает возгорание техники. + 차량 유폭 화재 확률에 대한 계수입니다. 값이 높을 수록 유폭 확률이 높아집니다.\n0으로 설정하면 차량 유폭 화재가 비활성화됩니다. + Coefficiente di probabilità degli incendi dei veicoli.\nValori maggiori aumentano la probabilità di incendi.\nImpostarlo su 0 disabilita incendi dei veicoli. + Multiplikator der Fahrzeugbrand Wahrscheinlichkeit.\nHöhere Werte erhöhen die Wahrscheinlichkeit.\nEin Null-Wert wird Munitionsbrände deaktivieren. + + + Destroy vehicles after cook-off + 유폭 후 차량 파괴 + 殉爆发生后摧毁载具 + Уничтожать технику после детонации + Destruir vehículos tras la detonación inducida por calor + 誘爆後に車両を破壊する + Zniszcz Pojazdy po Zakończeniu Samozapłonu + Zerstöre Fahrzeuge nach der Durchzündung + Distruggi Veicoli dopo Esplosione Munizioni + Destruction des véhicules après auto-inflammation + Destruir veículos após cozinhamento + + + Controls whether vehicles will always be destroyed after cooking off. + 誘爆の終了後に車両を必ず完全破壊するかどうかを設定します。 + Kontroluje, czy pojazdy będą zawsze niszczone po samozapłonie. + Steuert, ob Fahrzeuge nach dem Durchzünden immer zerstört werden. + Determina se veicoli saranno sempre distrutti dall'esplosione delle munizioni. + 유폭 후 차량이 항상 파괴되는지 여부를 조정합니다. + 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. + Определяет, всегда ли транспортные средства будут уничтожаться после детонации. + Controla si los vehículos siempre será destruidos despues de la detonación inducida por calor. + + + Enable vehicle ammo cook-off + 車両弾薬の誘爆を有効化 + Вкл. детонацию боеприпасов в технике. + 차량 내 탄약 유폭 활성화 + Abilita esplosioni delle munizioni dei veicoli + Aktiviert Fahrzeug Munitionsdurchzündung + + + Enables cooking off of vehicle ammunition. Fires ammunition projectiles while vehicle has ammunition remaining.\nThis doesn't include fire effects. + 車両弾薬の誘爆を有効化します。車両に積載されたままの弾薬と弾頭が発射されます。\nこれには火災エフェクトは含まれません。 + Вкл. детонацию боеприпасов на технике. Боеприпасы и боеголовки, которые остаются заряженными на транспортном средстве, будут приведены в действие. \nЭто не включает эффекты пожара. + 차량 내 탄약 유폭을 활성화합니다. 차량에 탄약이 남아 있는 동안 탄약 발사체를 발사합니다.\n여기엔 화재 효과가 포함되지 않습니다. + Abilita l'esplosione delle munizioni dei veicoli. Spara via pezzi di munizioni se il veicolo ha ancora munizioni rimanenti.\nNon include gli effetti di fuoco. + Aktiviert Durchzündung von Fahrzeugmunition. Schleudert Munitionsfragmente umher wenn das Fahrzeug noch Munition an Bord hat.\nBrandeffekte sind nicht mit einbegriffen. - Enable ammo box cook off + Enable ammo box cook-off Habilitar detonación inducida por calor en las cajas de munición - 弾薬箱に誘爆を有効化 + 弾薬箱の誘爆を有効化 Durchzündung für Munitionskisten ermöglichen - 탄약 상자 쿡오프 현상 활성화 + 탄약 상자 유폭 현상 활성화 Aktywuj samozapłon skrzyń z amunicją Auto-inflammation des caisses de munitions - Abilita esplosione cassa munizioni + Abilita esplosione casse munizioni 開啟彈藥箱殉爆效果 开启弹药箱殉爆效果 Разрешить детонацию ящиков с боеприпасами @@ -62,150 +121,49 @@ Povolit vynícení munice v krabicích - Enables cooking off of ammo boxes. - Habilita la detonación inducida por calor en las cajas de munición - 弾薬箱が誘爆するようになります。 - Ermöglicht Durchzündung von Munitionskisten. - 탄약 상자에 쿡오프 현상을 적용합니다. - Aktywuje samozapłon skrzyń z amunicją - Permet l'auto-inflammation des caisses de munitions. - Abilita l'esplosione della cassa di munizioni. - 開啟彈藥箱殉爆效果 - 开启弹药箱殉爆效果 - Активирует детонацию ящиков с боеприпасами - Permitir que caixas de munição cozinhem. - Zapíná vznícení munice v krabicích. - - - Enable Ammunition cook off - Habilitar la detonación inducida por calor en la munición - 弾薬の誘爆を有効化 - Durchzündung für Munition ermöglichen - 탄약 쿡오프 현상 활성화 - Aktywuj samozapłon amunicji - Auto-inflammation des munitions - Abilita Esplosione munizioni - 開啟彈藥殉爆效果 - 开启弹药殉爆效果 - Разрешить детонацию боекомплекта - Permitir cozinhar munição - Povolit vznícení munice - - - Enables Ammunition cook off. Fires ammunition projectiles while vehicle is on fire and has ammunition. - Habilita la detonación inducida por calor en la munición. Dispara proyectiles de munición mientras el vehículo está ardiendo y tiene munición - 弾薬が誘爆します。車両が燃えると、搭載している弾薬が激しく燃え上がります。 - Ermöglicht Durchzündung von Munition. Feuert Projektile der Munition ab, solange das Fahrzeug brennt und Munition besitzt. - Aktywuje samozapłon amunicji. Wystrzeliwuje pociski podczas gdy pojazd płonie i posiada amunicję. - Permet l'auto-inflammation des munitions. Tire des projectiles tant que le véhicule est en feu et contient des munitions. - Abilita l'esplosione delle munizioni. Spara munizioni di proiettili quando il veicolo va a fuoco e contiene munizioni. - 開啟彈藥殉爆效果。當一台載有彈藥的載具起火時, 將會有殉爆的效果 - 开启弹药殉爆效果。当一台载有弹药的载具起火时,将会有殉爆的效果。 - 쿡오프 현상을 활성화 합니다. 이것은 탄약에 불이 붙어 있는 동안 주변에 발사체를 발사합니다. - Активирует детонацию боекомплекта в горящей технике. - Permite que a munição cozinhe. Dispara projéteis de munição enquanto o veículo está em chamas e tem munição. - Zapíná vznícení munice. Vystřeluje projektily po dobu kdy vozidlo hoří a má munici. + Enables cooking off of ammo boxes.\nThis doesn't include fire effects. + 弾薬箱の誘爆を有効化します。\nこれには火災エフェクトは含まれません。 + Вкл. детонацию ящика с боеприпасами. \nЭто не включает эффекты огня. + 탄약 상자 유폭을 활성화합니다.\n여기엔 화재 효과가 포함되지 않습니다. + Abilita esplosioni delle casse di munizioni.\nNon include effetti di fuoco. + Aktiviert Munitionskisten Durchzündung.\nBrandeffekte sind nicht mit einbegriffen. - Ammunition cook off duration - Duración de la detonación inducida por calor de la munición - Munitionsdurchzündungsdauer - Czas trwania samozapłonu amunicji - 弾薬の誘爆持続時間 - Durée d'auto-inflammation des munitions - Durata esplosione munizioni - 彈藥殉爆效果持續時間 - 弹药殉爆效果持续时间 - 쿡오프 지속 시간 - Длительность детонации боеприпасов - Duração do cozinhamento de munição - Doba trvání vznícení munice + Ammo cook-off duration multiplier + 弾薬の誘爆の持続時間倍率 + Увеличение продолжительности детонации боеприпасов. + 탄약 유폭 시간 계수 + Coefficiente di durata esplisioni di munizioni + Fahrzeug Munitionsdurchzündung Dauer-Multiplikator - Multiplier for how long cook off lasts [Setting to 0 will disable ammo cookoff] - Multiplicador de cuanto dura la detonación inducida por calor [Ponerlo a cero la deshabilita] - Faktor für die Munitionsdurchzündungsdauer [0 zum Deaktivieren] - Multiplicateur permettant de régler la durée durant laquelle les munitions continuent d'exploser [Une valeur de 0 désactive l'auto-inflammation]. - Mnożnik decydujący jak długo ma trwać samozapłon amunicji [Ustawienie na 0 spowoduje wyłącznie samozapłonu] - 誘爆の持続時間を乗数で設定します。[0 に設定で誘爆を無効化] - Moltiplicatore della durata dell'esplosione [Impostare 0 disabiliterà l'esplosione delle munizioni] - 設定彈藥殉爆效果會持續多久時間 [輸入0來關閉殉爆效果] - 设定弹药殉爆效果会持续多久时间 [输入0来关闭殉爆效果] - 쿡오프 지속 시간의 배수 [0 이면 비활성] - Множитель длительности детонации [0 - отключает детонацию боеприпасов] - Multiplicação da duração do cozinhamento [0 faz com que o cozinhamento seja desativado] - Multiplikátor doby trvání vznícení munice [Nastavte 0 pro vypnutí vznícení munice] + Multiplier for how long ammunition cook-off lasts, for both vehicles and ammo boxes.\nSetting to 0 will disable ammo cook-off for both vehicles and ammo boxes. + 弾薬の誘爆の持続時間をどのくらいの長さにするかの倍率。車両弾薬と弾薬箱どちらにも影響します。\n0に設定すると弾薬の誘爆が無効化されます。 + Увеличение продолжительности детонации боеприпасов. Это влияет как на боеприпасы в технике, так и на ящики с боеприпасами. \nУстановка значения 0 отключает детонацию боеприпасов. + 차량과 탄약 상자 모두에 대해 탄약 유폭이 지속되는 시간에 대한 계수입니다.\n0으로 설정하면 차량과 탄약 상자 모두에 대해 탄약 유폭이 비활성화됩니다. + Coefficiente della durata di esplosioni delle munizioni, sia per veicoli che casse.\nImpostarlo su 0 disabilita esplosioni di veicoli e casse. + Multiplikator der Munitionsdurchzündungs-Dauer, gilt für Fahrzeuge und Munitionskisten.\nIhn auf 0 zu setzen wird Durchzünden deaktivieren. - - Cook-off probability coefficient - Coeficiente de probabilidad de detonación inducida por calor - 誘爆の可能性係数 - Coefficiente probabilità esplosione - Faktor für Wahrscheinlichkeit der Durchzündung - 殉爆發生機率係數 - 殉爆发生机率系数 - Coefficient de probabilité d'auto-inflammation - Współczynnik prawdopodobieństwa samozapłonu - Коэф. вероятности детонации - Probabilidade de Cozinhar - Koeficient pravděpodobnosti vznícení munice - 쿡오프 발생 확률 계수 + + Enable ammo removal during cook-off + 誘爆による弾薬の除去を有効化 + Retirer les munitions durant l'auto-inflammation + Aktiviert/Deaktiviert Entfernung der Munition beim Durchzünden + Abilita rimozione munizioni dopo l'esplosione + Włącz/Wyłącz usuwanie amunicji podczas samozapłonu + 启用/禁用殉爆过程中的弹药移除功能 + 유폭 시 탄약 제거 활성화/비활성화 + Вкл. удаление боеприпасов из-за детонации + Habilita/Deshabilita ka eliminación de munición durante la detonación inducida por calor - - Multiplier for cook-off probability. Higher value results in higher cook-off probability - Multiplicador de probabilidad de detonación inducida por calor. Valores más altos producen mayor probabilidad - 誘爆する可能性の乗数。高い値では誘爆する可能性が高まります。 - Moltiplicatore per la probabilità dell'esplosione. Un valore più alto aumenta la probabilità dell'esplosione - Faktor für Wahrscheinlichkeit der Durchzündung. Ein höherer Wert führt zu höherer Durchzündungswahrscheinlichkeit. - 調整殉爆發生機率係數。值越高代表越容易發生殉爆 - 调整殉爆发生机率系数。值越高代表越容易发生殉爆。 - Multiplicateur de probabilité de l'auto-inflammation. Plus la valeur est élevée, plus la probabilité de combustion est grande. - Mnożnik prawdopodobieństwa samozapłonu. Większa wartość oznacza większe prawdopodobieństwo samozapłonu - Множитель коэффициента вероятности детонации. Чем выше значение, тем выше вероятность - Multiplicador para a chance de cozinhamento. Valores mais altos aumentam as chances de ocorrer. - Multiplikátor pro pravděpodobnost vznícení munice. Vyšší hodnota znamená vyšší šanci vznícení munice. - 쿡오프가 일어날 확률에 계수를 곱합니다. 더 큰 숫자는 더 높은 확률의 쿡오프를 일으킵니다. - - - Destroy Vehicles After Cook-off - 쿡오프 후 차량 파괴 - 殉爆发生后摧毁载具 - Уничтожать технику после детонации - Destruir vehículos tras la detonación inducida por calor - 誘爆後に車両を破壊する - Zniszcz Pojazdy po Zakończeniu Samozapłonu - Zerstöre Fahrzeuge nach der Durchzündung - Destruction des véhicules après auto-inflammation - - - Controls whether vehicles will always be destroyed after cooking off. - 誘爆後に車両を破壊するかどうかを設定する。 - Kontroluje, czy pojazdy będą zawsze niszczone po samozapłonie. - Steuert, ob Fahrzeuge nach dem Durchzünden immer zerstört werden. - 쿡오프 후 차량이 항상 파괴되는지 여부를 조정합니다. - Contrôle si les véhicules seront toujours détruits après l'auto-inflammation. - - - Enable Cook-Off Vehicle Fire - 誘爆火災を有効化 - Véhicules - Feu durant l'auto-inflammation - Вкл. горение техники от детонации - Aktiviert das in Brand setzen des Fahrzeugs während des Durchzündens der Munition - Włącz pożar pojazdu podczas samozapłonu - 启用殉爆载具火灾 - 차량 쿡오프 화재 활성화 - Habilitar incendio a causa de la detonación inducida por calor - - - Whether or not vehicles will catch on fire during cook-off - 誘爆により車両が炎上するかどうかを設定します。 - Définit si les véhicules prennent feu durant l'auto-inflammation de leurs munitions. - Будет ли техника гореть при детонации боеприпасов - Ob Fahrzeuge in Brand gesetzt werden, während deren Munition durchzündet. - Określa, czy pojazdy zapalą się podczas samozapłonu ich amunicji. - 车辆在殉爆过程中是否会起火 - 쿡오프가 일어나면 차량에 불이 붙습니다. - Define si los vehículos salen ardiendo despues de una detonación inducida por calor. + + Removes all ammo during cook-off. + Retire des munitions des véhicules durant une auto-inflammation. + Entfernt Munition während dem Durchzünden der Munition eines Fahrzeuges. + 誘爆によって全ての弾薬を除去します。 + Все боеприпасы уничтожаются путем подрыва. + 유폭 중 모든 탄약을 제거합니다. + Rimuovi le munizioni dal veicolo durante le esplosioni. diff --git a/addons/csw/Cfg3den.hpp b/addons/csw/Cfg3den.hpp deleted file mode 100644 index 5d15e19d6b..0000000000 --- a/addons/csw/Cfg3den.hpp +++ /dev/null @@ -1,43 +0,0 @@ -class ctrlCombo; -class Cfg3DEN { - class Attributes { - class Default; - class Title: Default { - class Controls { - class Title; - }; - }; - class Combo: Title { - class Controls: Controls { - class Title: Title {}; - class Value; - }; - }; - class GVAR(assemblyModeControl): Combo { - class Controls: Controls { - class Title: Title {}; - class Value: Value { - class Items { - class Disable { - text = "$STR_DISABLED"; - value = 0; - }; - class Enable { - text = "$STR_CONFIG_JOYSTICK_ENABLED"; - value = 1; - }; - class EnableAndEmpty { - text = CSTRING(eden_enableAndEmpty); - value = 2; - }; - class Default { - text = "$STR_VEHICLE_DEFAULT"; - value = 3; - default = 1; - }; - }; - }; - }; - }; - }; -}; diff --git a/addons/csw/CfgVehicles.hpp b/addons/csw/CfgVehicles.hpp index dd5537f645..724d5ed513 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])]); }; }; }; @@ -137,7 +138,6 @@ class CfgVehicles { class StaticMGWeapon: StaticWeapon {}; class HMG_01_base_F: StaticMGWeapon { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; proxyWeapon = QGVAR(HMG_Static); @@ -197,7 +197,6 @@ class CfgVehicles { class GMG_TriPod; class GMG_01_base_F: GMG_TriPod { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; proxyWeapon = QGVAR(GMG_20mm); // Weapon Proxy (Shorter Reload Time) [CfgWeapons] @@ -231,7 +230,6 @@ class CfgVehicles { class AT_01_base_F: StaticMGWeapon { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; proxyWeapon = QGVAR(Titan_AT_Static); @@ -245,7 +243,6 @@ class CfgVehicles { }; class AA_01_base_F: StaticMGWeapon { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; proxyWeapon = QGVAR(Titan_AA_Static); // Weapon Proxy (Shorter Reload Time) [CfgWeapons] @@ -261,7 +258,6 @@ class CfgVehicles { class StaticMortar: StaticWeapon {}; class Mortar_01_base_F: StaticMortar { - // ENABLE_CSW_ATTRIBUTE; class ADDON { enabled = 1; magazineLocation = ""; 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 a1aa348659..87196f3377 100644 --- a/addons/csw/XEH_postInit.sqf +++ b/addons/csw/XEH_postInit.sqf @@ -6,24 +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(disableVanillaAssembly), { - params ["_staticWeapon"]; - TRACE_1("disableVanillaAssembly eh",_staticWeapon); - _staticWeapon enableWeaponDisassembly false; -}] call CBA_fnc_addEventHandler; - [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/XEH_preInit.sqf b/addons/csw/XEH_preInit.sqf index 6ecb2a0c2f..2cef0dfd2c 100644 --- a/addons/csw/XEH_preInit.sqf +++ b/addons/csw/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(initializedStaticTypes) = []; diff --git a/addons/csw/config.cpp b/addons/csw/config.cpp index 98abcea5c0..aab2b0416f 100644 --- a/addons/csw/config.cpp +++ b/addons/csw/config.cpp @@ -15,7 +15,6 @@ class CfgPatches { }; }; -#include "Cfg3den.hpp" #include "CfgEventHandlers.hpp" #include "CfgVehicles.hpp" #include "CfgWeapons.hpp" diff --git a/addons/csw/dev/checkStaticWeapons.sqf b/addons/csw/dev/checkStaticWeapons.sqf index 59e712cb70..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..4d6234f94a 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); @@ -39,7 +40,7 @@ private _nearSupplies = [_gunner] + ((_staticWeapon nearSupplies 10) select { } forEach ((magazineCargo _xSource) select {isClass (_cfgMagGroups >> _x)}); TRACE_2("",_xSource,_cswMagazines); - private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines; + private _compatibleMags = compatibleMagazines _weapon; if (_magazine != "") then { _compatibleMags insert [0, [_magazine]]; }; 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..65dd81cc41 100644 --- a/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_canDeployWeapon.sqf @@ -1,11 +1,11 @@ #include "..\script_component.hpp" /* - * Author:tcvm + * Author: tcvm * Checks if you can deploy a weapon on the tripod * * Arguments: * 0: Target Tripod - * 0: Player + * 1: Player * * Return Value: * Wether or not you can deploy the weapon @@ -16,10 +16,8 @@ * Public: No */ -params ["_target", "_player", "", "_carryWeaponClassname"]; -if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapon _player }; +params ["_target", "_player"]; // 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))) != ""} - +{(getText (configFile >> "CfgWeapons" >> secondaryWeapon _player >> 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..0d508bfa89 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: @@ -19,8 +19,5 @@ params ["_staticWeapon"]; // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select (_staticWeapon getVariable [QGVAR(assemblyMode), 3]); -private _notCrewed = (crew _staticWeapon) isEqualTo []; -private _deadCrew = !(alive (gunner _staticWeapon)); // need to eject body??? - -_assemblyMode && {_notCrewed || _deadCrew} +_assemblyMode && {alive _staticWeapon} && {((crew _staticWeapon) findIf {alive _x && {!unitIsUAV _x}}) == -1} // return diff --git a/addons/csw/functions/fnc_assemble_deployTripod.sqf b/addons/csw/functions/fnc_assemble_deployTripod.sqf index b2ba0e4ea5..29cc4b5876 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: @@ -19,16 +19,20 @@ params ["_player"]; TRACE_1("assemble_deployTripod",_player); + // Save magazines and attachments (handle loaded launchers which can become csw like CUP Metis) + private _secondaryWeaponInfo = (getUnitLoadout _player) select 1; + private _secondaryWeaponClassname = _secondaryWeaponInfo deleteAt 0; + + // Remove empty entries + _secondaryWeaponInfo = _secondaryWeaponInfo select {_x isNotEqualTo "" && {_x isNotEqualTo []}}; + // Remove the tripod from the launcher slot - private _secondaryWeaponClassname = secondaryWeapon _player; - // handle loaded launchers which can become csw like CUP Metis - private _secondaryWeaponMagazine = secondaryWeaponMagazine _player param [0, ""]; - _player removeWeaponGlobal (secondaryWeapon _player); + _player removeWeaponGlobal _secondaryWeaponClassname; private _onFinish = { params ["_args"]; - _args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponMagazine"]; - TRACE_3("deployTripod finish",_player,_secondaryWeaponClassname,_secondaryWeaponMagazine); + _args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponInfo"]; + TRACE_3("deployTripod finish",_player,_secondaryWeaponClassname,_secondaryWeaponInfo); private _tripodClassname = getText(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deploy"); @@ -36,12 +40,26 @@ private _cswTripod = createVehicle [_tripodClassname, [0, 0, 0], [], 0, "NONE"]; // Because the tripod can be a "full weapon" we disable any data that will allow it to be loaded _cswTripod setVariable [QGVAR(assemblyMode), 2, true]; // Explicitly set enabled&unload assembly mode and broadcast - if (_secondaryWeaponMagazine isNotEqualTo "") then { - _cswTripod setVariable [QGVAR(secondaryWeaponMagazine), _secondaryWeaponMagazine]; + + private _secondaryWeaponMagazines = []; + + { + // Magazines + if (_x isEqualType []) then { + _secondaryWeaponMagazines pushBack _x; + } else { + // Items + [_player, _x, true] call CBA_fnc_addItem; + }; + } forEach _secondaryWeaponInfo; + + // Only add magazines once the weapon is fully ready + if (_secondaryWeaponMagazines isNotEqualTo []) then { + _cswTripod setVariable [QGVAR(secondaryWeaponMagazines), _secondaryWeaponMagazines, true]; }; + if (!GVAR(defaultAssemblyMode)) then { - TRACE_1("global disableVanillaAssembly event",_cswTripod); // handles it being assembled when setting is disabled - [QGVAR(disableVanillaAssembly), [_cswTripod]] call CBA_fnc_globalEvent; + [_cswTripod, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); }; private _posATL = _player getRelPos [2, 0]; @@ -54,7 +72,7 @@ [_player, "PutDown"] call EFUNC(common,doGesture); // drag after deploying - if ((missionNamespace getVariable [QGVAR(dragAfterDeploy), false]) && {["ACE_dragging"] call EFUNC(common,isModLoaded)}) then { + if ((missionNamespace getVariable [QGVAR(dragAfterDeploy), false]) && {["ace_dragging"] call EFUNC(common,isModLoaded)}) then { if ([_player, _cswTripod] call EFUNC(dragging,canCarry)) then { TRACE_1("starting carry",_cswTripod); [_player, _cswTripod] call EFUNC(dragging,startCarry); @@ -66,15 +84,18 @@ private _onFailure = { params ["_args"]; - _args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponMagazine"]; - TRACE_3("deployTripod failure",_player,_secondaryWeaponClassname,_secondaryWeaponMagazine); + _args params ["_player", "_secondaryWeaponClassname", "_secondaryWeaponInfo"]; + TRACE_3("deployTripod failure",_player,_secondaryWeaponClassname,_secondaryWeaponInfo); - _player addWeaponGlobal _secondaryWeaponClassname; - if (_secondaryWeaponMagazine isNotEqualTo "") then { - _player addWeaponItem [_secondaryWeaponClassname, _secondaryWeaponMagazine, true]; - }; + // Add tripod back + [_player, _secondaryWeaponClassname] call CBA_fnc_addWeaponWithoutItems; + + // Add all attachments back + { + _player addWeaponItem [_secondaryWeaponClassname, _x, true]; + } forEach _secondaryWeaponInfo; }; private _deployTime = getNumber(configFile >> "CfgWeapons" >> _secondaryWeaponClassname >> QUOTE(ADDON) >> "deployTime"); - [TIME_PROGRESSBAR(_deployTime), [_player, _secondaryWeaponClassname, _secondaryWeaponMagazine], _onFinish, _onFailure, localize LSTRING(PlaceTripod_progressBar)] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_deployTime), [_player, _secondaryWeaponClassname, _secondaryWeaponInfo], _onFinish, _onFailure, LLSTRING(PlaceTripod_progressBar)] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; diff --git a/addons/csw/functions/fnc_assemble_deployWeapon.sqf b/addons/csw/functions/fnc_assemble_deployWeapon.sqf index f646047da2..974bf03431 100644 --- a/addons/csw/functions/fnc_assemble_deployWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_deployWeapon.sqf @@ -1,39 +1,54 @@ #include "..\script_component.hpp" /* - * Author:tcvm + * Author: tcvm * Deploys the current CSW * * Arguments: - * 0: Unit + * 0: Target + * 1: Unit + * 2: Args + * 3: Action Data * * Return Value: * None * * Example: - * [player] call ace_csw_fnc_assemble_deployWeapon + * [cursorObject, player] call ace_csw_fnc_assemble_deployWeapon * * Public: No */ [{ - params ["_tripod", "_player", "", "_carryWeaponClassname"]; - if (isNil "_carryWeaponClassname") then { _carryWeaponClassname = secondaryWeapon _player }; + params ["_tripod", "_player"]; + + // Save magazines and attachments (handle loaded launchers which can become csw like CUP Metis) + private _carryWeaponInfo = (getUnitLoadout _player) select 1; + private _carryWeaponClassname = _carryWeaponInfo deleteAt 0; + + // Remove empty entries + _carryWeaponInfo = _carryWeaponInfo select {_x isNotEqualTo "" && {_x isNotEqualTo []}}; + TRACE_3("assemble_deployWeapon_carryWeaponClassname",_tripod,_player,_carryWeaponClassname); private _tripodClassname = typeOf _tripod; + private _weaponConfig = configfile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON); + private _assembledClassname = getText (_weaponConfig >> "assembleTo" >> _tripodClassname); + + if (!isClass (configFile >> "CfgVehicles" >> _assembledClassname)) exitWith {ERROR_1("bad static classname [%1]",_assembledClassname);}; + _player removeWeaponGlobal _carryWeaponClassname; - private _assembledClassname = getText(configfile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "assembleTo" >> _tripodClassname); - private _deployTime = getNumber(configfile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "deployTime"); - if (!isClass (configFile >> "CfgVehicles" >> _assembledClassname)) exitWith {ERROR_1("bad static classname [%1]",_assembledClassname);}; + private _deployTime = getNumber (_weaponConfig >> "deployTime"); TRACE_4("",_carryWeaponClassname,_tripodClassname,_assembledClassname,_deployTime); private _onFinish = { params ["_args"]; - _args params ["_tripod", "_player", "_assembledClassname"]; + _args params ["_tripod", "_player", "_assembledClassname", "", "_carryWeaponInfo"]; TRACE_3("deployWeapon finish",_tripod,_player,_assembledClassname); + private _secondaryWeaponMagazines = _tripod getVariable [QGVAR(secondaryWeaponMagazines), []]; + private _tripodPos = getPosATL _tripod; private _tripodDir = getDir _tripod; deleteVehicle _tripod; @@ -41,13 +56,28 @@ _tripodPos set [2, (_tripodPos select 2) + 0.1]; // Delay a frame so tripod has a chance to be deleted [{ - params ["_assembledClassname", "_tripodDir", "_tripodPos"]; + params ["_assembledClassname", "_tripodDir", "_tripodPos", "_player", "_carryWeaponInfo", "_secondaryWeaponMagazines"]; private _csw = createVehicle [_assembledClassname, [0, 0, 0], [], 0, "NONE"]; // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] _csw setVariable [QGVAR(assemblyMode), 2, true]; // Explicitly set advanced assembly mode + unload, and broadcast + + { + // Magazines + if (_x isEqualType []) then { + _secondaryWeaponMagazines pushBack _x; + } else { + // Items + [_player, _x, true] call CBA_fnc_addItem; + }; + } forEach _carryWeaponInfo; + + // Only add magazines once the weapon is fully ready + if (_secondaryWeaponMagazines isNotEqualTo []) then { + _csw setVariable [QGVAR(secondaryWeaponMagazines), _secondaryWeaponMagazines, true]; + }; + if (!GVAR(defaultAssemblyMode)) then { - TRACE_1("global disableVanillaAssembly event",_csw); // handles it being assembled when setting is disabled - [QGVAR(disableVanillaAssembly), [_csw]] call CBA_fnc_globalEvent; + [_csw, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); }; _csw setDir _tripodDir; _csw setPosATL _tripodPos; @@ -56,23 +86,29 @@ }; [QGVAR(deployWeaponSucceeded), [_csw]] call CBA_fnc_localEvent; TRACE_2("csw placed",_csw,_assembledClassname); - }, [_assembledClassname, _tripodDir, _tripodPos]] call CBA_fnc_execNextFrame; + }, [_assembledClassname, _tripodDir, _tripodPos, _player, _carryWeaponInfo, _secondaryWeaponMagazines]] call CBA_fnc_execNextFrame; }; private _onFailure = { params ["_args"]; - _args params ["", "_player", "", "_carryWeaponClassname"]; + _args params ["", "_player", "", "_carryWeaponClassname", "_carryWeaponInfo"]; TRACE_2("deployWeapon failure",_player,_carryWeaponClassname); - _player addWeaponGlobal _carryWeaponClassname; + // Add weapon back + [_player, _carryWeaponClassname] call CBA_fnc_addWeaponWithoutItems; + + // Add all attachments back + { + _player addWeaponItem [_carryWeaponClassname, _x, true]; + } forEach _carryWeaponInfo; }; - private _codeCheck = { + private _condition = { params ["_args"]; _args params ["_tripod"]; - !isNull _tripod; + + alive _tripod }; - [TIME_PROGRESSBAR(_deployTime), [_tripod, _player, _assembledClassname, _carryWeaponClassname], _onFinish, _onFailure, localize LSTRING(AssembleCSW_progressBar), _codeCheck] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_deployTime), [_tripod, _player, _assembledClassname, _carryWeaponClassname, _carryWeaponInfo], _onFinish, _onFailure, LLSTRING(AssembleCSW_progressBar), _condition] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; - diff --git a/addons/csw/functions/fnc_assemble_pickupTripod.sqf b/addons/csw/functions/fnc_assemble_pickupTripod.sqf index 449a445dc2..0996c0f3d3 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: @@ -11,7 +11,7 @@ * None * * Example: - * [tripod, player] call ace_csw_fnc_assemble_pickupTripod + * [cursorObject, player] call ace_csw_fnc_assemble_pickupTripod * * Public: No */ @@ -20,28 +20,55 @@ params ["_tripod", "_player"]; TRACE_2("assemble_pickupTripod",_tripod,_player); - private _tripodClassname = getText(configOf _tripod >> QUOTE(ADDON) >> "disassembleTo"); - private _pickupTime = getNumber(configFile >> "CfgWeapons" >> _tripodClassname >> QUOTE(ADDON) >> "pickupTime"); + private _tripodClassname = getText (configOf _tripod >> QUOTE(ADDON) >> "disassembleTo"); + private _pickupTime = getNumber (configFile >> "CfgWeapons" >> _tripodClassname >> QUOTE(ADDON) >> "pickupTime"); private _onFinish = { params ["_args"]; _args params ["_tripod", "_player", "_tripodClassname"]; TRACE_3("assemble_pickupTripod finish",_tripod,_player,_tripodClassname); + // Save tripod position before it's deleted + private _tripodPos = getPosATL _tripod; + + // Eject dead units (all crew are dead at this point, otherwise condition would have failed), but ignore UAV units + { + if (unitIsUAV _x) then { + _tripod deleteVehicleCrew _x; + } else { + moveOut _x; + }; + } forEach (crew _tripod); + deleteVehicle _tripod; - _player addWeaponGlobal _tripodClassname; + [_player, "PutDown"] call EFUNC(common,doGesture); + + // If the player has space, give it to him + if ((alive _player) && {(secondaryWeapon _player) == ""}) exitWith { + [_player, _tripodClassname] call CBA_fnc_addWeaponWithoutItems; + }; + + // Try to find existing weapon holders + private _weaponHolder = nearestObject [_tripodPos, "WeaponHolder"]; + + // If there are none or too far away, make a new one + if (isNull _weaponHolder || {_tripodPos distance _weaponHolder > 2}) then { + _weaponHolder = createVehicle ["GroundWeaponHolder", [0, 0, 0], [], 0, "CAN_COLLIDE"]; + _weaponHolder setDir random [0, 180, 360]; + _weaponHolder setVehiclePosition [_tripodPos, [], 0, "CAN_COLLIDE"]; // places object on surface below + }; + + _weaponHolder addWeaponCargoGlobal [_tripodClassname, 1]; }; private _condition = { params ["_args"]; - _args params ["_tripod", "_player"]; - - !(isNull _tripod) && { (secondaryWeapon _player) isEqualTo "" } + _args params ["_tripod"]; + _tripod call FUNC(canPickupTripod) }; TRACE_3("",_pickupTime,typeOf _tripod,_tripodClassname); - [TIME_PROGRESSBAR(_pickupTime), [_tripod, _player, _tripodClassname], _onFinish, {}, localize LSTRING(PickupTripod_progressBar), _condition] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_pickupTime), [_tripod, _player, _tripodClassname], _onFinish, {}, LLSTRING(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..468f385efa 100644 --- a/addons/csw/functions/fnc_assemble_pickupWeapon.sqf +++ b/addons/csw/functions/fnc_assemble_pickupWeapon.sqf @@ -1,16 +1,17 @@ #include "..\script_component.hpp" /* - * Author:tcvm + * Author: tcvm * Dismounts the weapon from the tripod and drops its backpack beside * * Arguments: * 0: Static Weapon + * 1: Unit * * Return Value: * None * * Example: - * [weapon] call ace_csw_fnc_assemble_pickupWeapon + * [cursorObject, player] call ace_csw_fnc_assemble_pickupWeapon * * Public: No */ @@ -19,35 +20,44 @@ params ["_staticWeapon", "_player"]; TRACE_2("assemble_pickupWeapon",_staticWeapon,_player); - private _onDisassembleFunc = getText(configOf _staticWeapon >> QUOTE(ADDON) >> "disassembleFunc"); - private _carryWeaponClassname = getText(configOf _staticWeapon >> QUOTE(ADDON) >> "disassembleWeapon"); - private _turretClassname = getText(configOf _staticWeapon >> QUOTE(ADDON) >> "disassembleTurret"); - private _pickupTime = getNumber(configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "pickupTime"); - TRACE_4("",typeOf _staticWeapon,_carryWeaponClassname,_turretClassname,_pickupTime); - if (!isClass (configFile >> "CfgWeapons" >> _carryWeaponClassname)) exitWith {ERROR_1("bad weapon classname [%1]",_carryWeaponClassname);}; + private _weaponConfig = configOf _staticWeapon >> QUOTE(ADDON); + private _carryWeaponClassname = getText (_weaponConfig >> "disassembleWeapon"); + + if (!isClass (configFile >> "CfgWeapons" >> _carryWeaponClassname)) exitWith { + ERROR_1("bad weapon classname [%1]",_carryWeaponClassname); + }; + + private _turretClassname = getText (_weaponConfig >> "disassembleTurret"); + // Turret classname can equal nothing if the deploy bag is the "whole" weapon. e.g Kornet, Metis, other ATGMs - if ((_turretClassname isNotEqualTo "") && {!isClass (configFile >> "CfgVehicles" >> _turretClassname)}) exitWith {ERROR_1("bad turret classname [%1]",_turretClassname);}; + if ((_turretClassname != "") && {!isClass (configFile >> "CfgVehicles" >> _turretClassname)}) exitWith { + ERROR_1("bad turret classname [%1]",_turretClassname); + }; + + private _onDisassembleFunc = getText (_weaponConfig >> "disassembleFunc"); + + private _pickupTime = getNumber (configFile >> "CfgWeapons" >> _carryWeaponClassname >> QUOTE(ADDON) >> "pickupTime"); + TRACE_4("",typeOf _staticWeapon,_carryWeaponClassname,_turretClassname,_pickupTime); private _onFinish = { params ["_args"]; _args params ["_staticWeapon", "_player", "_carryWeaponClassname", "_turretClassname", "_onDisassembleFunc"]; TRACE_4("disassemble finish",_staticWeapon,_player,_carryWeaponClassname,_turretClassname); - private _weaponPos = getPosATL _staticWeapon; - _weaponPos set [2, (_weaponPos select 2) + 0.1]; + private _weaponPos = (getPosATL _staticWeapon) vectorAdd [0, 0, 0.1]; private _weaponDir = getDir _staticWeapon; - private _carryWeaponMag = ""; - private _carryWeaponMags = getArray (configFile >> "CfgWeapons" >> _carryWeaponClassname >> "magazines") apply {toLower _x}; + private _carryWeaponMag = []; + private _carryWeaponMags = compatibleMagazines _carryWeaponClassname; 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 [] && {_carryMag in _carryWeaponMags}) then { TRACE_3("Adding mag to secondary weapon",_xMag,_xAmmo,_carryMag); - _carryWeaponMag = _carryMag; + _carryWeaponMag = [_carryMag, _xAmmo]; DEC(_xAmmo); }; if ((_xAmmo > 0) && {_carryMag != ""}) then { @@ -70,25 +80,40 @@ }; [{ - params ["_player", "_weaponPos", "_carryWeaponClassname", "_carryWeaponMag"]; + params ["_player", "_weaponPos", "_carryWeaponClassname", "_carryWeaponMag", "_turretClassname"]; + + // Give the weapon to the player if possible if ((alive _player) && {(secondaryWeapon _player) == ""}) exitWith { - _player addWeapon _carryWeaponClassname; - if (_carryWeaponMag isNotEqualTo "") then { + [_player, _carryWeaponClassname] call CBA_fnc_addWeaponWithoutItems; + + if (_carryWeaponMag isNotEqualTo []) then { _player addWeaponItem [_carryWeaponClassname, _carryWeaponMag, true]; }; }; - private _weaponRelPos = _weaponPos getPos RELATIVE_DIRECTION(90); - private _weaponHolder = createVehicle ["groundWeaponHolder", [0, 0, 0], [], 0, "NONE"]; - _weaponHolder setDir random [0, 180, 360]; - _weaponHolder setPosATL [_weaponRelPos select 0, _weaponRelPos select 1, _weaponPos select 2]; - if (_carryWeaponMag isEqualTo "") then { - _weaponHolder addWeaponCargoGlobal [_carryWeaponClassname, 1]; - } else { - _weaponHolder addWeaponWithAttachmentsCargoGlobal [[_carryWeaponClassname, "", "", "", [_carryWeaponMag, 1], [], ""], 1]; + + // If there is no turret, place the ground holder where the turret was + if (_turretClassname != "") then { + _weaponPos = _weaponPos getPos RELATIVE_DIRECTION(90); }; - }, [_player, _weaponPos, _carryWeaponClassname, _carryWeaponMag]] call CBA_fnc_execNextFrame; + + // Create a new weapon holder (don't try to get an existing one, as no guarantee where it could be) + private _weaponHolder = createVehicle ["GroundWeaponHolder", [0, 0, 0], [], 0, "CAN_COLLIDE"]; + _weaponHolder setDir random [0, 180, 360]; + _weaponHolder setVehiclePosition [_weaponPos, [], 0, "CAN_COLLIDE"]; // places object on surface below + _weaponHolder addWeaponWithAttachmentsCargoGlobal [[_carryWeaponClassname, "", "", "", _carryWeaponMag, [], ""], 1]; + }, [_player, _weaponPos, _carryWeaponClassname, _carryWeaponMag, _turretClassname]] call CBA_fnc_execNextFrame; LOG("delete weapon"); + + // Eject dead units (all crew are dead or UAV at this point, otherwise condition would have failed), but ignore UAV units + { + if (unitIsUAV _x) then { + _staticWeapon deleteVehicleCrew _x; + } else { + moveOut _x; + }; + } forEach (crew _staticWeapon); + deleteVehicle _staticWeapon; LOG("end"); @@ -97,8 +122,9 @@ private _condition = { params ["_args"]; _args params ["_staticWeapon"]; - ((crew _staticWeapon) isEqualTo []) && (alive _staticWeapon) + + _staticWeapon call FUNC(assemble_canPickupWeapon) }; - [TIME_PROGRESSBAR(_pickupTime), [_staticWeapon, _player, _carryWeaponClassname, _turretClassname, _onDisassembleFunc], _onFinish, {}, localize LSTRING(DisassembleCSW_progressBar), _condition] call EFUNC(common,progressBar); + [TIME_PROGRESSBAR(_pickupTime), [_staticWeapon, _player, _carryWeaponClassname, _turretClassname, _onDisassembleFunc], _onFinish, {}, LLSTRING(DisassembleCSW_progressBar), _condition] call EFUNC(common,progressBar); }, _this] call CBA_fnc_execNextFrame; 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..2ec3b065da --- /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 (not used) + * + * Return Value: + * Can pickup + * + * Example: + * [cursorObject, player] call ace_csw_fnc_canPickupTripod + * + * Public: No + */ + +params ["_tripod"]; + +alive _tripod && {((crew _tripod) findIf {alive _x && {!unitIsUAV _x}}) == -1} // 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 62% rename from addons/csw/functions/fnc_reload_actionsLoad.sqf rename to addons/csw/functions/fnc_getLoadActions.sqf index 557811d440..e505c7f50f 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"]; @@ -44,9 +44,9 @@ private _cfgMagazines = configFile >> "CfgMagazines"; // micro-optimization private _displayName = getText (_cfgMagazines >> _carryMag >> "displayName"); private _picture = getText (_cfgMagazines >> _carryMag >> "picture"); private _text = if (_isBeltLinking) then { - format [localize LSTRING(actionLink), _displayName]; + format [LLSTRING(actionLink), _displayName]; } else { - format [localize LSTRING(loadX), _displayName]; + format [LLSTRING(loadX), _displayName]; }; private _action = [format ["load_%1", _forEachIndex], _text, _picture, _statement, _condition, {}, _x] call EFUNC(interact_menu,createAction); diff --git a/addons/csw/functions/fnc_getUnloadActions.sqf b/addons/csw/functions/fnc_getUnloadActions.sqf new file mode 100644 index 0000000000..dd119b0622 --- /dev/null +++ b/addons/csw/functions/fnc_getUnloadActions.sqf @@ -0,0 +1,75 @@ +#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; + private _config = configOf _target >> QUOTE(ADDON) >> "ammoUnloadTime"; + if (!isNull _config) then { + _timeToUnload = getNumber _config; + }; + + [ + 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 [LLSTRING(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_initVehicle.sqf b/addons/csw/functions/fnc_initVehicle.sqf new file mode 100644 index 0000000000..2d7241029f --- /dev/null +++ b/addons/csw/functions/fnc_initVehicle.sqf @@ -0,0 +1,102 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm + * Initializes CSW systems on vehicle + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_csw_fnc_initVehicle + * + * Public: No + */ + +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; +}; + +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 ["_vehicle"]; + if (!alive _vehicle) exitWith { TRACE_1("dead/deleted",_vehicle); }; + // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] + private _assemblyModeIndex = _vehicle getVariable [QGVAR(assemblyMode), 3]; + private _emptyWeapon = _assemblyModeIndex isEqualTo 2; + private _assemblyMode = [false, true, true, GVAR(defaultAssemblyMode)] select _assemblyModeIndex; + 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 ["_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 + [_vehicle, "disableWeaponAssembly", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + }; + }, [_vehicle]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly +}; + +// Add interactions for players +if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then { + GVAR(initializedStaticTypes) pushBack _typeOf; + TRACE_1("Adding Actions",_typeOf); + + if (_assemblyConfig) then { + private _disassembleAction = [QGVAR(disassemble), LLSTRING(DisassembleCSW_displayName), "", LINKFUNC(assemble_pickupWeapon), LINKFUNC(assemble_canPickupWeapon)] call EFUNC(interact_menu,createAction); + [_typeOf, 0, ["ACE_MainActions"], _disassembleAction] call EFUNC(interact_menu,addActionToClass); + }; + + + private _ammoActionPath = []; + private _magazineLocation = getText (_configOf >> QUOTE(ADDON) >> "magazineLocation"); + private _condition = { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; + // If magazine handling is enabled or weapon assembly/disassembly is enabled we enable ammo handling + if ((GVAR(ammoHandling) == 0) && {!([false, true, true, GVAR(defaultAssemblyMode)] select (_target getVariable [QGVAR(assemblyMode), 3]))}) exitWith { false }; + [_player, _target, ["isNotSwimming", "isNotSitting"]] call EFUNC(common,canInteractWith) + }; + private _childenCode = { + BEGIN_COUNTER(getActions); // can remove for final release + private _ret = (call FUNC(getLoadActions)) + (call FUNC(getUnloadActions)); + END_COUNTER(getActions); + _ret + }; + if (_configEnabled && {_magazineLocation != ""}) then { + private _positionCode = compile _magazineLocation; + private _ammoAction = [QGVAR(magazine), LLSTRING(AmmoHandling_displayName), "", {}, _condition, _childenCode, [], _positionCode, 4] call EFUNC(interact_menu,createAction); + _ammoActionPath = [_typeOf, 0, [], _ammoAction] call EFUNC(interact_menu,addActionToClass); + } else { + private _ammoAction = [QGVAR(magazine), LLSTRING(AmmoHandling_displayName), "", {}, _condition, _childenCode] call EFUNC(interact_menu,createAction); + _ammoActionPath = [_typeOf, 0, ["ACE_MainActions"], _ammoAction] call EFUNC(interact_menu,addActionToClass); + }; + + if (["ace_reload"] call EFUNC(common,isModLoaded)) then { + // move reload's check ammo action to the ammo handling point (remove and re-add) + [_typeOf, 0, ["ACE_MainActions", QEGVAR(reload,CheckAmmo)]] call EFUNC(interact_menu,removeActionFromClass); + private _checkAmmoAction = [QGVAR(checkAmmo), LELSTRING(reload,checkAmmo), "", EFUNC(reload,checkAmmo), EFUNC(reload,canCheckAmmo)] call EFUNC(interact_menu,createAction); + [_typeOf, 0, _ammoActionPath, _checkAmmoAction] call EFUNC(interact_menu,addActionToClass); + }; +}; 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_getLoadableMagazines.sqf b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf index 933625fb89..724ee4d09c 100644 --- a/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf +++ b/addons/csw/functions/fnc_reload_getLoadableMagazines.sqf @@ -70,7 +70,7 @@ private _return = []; ) exitWith { _return pushBack [_carryMag, _turretPath, _loadInfo, _magSource]; }; - } forEach ([_weapon] call CBA_fnc_compatibleMagazines); + } forEach (compatibleMagazines _weapon); } forEach _availableMagazines; } forEach (_vehicle weaponsTurret _turretPath); } forEach (allTurrets _vehicle); diff --git a/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf b/addons/csw/functions/fnc_reload_handleAddTurretMag.sqf index 9a2eae2bd4..d7af22d319 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 * @@ -24,8 +24,8 @@ params ["_vehicle", "_turret", "_magSource", "_carryMag", "_ammoReceived", ["_returnTo", _magSource]]; TRACE_6("reload_handleAddTurretMag",_vehicle,_turret,_magSource,_carryMag,_ammoReceived,_returnTo); -TRACE_2("",local _vehicle, _vehicle turretLocal _turret); -if (!(_vehicle turretLocal _turret)) exitWith {}; +TRACE_2("",local _vehicle,_vehicle turretLocal _turret); +if !(_vehicle turretLocal _turret) exitWith {}; ([_vehicle, _turret, _carryMag] call FUNC(reload_canLoadMagazine)) params ["_canAdd", "_loadedMag", "_neededAmmo", "_isBeltLinking"]; TRACE_4("canLoad",_canAdd,_loadedMag,_neededAmmo,_isBeltLinking); @@ -43,10 +43,10 @@ if (_canAdd) then { // setMagazineTurretAmmo is broken on split locality, use setAmmo for now (this may not work for multi turret vehicles) private _weapon = (_vehicle weaponsTurret _turret) param [0, ""]; - TRACE_3("setAmmo",_vehicle,_weapon, _currentAmmo); + TRACE_3("setAmmo",_vehicle,_weapon,_currentAmmo); _vehicle setAmmo [_weapon, _currentAmmo]; private _currentAmmo = _vehicle magazineTurretAmmo [_loadedMag, _turret]; - if ((_weapon == "") || {_currentAmmo != _currentAmmo}) then { ERROR_1("failed to setAmmo - %1", _this); }; + if ((_weapon == "") || {_currentAmmo != _currentAmmo}) then { ERROR_1("failed to setAmmo - %1",_this); }; } else { if (_loadedMag != "") then { TRACE_1("Removing emtpy mag",_loadedMag); diff --git a/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf b/addons/csw/functions/fnc_reload_handleRemoveTurretMag.sqf index d53d35a0d8..51036b525a 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 * @@ -23,8 +23,8 @@ params ["_vehicle", "_turretPath", "_carryMag", "_vehMag", "_unloadTo"]; TRACE_5("removeTurretMag EH",_vehicle,_turretPath,_carryMag,_vehMag,_unloadTo); -TRACE_3("",local _vehicle, _vehicle turretLocal _turretPath,local _unloadTo); -if (!(_vehicle turretLocal _turretPath)) exitWith {}; +TRACE_3("",local _vehicle,_vehicle turretLocal _turretPath,local _unloadTo); +if !(_vehicle turretLocal _turretPath) exitWith {}; private _magsInWeapon = []; // Check how much ammo it has now: { @@ -55,10 +55,10 @@ if ((_magsInWeapon isEqualTo []) && {_ammoInFirstMag > _ammoRemoved}) then { // setMagazineTurretAmmo is broken on split locality, use setAmmo for now private _weapon = (_vehicle weaponsTurret _turretPath) param [0, ""]; - TRACE_3("setAmmo",_vehicle,_weapon, _ammoLeft); + TRACE_3("setAmmo",_vehicle,_weapon,_ammoLeft); _vehicle setAmmo [_weapon, _ammoLeft]; private _currentAmmo = _vehicle magazineTurretAmmo [_vehMag, _turretPath]; - if ((_weapon == "") || {_currentAmmo != _ammoLeft}) then { ERROR_1("failed to setAmmo - %1", _this); }; + if ((_weapon == "") || {_currentAmmo != _ammoLeft}) then { ERROR_1("failed to setAmmo - %1",_this); }; } else { diff --git a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf index da8383b608..ca445400b0 100644 --- a/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf +++ b/addons/csw/functions/fnc_reload_handleReturnAmmo.sqf @@ -41,7 +41,7 @@ if ((_fullMagazines == 0) && {_bulletsRemaining == 0}) exitWith {}; private _container = _unloadTo getVariable [QGVAR(container), objNull]; if ((_container distance _unloadTo) > 10) then { _container = objNull; }; if (isNull _container) then { - _container = (nearestObjects [_unloadTo, [QGVAR(ammo_holder), "GroundWeaponHolder"], 10]) param [0, objNull]; + _container = (nearestObjects [_unloadTo, [["GroundWeaponHolder"], [QGVAR(ammo_holder)]] select GVAR(handleExtraMagazinesType), 10]) param [0, objNull]; }; diff --git a/addons/csw/functions/fnc_reload_loadMagazine.sqf b/addons/csw/functions/fnc_reload_loadMagazine.sqf index 42508daf1d..50081a87a5 100644 --- a/addons/csw/functions/fnc_reload_loadMagazine.sqf +++ b/addons/csw/functions/fnc_reload_loadMagazine.sqf @@ -23,11 +23,12 @@ params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit"]; TRACE_5("loadMagazine",_vehicle,_turret,_carryMag,_magSource,_unit); private _timeToLoad = 1; -if (!isNull(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime")) then { - _timeToLoad = getNumber(configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime"); +private _config = configOf _vehicle >> QUOTE(ADDON) >> "ammoLoadTime"; +if (!isNull _config) then { + _timeToLoad = getNumber _config; }; -private _displayName = format [localize LSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")]; +private _displayName = format [LLSTRING(loadX), getText (configFile >> "CfgMagazines" >> _carryMag >> "displayName")]; private _onFinish = { (_this select 0) params ["_vehicle", "_turret", "_carryMag", "_magSource", "_unit"]; @@ -51,7 +52,7 @@ private _onFinish = { [_magSource, _carryMag, _bestAmmoToSend] call EFUNC(common,removeSpecificMagazine); if (_bestAmmoToSend == 0) exitWith {}; - TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_bestAmmoToSend, _unit); + TRACE_6("calling addTurretMag event",_vehicle,_turret,_magSource,_carryMag,_bestAmmoToSend,_unit); [QGVAR(addTurretMag), [_vehicle, _turret, _magSource, _carryMag, _bestAmmoToSend, _unit]] call CBA_fnc_globalEvent; }; diff --git a/addons/csw/functions/fnc_staticWeaponInit.sqf b/addons/csw/functions/fnc_staticWeaponInit.sqf deleted file mode 100644 index fcef5df08e..0000000000 --- a/addons/csw/functions/fnc_staticWeaponInit.sqf +++ /dev/null @@ -1,98 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Initializes weapon to disable weapon disassembling - * - * Arguments: - * 0: Weapon - * - * Return Value: - * None - * - * Example: - * [weapon] call ace_csw_fnc_staticWeaponInit - * - * 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 -}; - -TRACE_2("",local _staticWeapon,_staticWeapon turretLocal [0]); -if (_configEnabled && {_staticWeapon turretLocal [0]}) then { // if turret is local to us, then handle mags/weapon - [{ - params ["_staticWeapon"]; - if (!alive _staticWeapon) exitWith { TRACE_1("dead/deleted",_staticWeapon); }; - // Assembly mode: [0=disabled, 1=enabled, 2=enabled&unload, 3=default] - private _assemblyModeIndex = _staticWeapon 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 -}; - -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); - if (_assemblyMode) then { // Disable vanilla assembly if assemblyMode eanbled - [QGVAR(disableVanillaAssembly), [_staticWeapon]] call CBA_fnc_localEvent; - }; - }, [_staticWeapon]] call CBA_fnc_execNextFrame; // need to wait a frame to allow setting object vars during assembly -}; - -// Add interactions for players -if (hasInterface && {!(_typeOf in GVAR(initializedStaticTypes))}) then { - GVAR(initializedStaticTypes) pushBack _typeOf; - TRACE_1("Adding Actions",_typeOf); - - if (_assemblyConfig) then { - private _disassembleAction = [QGVAR(disassemble), localize LSTRING(DisassembleCSW_displayName), "", {call FUNC(assemble_pickupWeapon)}, {call FUNC(assemble_canPickupWeapon)}] call EFUNC(interact_menu,createAction); - [_typeOf, 0, ["ACE_MainActions"], _disassembleAction] call EFUNC(interact_menu,addActionToClass); - }; - - - private _ammoActionPath = []; - private _magazineLocation = getText (_configOf >> QUOTE(ADDON) >> "magazineLocation"); - private _condition = { //IGNORE_PRIVATE_WARNING ["_target", "_player"]; - // If magazine handling is enabled or weapon assembly/disassembly is enabled we enable ammo handling - if ((GVAR(ammoHandling) == 0) && {!([false, true, true, GVAR(defaultAssemblyMode)] select (_target getVariable [QGVAR(assemblyMode), 3]))}) exitWith { false }; - [_player, _target, ["isNotSwimming", "isNotSitting"]] call EFUNC(common,canInteractWith) - }; - private _childenCode = { - BEGIN_COUNTER(getActions); // can remove for final release - private _ret = (call FUNC(reload_actionsLoad)) + (call FUNC(reload_actionsUnload)); - END_COUNTER(getActions); - _ret - }; - if (_configEnabled && {_magazineLocation != ""}) then { - private _positionCode = compile _magazineLocation; - private _ammoAction = [QGVAR(magazine), localize LSTRING(AmmoHandling_displayName), "", {}, _condition, _childenCode, [], _positionCode, 4] call EFUNC(interact_menu,createAction); - _ammoActionPath = [_typeOf, 0, [], _ammoAction] call EFUNC(interact_menu,addActionToClass); - } else { - private _ammoAction = [QGVAR(magazine), localize LSTRING(AmmoHandling_displayName), "", {}, _condition, _childenCode] call EFUNC(interact_menu,createAction); - _ammoActionPath = [_typeOf, 0, ["ACE_MainActions"], _ammoAction] call EFUNC(interact_menu,addActionToClass); - }; - - if (["ACE_reload"] call EFUNC(common,isModLoaded)) then { - // move reload's check ammo action to the ammo handling point (remove and re-add) - [_typeOf, 0, ["ACE_MainActions", QEGVAR(reload,CheckAmmo)]] call EFUNC(interact_menu,removeActionFromClass); - private _checkAmmoAction = [QGVAR(checkAmmo), localize ELSTRING(reload,checkAmmo), "", EFUNC(reload,checkAmmo), EFUNC(reload,canCheckAmmo)] call EFUNC(interact_menu,createAction); - [_typeOf, 0, _ammoActionPath, _checkAmmoAction] call EFUNC(interact_menu,addActionToClass); - }; -}; diff --git a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf index 23155ead0b..98200840a3 100644 --- a/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf +++ b/addons/csw/functions/fnc_staticWeaponInit_unloadExtraMags.sqf @@ -68,14 +68,38 @@ TRACE_1("Remove all loaded magazines",_magsToRemove); }; } forEach _magsToRemove; -if (_staticWeapon getVariable [QGVAR(secondaryWeaponMagazine), ""] isNotEqualTo "") then { - private _secondaryWeaponMagazine = _staticWeapon getVariable QGVAR(secondaryWeaponMagazine); - private _turret = allTurrets _staticWeapon param [0, []]; - private _vehicleMag = [_staticWeapon, _turret, _secondaryWeaponMagazine] call FUNC(reload_getVehicleMagazine); - TRACE_3("Re-add previous mag",_secondaryWeaponMagazine,_turret,_vehicleMag); - if (!isClass (configFile >> "CfgMagazines" >> _vehicleMag)) exitWith {}; - _staticWeapon addMagazineTurret [_vehicleMag, _turret, 1]; - _staticWeapon setVariable [QGVAR(secondaryWeaponMagazine), nil]; +private _secondaryWeaponMagazines = _staticWeapon getVariable [QGVAR(secondaryWeaponMagazines), []]; + +if (_secondaryWeaponMagazines isNotEqualTo []) then { + // Check if the static weapon can take magazines + private _turret = (allTurrets _staticWeapon) param [0, []]; + private _compatibleMagazinesTurret = flatten ((_staticWeapon weaponsTurret _turret) apply {compatibleMagazines _x}); + private _container = objNull; + + { + private _vehicleMag = [_staticWeapon, _turret, _x select 0] call FUNC(reload_getVehicleMagazine); + TRACE_3("Re-add previous mag",_x select 0,_turret,_vehicleMag); + + // If the magazine can be added to the static weapon, do it now + if (_vehicleMag in _compatibleMagazinesTurret) then { + _staticWeapon addMagazineTurret [_vehicleMag, _turret, _x select 1]; + } else { + // Find a suitable container to place items in if necessary + if (isNull _container) then { + _container = (nearestObjects [_staticWeapon, ["GroundWeaponHolder"], 10]) param [0, objNull]; + + // Create ammo storage container + if (isNull _container) then { + _container = createVehicle ["GroundWeaponHolder", getPosATL _staticWeapon, [], 0, "NONE"]; + }; + }; + + // If the mag can't be added to the static weapon, add it to the ground holder + _container addMagazineAmmoCargo [_x select 0, 1, _x select 1]; + }; + } forEach _secondaryWeaponMagazines; + + _staticWeapon setVariable [QGVAR(secondaryWeaponMagazines), nil, true]; }; if (_storeExtraMagazines) then { diff --git a/addons/csw/initSettings.sqf b/addons/csw/initSettings.inc.sqf similarity index 87% rename from addons/csw/initSettings.sqf rename to addons/csw/initSettings.inc.sqf index de3976896b..bc157e1164 100644 --- a/addons/csw/initSettings.sqf +++ b/addons/csw/initSettings.inc.sqf @@ -45,17 +45,12 @@ private _categoryArray = [format ["ACE %1", localize LSTRING(DisplayName)]]; [LSTRING(progressBarTimeCoefficent_displayName), LSTRING(progressBarTimeCoefficent_description)], _categoryArray, [0,2,1,2], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(progressBarTimeCoefficent), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + true // isGlobal ] call CBA_fnc_addSetting; [ QGVAR(dragAfterDeploy), "CHECKBOX", [LSTRING(dragAfterDeploy_displayName), LSTRING(dragAfterDeploy_description)], _categoryArray, - false, // default value - false, // isGlobal - {[QGVAR(dragAfterDeploy), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + false // default value ] call CBA_fnc_addSetting; diff --git a/addons/csw/script_config_macros_csw.hpp b/addons/csw/script_config_macros_csw.hpp index 1a0e1b3be5..6701159f29 100644 --- a/addons/csw/script_config_macros_csw.hpp +++ b/addons/csw/script_config_macros_csw.hpp @@ -1,15 +1 @@ #define CREATE_CSW_PROXY(weapon) class ##weapon; class GVAR(weapon): ##weapon { magazineReloadTime = 0.5; } - -// Need to be careful about breaking Attributes inheritance, doesn't seem to be any standard -#define ENABLE_CSW_ATTRIBUTE class Attributes { \ - class EGVAR(CSW,assemblyMode) { \ - property = QEGVAR(CSW,assemblyMode); \ - control = QEGVAR(CSW,assemblyModeControl); \ - displayName = ECSTRING(CSW,eden_enableCSW); \ - tooltip = ECSTRING(CSW,eden_enableCSW_tooltip); \ - expression = QUOTE( if (_value != 3) then {_this setVariable [ARR_3('%s',_value,true)]} ); \ - typeName = "NUMBER"; \ - condition = "objectVehicle"; \ - defaultValue = 3; \ - }; \ - } diff --git a/addons/csw/stringtable.xml b/addons/csw/stringtable.xml index a528c941e8..da794376ab 100644 --- a/addons/csw/stringtable.xml +++ b/addons/csw/stringtable.xml @@ -37,7 +37,7 @@ Rozložit Démonter Auseinandernehmen - Disassemblare + Disassembla Złóż Desmontar Разобрать @@ -53,12 +53,12 @@ Nastup Entrer Einsteigen - A bordo + Entra Wsiadać Entrar Войти Entrar - 乗る + 乗り込む 進入 进入 Bin @@ -71,7 +71,7 @@ Nabít %1 Charger %1 Załaduj %1 - Carico %1 + Carica %1 Загрузить %1 Load %1 Carregar %1 @@ -118,7 +118,7 @@ Erweiterter Zusammenbau Montagem Avançada Assemblage avancé - アドバンスド設置 + 高度な組み立て 進階組裝 高级组装 Montaggio avanzato @@ -133,10 +133,10 @@ Benutze ACE um unterstützte statische Waffen zu montieren/demontieren. Geladene Munition ist auf ein einzelnes Magazin reduziert. Usar o ACE para Montar/Desmontar armas estáticas suportadas. Munição carregada é reduzida para um único carregador. Utilise ACE pour l'assemblage/le désassemblage des armes statiques supportées.\nLes munitions chargées sont réduites à un seul chargeur. - 対応している設置型火器に ACE3 の設置と解体を使用します。装填済みの弾倉は 1 つの弾倉に減少します。 + 対応している設置型火器に ACE の設置と解体を使用します。装填済みの弾倉は1つの弾倉のみに減少します。 使用ACE來組裝/拆解固定型武器。上膛的限制為單個彈匣。 使用 ACE 来组装/拆解固定式武器。限制弹药为一个弹匣。 - Utilizzare ace per l'Assemblaggio/smontaggio di armi statiche supportate. Le munizioni cariche sono ridotte ad un solo caricatore. + Utilizza ACE per assemblaggio/smontaggio di armi statiche supportate. Le munizioni caricate sono ridotte ad un solo caricatore. Použít ACE pro složení/rozložení podporovaných statických zbraní. Nabitá munice je snížená na jeden zásobník. Użyj ACE do składania/rozkładania broni statycznych. Załadowana amunicja zostaje zredukowana do jednego magazynku. Usar el ACE para el ensamblado/desamblado de armas estáticas soportadas. La munición cargada es reducida a un sólo cargador @@ -148,10 +148,10 @@ Spare extra Munition Economizar munição extra Conserver le surplus de munitions - 過剰弾薬を保持 + 追加の弾薬を保持 保存額外彈藥 保存额外弹药 - Risparmiare munizioni extra + Conserva munizioni extra Uložit munici navíc. Zapisz dodatkową amunicje Guardar munición extra @@ -163,10 +163,10 @@ Lager extra Magazine neben der statischen Waffe Carregar munições extras próximo à arma estática Range les chargeurs en surplus auprès de l'arme statique. - 次の設置型火器用に過剰弾薬を保持します。 + 追加の弾倉を固定火器の横に保管します。 在固定型武器旁存放額外彈匣 在固定式武器旁边存放额外的弹匣 - Conservare i caricatori extra accanto all'arma statica + Conserva i caricatori extra accanto all'arma statica Ukládat munici navíc vedle statické zbraně. Dodatkowe magazynki przechowuj obok broni statycznej Almacenar cargadores extra junto al arma estática @@ -176,28 +176,33 @@ Ammo Storage Munitionslager + Scorta di munizioni 탄약 보관 Magazyn amunicji - 弾薬の格納 + 弾薬保管位置 弹药存储 Хранилище боеприпасов Almacenamiento de munición Stockage des munitions + Armazenamento de Munição Determines whether extra magazines are stored on the ground or inside an ammo box Legt fest, ob zusätzliche Magazine auf dem Boden oder in einer Munitionskiste aufbewahrt werden + 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 Détermine si les chargeurs supplémentaires sont stockés par terre ou dans une caisse de munitions. + Determina se munições extras são armazenadas no chão ou dentro de uma caixa de munição Ground Boden + Suolo 지면 Ziemia 地面 @@ -205,10 +210,12 @@ Земля Suelo Sol + Solo Ammo Box Munitionskiste + Cassa di munizioni 탄약 상자 Skrzynka amunicyjna 弾薬箱 @@ -216,6 +223,7 @@ Коробка с боеприпасами Caja de munición Caisse de munitions + Caixa de Munição Ammo handling @@ -240,7 +248,7 @@ 弾薬の装填と除去を許可します。 允許裝填或卸載彈匣 允许装卸弹匣 - Permettere il carico e lo scarico dei caricatori + Permetti caricamento e scaricamento delle munizioni Povolit nabíjení a vybíjení zásobníků. Zezwalaj na ładowanie i rozładowywanie magazynków Permitir la carga y descarga de cargadores @@ -252,10 +260,10 @@ Interaktionsdauerkoeffizient Coeficiente de tempo para a interação Coefficient du temps d'interaction - インタラクション時間係数 + インタラクションの所要時間係数 互動時間係數 交互时间系数 - Coefficente per il tempo di interazione + Coefficiente per il tempo di interazione Koeficient času interakce Współczynnik czasu interakcji Coeficiente de tiempo de interacción @@ -267,7 +275,7 @@ Skaliert die Zeit die benötigt wird um statische Waffen aufzubauen und nachzuladen. Escala o tempo requerido para montar e recarregar armas estáticas. Définit l'échelle de temps nécessaire à l'assemblage et au rechargement des armes statiques. - 設置型火器の設置と再装填時間を管理できます。 + 設置型火器の設置と再装填の所要時間を管理できます。 設置組裝及裝填組裝固定型武器 衡量组装和重新装填固定式武器所需的时间 Tempo necessario per assemblare e ricaricare le armi statiche @@ -285,7 +293,7 @@ 設置後に三脚を引きずる 在佈置三腳架後拖拉 部署后拖动三脚架 - Trascinare i treppiedi dopo lo schieramento + Trascina i treppiedi dopo il montaggio Tahat trojnožku po položení Przeciągnij statyw po rozmieszczeniu Arrastrar trípodes despues de desplegarlos @@ -300,7 +308,7 @@ 三脚を設置後、動かせるよう三脚を引きずるようにします。 在部署三腳架後,開始拖動它使其在你所要的精準位置 部署好三脚架后,开始拖动它到一个精确的位置 - Dopo aver posizionato un treppiede, iniziate a trascinarlo in una posizione precisa + Dopo aver montato un treppiede, inizia a trascinarlo su una posizione precisa Po položení trojnožky začít automaticky tahání pro lepší polohu. Po rozłożeniu trójnogu zacznij od przeciągania go w określone miejsce Después de desplegar un trípode, comenzar a arrastrarlo hacia la ubicación precisa @@ -315,7 +323,7 @@ 三脚を拾う 撿起三腳架 捡起三脚架 - Recupero treppiede + Recupera treppiede Složit trojnožku Podnieś Trójnóg Recoger trípode @@ -330,7 +338,7 @@ 火器を乗せる 裝載武器 装载武器 - Montare l'arma + Monta l'arma Připevnit zbraň Zamontuj Broń Montar arma @@ -357,7 +365,7 @@ Montiere Waffe... Montando Arma... Assemblage de l'arme... - 火器を設置中です・・・ + 火器を組み立て中です・・・ 組裝武器中... 正在组装武器... Montaggio arma... @@ -372,7 +380,7 @@ Nehme Dreibein auf... Carregando Tripé... Récupération du trépied... - 三脚を取得中です・・・ + 三脚を回収中・・・ 撿起三腳架... 捡起三脚架... Recupero treppiede... @@ -390,7 +398,7 @@ 三脚を設置中です・・・ 部署三腳架... 部署三脚架... - Piazzare treppiede... + Piazzamento treppiede... Pokládám trojnožku... Rozmieszczanie Trójnogu... Ubicando trípode... @@ -420,7 +428,7 @@ この火器で共用火器を有効化します。 對此武器啟用班組支援能力 在该武器上启用班组支援能力 - Abilita l'abilità dell'equipaggio su quest'arma + Abilita il servizio da equipaggio su quest'arma Zapne CSW funkce na této zbrani Włącza opcje systemu CSW na tej broni Habilitar el manejo de uso colectivo para esta arma @@ -432,10 +440,10 @@ Aktiviere und lasse diese Waffe leer Ativado e deixar arma vazia Activer et laisser l'arme vide - 火器有効化し空を維持 + 有効にして火器を空のままにする 啟用並不裝填武器 启用并不装填武器 - Abilitato e lascia l'arma vuota + Abilita e lascia l'arma vuota Povolit a nechat zbraň prázdnou Włącz i pozostaw broń pustą Habilitar y dejar el arma vacía @@ -467,7 +475,7 @@ [CSW] 設置型ミニ スパイク ランチャー (AT) [CSW] 固定型 "迷你長釘"導彈發射器(對地) [班组] 固定式"迷你长钉"导弹发射器(反坦) - [CSW] Static Mini-Spike Launcher (AT) + [CSW] Lanciatore Mini-Spike (AT) Statico [CSW] Statický raketomet Mini-Spike (protitankový) [CSW] Static Mini-Spike Launcher (AT) [CSW] Mini-Spike Przeciwpancerny pocisk rakietowy @@ -483,7 +491,7 @@ [CSW] 設置型ミニ スパイク ランチャー (AA) [CSW] 固定型 "迷你長釘"導彈發射器(對空) [班组] 固定式"迷你长钉"导弹发射器(防空) - [CSW] Static Mini-Spike Launcher (AA) + [CSW] Lanciatore Mini-Spike (AA) Statico [CSW] Statický raketomet Mini-Spike (protiletadlový) [CSW] Static Mini-Spike Launcher (AA) [CSW] Mini-Spike Przeciwlotniczy pocisk rakietowy @@ -499,7 +507,7 @@ [CSW] 設置型 XM312 [CSW] 固定型 XM312重機槍 [班组] 固定式 XM312 重机枪 - [CSW] Static XM312 Gun + [CSW] XM312 Statico [CSW] Statická zbraň XM312 [CSW] Static XM312 Gun [CSW] Statyczny karabin maszynowy XM312 @@ -515,8 +523,10 @@ [CSW] Станковый M2 со щитом [CSW] 設置型 防盾付き M2 [CSW] Statisches M2 mit Schild + [CSW] M2 Statico con Scudo [班组] 固定式防盾型 M2 重机枪 [CSW] 거치형 M2 (방패) + [CSW] Arma Estática - M2 com Escudo [CSW] Static XM312 Gun (Autonomous) @@ -527,7 +537,7 @@ [CSW] 設置型 XM312 (自律型) [CSW] 固定型 XM312重機槍(自主型) [班组] 固定式 XM312 重机枪(自主) - [CSW] Static XM312 Gun (Autonomo) + [CSW] XM312 Statico (Autonomo) [CSW] Statická zbraň XM312 (autonomická) [CSW] Static XM312 Gun (Autonomous) [CSW] Statyczny karabin maszynowy XM312 (Dron) @@ -543,7 +553,7 @@ [CSW] 設置型 XM307 [CSW] 固定型XM307榴彈機槍 [班组] 固定式 XM307 榴弹发射器 - [CSW] Static XM307 Gun + [CSW] XM307 Statico [CSW] Statická zbraň XM307 [CSW] Static XM307 Gun [CSW] Statyczny granatnik automatyczny XM307 @@ -559,7 +569,7 @@ [CSW] 設置型 XM307 (自律型) [CSW] 固定型 XM307榴彈機槍(自主型) [班组] 固定式 XM307 榴弹发射器(自主) - [CSW] Static XM307 Gun (Autonomo) + [CSW] XM307 Statico (Autonomo) [CSW] Statická zbraň XM307 (autonomická) [CSW] Static XM307 Gun (Autonomous) [CSW] Statyczny granatnik automatyczny XM307 (Dron) @@ -575,7 +585,7 @@ [CSW] 12.7x108 mm HMG ベルト [CSW]12.7x108毫米 重機槍彈鏈 [班组] 12.7x108 mm 重机枪弹链 - [CSW] 12.7x108mm HMG Belt + [CSW] Nastro da HMG 12.7x108mm [CSW] Pás 12.7×108mm pro těžký kulomet [CSW] 12.7x108mm HMG Belt [CSW] Taśma 12.7x108mm CKM @@ -591,7 +601,7 @@ [CSW] 12.7x99 mm HMG ベルト [CSW]12.7x99毫米 重機槍彈鏈 [班组] 12.7x99 mm 重机枪弹链 - [CSW] 12.7x99mm HMG Belt + [CSW] Nastro da HMG 12.7x99mm [CSW] Pás 12.7×99mm pro těžký kulomet [CSW] 12.7x99mm HMG Belt [CSW] Taśma 12.7x99mm CKM @@ -604,10 +614,10 @@ [CSW] 12.7x99mm Leuchtspur HMG-Gurt (Rot) [CSW] Cinto de Munição - 12.7x99mm HMG (Traçante Vermelho) [CSW] Bande 12,7x99 mm HMG traçantes (Rouges) - [CSW] 12.7x99 mm HMG 曳光弾ベルト (赤) + [CSW] 12.7x99 mm HMG トレーサーベルト (赤) [CSW] 12.7x99毫米 重機槍曳光彈鏈(紅色) [班组] 12.7x99 mm 重机枪弹链(曳光,红) - [CSW] 12.7x99mm Tracer HMG Belt (Red) + [CSW] Nastro da HMG 12.7x99mm Traccianti (Red) [CSW] Pás 12.7×99mm pro těžký kulomet (červená stopovka) [CSW] 12.7x99mm Tracer HMG Belt (Red) [CSW] Taśma 12.7x99mm CKM Smugowa (Czerwona) @@ -620,10 +630,10 @@ [CSW] 12.7x99mm Leuchtspur HMG-Gurt (Grün) [CSW] Cinto de Munição - 12.7x99mm HMG (Traçante Verde) [CSW] Bande 12,7x99 mm HMG traçantes (Vertes) - [CSW] 12.7x99 mm HMG 曳光弾ベルト (緑) + [CSW] 12.7x99 mm HMG トレーサーベルト (緑) [CSW] 12.7x99毫米 重機槍曳光彈鏈(綠色) [班组] 12.7x99 mm 重机枪弹链(曳光,绿) - [CSW] 12.7x99mm Tracer HMG Belt (Green) + [CSW] Nastro da HMG 12.7x99mm Traccianti (Green) [CSW] Pás 12.7×99mm pro těžký kulomet (zelená stopovka) [CSW] 12.7x99mm Tracer HMG Belt (Green) [CSW] Taśma 12.7x99mm CKM Smugowa (Zielona) @@ -636,10 +646,10 @@ [CSW] 12.7x99mm Leuchtspur HMG-Gurt (Gelb) [CSW] Cinto de Munição - 12.7x99mm HMG (Traçante Amarelo) [CSW] Bande 12,7x99 mm HMG traçantes (Jaunes) - [CSW] 12.7x99 mm HMG 曳光弾ベルト (黄) + [CSW] 12.7x99 mm HMG トレーサーベルト (黄) [CSW] 12.7x99毫米 重機槍曳光彈鏈(黃色) [班组] 12.7x99 mm 重机枪弹链(曳光,黄) - [CSW] 12.7x99mm Tracer HMG Belt (Yellow) + [CSW] Nastro da HMG 12.7x99mm Traccianti (Yellow) [CSW] Pás 12.7×99mm pro těžký kulomet (žlutá stopovka) [CSW] 12.7x99mm Tracer HMG Belt (Yellow) [CSW] Taśma 12.7x99mm CKM Smugowa (Żółta) @@ -652,10 +662,10 @@ [CSW] 20mm Granate GMG-Gurt [CSW] Cinto de Munição - Granada 20mm GMG [CSW] Bande grenades 20 mm GMG - [CSW] 20 mm てき弾 GMG ベルト + [CSW] 20 mm 擲弾 GMG ベルト [CSW]20毫米 榴彈 榴彈機槍彈鏈 [班组] 20 mm 榴弹发射器弹链 - [CSW] 20mm Grenade GMG Belt + [CSW] Nastro di Granate 20mm da GMG [CSW] Pás 20mm granátů pro granátomet [CSW] 20mm Grenade GMG Belt [CSW] Taśma 20mm do granatnika @@ -671,7 +681,7 @@ M3 三脚 M3 三腳架 M3 三脚架 - M3 Tripod + Treppiede M3 M3 trojnožka M3 Tripod Trójnóg M3 @@ -687,7 +697,7 @@ [CSW] 6P57 設置型三脚 [CSW] 6P57 部署型三腳架 [班组] 6P57 部署型三脚架 - [CSW] 6P57 Deployable Tripod + [CSW] Treppiede 6P57 piazzabile [CSW] 6P57 trojnožka [CSW] 6P57 Deployable Tripod [CSW] Trójnóg Rozkładany 6P57 @@ -703,7 +713,7 @@ [CSW] 6P57 設置型三脚 (低座) [CSW] 6P57 部署型(低位) [班组] 6P57 部署型(低) - [CSW] 6P57 Deployable Tripod (Low) + [CSW] Treppiede 6P57 piazzabile (Basso) [CSW] 6P57 trojnožka (nízká) [CSW] 6P57 Deployable Tripod (Low) [CSW] Trójnóg Rozkładany 6P57 (Niski) @@ -719,7 +729,7 @@ [CSW] M220 設置型三脚 [CSW] M220 部署型三腳架 [班组] M220 部署型三脚架 - [CSW] M220 Deployable Tripod + [CSW] Treppiede M220 piazzabile [CSW] M220 trojnožka [CSW] M220 Deployable Tripod [CSW] Trójnóg Rozkładany M220 @@ -735,7 +745,7 @@ [CSW] SAG-30 設置型三脚 [CSW] SAG-30 部署型三腳架 [班组] SAG-30 部署型三脚架 - [CSW] SAG-30 Deployable Tripod + [CSW] Treppiede SAG-30 piazzabile [CSW] SAG-30 trojnožka [CSW] SAG-30 Deployable Tripod [CSW] Trójnóg Rozkładany SAG-30 @@ -751,7 +761,7 @@ 6P57 三脚 6P57 三腳架 6P57 三脚架 - 6P57 Tripod + Treppiede 6P57 6P57 trojnožka 6P57 Tripod Trójnóg 6P57 @@ -767,7 +777,7 @@ SAG-30 三脚 SAG-30 三腳架 SAG-30 三脚架 - SAG-30 Tripod + Treppiede SAG-30 SAG-30 trojnožka SAG-30 Tripod Trójnóg SAG-30 @@ -783,7 +793,7 @@ M220 三脚 M220 三腳架 M220 三脚架 - M220 Tripod + Treppiede M220 M220 trojnožka M220 Tripod Trójnóg M220 @@ -799,7 +809,7 @@ [CSW] M3 設置型三脚 [CSW] M3 部屬型三腳架 [班组] M3 部属型三脚架 - [CSW] M3 Deployable Tripod + [CSW] Treppiede M3 piazzabile [CSW] M3 trojnožka [CSW] M3 Deployable Tripod [CSW] Trójnóg Rozkładany M3 @@ -815,7 +825,7 @@ [CSW] M3 設置型三脚 (低座) [CSW] M3 部署型三腳架(低位) [班组] M3 部署型三脚架(低) - [CSW] M3 Deployable Tripod (Low) + [CSW] Treppiede M3 piazzabile (Basso) [CSW] M3 trojnožka (nízká) [CSW] M3 Deployable Tripod (Low) [CSW] Trójnóg Rozkładany M3 (Niski) @@ -831,7 +841,7 @@ [CSW] 迫撃砲基盤 [CSW] 迫擊炮基座 [班组] 迫击炮底座 - [CSW] Mortar Baseplate + [CSW] Base di Mortaio [CSW] Podstavec pro minomet [CSW] Mortar Baseplate [CSW] Podstawa Moździerza @@ -847,7 +857,7 @@ 迫撃砲基盤 迫擊炮基座 迫击炮底座 - Mortar Baseplate + Base di Mortaio Podstavec pro minomet Mortar Baseplate Podstawa Moździerza @@ -863,7 +873,7 @@ [CSW] Mk6 迫撃砲発射筒 [CSW] Mk6 迫擊炮炮管 [班组] Mk6 迫击炮管 - [CSW] Mk6 Mortar Tube + [CSW] Tubo di Mortaio Mk6 [CSW] Minomet Mk6 hlaveň [CSW] Mk6 Mortar Tube [CSW] Rura Moździerza Mk6 @@ -879,7 +889,7 @@ [CSW] M252 発射筒バッグ [CSW] M252 炮管袋 [班组] M252 炮管包 - [CSW] M252 Tube Bag + [CSW] Borsa per Tubo M252 [CSW] M252 minometná hlaveň v pouzdře [CSW] M252 Tube Bag [CSW] Torba na M252 @@ -895,7 +905,7 @@ [CSW] M2 ガン バッグ [CSW] M2槍械袋 [班组] M2 枪械包 - [CSW] M2 Gun Bag + [CSW] Borsa per Mitra M2 [CSW] M2 zbraň v pouzdře [CSW] M2 Gun Bag [CSW] Torba na M2 @@ -911,7 +921,7 @@ [CSW] Mk19 ガン バッグ [CSW] Mk19槍械袋 [班组] Mk19 枪械包 - [CSW] MK19 Gun Bag + [CSW] Borsa per Mitra MK19 [CSW] MK19 zbraň v pouzdře [CSW] MK19 Gun Bag [CSW] Torba na MK19 @@ -927,7 +937,7 @@ [CSW] BGM-71 TOW ランチャー バッグ [CSW] BGM-71 拖式飛彈發射器袋 [班组] BGM-71 陶式导弹发射器包 - [CSW] BGM-71 TOW Launcher Bag + [CSW] Borsa per Lanciatore BGM-71 TOW [CSW] BGM-71 TOW raketomet v pouzdře [CSW] BGM-71 TOW Launcher Bag [CSW] Torba na BGM-71 TOW @@ -943,7 +953,7 @@ [CSW] DShK ガン バッグ [CSW]DShK 槍械袋 [班组] DShK 枪械包 - [CSW] DSHK Gun Bag + [CSW] Borsa per Mitra DSHK [CSW] DSHK zbraň v pouzdře [CSW] DSHK Gun Bag [CSW] Torba na DSzK @@ -959,7 +969,7 @@ [CSW] 2B14 発射筒バッグ [CSW] 2B14 炮管袋 [班组] 2B14 炮管包 - [CSW] 2B14 Tube Bag + [CSW] Borsa per Tubo 2B14 [CSW] 2B14 minometná hlaveň v pouzdře [CSW] 2B14 Tube Bag [CSW] Torba na 2B14 @@ -975,7 +985,7 @@ [CSW] NSV ガン バッグ [CSW] NSV 槍械袋 [班组] NSV 枪械包 - [CSW] NSV Gun Bag + [CSW] Borsa per Mitra NSV [CSW] NSV zbraň v pouzdře [CSW] NSV Gun Bag [CSW] Torba na NSV @@ -991,7 +1001,7 @@ [CSW] KORD ガン バッグ [CSW] KORD 槍械袋 [班组] KORD 枪械包 - [CSW] KORD Gun Bag + [CSW] Borsa per Mitra KORD [CSW] KORD zbraň v pouzdře [CSW] KORD Gun Bag [CSW] Torba na KORD @@ -1007,7 +1017,7 @@ [CSW] AGS-30 バッグ [CSW] AGS-30 槍械袋 [班组] AGS-30 枪械包 - [CSW] AGS-30 Gun Bag + [CSW] Borsa per GMG AGS-30 [CSW] ASG-30 zbraň v pouzdře [CSW] AGS-30 Gun Bag [CSW] Torba na AGS-30 @@ -1023,7 +1033,7 @@ [CSW] 9K115 メティス ランチャー バッグ [CSW] 9K115 麥士蒂索人發射器袋 [班组] 9K115 麦士蒂索人反坦克发射器包 - [CSW] 9K115 Metis Launcher Bag + [CSW] Borsa per Lanciatore 9K115 Metis [CSW] 9K115 Metis raketomet v pouzdře [CSW] Torba na 9K115 Metis [CSW] 9k115 Metis Launcher Bag @@ -1039,7 +1049,7 @@ [CSW] 9M113 コルネット ランチャー バッグ [CSW] 9M113 短號發射器 [班组] 9M113 短号发射器 - [CSW] 9M113 Kornet Launcher + [CSW] Borsa per Lanciatore 9M113 Kornet [CSW] 9M113 Kornet raketomet [CSW] Wyrzutnia 9M113 Kornet [CSW] 9m113 Kornet Launcher @@ -1055,7 +1065,7 @@ SPG-9 三脚 SPG-9 三腳架 SPG-9 三脚架 - SPG-9 Tripod + Treppiede SPG-9 SPG-9 trojnožka SPG-9 Tripod Trójnóg SPG-9 @@ -1071,7 +1081,7 @@ [CSW] SPG-9 設置型三脚 [CSW] SPG-9 部署型三腳架 [班组] SPG-9 部署型三脚架 - [CSW] SPG-9 Deployable Tripod + [CSW] Treppiede SPG-9 piazzabile [CSW] SPG-9 trojnožka [CSW] SPG-9 Deployable Tripod [CSW] Trójnóg rozkładany SPG-9 @@ -1087,7 +1097,7 @@ [CSW] SPG-9 ランチャー バッグ [CSW] SPG-9 發射器袋 [班组] SPG-9 发射器包 - [CSW] SPG-9 Launcher Bag + [CSW] Borsa per Lanciatore SPG-9 [CSW] SPG-9 raketomet v pouzdře [CSW] SPG-9 Launcher Bag [CSW] Torba na SPG-9 @@ -1103,12 +1113,29 @@ [CSW] SPG-9M ランチャー バッグ [CSW] SPG-9M 發射器袋 [班组] SPG-9M 发射器包 - [CSW] SPG-9M Launcher Bag + [CSW] Borsa per Lanciatore SPG-9M [CSW] SPG-9M raketomet v pouzdře [CSW] SPG-9M Launcher Bag [CSW] Torba na SPG-9M [CSW] Сумка с СПГ-9М орудием [CSW] SPG-9M 발사기 가방 + + + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[班组\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + ^\[CSW\] + diff --git a/addons/dagr/XEH_postInit.sqf b/addons/dagr/XEH_postInit.sqf index 4c3fce167d..34dc981843 100644 --- a/addons/dagr/XEH_postInit.sqf +++ b/addons/dagr/XEH_postInit.sqf @@ -2,7 +2,7 @@ if (!hasInterface) exitWith {}; -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" GVAR(outputPFH) = -1; @@ -30,4 +30,4 @@ GVAR(vectorConnected) = false; GVAR(noVectorData) = true; GVAR(vectorGrid) = "00000000"; -[QEGVAR(vector,rangefinderData), FUNC(handleRangeFinderData)] call CBA_fnc_addEventHandler; +[QEGVAR(vector,rangefinderData), LINKFUNC(handleRangeFinderData)] call CBA_fnc_addEventHandler; diff --git a/addons/dagr/functions/fnc_menuInit.sqf b/addons/dagr/functions/fnc_menuInit.sqf index 5bc757e295..fc05185638 100644 --- a/addons/dagr/functions/fnc_menuInit.sqf +++ b/addons/dagr/functions/fnc_menuInit.sqf @@ -541,7 +541,7 @@ GVAR(menuRun) = true; }; case "options": { (__dsp displayCtrl __Option0) ctrlSetText "Signal Delay"; - (__dsp displayCtrl __Option1) ctrlSetText (if (GVAR(useDegrees)) then { "Direction: Deg" } else { "Direction: MIL" }); + (__dsp displayCtrl __Option1) ctrlSetText (["Direction: MIL", "Direction: Deg"] select GVAR(useDegrees)); (__dsp displayCtrl (__Selection0 + GVAR(selection))) ctrlSetText QPATHTOF(UI\DAGR_Selection.paa); if (GVAR(SEL)) then { GVAR(vectorConnected) = false; diff --git a/addons/dagr/functions/fnc_outputData.sqf b/addons/dagr/functions/fnc_outputData.sqf index 21e19ff023..b7064ce248 100644 --- a/addons/dagr/functions/fnc_outputData.sqf +++ b/addons/dagr/functions/fnc_outputData.sqf @@ -65,10 +65,10 @@ GVAR(outputPFH) = [{ private _dagrTime = [daytime, "HH:MM"] call bis_fnc_timeToString; // Output - __gridControl ctrlSetText format ["%1", _dagrGrid]; - __speedControl ctrlSetText format ["%1", _dagrSpeed]; - __elevationControl ctrlSetText format ["%1", _dagrElevation]; - __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _dagrHeading] } else { format ["%1 �", _dagrHeading] }); - __timeControl ctrlSetText format ["%1", _dagrTime]; + __gridControl ctrlSetText _dagrGrid; + __speedControl ctrlSetText _dagrSpeed; + __elevationControl ctrlSetText _dagrElevation; + __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { str _dagrHeading } else { format ["%1 �", _dagrHeading] }); + __timeControl ctrlSetText _dagrTime; }, GVAR(updateInterval), []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/dagr/functions/fnc_outputVector.sqf b/addons/dagr/functions/fnc_outputVector.sqf index 5eb1b9bffa..e9bd0ea6c3 100644 --- a/addons/dagr/functions/fnc_outputVector.sqf +++ b/addons/dagr/functions/fnc_outputVector.sqf @@ -89,8 +89,8 @@ private _dagrDist = str GVAR(LAZDIST) + "m"; GVAR(vectorGrid) = _dagrGrid; // OUTPUT -__gridControl ctrlSetText format ["%1", _dagrGrid]; -__speedControl ctrlSetText format ["%1", _dagrDist]; -__elevationControl ctrlSetText format ["%1", _dagrElevation]; -__headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _bearing] } else { format ["%1°", _bearing] }); -__timeControl ctrlSetText format ["%1", _dagrTime]; +__gridControl ctrlSetText _dagrGrid; +__speedControl ctrlSetText _dagrDist; +__elevationControl ctrlSetText _dagrElevation; +__headingControl ctrlSetText (if (!GVAR(useDegrees)) then { str _bearing } else { format ["%1°", _bearing] }); +__timeControl ctrlSetText _dagrTime; diff --git a/addons/dagr/functions/fnc_outputWP.sqf b/addons/dagr/functions/fnc_outputWP.sqf index 2e0588ccc4..27944f0bb9 100644 --- a/addons/dagr/functions/fnc_outputWP.sqf +++ b/addons/dagr/functions/fnc_outputWP.sqf @@ -85,10 +85,10 @@ GVAR(outputPFH) = [{ }); // Output - __gridControl ctrlSetText format ["%1", _dagrGrid]; - __speedControl ctrlSetText format ["%1", _bearing]; - __elevationControl ctrlSetText format ["%1", _dagrGrid2]; - __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { format ["%1", _dagrHeading] } else { format ["%1°", _dagrHeading] }); - __timeControl ctrlSetText format ["%1", _dagrDistance]; + __gridControl ctrlSetText _dagrGrid; + __speedControl ctrlSetText str _bearing; + __elevationControl ctrlSetText _dagrGrid2; + __headingControl ctrlSetText (if (!GVAR(useDegrees)) then { str _dagrHeading } else { format ["%1°", _dagrHeading] }); + __timeControl ctrlSetText _dagrDistance; }, GVAR(updateInterval), []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/dagr/initKeybinds.sqf b/addons/dagr/initKeybinds.inc.sqf similarity index 100% rename from addons/dagr/initKeybinds.sqf rename to addons/dagr/initKeybinds.inc.sqf diff --git a/addons/dagr/stringtable.xml b/addons/dagr/stringtable.xml index 38dfd89254..3251052002 100644 --- a/addons/dagr/stringtable.xml +++ b/addons/dagr/stringtable.xml @@ -41,9 +41,9 @@ Переключить DAGR Mostrar DAGR Přepnout DAGR - Apri DAGR + Apri/Chiudi DAGR Activer/Désactiver le DAGR - DAGR を常に表示 + DAGR 表示切替 DAGR 토글 切換軍用GPS接收器 切换军用 GPS 接收器 @@ -59,7 +59,7 @@ Defense Advanced GPS Receiver Defense Advanced GPS Receiver Defense Advanced GPS Receiver - アドバンスド DAGR の受信を定義します + 国防のための高度なGPS受信機 (Defense Advanced GPS Receiver) 국방 고급위성항법시스템 수신기 軍用高級防禦GPS接收器 军用高级防御 GPS 接收器 diff --git a/addons/disarming/XEH_postInit.sqf b/addons/disarming/XEH_postInit.sqf index 6944f8b146..5b123af297 100644 --- a/addons/disarming/XEH_postInit.sqf +++ b/addons/disarming/XEH_postInit.sqf @@ -1,4 +1,4 @@ #include "script_component.hpp" -[QGVAR(dropItems), FUNC(eventTargetStart)] call CBA_fnc_addEventHandler; -[QGVAR(debugCallback), FUNC(eventCallerFinish)] call CBA_fnc_addEventHandler; +[QGVAR(dropItems), LINKFUNC(eventTargetStart)] call CBA_fnc_addEventHandler; +[QGVAR(debugCallback), LINKFUNC(eventCallerFinish)] call CBA_fnc_addEventHandler; diff --git a/addons/disarming/functions/fnc_disarmDropItems.sqf b/addons/disarming/functions/fnc_disarmDropItems.sqf index 26e00dfa5f..6e842e739a 100644 --- a/addons/disarming/functions/fnc_disarmDropItems.sqf +++ b/addons/disarming/functions/fnc_disarmDropItems.sqf @@ -30,7 +30,7 @@ private _fncSumArray = { }; //Sanity Checks -if (!([_target] call FUNC(canBeDisarmed))) exitWith { +if !([_target] call FUNC(canBeDisarmed)) exitWith { [_caller, _target, "Debug: Cannot disarm target"] call FUNC(eventTargetFinish); }; if (_doNotDropAmmo && {({_x in _listOfItemsToRemove} count (magazines _target)) > 0}) exitWith { @@ -50,7 +50,7 @@ if (!_doNotDropAmmo) then { if ((_x getVariable [QGVAR(disarmUnit), objNull]) == _target) exitWith { _holder = _x; }; - } count ((getpos _target) nearObjects [DISARM_CONTAINER, 3]); + } forEach ((getpos _target) nearObjects [DISARM_CONTAINER, 3]); }; //Create a new weapon holder @@ -74,7 +74,6 @@ if (_holder getVariable [QGVAR(holderInUse), false]) exitWith { }; _holder setVariable [QGVAR(holderInUse), true]; - //Remove Magazines private _targetMagazinesStart = magazinesAmmo _target; private _holderMagazinesStart = magazinesAmmoCargo _holder; @@ -96,7 +95,7 @@ if (({((_x select 0) in _listOfItemsToRemove) && {(getNumber (configFile >> "Cfg [_caller, _target, "Debug: Didn't Remove Magazines"] call FUNC(eventTargetFinish); }; //Verify holder has mags unit had -if (!([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved))) then { +if !([_targetMagazinesStart, _targetMagazinesEnd, _holderMagazinesStart, _holderMagazinesEnd] call FUNC(verifyMagazinesMoved)) then { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Crate Magazines not in holder"] call FUNC(eventTargetFinish); }; @@ -238,7 +237,7 @@ if (_holderIsEmpty) then { [_caller, _target, "Debug: Drop Actions Timeout"] call FUNC(eventTargetFinish); }; //If target lost disarm status: - if (!([_target] call FUNC(canBeDisarmed))) exitWith { + if !([_target] call FUNC(canBeDisarmed)) exitWith { _holder setVariable [QGVAR(holderInUse), false]; [_caller, _target, "Debug: Target cannot be disarmed"] call FUNC(eventTargetFinish); }; diff --git a/addons/disarming/functions/fnc_eventTargetStart.sqf b/addons/disarming/functions/fnc_eventTargetStart.sqf index 7173f66a76..a7154ce2e4 100644 --- a/addons/disarming/functions/fnc_eventTargetStart.sqf +++ b/addons/disarming/functions/fnc_eventTargetStart.sqf @@ -32,7 +32,7 @@ private _itemsToAdd = []; } forEach _listOfObjectsToRemove; { - if (!(_x in _listOfObjectsToRemove)) then { + if !(_x in _listOfObjectsToRemove) then { _listOfObjectsToRemove pushBack _x; }; } forEach _itemsToAdd; diff --git a/addons/disarming/functions/fnc_openDisarmDialog.sqf b/addons/disarming/functions/fnc_openDisarmDialog.sqf index a3762aec9f..6cf15f4cad 100644 --- a/addons/disarming/functions/fnc_openDisarmDialog.sqf +++ b/addons/disarming/functions/fnc_openDisarmDialog.sqf @@ -16,11 +16,14 @@ * * Public: No */ + params ["_caller", "_target"]; -#define DEFUALTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" + +#define DEFAULTPATH "\A3\Ui_f\data\GUI\Cfg\Ranks\%1_gs.paa" + //Sanity Checks if (_caller != ACE_player) exitWith {ERROR("Player isn't caller?");}; -if (!([_player, _target] call FUNC(canPlayerDisarmUnit))) exitWith {ERROR("Can't Disarm Unit");}; +if !([_player, _target] call FUNC(canPlayerDisarmUnit)) exitWith {ERROR("Can't Disarm Unit");}; if (dialog) then {ERROR("Dialog open when trying to open disarm dialog"); closeDialog 0;}; disableSerialization; @@ -74,8 +77,8 @@ GVAR(disarmTarget) = _target; private _rankPicture = _display displayCtrl 1203; //Show rank and name (just like BIS's inventory) - private _icon = format [DEFUALTPATH, toLower (rank _target)]; - if (_icon isEqualTo DEFUALTPATH) then {_icon = ""}; + private _icon = format [DEFAULTPATH, toLowerANSI (rank _target)]; + if (_icon isEqualTo DEFAULTPATH) then {_icon = ""}; _rankPicture ctrlSetText _icon; _playerName ctrlSetText ([GVAR(disarmTarget), false, true] call EFUNC(common,getName)); @@ -93,7 +96,7 @@ GVAR(disarmTarget) = _target; if ((_x getVariable [QGVAR(disarmUnit), objNull]) == _target) exitWith { _holder = _x; }; - } count ((getpos _target) nearObjects [DISARM_CONTAINER, 3]); + } forEach ((getpos _target) nearObjects [DISARM_CONTAINER, 3]); //If a holder exists, show it's inventory if (!isNull _holder) then { diff --git a/addons/disarming/functions/fnc_showItemsInListbox.sqf b/addons/disarming/functions/fnc_showItemsInListbox.sqf index e05e27c87e..11d7bd470b 100644 --- a/addons/disarming/functions/fnc_showItemsInListbox.sqf +++ b/addons/disarming/functions/fnc_showItemsInListbox.sqf @@ -55,7 +55,7 @@ params ["_listBoxCtrl", "_itemsCountArray"]; }; }; - _listBoxCtrl lbAdd format ["%1", _displayName]; + _listBoxCtrl lbAdd _displayName; _listBoxCtrl lbSetData [((lbSize _listBoxCtrl) - 1), _classname]; _listBoxCtrl lbSetPicture [((lbSize _listBoxCtrl) - 1), _picture]; _listBoxCtrl lbSetTextRight [((lbSize _listBoxCtrl) - 1), str _count]; diff --git a/addons/dogtags/CfgEventHandlers.hpp b/addons/dogtags/CfgEventHandlers.hpp index 2a3f71f852..f6503c2479 100644 --- a/addons/dogtags/CfgEventHandlers.hpp +++ b/addons/dogtags/CfgEventHandlers.hpp @@ -3,11 +3,13 @@ class Extended_PreStart_EventHandlers { 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/dogtags/CfgVehicles.hpp b/addons/dogtags/CfgVehicles.hpp index cc56410699..56be52b53e 100644 --- a/addons/dogtags/CfgVehicles.hpp +++ b/addons/dogtags/CfgVehicles.hpp @@ -4,7 +4,7 @@ class CfgVehicles { class ACE_Actions { class ACE_Dogtag { displayName = CSTRING(itemName); - condition = QUOTE([ARR_2(_player,_target)] call FUNC(canTakeDogtag)); + condition = QUOTE([ARR_2(_player,_target)] call FUNC(canCheckDogtag)); statement = ""; exceptions[] = {"isNotSwimming", "isNotInside"}; showDisabled = 0; diff --git a/addons/dogtags/CfgWeapons.hpp b/addons/dogtags/CfgWeapons.hpp index 0f795d8d08..ac73ee68f7 100644 --- a/addons/dogtags/CfgWeapons.hpp +++ b/addons/dogtags/CfgWeapons.hpp @@ -16,8 +16,8 @@ class CfgWeapons { author = ECSTRING(common,ACETeam); scope = 0; displayName = CSTRING(itemName); - model = QUOTE(PATHTOF(data\ace_dogtag.p3d)); - picture = QUOTE(PATHTOF(data\dogtagSingle.paa)); + model = QPATHTOF(data\ace_dogtag.p3d); + picture = QPATHTOF(data\dogtagSingle.paa); class ItemInfo: CBA_MiscItem_ItemInfo { mass = 0; //too small to for 1 ? }; diff --git a/addons/dogtags/XEH_PREP.hpp b/addons/dogtags/XEH_PREP.hpp index 5917600139..9ff33a26a2 100644 --- a/addons/dogtags/XEH_PREP.hpp +++ b/addons/dogtags/XEH_PREP.hpp @@ -1,15 +1,11 @@ - PREP(addDogtagActions); -PREP(addDogtagItem); PREP(bloodType); PREP(canCheckDogtag); PREP(canTakeDogtag); PREP(checkDogtag); -PREP(checkDogtagItem); +PREP(disableFactionDogtags); PREP(getDogtagData); PREP(getDogtagItem); -PREP(sendDogtagData); PREP(showDogtag); PREP(ssn); PREP(takeDogtag); -PREP(disableFactionDogtags); diff --git a/addons/dogtags/XEH_postInit.sqf b/addons/dogtags/XEH_postInit.sqf index 6653d80211..3ced843f47 100644 --- a/addons/dogtags/XEH_postInit.sqf +++ b/addons/dogtags/XEH_postInit.sqf @@ -1,19 +1,87 @@ #include "script_component.hpp" -[QGVAR(showDogtag), DFUNC(showDogtag)] call CBA_fnc_addEventHandler; -[QGVAR(sendDogtagData), DFUNC(sendDogtagData)] call CBA_fnc_addEventHandler; -[QGVAR(getDogtagItem), DFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; -[QGVAR(addDogtagItem), DFUNC(addDogtagItem)] call CBA_fnc_addEventHandler; +if (hasInterface || isServer) then { + [QGVAR(broadcastDogtagInfo), { + GVAR(dogtagsData) set _this; + }] call CBA_fnc_addEventHandler; -// Add actions and event handlers only if ace_medical is loaded + if (isServer) then { + // Sync dogtag data from server to client + [QGVAR(requestSyncDogtagDataJIP), { + params ["_clientOwner"]; + + { + [QGVAR(broadcastDogtagInfo), [_x, _y], _clientOwner] call CBA_fnc_ownerEvent; + } forEach GVAR(dogtagsData); + }] call CBA_fnc_addEventHandler; + + [QGVAR(getDogtagItem), LINKFUNC(getDogtagItem)] call CBA_fnc_addEventHandler; + } else { + // To be here, hasInterface must be true + [QGVAR(requestSyncDogtagDataJIP), clientOwner] call CBA_fnc_serverEvent; + }; +}; + +if (hasInterface) then { + // If the arsenal is loaded, show the custom names for dog tags when in the arsenal + if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(arsenal,rightPanelFilled), { + params ["_display", "_leftPanelIDC", "_rightPanelIDC"]; + + if !(_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) exitWith {}; + + private _rightPanel = _display displayCtrl 15; + private _cfgWeapons = configFile >> "CfgWeapons"; + + TRACE_1("passed",_rightPanel); + + for "_i" from 0 to (lnbSize _rightPanel select 0) - 1 do { + private _item = _rightPanel lnbData [_i, 0]; + + if (_item isKindOf ["ACE_dogtag", _cfgWeapons]) then { + private _name = (GVAR(dogtagsData) getOrDefault [_item, []]) param [0, ""]; + + // If data doesn't exist or body has no name, set name as "unknown" + if (_name == "") then { + _name = LELSTRING(common,unknown); + }; + + _rightPanel lnbSetText [[_i, 1], [LLSTRING(itemName), ": ", _name] joinString ""]; + }; + }; + }] call CBA_fnc_addEventHandler; + }; + + // Add context menu option + [ + "ACE_dogtag", + ["GROUND", "CARGO", "CONTAINER"], + LLSTRING(checkItem), + nil, + QPATHTOF(data\dogtag_icon_ca.paa), + [ + {true}, + {true} + ], + { + [GVAR(dogtagsData) getOrDefault [_this select 2, []]] call FUNC(showDogtag); + + false + } + ] call CBA_fnc_addItemContextMenuOption; +}; + +// Add actions and event handlers only if ace_medical is enabled // - Adding actions via config would create a dependency -if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { +["CBA_settingsInitialized", { + if !(GETEGVAR(medical,enabled,false)) exitWith {}; + if (hasInterface) then { private _checkTagAction = [ "ACE_CheckDogtag", - format ["%1: %2", localize LSTRING(itemName), localize LSTRING(checkDogtag)], + format ["%1: %2", LLSTRING(itemName), LLSTRING(checkDogtag)], QPATHTOF(data\dogtag_icon_ca.paa), - {[_player,_target] call FUNC(checkDogtag)}, + {[_player, _target] call FUNC(checkDogtag)}, {!isNil {_target getVariable QGVAR(dogtagData)}} ] call EFUNC(interact_menu,createAction); @@ -21,9 +89,9 @@ if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { private _takeTagAction = [ "ACE_TakeDogtag", - format ["%1: %2", localize LSTRING(itemName), localize LSTRING(takeDogtag)], + format ["%1: %2", LLSTRING(itemName), LLSTRING(takeDogtag)], QPATHTOF(data\dogtag_icon_ca.paa), - {[_player,_target] call FUNC(takeDogtag)}, + {[_player, _target] call FUNC(takeDogtag)}, {(!isNil {_target getVariable QGVAR(dogtagData)}) && {((_target getVariable [QGVAR(dogtagTaken), objNull]) != _target)}} ] call EFUNC(interact_menu,createAction); @@ -33,46 +101,19 @@ if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { if (isServer) then { ["ace_placedInBodyBag", { params ["_target", "_bodyBag", "_isGrave"]; + if (_isGrave) exitWith {}; TRACE_2("ace_placedInBodyBag eh",_target,_bodyBag); - private _dogTagData = [_target] call FUNC(getDogtagData); - _bodyBag setVariable [QGVAR(dogtagData), _dogTagData, true]; + private _dogtagData = _target call FUNC(getDogtagData); + _bodyBag setVariable [QGVAR(dogtagData), _dogtagData, true]; if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then { _bodyBag setVariable [QGVAR(dogtagTaken), _bodyBag, true]; }; }] call CBA_fnc_addEventHandler; }; -}; +}] call CBA_fnc_addEventHandler; -// If the arsenal is loaded, show the custom names for dog tags when in the arsenal -if (["ACE_Arsenal"] call EFUNC(common,isModLoaded)) then { - [QEGVAR(arsenal,rightPanelFilled), { - params ["_display", "_leftPanelIDC", "_rightPanelIDC"]; - - if (_leftPanelIDC in [2010, 2012, 2014] && {_rightPanelIDC == 38}) then { - LOG("passed"); - private _rightPanel = _display displayCtrl 15; - private _allDogtags = missionNamespace getVariable [QGVAR(allDogtags), []]; - private _allDogtagsData = missionNamespace getVariable [QGVAR(allDogtagDatas), []]; - private _cfgWeapons = configFile >> "CfgWeapons"; - private _item = ""; - private _dogtagData = []; - - for "_i" from 0 to (lnbSize _rightPanel select 0) - 1 do { - _item = _rightPanel lnbData [_i, 0]; - - if (_item isKindOf ["ACE_dogtag", _cfgWeapons]) then { - _dogtagData = _allDogtagsData param [_allDogtags find _item, []]; - - // If data doesn't exist, put name as "unknown" - _rightPanel lnbSetText [[_i, 1], [LLSTRING(itemName), ": ", _dogtagData param [0, LELSTRING(common,unknown)]] joinString ""]; - }; - }; - }; - }] call CBA_fnc_addEventHandler; -}; - -// Disable dogtags for civilians +// Disable dog tags for civilians "CIV_F" call FUNC(disableFactionDogtags); diff --git a/addons/dogtags/XEH_preInit.sqf b/addons/dogtags/XEH_preInit.sqf index 5ad43b0229..482551de0a 100644 --- a/addons/dogtags/XEH_preInit.sqf +++ b/addons/dogtags/XEH_preInit.sqf @@ -6,6 +6,14 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -GVAR(disabledFactions) = [] call CBA_fnc_createNamespace; +GVAR(disabledFactions) = createHashMap; + +if (hasInterface || isServer) then { + GVAR(dogtagsData) = createHashMap; + + if (!isServer) exitWith {}; + + GVAR(idCounter) = 0; +}; ADDON = true; diff --git a/addons/dogtags/functions/fnc_addDogtagActions.sqf b/addons/dogtags/functions/fnc_addDogtagActions.sqf index 7c7a2e5e8f..9b2f3147b5 100644 --- a/addons/dogtags/functions/fnc_addDogtagActions.sqf +++ b/addons/dogtags/functions/fnc_addDogtagActions.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL, mharis001 - * Returns children actions for checking dogtags in player's inventory. + * Returns children actions for checking dog tags in the player's inventory. * * Arguments: * 0: Player @@ -10,7 +10,7 @@ * Actions * * Example: - * [_player] call ace_dogtags_fnc_addDogtagActions + * player call ace_dogtags_fnc_addDogtagActions * * Public: No */ @@ -23,12 +23,21 @@ private _fnc_getActions = { { private _config = _cfgWeapons >> _x; - if (getNumber (_config >> QGVAR(tagID)) > 0) then { - private _displayName = getText (_config >> "displayName"); - private _picture = getText (_config >> "picture"); - private _action = [_x, _displayName, _picture, FUNC(checkDogtagItem), {true}, {}, _x] call EFUNC(interact_menu,createAction); - _actions pushBack [_action, [], _player]; + if (getNumber (_config >> QGVAR(tagID)) > 0) then { + _actions pushBack [ + [ + _x, + getText (_config >> "displayName"), + getText (_config >> "picture"), + {[GVAR(dogtagsData) getOrDefault [_this select 2, []]] call FUNC(showDogtag)}, + {true}, + {}, + _x + ] call EFUNC(interact_menu,createAction), + [], + _player + ]; }; } forEach (_player call EFUNC(common,uniqueItems)); diff --git a/addons/dogtags/functions/fnc_addDogtagItem.sqf b/addons/dogtags/functions/fnc_addDogtagItem.sqf deleted file mode 100644 index 970bb1926e..0000000000 --- a/addons/dogtags/functions/fnc_addDogtagItem.sqf +++ /dev/null @@ -1,31 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: SzwedzikPL - * Adds dogtag item to unit (triggered by server). - * - * Arguments: - * 0: Item class - * 1: Dogtag data - * - * Return Value: - * None - * - * Example: - * ["itemClass", ["name", "610-27-5955", "A POS"]] call ace_dogtags_fnc_addDogtagItem - * - * Public: No - */ - -params ["_item", "_dogtagData"]; - -if (_item == "") exitWith {}; - -[ace_player, _item] call CBA_fnc_addItem; - -_dogtagData params ["_nickName"]; -private _displayText = format [localize LSTRING(takeDogtagSuccess), _nickName]; - -// display message -[{ - [_this, 2.5] call EFUNC(common,displayTextStructured); -}, _displayText, DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_bloodType.sqf b/addons/dogtags/functions/fnc_bloodType.sqf index 5e03c586fa..53b6007370 100644 --- a/addons/dogtags/functions/fnc_bloodType.sqf +++ b/addons/dogtags/functions/fnc_bloodType.sqf @@ -1,16 +1,16 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Reports a blood type depending on the units name. + * Reports a blood type depending on the unit's name. * * Arguments: - * 0: Name of a unit + * 0: Unit name * * Return Value: * A random blood type * * Example: - * _bloodType = ["name"] call ace_dogtags_fnc_bloodType + * "name" call ace_dogtags_fnc_bloodType * * Public: No */ diff --git a/addons/dogtags/functions/fnc_canCheckDogtag.sqf b/addons/dogtags/functions/fnc_canCheckDogtag.sqf index 399ad5db25..a5ed987fc0 100644 --- a/addons/dogtags/functions/fnc_canCheckDogtag.sqf +++ b/addons/dogtags/functions/fnc_canCheckDogtag.sqf @@ -1,26 +1,26 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Checks if dogtag can be checked. + * Checks if the target's dog tag can be checked by the unit. * * Arguments: - * 0: Player + * 0: Player (not used) * 1: Target * * Return Value: - * True if dogtag can be checked + * If dog tag can be checked * * Example: - * _canCheck = [player, unit] call ace_dogtags_fnc_canCheckDogtag + * [player, cursorObject] call ace_dogtags_fnc_canCheckDogtag * * Public: No */ -params ["_player", "_target"]; +params ["", "_target"]; if (isNull _target) exitWith {false}; -// check if disabled for faction -if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; +// Check if disabled for faction +if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; -(!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} +!(_target call EFUNC(common,isAwake)) diff --git a/addons/dogtags/functions/fnc_canTakeDogtag.sqf b/addons/dogtags/functions/fnc_canTakeDogtag.sqf index 7ae38f7c41..c56db0b893 100644 --- a/addons/dogtags/functions/fnc_canTakeDogtag.sqf +++ b/addons/dogtags/functions/fnc_canTakeDogtag.sqf @@ -1,17 +1,17 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Checks if dogtag can be taken. + * Checks if the target's dog tag can be taken by the unit. * * Arguments: * 0: Player * 1: Target * * Return Value: - * True if dogtag can be taken + * If dog tag can be taken * * Example: - * _canTake = [player, unit] call ace_dogtags_fnc_canTakeDogtag + * [player, cursorObject] call ace_dogtags_fnc_canTakeDogtag * * Public: No */ @@ -20,7 +20,10 @@ params ["_player", "_target"]; if (isNull _target) exitWith {false}; -// check if disabled for faction -if ([GVAR(disabledFactions) getVariable faction _target] param [0, false]) exitWith {false}; +// Check if disabled for faction +if ((faction _target) in GVAR(disabledFactions)) exitWith {false}; -(!alive _target) || {_target getVariable ["ACE_isUnconscious", false]} +// CBA_fnc_canAddItem doesn't account for mass 0 items and unit not having any containers +!(_target call EFUNC(common,isAwake)) && {(uniform _player + vest _player + backpack _player) != ""} && {[_player, "ACE_dogtag_1"] call CBA_fnc_canAddItem} +// Todo: Use code below in 2.18 +// _player canAdd ["ACE_dogtag_1", 1, true] diff --git a/addons/dogtags/functions/fnc_checkDogtag.sqf b/addons/dogtags/functions/fnc_checkDogtag.sqf index dcceb8c2c0..4b2f2d533f 100644 --- a/addons/dogtags/functions/fnc_checkDogtag.sqf +++ b/addons/dogtags/functions/fnc_checkDogtag.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Checks unit dogtag. + * Checks the unit's dog tag. * * Arguments: * 0: Player @@ -11,17 +11,17 @@ * None * * Example: - * [player, unit] call ace_dogtags_fnc_checkDogtag + * [player, cursorObject] call ace_dogtags_fnc_checkDogtag * * Public: No */ params ["_player", "_target"]; -// animation +// Animation _player call EFUNC(common,goKneeling); -// sound +// Sound private _position = _target modelToWorldWorld (_target selectionPosition "neck"); playSound3D [ @@ -34,10 +34,8 @@ playSound3D [ 50 ]; -// display dogtag +// Display dog tag private _doubleTags = (_target getVariable [QGVAR(dogtagTaken), objNull]) != _target; -private _dogTagData = [_target] call FUNC(getDogTagData); +private _dogtagData = _target call FUNC(getDogtagData); -[{ - [QGVAR(showDogtag), _this] call CBA_fnc_localEvent; -}, [_dogTagData, _doubleTags], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; +[LINKFUNC(showDogtag), [_dogtagData, _doubleTags], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_checkDogtagItem.sqf b/addons/dogtags/functions/fnc_checkDogtagItem.sqf deleted file mode 100644 index 09526d83ed..0000000000 --- a/addons/dogtags/functions/fnc_checkDogtagItem.sqf +++ /dev/null @@ -1,22 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: SzwedzikPL - * Check dogtag self menu action. - * - * Arguments: - * 0: Player - * 1: Target - * 2: Item class - * - * Return Value: - * None - * - * Example: - * [player, unit, "itemClass"] call ace_dogtags_fnc_checkDogtagItem - * - * Public: No - */ - -params ["_player", "_target", "_item"]; - -[QGVAR(sendDogtagData), [_player, _item]] call CBA_fnc_serverEvent; diff --git a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf index f1ea5f5c06..b1ac145d9a 100644 --- a/addons/dogtags/functions/fnc_disableFactionDogtags.sqf +++ b/addons/dogtags/functions/fnc_disableFactionDogtags.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Disable this faction from using dogtags. + * Disables this faction from using dog tags. * * Arguments: * 0: Faction @@ -17,4 +17,9 @@ params [["_faction", "", [""]]]; -GVAR(disabledFactions) setVariable [_faction, true]; +_faction = configName (configFile >> "CfgFactionClasses" >> _faction); + +// Faction doesn't exist +if (_faction == "") exitWith {}; + +GVAR(disabledFactions) set [_faction, true]; diff --git a/addons/dogtags/functions/fnc_getDogtagData.sqf b/addons/dogtags/functions/fnc_getDogtagData.sqf index 6a850543fc..4aaf930fa2 100644 --- a/addons/dogtags/functions/fnc_getDogtagData.sqf +++ b/addons/dogtags/functions/fnc_getDogtagData.sqf @@ -1,19 +1,19 @@ #include "..\script_component.hpp" /* * Author: esteldunedain - * Get unit dogtag data. + * Gets unit's dog tag data. * * Arguments: * 0: Target * * Return Value: - * Dogtag Data + * Dog tag Data * 0: Name * 1: SSN * 2: Blood Type * * Example: - * _dogtagData = [unit, player] call ace_dogtags_fnc_getDogtagData + * player call ace_dogtags_fnc_getDogtagData * * Public: No */ @@ -21,17 +21,20 @@ params ["_target"]; // Check if the data was already created -private _dogTagData = _target getVariable QGVAR(dogtagData); -if (!isNil "_dogTagData") exitWith {_dogTagData}; +private _dogtagData = _target getVariable QGVAR(dogtagData); + +if (!isNil "_dogtagData") exitWith {_dogtagData}; // Create dog tag data once for the unit: nickname, code (eg. 135-13-900) and blood type private _targetName = [_target, false, true] call EFUNC(common,getName); -private _dogTagData = [ +private _dogtagData = [ _targetName, _targetName call FUNC(ssn), _targetName call FUNC(bloodType) ]; + // Store it -_target setVariable [QGVAR(dogtagData), _dogTagData, true]; -_dogTagData +_target setVariable [QGVAR(dogtagData), _dogtagData, true]; + +_dogtagData diff --git a/addons/dogtags/functions/fnc_getDogtagItem.sqf b/addons/dogtags/functions/fnc_getDogtagItem.sqf index 04112bcc94..4f8cc94cc7 100644 --- a/addons/dogtags/functions/fnc_getDogtagItem.sqf +++ b/addons/dogtags/functions/fnc_getDogtagItem.sqf @@ -1,7 +1,8 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Server: creates new dogtag item and send it to client. + * Server: Creates a new dog tag item and sends it to client. + * It broacasts the dog tag info to all machines with interfaces. * * Arguments: * 0: Player @@ -11,29 +12,37 @@ * None * * Example: - * [player, unit] call ace_dogtags_fnc_getDogtagItem + * [player, cursorObject] call ace_dogtags_fnc_getDogtagItem * * Public: No */ -if(!isServer) exitWith {}; +if (!isServer) exitWith {}; params ["_player", "_target"]; TRACE_2("getDogtagItem",_player,_target); -private _allDogtags = missionNamespace getVariable [QGVAR(allDogtags), []]; -private _allDogtagDatas = missionNamespace getVariable [QGVAR(allDogtagDatas), []]; +GVAR(idCounter) = GVAR(idCounter) + 1; -private _nextID = count _allDogtags + 1; - -if (_nextID > 999) exitWith {ERROR("Ran out of IDs");}; +if (GVAR(idCounter) > 999) exitWith {ERROR("Ran out of IDs");}; private _dogTagData = [_target] call FUNC(getDogTagData); -private _item = format ["ACE_dogtag_%1", _nextID]; -_allDogtags pushBack _item; -_allDogtagDatas pushBack _dogTagData; +private _item = format ["ACE_dogtag_%1", GVAR(idCounter)]; -missionNamespace setVariable [QGVAR(allDogtags), _allDogtags]; -missionNamespace setVariable [QGVAR(allDogtagDatas), _allDogtagDatas]; +// Broadcast data globally, so that clients can use it where needed +[QGVAR(broadcastDogtagInfo), [_item, _dogTagData]] call CBA_fnc_globalEvent; -[QGVAR(addDogtagItem), [_item, _dogTagData], [_player]] call CBA_fnc_targetEvent; +// Dog tags have no mass, so no need to check if it can fit in container, but check if unit has an inventory at all +[_player, _item, true] call CBA_fnc_addItem; + +private _name = _dogtagData param [0, ""]; + +// If data doesn't exist or body has no name, set name as "unknown" +if (_name == "") then { + _name = LELSTRING(common,unknown); +}; + +// Display message +[{ + [QEGVAR(common,displayTextStructured), [_this select 0, 2.5], _this select 1] call CBA_fnc_targetEvent; +}, [format [LLSTRING(takeDogtagSuccess), _name], _player], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; diff --git a/addons/dogtags/functions/fnc_sendDogtagData.sqf b/addons/dogtags/functions/fnc_sendDogtagData.sqf deleted file mode 100644 index 2351e61166..0000000000 --- a/addons/dogtags/functions/fnc_sendDogtagData.sqf +++ /dev/null @@ -1,33 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: SzwedzikPL - * Server: returns to client data on given dogtag. - * - * Arguments: - * 0: Player - * 1: Target - * - * Return Value: - * None - * - * Example: - * [player, unit] call ace_dogtags_fnc_sendDogtagData - * - * Public: No - */ - -if (!isServer) exitWith {}; - -params ["_target", "_item"]; -TRACE_2("sendDogtagData",_target,_item); - -private _allDogtags = missionNameSpace getVariable [QGVAR(allDogtags), []]; -private _allDogtagDatas = missionNameSpace getVariable [QGVAR(allDogtagDatas), []]; - -private _dogtagData = []; -private _index = _allDogtags find _item; -if (_index >= 0) then { - _dogtagData = _allDogtagDatas select _index; -}; - -[QGVAR(showDogtag), [_dogtagData], [_target]] call CBA_fnc_targetEvent; diff --git a/addons/dogtags/functions/fnc_showDogtag.sqf b/addons/dogtags/functions/fnc_showDogtag.sqf index 4865ff7de2..5de9a9fc62 100644 --- a/addons/dogtags/functions/fnc_showDogtag.sqf +++ b/addons/dogtags/functions/fnc_showDogtag.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * Shows dogtag. + * Shows dog tag. * * Arguments: - * 0: Dogtag data + * 0: Dog tag data * 1: Display as double tag * * Return Value: @@ -27,9 +27,17 @@ if (_doubleTags) then { } else { (QGVAR(tag) call BIS_fnc_rscLayer) cutRsc [QGVAR(singleTag), "PLAIN", 1, true]; }; -private _display = uiNamespace getvariable [QGVAR(tag), displayNull]; -if(isNull _display) exitWith {}; + +private _display = uiNamespace getVariable [QGVAR(tag), displayNull]; + +if (isNull _display) exitWith {}; private _control = _display displayCtrl 1001; -_dogtagData params ["_nickName", "_code", "_bloodType"]; -_control ctrlSetStructuredText parseText format ["%1
%2
%3", toUpper _nickName, _code, _bloodType]; +_dogtagData params ["_name", "_code", "_bloodType"]; + +// If data doesn't exist or body has no name, set name as "unknown" +if (_name == "") then { + _name = LELSTRING(common,unknown); +}; + +_control ctrlSetStructuredText parseText format ["%1
%2
%3", toUpper _name, _code, _bloodType]; diff --git a/addons/dogtags/functions/fnc_ssn.sqf b/addons/dogtags/functions/fnc_ssn.sqf index 0ba3499c0b..794422ddd1 100644 --- a/addons/dogtags/functions/fnc_ssn.sqf +++ b/addons/dogtags/functions/fnc_ssn.sqf @@ -1,16 +1,16 @@ #include "..\script_component.hpp" /* * Author: kymckay - * Reports a social security number generated from the units name. + * Reports a social security number generated from the unit's name. * * Arguments: - * 0: Name of a unit + * 0: Unit name * * Return Value: * A random three/two/four format social security number * * Example: - * _ssn = ["AAA"] call ace_dogtags_fnc_ssn + * "name" call ace_dogtags_fnc_ssn * * Public: No */ @@ -18,19 +18,20 @@ params ["_name"]; private _chars = toArray _name; -private _length = count _chars; + // Warning, for strings containing non-latin characters, `_count _name` != `_count _chars` +private _length = count _chars; _chars pushBack _length; _length = _length + 1; private _remainder = 0; -private _nums = [0,0,0,0,0,0,0,0,0]; +private _nums = [0, 0, 0, 0, 0, 0, 0, 0, 0]; for "_index" from 0 to (8 max _length) do { private _inputChar = _chars select (_index % _length); - _nums set [(_index % 9), ((_nums select (_index % 9)) + _inputChar + _remainder) % 10]; + _nums set [_index % 9, ((_nums select (_index % 9)) + _inputChar + _remainder) % 10]; _remainder = (_inputChar + _remainder) % 256; }; -([_nums select [0,3],_nums select [3,2], _nums select [5,4]] apply { _x joinString "" }) joinString "-" +([_nums select [0, 3], _nums select [3, 2], _nums select [5, 4]] apply { _x joinString "" }) joinString "-" diff --git a/addons/dogtags/functions/fnc_takeDogtag.sqf b/addons/dogtags/functions/fnc_takeDogtag.sqf index 1972c91ee0..b374c27121 100644 --- a/addons/dogtags/functions/fnc_takeDogtag.sqf +++ b/addons/dogtags/functions/fnc_takeDogtag.sqf @@ -1,8 +1,8 @@ #include "..\script_component.hpp" /* * Author: SzwedzikPL - * If dogtag is not already taken triggers event on server. - * If dogtag already taken displays info about it. + * If the dog tag hasn't already been taken, it triggers an event on the server. + * If the dog tag has already been taken, it displays info about it. * * Arguments: * 0: Player @@ -12,17 +12,17 @@ * None * * Example: - * [player, unit] call ace_dogtags_fnc_takeDogtag + * [player, cursorObject] call ace_dogtags_fnc_takeDogtag * * Public: No */ params ["_player", "_target"]; -// animation +// Animation _player call EFUNC(common,goKneeling); -// sound +// Sound private _position = _target modelToWorldWorld (_target selectionPosition "neck"); playSound3D [ @@ -35,12 +35,11 @@ playSound3D [ 50 ]; -// display message +// Display message if ((_target getVariable [QGVAR(dogtagTaken), objNull]) == _target) then { - [{ - [_this, 2.5] call EFUNC(common,displayTextStructured); - }, localize LSTRING(dogtagAlreadyTaken), DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; + [EFUNC(common,displayTextStructured), [LLSTRING(dogtagAlreadyTaken), 2.5], DOGTAG_SHOW_DELAY] call CBA_fnc_waitAndExecute; } else { _target setVariable [QGVAR(dogtagTaken), _target, true]; + [QGVAR(getDogtagItem), [_player, _target]] call CBA_fnc_serverEvent; }; diff --git a/addons/dogtags/stringtable.xml b/addons/dogtags/stringtable.xml index ac9dc939f5..73d2d07e56 100644 --- a/addons/dogtags/stringtable.xml +++ b/addons/dogtags/stringtable.xml @@ -6,7 +6,7 @@ Nieśmiertelnik Жетон Identifikační známka - ドッグ タグ + ドッグタグ Erkennungsmarke 군번줄 Plaque d'identification @@ -22,7 +22,7 @@ Sprawdź nieśmiertelnik Проверить жетон Zkontrolovat známku - ドッグ タグを見る + ドッグタグを確認 Erkennungsmarke prüfen 군번줄 확인 Vérifier la plaque d'identification @@ -54,7 +54,7 @@ Zabierz Взять Vezmi - 取る + 拾う Nehmen 회수 Prendre @@ -66,11 +66,11 @@ Al - Dogtag taken from %1... + Dog Tag taken from %1... 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... @@ -82,11 +82,11 @@ Künye %1 kişisinden alındı - Somebody else has already taken the dogtag... + Somebody else has already taken the Dog Tag... 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... @@ -98,12 +98,12 @@ Başka biri zaten künyeyi almış - Onscreen display for checking dogtags + Onscreen display for checking Dog Tags Anzeige um Erkennungsmarke zu überprüfen 在畫面中顯示檢查兵籍牌 在画面中显示检查兵籍牌 - 確認中のドッグタグを画面上で表示します - Display su schermo per il controllo delle piastrine + 確認中のドッグタグを画面上に表示します + Indicatore su schermo per il controllo delle piastrine Wyświetlacz ekranowy dla sprawdzania nieśmiertelników Экран для проверки жетонов Tela de Exibição para verificar dogtags diff --git a/addons/dragging/XEH_PREP.hpp b/addons/dragging/XEH_PREP.hpp index 37b9722e8e..0861c9533d 100644 --- a/addons/dragging/XEH_PREP.hpp +++ b/addons/dragging/XEH_PREP.hpp @@ -26,6 +26,8 @@ PREP(resumeDrag); PREP(setCarryable); PREP(setDraggable); PREP(startCarry); +PREP(startCarryLocal); PREP(startCarryPFH); PREP(startDrag); +PREP(startDragLocal); PREP(startDragPFH); diff --git a/addons/dragging/XEH_postInit.sqf b/addons/dragging/XEH_postInit.sqf index 32b7d72faa..ae277bf4d2 100644 --- a/addons/dragging/XEH_postInit.sqf +++ b/addons/dragging/XEH_postInit.sqf @@ -4,16 +4,6 @@ if (isServer) then { // Release object on disconnection. Function is identical to killed addMissionEventHandler ["HandleDisconnect", LINKFUNC(handleKilled)]; - - // Handle surrending and handcuffing - ["ace_captiveStatusChanged", { - params ["_unit", "_state"]; - - // If surrended or handcuffed, drop dragged/carried object - if (_state) then { - _unit call FUNC(handleKilled); - }; - }] call CBA_fnc_addEventHandler; }; if (!hasInterface) exitWith {}; @@ -38,12 +28,48 @@ if (isNil QGVAR(maxWeightCarryRun)) then { ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; ["weapon", LINKFUNC(handlePlayerWeaponChanged)] call CBA_fnc_addPlayerEventHandler; +// When changing cameras, drop carried and dragged objects +["featureCamera", { + params ["_unit", "_camera"]; + + // Unit can either drag or carry, functions themselves handle which ones are executed + switch (_camera) do { + // Default camera + case "": { + _unit call FUNC(resumeDrag); + _unit call FUNC(resumeCarry); + }; + // Arsenals make the unit change animations, which makes the unit drop dragged/carried objects regardless + case "arsenal"; + case "ace_arsenal": { + _unit call FUNC(handleKilled); + }; + default { + _unit call FUNC(pauseDrag); + _unit call FUNC(pauseCarry); + }; + }; +}] call CBA_fnc_addPlayerEventHandler; + // Handle waking up dragged unit and falling unconscious while dragging ["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; // Display event handler ["MouseZChanged", {(_this select 1) call FUNC(handleScrollWheel)}] call CBA_fnc_addDisplayHandler; +// Handle surrendering and handcuffing +["ace_captiveStatusChanged", { + params ["_unit", "_state"]; + + // If surrended or handcuffed, drop dragged/carried object + if (_state && {local _unit}) then { + _unit call FUNC(handleKilled); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(startCarry), LINKFUNC(startCarryLocal)] call CBA_fnc_addEventHandler; +[QGVAR(startDrag), LINKFUNC(startDragLocal)] call CBA_fnc_addEventHandler; + [QGVAR(carryingContainerClosed), { params ["_container", "_owner"]; TRACE_2("carryingContainerClosed EH",_container,_owner); @@ -81,27 +107,4 @@ if (isNil QGVAR(maxWeightCarryRun)) then { }; }] call CBA_fnc_addEventHandler; -// When changing cameras, drop carried and dragged objects -["featureCamera", { - params ["_unit", "_camera"]; - - // Unit can either drag or carry, functions themselves handle which ones are executed - switch (_camera) do { - // Default camera - case "": { - _unit call FUNC(resumeDrag); - _unit call FUNC(resumeCarry); - }; - // Arsenals make the unit change animations, which makes the unit drop dragged/carried objects regardless - case "arsenal"; - case "ace_arsenal": { - _unit call FUNC(handleKilled); - }; - default { - _unit call FUNC(pauseDrag); - _unit call FUNC(pauseCarry); - }; - }; -}] call CBA_fnc_addPlayerEventHandler; - -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" diff --git a/addons/dragging/XEH_preInit.sqf b/addons/dragging/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/dragging/XEH_preInit.sqf +++ b/addons/dragging/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/dragging/functions/fnc_canCarry.sqf b/addons/dragging/functions/fnc_canCarry.sqf index dce4440a8e..be3015868b 100644 --- a/addons/dragging/functions/fnc_canCarry.sqf +++ b/addons/dragging/functions/fnc_canCarry.sqf @@ -28,12 +28,12 @@ if ((_unit getHitPointDamage "HitLegs") >= 0.5) exitWith {false}; // Static weapons need to be empty for carrying (ignore UAV AI) if (_target isKindOf "StaticWeapon") exitWith { - (crew _target) findIf {getText (configOf _x >> "simulation") != "UAVPilot"} == -1 + (crew _target) findIf {!unitIsUAV _x} == -1 }; // Units need to be unconscious or limping; Units also need to not be in ragdoll, as that causes desync issues if (_target isKindOf "CAManBase") exitWith { - !(alive _target != isAwake _target) && + isAwake _target && // not ragdolled {lifeState _target == "INCAPACITATED" || {_target getHitPointDamage "HitLegs" >= 0.5}} }; diff --git a/addons/dragging/functions/fnc_canDrag.sqf b/addons/dragging/functions/fnc_canDrag.sqf index 7083eec76b..586e23feaf 100644 --- a/addons/dragging/functions/fnc_canDrag.sqf +++ b/addons/dragging/functions/fnc_canDrag.sqf @@ -24,12 +24,12 @@ if !([_unit, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith)) exi // Static weapons need to be empty for dragging (ignore UAV AI) if (_target isKindOf "StaticWeapon") exitWith { - (crew _target) findIf {getText (configOf _x >> "simulation") != "UAVPilot"} == -1 + (crew _target) findIf {!unitIsUAV _x} == -1 }; // Units need to be unconscious or limping; Units also need to not be in ragdoll, as that causes desync issues if (_target isKindOf "CAManBase") exitWith { - !(alive _target != isAwake _target) && + isAwake _target && // not ragdolled {lifeState _target == "INCAPACITATED" || {_target getHitPointDamage "HitLegs" >= 0.5}} }; diff --git a/addons/dragging/functions/fnc_carryObject.sqf b/addons/dragging/functions/fnc_carryObject.sqf index dfff18a3c0..579e6a0ac3 100644 --- a/addons/dragging/functions/fnc_carryObject.sqf +++ b/addons/dragging/functions/fnc_carryObject.sqf @@ -19,6 +19,12 @@ params ["_unit", "_target"]; TRACE_2("params",_unit,_target); +// If in ViV cargo, unload it first +// Warn user if it failed to unload (shouldn't happen) +if (!isNull isVehicleCargo _target && {!(objNull setVehicleCargo _target)}) then { + WARNING_1("ViV Unload Failed %1",_target); +}; + // Get attachTo offset and direction private _position = _target getVariable [QGVAR(carryPosition), [0, 0, 0]]; private _direction = _target getVariable [QGVAR(carryDirection), 0]; @@ -53,21 +59,18 @@ _unit setVariable [QGVAR(releaseActionID), [ ] call EFUNC(common,addActionEventHandler)]; // Add anim changed EH -[_unit, "AnimChanged", FUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; +[_unit, "AnimChanged", LINKFUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; // Prevent UAVs from firing private _UAVCrew = _target call EFUNC(common,getVehicleUAVCrew); if (_UAVCrew isNotEqualTo []) then { { - _target deleteVehicleCrew _x; + [_x, true] call EFUNC(common,disableAiUAV); } forEach _UAVCrew; - _target setVariable [QGVAR(isUAV), true, true]; + _target setVariable [QGVAR(isUAV), _UAVCrew, true]; }; // Check everything -[FUNC(carryObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; - -// Reset current dragging height -GVAR(currentHeightChange) = 0; +[LINKFUNC(carryObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/dragging/functions/fnc_carryObjectPFH.sqf b/addons/dragging/functions/fnc_carryObjectPFH.sqf index e00666bb23..e0a58a26eb 100644 --- a/addons/dragging/functions/fnc_carryObjectPFH.sqf +++ b/addons/dragging/functions/fnc_carryObjectPFH.sqf @@ -35,15 +35,9 @@ if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith { _idPFH call CBA_fnc_removePerFrameHandler; }; -// Drop if the crate is destroyed OR target moved away from carrier (weapon disassembled) OR carrier starts limping -if !(alive _target && {_unit distance _target <= 10} && {_unit getHitPointDamage "HitLegs" < 0.5}) exitWith { - TRACE_2("dead/distance",_unit,_target); - - if ((_unit distance _target > 10) && {(CBA_missionTime - _startTime) < 1}) exitWith { - // attachTo seems to have some kind of network delay and target can return an odd position during the first few frames, - // So wait a full second to exit if out of range (this is critical as we would otherwise detach and set it's pos to weird pos) - TRACE_3("ignoring bad distance at start",_unit distance _target,_startTime,CBA_missionTime); - }; +// Drop if the target is destroyed +if (!alive _target) exitWith { + TRACE_2("dead",_unit,_target); [_unit, _target] call FUNC(dropObject_carry); @@ -53,8 +47,34 @@ if !(alive _target && {_unit distance _target <= 10} && {_unit getHitPointDamage _idPFH call CBA_fnc_removePerFrameHandler; }; -// Drop static if crew is in it (UAV crew deletion may take a few frames) -if (_target isKindOf "StaticWeapon" && {(crew _target) isNotEqualTo []} && {!(_target getVariable [QGVAR(isUAV), false])}) then { +// Drop if the target moved away from carrier (e.g. weapon disassembled) +// attachTo seems to have some kind of network delay and target can return an odd position during the first few frames, +// So wait a full second to exit if out of range (this is critical as we would otherwise detach and set it's pos to weird pos) +if (_unit distance _target > 10 && {(CBA_missionTime - _startTime) >= 1}) exitWith { + TRACE_2("distance",_unit,_target); + + [_unit, _target] call FUNC(dropObject_carry); + + _unit setVariable [QGVAR(hint), nil]; + call EFUNC(interaction,hideMouseHint); + + _idPFH call CBA_fnc_removePerFrameHandler; +}; + +// Drop if the carrier starts limping +if (_unit getHitPointDamage "HitLegs" >= 0.5) exitWith { + TRACE_2("limping",_unit,_target); + + [_unit, _target] call FUNC(dropObject_carry); + + _unit setVariable [QGVAR(hint), nil]; + call EFUNC(interaction,hideMouseHint); + + _idPFH call CBA_fnc_removePerFrameHandler; +}; + +// Drop static if either non-UAV crew or new UAV crew is in it (ignore saved UAV crew) +if (_target isKindOf "StaticWeapon" && {((crew _target) - (_target getVariable [QGVAR(isUAV), []])) isNotEqualTo []}) exitWith { TRACE_2("static weapon crewed",_unit,_target); [_unit, _target] call FUNC(dropObject_carry); @@ -72,13 +92,13 @@ if (_previousHint isEqualType "") exitWith {}; // Mouse hint private _hintLMB = LLSTRING(Drop); -getCursorObjectParams params ["_cursorObject", "", "_distance"]; +private _cursorObject = cursorObject; if ( !isNull _cursorObject && {[_unit, _cursorObject, ["isNotCarrying"]] call EFUNC(common,canInteractWith)} && { if (_target isKindOf "CAManBase") then { - (_distance <= MAX_LOAD_DISTANCE_MAN) && {[_cursorObject, 0, true] call EFUNC(common,nearestVehiclesFreeSeat) isNotEqualTo []} + (_unit distance _cursorObject <= MAX_LOAD_DISTANCE_MAN) && {[_cursorObject, 0, true] call EFUNC(common,nearestVehiclesFreeSeat) isNotEqualTo []} } else { ["ace_cargo"] call EFUNC(common,isModLoaded) && {EGVAR(cargo,enable)} && diff --git a/addons/dragging/functions/fnc_dragObject.sqf b/addons/dragging/functions/fnc_dragObject.sqf index ddad0ad7bb..87272491da 100644 --- a/addons/dragging/functions/fnc_dragObject.sqf +++ b/addons/dragging/functions/fnc_dragObject.sqf @@ -19,6 +19,12 @@ params ["_unit", "_target"]; TRACE_2("params",_unit,_target); +// If in ViV cargo, unload it first +// Warn user if it failed to unload (shouldn't happen) +if (!isNull isVehicleCargo _target && {!(objNull setVehicleCargo _target)}) then { + WARNING_1("ViV Unload Failed %1",_target); +}; + // Get attachTo offset and direction. private _position = _target getVariable [QGVAR(dragPosition), [0, 0, 0]]; private _direction = _target getVariable [QGVAR(dragDirection), 0]; @@ -57,7 +63,7 @@ GVAR(releaseActionID) = [0xF1, [false, false, false], { ["", LLSTRING(Drop)] call EFUNC(interaction,showMouseHint); // Block firing -if !(GVAR(dragAndFire)) then { +if (!GVAR(dragAndFire)) then { _unit setVariable [QGVAR(blockFire), [ _unit, "DefaultAction", {true}, @@ -66,23 +72,21 @@ if !(GVAR(dragAndFire)) then { }; // Add anim changed EH -[_unit, "AnimChanged", FUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; +[_unit, "AnimChanged", LINKFUNC(handleAnimChanged), [_unit]] call CBA_fnc_addBISEventHandler; // Prevent UAVs from firing private _UAVCrew = _target call EFUNC(common,getVehicleUAVCrew); + if (_UAVCrew isNotEqualTo []) then { { - _target deleteVehicleCrew _x; + [_x, true] call EFUNC(common,disableAiUAV); } forEach _UAVCrew; - _target setVariable [QGVAR(isUAV), true, true]; + _target setVariable [QGVAR(isUAV), _UAVCrew, true]; }; // Check everything -[FUNC(dragObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; - -// Reset current dragging height. -GVAR(currentHeightChange) = 0; +[LINKFUNC(dragObjectPFH), 0.5, [_unit, _target, CBA_missionTime]] call CBA_fnc_addPerFrameHandler; // Fixes not being able to move when in combat pace [_unit, "forceWalk", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); diff --git a/addons/dragging/functions/fnc_dragObjectPFH.sqf b/addons/dragging/functions/fnc_dragObjectPFH.sqf index a2895f4216..249f3866bb 100644 --- a/addons/dragging/functions/fnc_dragObjectPFH.sqf +++ b/addons/dragging/functions/fnc_dragObjectPFH.sqf @@ -31,23 +31,28 @@ if !(_unit getVariable [QGVAR(isDragging), false]) exitWith { _idPFH call CBA_fnc_removePerFrameHandler; }; -// Drop if the crate is destroyed OR (target moved away from carrier (weapon disasembled)) -if (!alive _target || {_unit distance _target > 10}) then { - TRACE_2("dead/distance",_unit,_target); - - if ((_unit distance _target > 10) && {(CBA_missionTime - _startTime) < 1}) exitWith { - // attachTo seems to have some kind of network delay and target can return an odd position during the first few frames, - // So wait a full second to exit if out of range (this is critical as we would otherwise detach and set it's pos to weird pos) - TRACE_3("ignoring bad distance at start",_unit distance _target,_startTime,CBA_missionTime); - }; +// Drop if the target is destroyed +if (!alive _target) exitWith { + TRACE_2("dead",_unit,_target); [_unit, _target] call FUNC(dropObject); _idPFH call CBA_fnc_removePerFrameHandler; }; -// Drop static if crew is in it (UAV crew deletion may take a few frames) -if (_target isKindOf "StaticWeapon" && {(crew _target) isNotEqualTo []} && {!(_target getVariable [QGVAR(isUAV), false])}) then { +// Drop if the target moved away from carrier (e.g. weapon disassembled) +// attachTo seems to have some kind of network delay and target can return an odd position during the first few frames, +// So wait a full second to exit if out of range (this is critical as we would otherwise detach and set it's pos to weird pos) +if (_unit distance _target > 10 && {(CBA_missionTime - _startTime) >= 1}) exitWith { + TRACE_2("distance",_unit,_target); + + [_unit, _target] call FUNC(dropObject); + + _idPFH call CBA_fnc_removePerFrameHandler; +}; + +// Drop static if either non-UAV crew or new UAV crew is in it (ignore saved UAV crew) +if (_target isKindOf "StaticWeapon" && {((crew _target) - (_target getVariable [QGVAR(isUAV), []])) isNotEqualTo []}) exitWith { TRACE_2("static weapon crewed",_unit,_target); [_unit, _target] call FUNC(dropObject); diff --git a/addons/dragging/functions/fnc_dropObject.sqf b/addons/dragging/functions/fnc_dropObject.sqf index debe757101..119eaf415a 100644 --- a/addons/dragging/functions/fnc_dropObject.sqf +++ b/addons/dragging/functions/fnc_dropObject.sqf @@ -26,14 +26,14 @@ if (!isNil QGVAR(releaseActionID)) then { }; // Stop blocking -if !(GVAR(dragAndFire)) then { +if (!GVAR(dragAndFire)) then { [_unit, "DefaultAction", _unit getVariable [QGVAR(blockFire), -1]] call EFUNC(common,removeActionEventHandler); }; private _inBuilding = _unit call FUNC(isObjectOnObject); // Play release animation -if !(_unit getVariable ["ACE_isUnconscious", false]) then { +if (_unit call EFUNC(common,isAwake)) then { [_unit, "released"] call EFUNC(common,doGesture); }; @@ -80,14 +80,16 @@ if (_unit getVariable ["ACE_isUnconscious", false]) then { [_unit, "unconscious", 2] call EFUNC(common,doAnimation); }; -// Recreate UAV crew (add a frame delay or this may cause the vehicle to be moved to [0,0,0]) -if (_target getVariable [QGVAR(isUAV), false]) then { - [{ - params ["_target"]; - if (!alive _target) exitWith {}; - TRACE_2("restoring uav crew",_target,getPosASL _target); - createVehicleCrew _target; - }, [_target]] call CBA_fnc_execNextFrame; +// Reenable UAV crew +private _UAVCrew = _target getVariable [QGVAR(isUAV), []]; + +if (_UAVCrew isNotEqualTo []) then { + // Reenable AI + { + [_x, false] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _target setVariable [QGVAR(isUAV), nil, true]; }; // Fixes not being able to move when in combat pace diff --git a/addons/dragging/functions/fnc_dropObject_carry.sqf b/addons/dragging/functions/fnc_dropObject_carry.sqf index 3b8e34f0b1..d244d93a2e 100644 --- a/addons/dragging/functions/fnc_dropObject_carry.sqf +++ b/addons/dragging/functions/fnc_dropObject_carry.sqf @@ -30,12 +30,21 @@ private _inBuilding = _unit call FUNC(isObjectOnObject); [QEGVAR(common,fixCollision), _unit] call CBA_fnc_localEvent; [QEGVAR(common,fixCollision), _target, _target] call CBA_fnc_targetEvent; -// Release object -detach _target; +private _cursorObject = cursorObject; +_tryLoad = _tryLoad && {!isNull _cursorObject} && {[_unit, _cursorObject, ["isNotCarrying"]] call EFUNC(common,canInteractWith)}; +private _loadCargo = false; + +// Don't release object if loading into vehicle (object might be released into vehicle) +if (_tryLoad && {!(_target isKindOf "CAManBase")} && {["ace_cargo"] call EFUNC(common,isModLoaded)} && {[_target, _cursorObject] call EFUNC(cargo,canLoadItemIn)}) then { + _loadCargo = true; +} else { + // Release object + detach _target; +}; // Fix anim when aborting carrying persons if (_target isKindOf "CAManBase" || {animationState _unit in CARRY_ANIMATIONS}) then { - if (vehicle _unit == _unit && {!(_unit getVariable ["ACE_isUnconscious", false])}) then { + if (isNull objectParent _unit && {_unit call EFUNC(common,isAwake)}) then { [_unit, "", 2] call EFUNC(common,doAnimation); }; @@ -50,11 +59,12 @@ if (_target isKindOf "CAManBase" || {animationState _unit in CARRY_ANIMATIONS}) _unit removeWeapon "ACE_FakePrimaryWeapon"; // Reselect weapon and re-enable sprint -private _previousWeaponIndex = _unit getVariable [QGVAR(previousWeapon), -1]; -_unit setVariable [QGVAR(previousWeapon), nil, true]; +private _previousWeaponState = _unit getVariable QGVAR(previousWeapon); -if (_previousWeaponIndex != -1) then { - _unit action ["SwitchWeapon", _unit, _unit, _previousWeaponIndex]; +if (!isNil "_previousWeaponState") then { + _unit selectWeapon _previousWeaponState; + + _unit setVariable [QGVAR(previousWeapon), nil, true]; }; [_unit, "forceWalk", QUOTE(ADDON), false] call EFUNC(common,statusEffect_set); @@ -77,14 +87,16 @@ if !(_target isKindOf "CAManBase") then { [QEGVAR(common,fixFloating), _target, _target] call CBA_fnc_targetEvent; }; -// Recreate UAV crew (add a frame delay or this may cause the vehicle to be moved to [0,0,0]) -if (_target getVariable [QGVAR(isUAV), false]) then { - [{ - params ["_target"]; - if (!alive _target) exitWith {}; - TRACE_2("restoring uav crew",_target,getPosASL _target); - createVehicleCrew _target; - }, [_target]] call CBA_fnc_execNextFrame; +// Reenable UAV crew +private _UAVCrew = _target getVariable [QGVAR(isUAV), []]; + +if (_UAVCrew isNotEqualTo []) then { + // Reenable AI + { + [_x, false] call EFUNC(common,disableAiUAV); + } forEach _UAVCrew; + + _target setVariable [QGVAR(isUAV), nil, true]; }; // Reset mass @@ -97,29 +109,19 @@ if (_mass != 0) then { // Reset temp direction _target setVariable [QGVAR(carryDirection_temp), nil]; -getCursorObjectParams params ["_cursorObject", "", "_distance"]; - -// Try loading into vehicle -if (_tryLoad && {!isNull _cursorObject} && {[_unit, _cursorObject, ["isNotCarrying"]] call EFUNC(common,canInteractWith)}) then { - if (_target isKindOf "CAManBase") then { - if (_distance > MAX_LOAD_DISTANCE_MAN) exitWith {}; - +// (Try) loading into vehicle +if (_loadCargo) then { + [_unit, _target, _cursorObject] call EFUNC(cargo,startLoadIn); +} else { + if (_tryLoad && {_unit distance _cursorObject <= MAX_LOAD_DISTANCE_MAN} && {_target isKindOf "CAManBase"}) then { private _vehicles = [_cursorObject, 0, true] call EFUNC(common,nearestVehiclesFreeSeat); if ([_cursorObject] isEqualTo _vehicles) then { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_unit, _target, _cursorObject] call EFUNC(medical_treatment,loadUnit); } else { [_unit, _target, _cursorObject] call EFUNC(common,loadPerson); }; }; - } else { - if ( - ["ace_cargo"] call EFUNC(common,isModLoaded) && - {EGVAR(cargo,enable)} && - {[_target, _cursorObject] call EFUNC(cargo,canLoadItemIn)} - ) then { - [_unit, _target, _cursorObject] call EFUNC(cargo,startLoadIn); - }; }; }; diff --git a/addons/dragging/functions/fnc_getWeight.sqf b/addons/dragging/functions/fnc_getWeight.sqf index f6b93feca0..f6cb466165 100644 --- a/addons/dragging/functions/fnc_getWeight.sqf +++ b/addons/dragging/functions/fnc_getWeight.sqf @@ -11,7 +11,7 @@ * Weight * * Example: - * [cursorTarget] call ace_dragging_fnc_getWeight + * cursorTarget call ace_dragging_fnc_getWeight * * Public: No */ @@ -23,19 +23,20 @@ if (GVAR(weightCoefficient) == 0) exitWith {0}; private _weight = loadAbs _object; -if !(GVAR(skipContainerWeight)) then { +if (!GVAR(skipContainerWeight)) then { // Add the mass of the object itself // getMass handles PhysX mass, this should be 0 for SupplyX containers and WeaponHolders // Use originalMass in case we're checking weight for a carried object - _weight = _weight + ((_object getVariable [QGVAR(originalMass), getMass _object])); + _weight = _weight + (_object getVariable [QGVAR(originalMass), getMass _object]); }; -// Contents of backpacks get counted twice (https://github.com/acemod/ACE3/pull/8457#issuecomment-1062522447 and https://feedback.bistudio.com/T167469) -// This is a workaround until that is fixed on BI's end -{ - _x params ["", "_container"]; - _weight = _weight - (loadAbs _container); -} forEach (everyContainer _object); +// Fixed in https://feedback.bistudio.com/T167469 on 2.16 profiling branch and for 2.18 stable +if ((productVersion select 3) < 152017) then { + { + _x params ["", "_container"]; + _weight = _weight - (loadAbs _container); + } forEach (everyContainer _object); +}; // Mass in Arma isn't an exact amount but rather a volume/weight value // This attempts to work around that by making it a usable value (sort of) diff --git a/addons/dragging/functions/fnc_handleScrollWheel.sqf b/addons/dragging/functions/fnc_handleScrollWheel.sqf index 8b522e34bc..c7641a8ffa 100644 --- a/addons/dragging/functions/fnc_handleScrollWheel.sqf +++ b/addons/dragging/functions/fnc_handleScrollWheel.sqf @@ -27,7 +27,7 @@ private _carriedItem = _unit getVariable [QGVAR(carriedObject), objNull]; // Disabled for persons if (_carriedItem isKindOf "CAManBase") exitWith {false}; -if !(CBA_events_control) then { +if (!CBA_events_control) then { // Raise/lower // Move carried item 15 cm per scroll interval _scrollAmount = _scrollAmount * 0.15; diff --git a/addons/dragging/functions/fnc_pauseCarry.sqf b/addons/dragging/functions/fnc_pauseCarry.sqf index bfe27420f6..49c91e166f 100644 --- a/addons/dragging/functions/fnc_pauseCarry.sqf +++ b/addons/dragging/functions/fnc_pauseCarry.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: johnb43 - * Removes user input affecting dragging. + * Removes user input affecting carrying. * * Arguments: * 0: Unit diff --git a/addons/dragging/functions/fnc_resumeCarry.sqf b/addons/dragging/functions/fnc_resumeCarry.sqf index 233d60e298..e7cdeb5dc6 100644 --- a/addons/dragging/functions/fnc_resumeCarry.sqf +++ b/addons/dragging/functions/fnc_resumeCarry.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -// If not dragging, don't do anything +// If not carrying, don't do anything if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith {}; // If action is already present, don't add it again diff --git a/addons/dragging/functions/fnc_setCarryable.sqf b/addons/dragging/functions/fnc_setCarryable.sqf index 0348bd0483..60b9854f41 100644 --- a/addons/dragging/functions/fnc_setCarryable.sqf +++ b/addons/dragging/functions/fnc_setCarryable.sqf @@ -54,10 +54,27 @@ GVAR(initializedClasses_carry) = _initializedClasses; [QGVAR(carryingContainerClosed), [_object, _owner], _owner] call CBA_fnc_targetEvent; }, false] call CBA_fnc_addClassEventHandler; -private _icon = [QUOTE(PATHTOF(UI\icons\box_carry.paa)), QUOTE(PATHTOF(UI\icons\person_carry.paa))] select (_object isKindOf "Man"); +private _icon = [QPATHTOF(UI\icons\box_carry.paa), QPATHTOF(UI\icons\person_carry.paa)] select (_object isKindOf "CAManBase"); -private _carryAction = [QGVAR(carry), LLSTRING(Carry), _icon, {[_player, _target] call FUNC(startCarry)}, {[_player, _target] call FUNC(canCarry)}] call EFUNC(interact_menu,createAction); -private _dropAction = [QGVAR(drop_carry), LLSTRING(Drop), "", {[_player, _target] call FUNC(dropObject_carry)}, {[_player, _target] call FUNC(canDrop_carry)}] call EFUNC(interact_menu,createAction); +private _carryAction = [ + QGVAR(carry), + LLSTRING(Carry), + _icon, + { + [_player, _target] call FUNC(startCarry) + }, { + [_player, _target] call FUNC(canCarry) +}] call EFUNC(interact_menu,createAction); + +private _dropAction = [ + QGVAR(drop_carry), + LLSTRING(Drop), + "", + { + [_player, _target] call FUNC(dropObject_carry) + }, { + [_player, _target] call FUNC(canDrop_carry) +}] call EFUNC(interact_menu,createAction); [_type, 0, ["ACE_MainActions"], _carryAction] call EFUNC(interact_menu,addActionToClass); [_type, 0, [], _dropAction] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/dragging/functions/fnc_setDraggable.sqf b/addons/dragging/functions/fnc_setDraggable.sqf index d2adba1a61..e024ec5be2 100644 --- a/addons/dragging/functions/fnc_setDraggable.sqf +++ b/addons/dragging/functions/fnc_setDraggable.sqf @@ -54,11 +54,27 @@ GVAR(initializedClasses) = _initializedClasses; [QGVAR(draggingContainerClosed), [_object, _owner], _owner] call CBA_fnc_targetEvent; }, false] call CBA_fnc_addClassEventHandler; +private _icon = [QPATHTOF(UI\icons\box_drag.paa), QPATHTOF(UI\icons\person_drag.paa)] select (_object isKindOf "CAManBase"); -private _icon = [QUOTE(PATHTOF(UI\icons\box_drag.paa)), QUOTE(PATHTOF(UI\icons\person_drag.paa))] select (_object isKindOf "Man"); +private _dragAction = [ + QGVAR(drag), + LLSTRING(Drag), + _icon, + { + [_player, _target] call FUNC(startDrag) + }, { + [_player, _target] call FUNC(canDrag) +}] call EFUNC(interact_menu,createAction); -private _dragAction = [QGVAR(drag), LLSTRING(Drag), _icon, {[_player, _target] call FUNC(startDrag)}, {[_player, _target] call FUNC(canDrag)}] call EFUNC(interact_menu,createAction); -private _dropAction = [QGVAR(drop), LLSTRING(Drop), "", {[_player, _target] call FUNC(dropObject)}, {[_player, _target] call FUNC(canDrop)}] call EFUNC(interact_menu,createAction); +private _dropAction = [ + QGVAR(drop), + LLSTRING(Drop), + "", + { + [_player, _target] call FUNC(dropObject); + }, { + [_player, _target] call FUNC(canDrop) +}] call EFUNC(interact_menu,createAction); [_type, 0, ["ACE_MainActions"], _dragAction] call EFUNC(interact_menu,addActionToClass); [_type, 0, [], _dropAction] call EFUNC(interact_menu,addActionToClass); diff --git a/addons/dragging/functions/fnc_startCarry.sqf b/addons/dragging/functions/fnc_startCarry.sqf index 040b701f71..3e2cc17efd 100644 --- a/addons/dragging/functions/fnc_startCarry.sqf +++ b/addons/dragging/functions/fnc_startCarry.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Author: commy2, PiZZADOX - * Starts the carrying process. + * Author: johnb43 + * Starts the carrying process safely. * * Arguments: * 0: Unit that should do the carrying @@ -11,82 +11,11 @@ * None * * Example: - * [player, cursorTarget] call ace_dragging_fnc_startCarry; + * [player, cursorTarget] call ace_dragging_fnc_startCarry * * Public: No */ - params ["_unit", "_target"]; -TRACE_2("params",_unit,_target); -// Exempt from weight check if object has override variable set -private _weight = 0; - -if !(_target getVariable [QGVAR(ignoreWeightCarry), false]) then { - _weight = _target call FUNC(getWeight); -}; - -// Exit if object weight is over global var value -if (_weight > GETMVAR(ACE_maxWeightCarry,1E11)) exitWith { - [LLSTRING(UnableToDrag)] call EFUNC(common,displayTextStructured); -}; - -private _timer = CBA_missionTime + 5; - -// Handle objects vs. persons -if (_target isKindOf "CAManBase") then { - private _primaryWeapon = primaryWeapon _unit; - - // Add a primary weapon if the unit has none - if (_primaryWeapon == "") then { - _unit addWeapon "ACE_FakePrimaryWeapon"; - _primaryWeapon = "ACE_FakePrimaryWeapon"; - }; - - // Select primary, otherwise the drag animation actions don't work - _unit selectWeapon _primaryWeapon; - - // Move a bit closer and adjust direction when trying to pick up a person - [QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent; - _target setPosASL (getPosASL _unit vectorAdd (vectorDir _unit)); - - [_unit, "AcinPknlMstpSnonWnonDnon_AcinPercMrunSnonWnonDnon", 2] call EFUNC(common,doAnimation); - [_target, "AinjPfalMstpSnonWrflDnon_carried_Up", 2] call EFUNC(common,doAnimation); - - _timer = CBA_missionTime + 10; -} else { - // Select no weapon and stop sprinting - private _previousWeaponIndex = [_unit] call EFUNC(common,getFiremodeIndex); - _unit setVariable [QGVAR(previousWeapon), _previousWeaponIndex, true]; - - _unit action ["SwitchWeapon", _unit, _unit, 299]; - - [_unit, "AmovPercMstpSnonWnonDnon", 0] call EFUNC(common,doAnimation); - - private _canRun = _weight call FUNC(canRun_carry); - - // Only force walking if we're overweight - [_unit, "forceWalk", QUOTE(ADDON), !_canRun] call EFUNC(common,statusEffect_set); - [_unit, "blockSprint", QUOTE(ADDON), _canRun] call EFUNC(common,statusEffect_set); -}; - -[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); - -// Prevent multiple players from accessing the same object -[_unit, _target, true] call EFUNC(common,claim); - -// Prevents dragging and carrying at the same time -_unit setVariable [QGVAR(isCarrying), true, true]; - -// Required for aborting animation -_unit setVariable [QGVAR(carriedObject), _target, true]; - -[FUNC(startCarryPFH), 0.2, [_unit, _target, _timer]] call CBA_fnc_addPerFrameHandler; - -// Disable collisions by setting the PhysX mass to almost zero -private _mass = getMass _target; - -if (_mass > 1) then { - _target setVariable [QGVAR(originalMass), _mass, true]; - [QEGVAR(common,setMass), [_target, 1e-12]] call CBA_fnc_globalEvent; // Force global sync -}; +// Try to claim the object +[QEGVAR(common,claimSafe), [_unit, _target, true, QGVAR(startCarry)]] call CBA_fnc_serverEvent; diff --git a/addons/dragging/functions/fnc_startCarryLocal.sqf b/addons/dragging/functions/fnc_startCarryLocal.sqf new file mode 100644 index 0000000000..743a56e1f4 --- /dev/null +++ b/addons/dragging/functions/fnc_startCarryLocal.sqf @@ -0,0 +1,96 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, PiZZADOX + * Starts the carrying process. + * + * Arguments: + * 0: Unit that should do the carrying + * 1: Object to carry + * 2: If object was successfully claimed + * + * Return Value: + * None + * + * Example: + * [player, cursorTarget, true] call ace_dragging_fnc_startCarryLocal + * + * Public: No + */ + +params ["_unit", "_target", "_claimed"]; +TRACE_3("params",_unit,_target,_claimed); + +if (!_claimed) exitWith { WARNING_1("already claimed %1",_this) }; + +// Exempt from weight check if object has override variable set +private _weight = 0; + +if !(_target getVariable [QGVAR(ignoreWeightCarry), false]) then { + _weight = _target call FUNC(getWeight); +}; + +// 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); +}; + +private _timer = CBA_missionTime + 5; + +// Handle objects vs. persons +if (_target isKindOf "CAManBase") then { + private _primaryWeapon = primaryWeapon _unit; + + // Add a primary weapon if the unit has none + if (_primaryWeapon == "") then { + _unit addWeapon "ACE_FakePrimaryWeapon"; + _primaryWeapon = "ACE_FakePrimaryWeapon"; + }; + + // Select primary, otherwise the carry animation actions don't work + _unit selectWeapon _primaryWeapon; // This turns off lasers/lights + + // Move a bit closer and adjust direction when trying to pick up a person + [QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent; + _target setPosASL (getPosASL _unit vectorAdd (vectorDir _unit)); + + [_unit, "AcinPknlMstpSnonWnonDnon_AcinPercMrunSnonWnonDnon", 2] call EFUNC(common,doAnimation); + [_target, "AinjPfalMstpSnonWrflDnon_carried_Up", 2] call EFUNC(common,doAnimation); + + _timer = CBA_missionTime + 10; +} else { + // Select no weapon and stop sprinting + if (currentWeapon _unit != "") then { + _unit setVariable [QGVAR(previousWeapon), (weaponState _unit) select [0, 3], true]; + + _unit action ["SwitchWeapon", _unit, _unit, 299]; + }; + + [_unit, "AmovPercMstpSnonWnonDnon", 0] call EFUNC(common,doAnimation); + + private _canRun = _weight call FUNC(canRun_carry); + + // Only force walking if we're overweight + [_unit, "forceWalk", QUOTE(ADDON), !_canRun] call EFUNC(common,statusEffect_set); + [_unit, "blockSprint", QUOTE(ADDON), _canRun] call EFUNC(common,statusEffect_set); +}; + +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + +// Prevents dragging and carrying at the same time +_unit setVariable [QGVAR(isCarrying), true, true]; + +// Required for aborting animation +_unit setVariable [QGVAR(carriedObject), _target, true]; + +[LINKFUNC(startCarryPFH), 0.2, [_unit, _target, _timer]] call CBA_fnc_addPerFrameHandler; + +// Disable collisions by setting the PhysX mass to almost zero +private _mass = getMass _target; + +if (_mass > 1) then { + _target setVariable [QGVAR(originalMass), _mass, true]; + [QEGVAR(common,setMass), [_target, 1e-12]] call CBA_fnc_globalEvent; // Force global sync +}; diff --git a/addons/dragging/functions/fnc_startCarryPFH.sqf b/addons/dragging/functions/fnc_startCarryPFH.sqf index ca34275a2c..f928ef942a 100644 --- a/addons/dragging/functions/fnc_startCarryPFH.sqf +++ b/addons/dragging/functions/fnc_startCarryPFH.sqf @@ -32,9 +32,9 @@ if !(_unit getVariable [QGVAR(isCarrying), false]) exitWith { _idPFH call CBA_fnc_removePerFrameHandler; }; -// Same as dragObjectPFH, checks if object is deleted or dead OR (target moved away from carrier (weapon disasembled)) -if (!alive _target || {_unit distance _target > 10}) then { - TRACE_4("dead/distance",_unit,_target,_timeOut,CBA_missionTime); +// Drop if the target is destroyed, if the target moved away from carrier (e.g. weapon disassembled) or if the carrier starts limping +if !(alive _target && {_unit distance _target <= 10} && {_unit getHitPointDamage "HitLegs" < 0.5}) exitWith { + TRACE_4("dead/distance/limping",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(dropObject_carry); _idPFH call CBA_fnc_removePerFrameHandler; @@ -42,7 +42,7 @@ if (!alive _target || {_unit distance _target > 10}) then { // Handle persons vs. objects if (_target isKindOf "CAManBase") then { - // Drop if in timeout + // Carry person after timeout (animation takes a long time to finish) if (CBA_missionTime > _timeOut) exitWith { TRACE_4("Start carry person",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(carryObject); @@ -50,13 +50,13 @@ if (_target isKindOf "CAManBase") then { _idPFH call CBA_fnc_removePerFrameHandler; }; } else { - // Drop if in timeout + // Timeout: Drop target. CBA_missionTime, because anim length is linked to ingame time if (CBA_missionTime > _timeOut) exitWith { 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_startDrag.sqf b/addons/dragging/functions/fnc_startDrag.sqf index cd298804e6..8dd6db6dee 100644 --- a/addons/dragging/functions/fnc_startDrag.sqf +++ b/addons/dragging/functions/fnc_startDrag.sqf @@ -1,104 +1,21 @@ #include "..\script_component.hpp" /* - * Author: commy2, PiZZADOX, Malbryn - * Starts the dragging process. + * Author: johnb43 + * Starts the dragging process safely. * * Arguments: - * 0: Unit that should do the dragging + * 0: Unit that should do the carrying * 1: Object to drag * * Return Value: * None * * Example: - * [player, cursorTarget] call ace_dragging_fnc_startDrag; + * [player, cursorTarget] call ace_dragging_fnc_startDrag * * Public: No */ - params ["_unit", "_target"]; -TRACE_2("params",_unit,_target); -// Exempt from weight check if object has override variable set -private _weight = 0; - -if !(_target getVariable [QGVAR(ignoreWeightDrag), false]) then { - _weight = _target call FUNC(getWeight); -}; - -// Exit if object weight is over global var value -if (_weight > GETMVAR(ACE_maxWeightDrag,1E11)) exitWith { - [LLSTRING(UnableToDrag)] call EFUNC(common,displayTextStructured); -}; - -private _primaryWeapon = primaryWeapon _unit; - -// Add a primary weapon if the unit has none -if !(GVAR(dragAndFire)) then { - if (_primaryWeapon == "") then { - _unit addWeapon "ACE_FakePrimaryWeapon"; - _primaryWeapon = "ACE_FakePrimaryWeapon"; - }; - - _unit selectWeapon _primaryWeapon; -} else { // Making sure the unit is holding a primary weapon or handgun - private _handgunWeapon = handgunWeapon _unit; - - if !(currentWeapon _unit in [_primaryWeapon, _handgunWeapon]) then { - if (_primaryWeapon != "") then { - // Use primary if possible - _unit selectWeapon _primaryWeapon; - } else { - if (_handgunWeapon != "") then { - // Use pistol if unit has no primary - _unit selectWeapon _handgunWeapon; - } else { - // Add fake weapon if no weapons besides launcher are available - _unit addWeapon "ACE_FakePrimaryWeapon"; - _unit selectWeapon "ACE_FakePrimaryWeapon"; - }; - }; - }; -}; - -// Save the weapon so we can monitor if it changes -_unit setVariable [QGVAR(currentWeapon), currentWeapon _unit]; - -[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); - -// Prevent multiple players from accessing the same object -[_unit, _target, true] call EFUNC(common,claim); - -// Can't play action that depends on weapon if it was added the same frame -if !(_unit call EFUNC(common,isSwimming)) then { - [{ - private _unitWeapon = _this getVariable [QGVAR(currentWeapon), ""]; - - if (_unitWeapon isKindOf ["Pistol", configFile >> "CfgWeapons"]) then { - [_this, "ACE_dragWithPistol"] call EFUNC(common,doGesture); - } else { - [_this, "ACE_dragWithRifle"] call EFUNC(common,doGesture); - }; - }, _unit] call CBA_fnc_execNextFrame; -}; - -// Move a bit closer and adjust direction when trying to pick up a person -if (_target isKindOf "CAManBase") then { - [QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent; - _target setPosASL (getPosASL _unit vectorAdd (vectorDir _unit vectorMultiply 1.5)); - - [_target, "AinjPpneMrunSnonWnonDb_grab", 2] call EFUNC(common,doAnimation); -}; - -// Prevents dragging and carrying at the same time -_unit setVariable [QGVAR(isDragging), true, true]; - -[FUNC(startDragPFH), 0.2, [_unit, _target, CBA_missionTime + 5]] call CBA_fnc_addPerFrameHandler; - -// Disable collisions by setting the physx mass to almost zero -private _mass = getMass _target; - -if (_mass > 1) then { - _target setVariable [QGVAR(originalMass), _mass, true]; - [QEGVAR(common,setMass), [_target, 1e-12]] call CBA_fnc_globalEvent; // Force global sync -}; +// Try to claim the object +[QEGVAR(common,claimSafe), [_unit, _target, true, QGVAR(startDrag)]] call CBA_fnc_serverEvent; diff --git a/addons/dragging/functions/fnc_startDragLocal.sqf b/addons/dragging/functions/fnc_startDragLocal.sqf new file mode 100644 index 0000000000..de41d712a4 --- /dev/null +++ b/addons/dragging/functions/fnc_startDragLocal.sqf @@ -0,0 +1,110 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, PiZZADOX, Malbryn + * Starts the dragging process. + * + * Arguments: + * 0: Unit that should do the dragging + * 1: Object to drag + * 2: If object was successfully claimed + * + * Return Value: + * None + * + * Example: + * [player, cursorTarget, true] call ace_dragging_fnc_startDragLocal + * + * Public: No + */ + +params ["_unit", "_target", "_claimed"]; +TRACE_3("params",_unit,_target,_claimed); + +if (!_claimed) exitWith { WARNING_1("already claimed %1",_this) }; + +// Exempt from weight check if object has override variable set +private _weight = 0; + +if !(_target getVariable [QGVAR(ignoreWeightDrag), false]) then { + _weight = _target call FUNC(getWeight); +}; + +// 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); +}; + +private _primaryWeapon = primaryWeapon _unit; + +// Add a primary weapon if the unit has none +if (!GVAR(dragAndFire)) then { + if (_primaryWeapon == "") then { + _unit addWeapon "ACE_FakePrimaryWeapon"; + _primaryWeapon = "ACE_FakePrimaryWeapon"; + }; + + // Keep the laser/light on if the weapon is already selected + if (currentWeapon _unit != _primaryWeapon) then { + _unit selectWeapon _primaryWeapon; + }; +} else { // Making sure the unit is holding a primary weapon or handgun + private _handgunWeapon = handgunWeapon _unit; + + if !(currentWeapon _unit in [_primaryWeapon, _handgunWeapon]) then { + if (_primaryWeapon != "") then { + // Use primary if possible + _unit selectWeapon _primaryWeapon; + } else { + if (_handgunWeapon != "") then { + // Use pistol if unit has no primary + _unit selectWeapon _handgunWeapon; + } else { + // Add fake weapon if no weapons besides launcher are available + _unit addWeapon "ACE_FakePrimaryWeapon"; + _unit selectWeapon "ACE_FakePrimaryWeapon"; + }; + }; + }; +}; + +// Save the weapon so we can monitor if it changes +_unit setVariable [QGVAR(currentWeapon), currentWeapon _unit]; + +[_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); + +// Can't play action that depends on weapon if it was added the same frame +if !(_unit call EFUNC(common,isSwimming)) then { + [{ + private _unitWeapon = _this getVariable [QGVAR(currentWeapon), ""]; + + if (_unitWeapon isKindOf ["Pistol", configFile >> "CfgWeapons"]) then { + [_this, "ACE_dragWithPistol"] call EFUNC(common,doGesture); + } else { + [_this, "ACE_dragWithRifle"] call EFUNC(common,doGesture); + }; + }, _unit] call CBA_fnc_execNextFrame; +}; + +// Move a bit closer and adjust direction when trying to pick up a person +if (_target isKindOf "CAManBase") then { + [QEGVAR(common,setDir), [_target, getDir _unit + 180], _target] call CBA_fnc_targetEvent; + _target setPosASL (getPosASL _unit vectorAdd (vectorDir _unit vectorMultiply 1.5)); + + [_target, "AinjPpneMrunSnonWnonDb_grab", 2] call EFUNC(common,doAnimation); +}; + +// Prevents dragging and carrying at the same time +_unit setVariable [QGVAR(isDragging), true, true]; + +[LINKFUNC(startDragPFH), 0.2, [_unit, _target, CBA_missionTime + 5]] call CBA_fnc_addPerFrameHandler; + +// Disable collisions by setting the physx mass to almost zero +private _mass = getMass _target; + +if (_mass > 1) then { + _target setVariable [QGVAR(originalMass), _mass, true]; + [QEGVAR(common,setMass), [_target, 1e-12]] call CBA_fnc_globalEvent; // Force global sync +}; diff --git a/addons/dragging/functions/fnc_startDragPFH.sqf b/addons/dragging/functions/fnc_startDragPFH.sqf index 07dfe2064f..daf887c362 100644 --- a/addons/dragging/functions/fnc_startDragPFH.sqf +++ b/addons/dragging/functions/fnc_startDragPFH.sqf @@ -32,15 +32,15 @@ if !(_unit getVariable [QGVAR(isDragging), false]) exitWith { _idPFH call CBA_fnc_removePerFrameHandler; }; -// Same as dragObjectPFH, checks if object is deleted, dead or target moved away from carrier (e.g. weapon disassembled) -if (!alive _target || {_unit distance _target > 10}) then { +// Drop if the target is destroyed or if the target moved away from carrier (e.g. weapon disassembled) +if (!alive _target || {_unit distance _target > 10}) exitWith { TRACE_4("dead/distance",_unit,_target,_timeOut,CBA_missionTime); [_unit, _target] call FUNC(dropObject); _idPFH call CBA_fnc_removePerFrameHandler; }; -// Timeout: Do nothing, quit. CBA_missionTime, because anim length is linked to ingame time +// Timeout: Drop target. CBA_missionTime, because anim length is linked to ingame time if (CBA_missionTime > _timeOut) exitWith { TRACE_4("timeout",_unit,_target,_timeOut,CBA_missionTime); _idPFH call CBA_fnc_removePerFrameHandler; diff --git a/addons/dragging/initKeybinds.sqf b/addons/dragging/initKeybinds.inc.sqf similarity index 93% rename from addons/dragging/initKeybinds.sqf rename to addons/dragging/initKeybinds.inc.sqf index 8ee36d0283..a8792f3576 100644 --- a/addons/dragging/initKeybinds.sqf +++ b/addons/dragging/initKeybinds.inc.sqf @@ -5,7 +5,7 @@ if (!alive _player) exitWith {false}; if !([_player, objNull, ["isNotDragging", "isNotCarrying", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // If we are drag/carrying something right now then just drop it: + // If we are dragging/carrying something right now then just drop it if (_player getVariable [QGVAR(isDragging), false]) exitWith { [_player, _player getVariable [QGVAR(draggedObject), objNull]] call FUNC(dropObject); @@ -34,7 +34,7 @@ if (!alive _player) exitWith {false}; if !([_player, objNull, ["isNotDragging", "isNotCarrying"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // If we are drag/carrying something right now then just drop it: + // If we are dragging/carrying something right now then just drop it if (_player getVariable [QGVAR(isDragging), false]) exitWith { [_player, _player getVariable [QGVAR(draggedObject), objNull]] call FUNC(dropObject); diff --git a/addons/dragging/initSettings.sqf b/addons/dragging/initSettings.inc.sqf similarity index 97% rename from addons/dragging/initSettings.sqf rename to addons/dragging/initSettings.inc.sqf index 039327330d..37feef4cbc 100644 --- a/addons/dragging/initSettings.sqf +++ b/addons/dragging/initSettings.inc.sqf @@ -21,7 +21,7 @@ [LSTRING(allowRunWithLightweight_DisplayName), LSTRING(allowRunWithLightweight_Description)], LLSTRING(SettingsName), true, - true + 1 ] call CBA_fnc_addSetting; [ @@ -30,5 +30,5 @@ [LSTRING(skipContainerWeight_DisplayName), LSTRING(skipContainerWeight_Description)], LLSTRING(SettingsName), false, - true + 1 ] call CBA_fnc_addSetting; diff --git a/addons/dragging/stringtable.xml b/addons/dragging/stringtable.xml index d98cf4c2a1..c2f96ce55a 100644 --- a/addons/dragging/stringtable.xml +++ b/addons/dragging/stringtable.xml @@ -61,8 +61,10 @@ Objeyi Taşı/Bırak Arrastrar/Soltar Objeto Objekt tragen/loslassen + Trasporta/Lascia Oggetto 背负/释放物体 물건 업기/놓기 + Carregar/Soltar Objeto Item too heavy @@ -101,6 +103,7 @@ 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 @@ -110,11 +113,13 @@ Subir/Bajar | (Ctrl + Scroll) Rotar 抬起/放低 |(Ctrl + 鼠标滚轮)旋转 높이기/내리기 | (컨트롤 + 스크롤) 회전 + Subir/Abaixar | (Ctrl + Scroll) Rotacionar ACE Dragging ACE Traînage d'objets et d'unités ACE Ziehen + ACE Trascinamento ACE Húzás ACE Перетаскивание ACE Arrastrar @@ -122,11 +127,13 @@ ACE ドラッグ ACE 拖曳 ACE 끌기 + ACE Arraste Allow firing while dragging Arme utilisable durant le traînage Schießen während des Ziehens erlauben + Permetti di sparare durante il trascinamento Húzás közbeni tüzelés engedélyezése Стрельба во время перетаскивания Permitir disparar mientras se arrastra @@ -134,11 +141,13 @@ 搬送中に射撃許可 允许在拖动时开火 끌기 중 사격 가능하게 하기 + Permitir disparar enquanto arrasta Allow the player to fire their gun while dragging. Cette option permet aux joueurs de faire usage de leur arme pendant qu'ils traînent un objet ou une unité.\nL'arme secondaire est utilisée si le joueur en est équipé. Erlaubt dem Spieler während des Ziehens das Abfeuern der Waffe. + Permette al giocatore di fare fuoco con la propria arma mentre trascina qualcosa o qualcuno. Húzás közben a játékos elsütheti a fegyverét. Позволяет игроку стрелять во время перетаскивания Permite al jugador disparar mientras está arrastrando. @@ -146,50 +155,77 @@ プレイヤーが引きずっている最中でも射撃できるようにします。 允许玩家在拖动时开火。 플레이어가 뭔가를 끌고 있는 동안에 무기를 사용할 수 있게 합니다. + Permite ao jogador disparar sua arma enquanto arrasta. Allow Running with Lightweight Objects 軽量物を持って走れるようにする + Permetti la corsa con oggetti leggeri Zezwól na Bieganie z Lekkimi Obiektami Erlauben das Sprinten mit leichten Gegenständen 가벼운 개체 들고 달리기 허용 Autoriser la course avec des objets légers + Permitir corrida com objetos leves + Позволяет работать с легкими объектами + Permitir correr con objetos ligeros Allow the player to run when carrying lightweight objects. プレイヤーが軽量オブジェクトを持ち運んでいるときに走れるようにする。 + Permetti al giocatore di correre se l'oggetto trasportato è leggero. Zezwalaj graczowi na bieganie podczas przenoszenia lekkich przedmiotów. Erlauben Sie dem Spieler, zu rennen, wenn er leichte Gegenstände trägt. 가벼운 개체를 들고 다닐 때 플레이어가 뛸 수 있도록 허용합니다. Autorise le joueur à courir lorsqu'il porte un objet léger. + Permite ao jogador correr enquanto carrega objetos leves. + Разрешите игроку бегать при переноске легких предметов. + Permite al jugador correr cuando porta objetos ligeros. Skip Object Weight オブジェクトの重量を無視 + Ignora Peso Contenitore Pomiń Wagę Obiektu Objektgewicht überspringen 개체 무게 무시 Ignorer le poids de l'objet + Ignorar Peso do Objeto + Игнорировать вес объекта + Ignora peso del objeto Determines whether object's weight is added onto weight calculations. - 重量計算にオブジェクトの重量を追加するかどうかを決定します。 + 重量計算にオブジェクトの重量を追加するかどうかを定義します。 + Determina se la massa del contenitore è sommata alla massa del contenuto per i calcoli di peso. Określa, czy waga obiektu jest dodawana do obliczeń ciężaru. Legt fest, ob das Gewicht des Objekts zu den Gewichtsberechnungen hinzugefügt wird. 무게 계산에 개체의 무게를 추가할 지 여부를 결정합니다. 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. + Определяет, добавляется ли вес объекта при расчете веса. + Determina si el peso del objeto es añadido en los cálculos de peso. Max Weight Coefficient Coefficient de poids maximal 최대 무게 계수 + Coefficiente di peso massimo + Coeficiente Máximo de Peso Maximaler Gewichtskoeffizient + 最大重量係数 + Максимальный коэффициент веса + Máximo Coeficiente de Peso Modifies weight limit calculations. Set to 0 to ignore. Modifie les calculs de limite de poids. Configurer à 0 pour ignorer. 무게 제한 계산을 수정합니다. 무시하려면 0으로 설정하십시오. + Altera il calcolo di peso massimo trasportabile. Impostalo su 0 per ignorare del tutto il peso. + 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 для игнорирования. + Modifica el límite de peso de los cálculos. Poner a 0 para que lo ignore. diff --git a/addons/dragon/XEH_postInit.sqf b/addons/dragon/XEH_postInit.sqf index 0305fe772a..2360a5bd97 100644 --- a/addons/dragon/XEH_postInit.sqf +++ b/addons/dragon/XEH_postInit.sqf @@ -6,7 +6,7 @@ ["vehicle", { params ["","_vehicle"]; TRACE_2("vehicle change",_vehicle,typeOf _vehicle); - if (!(_vehicle isKindOf QGVAR(staticBase))) exitWith {}; + if !(_vehicle isKindOf QGVAR(staticBase)) exitWith {}; _vehicle animate ["rest_rotate", 0]; @@ -14,7 +14,7 @@ [GVAR(pfID)] call CBA_fnc_removePerFrameHandler; private _lastView = cameraView; - if (!(_lastView in ["INTERNAL", "EXTERNAL"])) then { _lastView == "INTERNAL"; }; + if !(_lastView in ["INTERNAL", "EXTERNAL"]) then { _lastView == "INTERNAL"; }; GVAR(pfID) = [{ params ["_args"]; 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/dragon/functions/fnc_sightAttach.sqf b/addons/dragon/functions/fnc_sightAttach.sqf index 76ad9c3356..de085942b7 100644 --- a/addons/dragon/functions/fnc_sightAttach.sqf +++ b/addons/dragon/functions/fnc_sightAttach.sqf @@ -21,7 +21,7 @@ params ["_target", "_unit", ["_event", false]]; TRACE_3("sightAttach",_target,_unit,_event); if (_event isEqualTo true) then { // this is actually needed as 3rd arg may not be bool - if (!(_target turretLocal [0])) exitWith {}; + if !(_target turretLocal [0]) exitWith {}; _target setVariable [QGVAR(sightAttached), true, true]; _target animate ["optic_hide", 0]; _target addWeapon QGVAR(superStatic); diff --git a/addons/dragon/functions/fnc_sightDetach.sqf b/addons/dragon/functions/fnc_sightDetach.sqf index c9d03e22e6..a5ac159a33 100644 --- a/addons/dragon/functions/fnc_sightDetach.sqf +++ b/addons/dragon/functions/fnc_sightDetach.sqf @@ -23,7 +23,7 @@ params ["_target", "_unit", ["_event", false]]; TRACE_3("sightDetach",_target,_unit,_event); if (_event isEqualTo true) then { // this is actually needed as 3rd arg may not be bool - if (!(_target turretLocal [0])) exitWith {}; + if !(_target turretLocal [0]) exitWith {}; _target setVariable [QGVAR(sightAttached), false, true]; _target animate ["optic_hide", 1]; _target removeWeapon QGVAR(superStatic); diff --git a/addons/dragon/stringtable.xml b/addons/dragon/stringtable.xml index 4170974dc5..d6269eb82b 100644 --- a/addons/dragon/stringtable.xml +++ b/addons/dragon/stringtable.xml @@ -71,7 +71,7 @@ SU-36/P デイサイト SU-36/P 日間瞄具 SU-36/P 常规瞄具 - SU-36/P Daysight + SU-36/P Mirino Diurno SU-36/P denní puškohled SU-36/P Celownik dzienny SU-36/P Daysight @@ -84,10 +84,10 @@ Ein leichte, billige Visierung for Tageseinsätze. Beinhaltet den Zielsuchcomputer für das ganze System. Uma mira leve e comum utilizada para operações de dia. Contêm o computador de orientação para todo o sistema. Un viseur léger et bon marché utilisé pour les opérations de jour.\nContient l'ordinateur de guidage pour tout le système. - 昼間時に使用される軽量で、低価格の照準器です。システム全体の誘導コンピュータを備えています。 + 昼間時に使用される軽量で、低価格の照準器。システム全体の誘導コンピュータを備えている。 一個輕量,便宜適合日間行動使用的廉價瞄具。內含全套制導電腦系統 一种用于日间作战的轻型廉价瞄准具。包含整个系统的制导计算机 - Una luce,un mirino usato per le operazioni diurne.Contiene il computer di guida per l'intero sistema + Un mirino leggero ed economico usato per le operazioni diurne. Contiene il computer di guida per l'intero sistema. Lehký a levný puškohled pro použití za denního světla. Obsahuje navigační počítač pro celý systém. Lekki, tani celownik używany do działania w trakcie dnia. Zawiera komputer naprowadząjący dla całego systemu Лёгкий дешёвый прицел, используемый для дневных операций. Содержит компьютер для всей системы @@ -102,7 +102,7 @@ 特徴的な飛行特性を持つ、ワイヤ誘導の SACLOS ミサイルです。 一個有線制導半自動指令型飛彈並有著獨特的飛航動作 具有独特飞行特性的线导半自动指令型导弹 - Un missile SACLOS filo-guidato con uniche caratterische di volo + Un missile SACLOS filo-guidato con una caratterisca di volo particolare Drátem naváděná SACLOS raketa s unikátními letovými vlastnostmi Naprowadzany przewodowo rakietowy pocisk SACLOS o unikalnej charakterystyce lotu Ракета SACLOS с проводным наведением с уникальной характеристикой полета 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 bee84c5b0f..81ab1b5406 100644 --- a/addons/explosives/XEH_postInit.sqf +++ b/addons/explosives/XEH_postInit.sqf @@ -27,7 +27,7 @@ }; }; }] call CBA_fnc_addEventHandler; -[QGVAR(startDefuse), FUNC(startDefuse)] call CBA_fnc_addEventHandler; +[QGVAR(startDefuse), LINKFUNC(startDefuse)] call CBA_fnc_addEventHandler; //When getting knocked out in medical, trigger deadman explosives: //Event is global, only run on server (ref: ace_medical_fnc_setUnconscious) @@ -50,13 +50,15 @@ if (isServer) then { ["ace_unconscious", { params ["_unit", "_isUnconscious"]; if (!_isUnconscious) exitWith {}; - TRACE_1("Knocked Out, Doing Deadman", _unit); + TRACE_1("Knocked Out, Doing Deadman",_unit); [_unit] call FUNC(onIncapacitated); }] call CBA_fnc_addEventHandler; }; 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 6970d2b7f4..e39270f0bb 100644 --- a/addons/explosives/XEH_preInit.sqf +++ b/addons/explosives/XEH_preInit.sqf @@ -8,7 +8,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" + +GVAR(activeTrigger) = ""; GVAR(detonationHandlers) = []; GVAR(excludedMines) = []; diff --git a/addons/explosives/functions/fnc_addCellphoneIED.sqf b/addons/explosives/functions/fnc_addCellphoneIED.sqf index 2ac69b73ae..d35b303fc1 100644 --- a/addons/explosives/functions/fnc_addCellphoneIED.sqf +++ b/addons/explosives/functions/fnc_addCellphoneIED.sqf @@ -29,10 +29,10 @@ private _hasRequired = true; private _detonators = [_unit] call FUNC(getDetonators); { - if !(_x in _detonators) exitWith{ + if !(_x in _detonators) exitWith { _hasRequired = false; }; -} count _requiredItems; +} forEach _requiredItems; private _code = ""; while {true} do { diff --git a/addons/explosives/functions/fnc_addClacker.sqf b/addons/explosives/functions/fnc_addClacker.sqf index 2292bfcb79..794aec0a10 100644 --- a/addons/explosives/functions/fnc_addClacker.sqf +++ b/addons/explosives/functions/fnc_addClacker.sqf @@ -31,7 +31,7 @@ private _detonators = [_unit] call FUNC(getDetonators); if !(_x in _detonators) exitWith{ _hasRequired = false; }; -} count _requiredItems; +} forEach _requiredItems; if !(_hasRequired) exitWith {}; private _config = ConfigFile >> "CfgMagazines" >> _magazineClass >> "ACE_Triggers" >> configName _config; diff --git a/addons/explosives/functions/fnc_addDetonateActions.sqf b/addons/explosives/functions/fnc_addDetonateActions.sqf index c353f973c3..d950278c35 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,24 +124,27 @@ 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 private _procressedMags = []; { private _mag = _x; - if (!(_mag in _procressedMags)) then { + if !(_mag in _procressedMags) then { _procressedMags pushBack _x; private _magConfig = configFile >> "CfgMagazines" >> _mag; private _supportedTriggers = getArray (_magConfig >> "ACE_Triggers" >> "SupportedTriggers"); diff --git a/addons/explosives/functions/fnc_addTriggerActions.sqf b/addons/explosives/functions/fnc_addTriggerActions.sqf index d3632d5bb7..b6b6e0ce41 100644 --- a/addons/explosives/functions/fnc_addTriggerActions.sqf +++ b/addons/explosives/functions/fnc_addTriggerActions.sqf @@ -31,7 +31,7 @@ private _children = []; if !(_x in _detonators) exitWith { _hasRequiredItems = false; }; - } count _required; + } forEach _required; if (_hasRequiredItems && {(!_isAttached) || {(getNumber (_x >> "isAttachable")) == 1}}) then { _children pushBack [ diff --git a/addons/explosives/functions/fnc_canDefuse.sqf b/addons/explosives/functions/fnc_canDefuse.sqf index 0edb98cff5..54bf8477bc 100644 --- a/addons/explosives/functions/fnc_canDefuse.sqf +++ b/addons/explosives/functions/fnc_canDefuse.sqf @@ -24,7 +24,7 @@ if (isNull _explosive) exitWith { deleteVehicle _target; false }; -if (vehicle _unit != _unit || {(_unit call EFUNC(common,uniqueItems)) findAny GVAR(defusalKits) == -1}) exitWith {false}; +if (!isNull objectParent _unit || {(_unit call EFUNC(common,uniqueItems)) findAny GVAR(defusalKits) == -1}) exitWith {false}; if (GVAR(RequireSpecialist) && {!([_unit] call EFUNC(Common,isEOD))}) exitWith {false}; 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_dialPhone.sqf b/addons/explosives/functions/fnc_dialPhone.sqf index 860f7ddfde..f0609e2b0d 100644 --- a/addons/explosives/functions/fnc_dialPhone.sqf +++ b/addons/explosives/functions/fnc_dialPhone.sqf @@ -30,7 +30,7 @@ for "_i" from 1 to _ran do { }; if (_unit == ace_player) then { ctrlSetText [1400,"Calling"]; - [FUNC(dialingPhone), 0.25, [_unit,4,_arr,_code]] call CALLSTACK(CBA_fnc_addPerFrameHandler); + [LINKFUNC(dialingPhone), 0.25, [_unit,4,_arr,_code]] call CALLSTACK(CBA_fnc_addPerFrameHandler); } else { private _explosive = [_code] call FUNC(getSpeedDialExplosive); if ((count _explosive) > 0) then { diff --git a/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf b/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf index 8490eab452..0f4e5d923f 100644 --- a/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf +++ b/addons/explosives/functions/fnc_getSpeedDialExplosive.sqf @@ -24,7 +24,6 @@ private _explosive = []; if ((_x select 1) == _code) exitWith { _explosive = _x; }; - false -} count GVAR(CellphoneIEDs); +} forEach GVAR(CellphoneIEDs); _explosive diff --git a/addons/explosives/functions/fnc_onIncapacitated.sqf b/addons/explosives/functions/fnc_onIncapacitated.sqf index 09d1d7b21f..5e7b8797e1 100644 --- a/addons/explosives/functions/fnc_onIncapacitated.sqf +++ b/addons/explosives/functions/fnc_onIncapacitated.sqf @@ -37,7 +37,7 @@ TRACE_2("placed",_deadman,_range); //Handle deadman connected to explosive in inventory private _connectedInventoryExplosive = _unit getVariable [QGVAR(deadmanInvExplosive), ""]; if (_connectedInventoryExplosive != "") then { - if (!(_connectedInventoryExplosive in (magazines _unit))) exitWith {}; + if !(_connectedInventoryExplosive in (magazines _unit)) exitWith {}; //Remove mag and reset variable _unit removeMagazine _connectedInventoryExplosive; 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/functions/fnc_setupExplosive.sqf b/addons/explosives/functions/fnc_setupExplosive.sqf index 423e8932c3..918bbb0c33 100644 --- a/addons/explosives/functions/fnc_setupExplosive.sqf +++ b/addons/explosives/functions/fnc_setupExplosive.sqf @@ -161,7 +161,7 @@ GVAR(TweakedAngle) = 0; private _placeAngle = 0; private _expSetupVehicle = _setupObjectClass createVehicle (_virtualPosASL call EFUNC(common,ASLToPosition)); - TRACE_1("Planting Mass", (getMass _expSetupVehicle)); + TRACE_1("Planting Mass",(getMass _expSetupVehicle)); //If the object is too heavy, it can kill a player if it colides if ((getMass _expSetupVehicle) > 5) then {_expSetupVehicle setMass 5;}; 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/initSettings.sqf b/addons/explosives/initSettings.inc.sqf similarity index 100% rename from addons/explosives/initSettings.sqf rename to addons/explosives/initSettings.inc.sqf diff --git a/addons/explosives/stringtable.xml b/addons/explosives/stringtable.xml index 31b0d41eb3..168a830254 100644 --- a/addons/explosives/stringtable.xml +++ b/addons/explosives/stringtable.xml @@ -46,7 +46,7 @@ Robbantás Detonar Подрыв - 点火 + 起爆 폭파 引爆 引爆 @@ -62,12 +62,52 @@ 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 + Подрыв всех на активном детонаторе + 選択した点火装置を全て起爆 + 활성화된 격발기의 모든 것을 폭파 + Détoner tout sur le détonateur actif + Detonar Todos al Activar el detonador + + + Set Active Clacker + Als Standardzünder wählen + Imposta Detonatore Attivo + Установить активный детонатор + この点火装置を選択 + 격발기 활성 설정 + Définir le détonateur actif + Establecer el Detonador Activo + + + Cycle Active Clacker + Standardzünder wechseln + Cambia Detonatore Attivo + Цикл активного детонатора + 点火装置を切り替え + 격발기 활성 전환 + Modifier le détonateur actif + Ciclar el Detonador Activo + + + Active Clacker + Standardzünder + Detonatore Attivo + Активный детонатор + 選択中の点火装置 + 격발기 활성 + Détonateur actif + Activar Detonador + Explosive code: %1 Sprengstoffcode: %1 @@ -227,7 +267,7 @@ Używany do zdalnego detonowania ładunków wybuchowych Utilisé pour déclencher des explosifs à distance. Používaný ke vzdálenému odpalování výbušnin - Usato per l'attivazione a distanza degli esplosivi + Usato per l'innesco a distanza degli esplosivi Robbanóanyagok távoli robbantásához való Usado para acionar explosivos remotamente Используется для удаленной детонации СВУ @@ -248,7 +288,7 @@ M57 Gyújtóeszköz M57 Dispositivo de Detonação Взрыватель M57 - M57 起爆装置 + M57 点火装置 격발기 (M57) M57 引爆装置 M57 引爆裝置 @@ -261,7 +301,7 @@ Używany do zdalnego detonowania ładunków wybuchowych Utilisé pour déclencher des explosifs à distance. Používané ke vzdálenému odpalování výbušnin - Usato per l'attivazione a distanza degli esplosivi + Usato per l'innesco a distanza degli esplosivi Robbanóanyagok távoli robbantásához Usado para acionar explosivos remotamente Используется для удаленной детонации зарядов @@ -282,7 +322,7 @@ M152 Gyújtóeszköz M152 Dispositivo de Detonação Взрыватель M152 - M152 起爆装置 + M152 点火装置 격발기 (M152) M152 引爆装置 M152 引爆裝置 @@ -329,7 +369,7 @@ Umożliwia rozbrajanie ładunków wybuchowych Outils nécessaires au désamorçage des explosifs. Dovoluje zneškodňování výbušnin - Consente la disattivazione degli ordigni esplosivi + Consente il disinnesco degli ordigni esplosivi Robbanóanyagok hatástalanítását teszi lehetővé Permite o desarme de explosivos Позволяет обезвреживать взрывчатку @@ -346,7 +386,7 @@ Dodaj do szybkiego wybierania Ajouter à la numérotation rapide Přidat jako rychlou volbu - Aggiungi alla selezione rapida + Aggiungi alle chiamate rapide Hozzáadás a gyorstárcsázóhoz Adicionar à ligação rápida Добавить в быстрый вызов @@ -380,7 +420,7 @@ Wybierz numer Composer Vytočit - Composizione numero + Componi numero Tárcsázás Discar Hабрать @@ -397,7 +437,7 @@ W górę Haut Nahoru - Sopra + Su Fel Cima Вызов @@ -414,7 +454,7 @@ W dół Bas Dolu - Sotto + Giù Le Baixo Сброс @@ -465,7 +505,7 @@ Menu umieszczania Menu de placement Menu umístění - Menù di collocamento + Menù di piazzamento Elhelyezési menü Menu de posicionamento Меню установки @@ -499,7 +539,7 @@ Rozbrajanie ładunku... Désamorçage de l'explosif... Zneškodňuji Výbušninu... - Esposivo in fase di disattivazione... + Disinnescando l'Esplosivo... Robbanóanyag hatástalanítása... Desarmando Explosivo... Обезвреживание... @@ -516,7 +556,7 @@ Czasomierz Minuteur Časovač - Cronometro + Spoletta a tempo Időzítő Timer Таймер @@ -537,7 +577,7 @@ Idő: %1m %2s Tempo: %1m %2s Время: %1m %2c - 設定時間: %1分 %2秒 + タイマー: %1分 %2秒 시간: %1분 %2초 时间:%1分%2秒 時間: %1分%2秒 @@ -550,11 +590,11 @@ Ustaw czas Valider la durée Nastavit čas - Modifica il conto alla rovescia + Imposta tempo della spoletta Idő beállítása Configurar Tempo Установить время - 時間を設定 + タイマーを設定 시간 설정 设定时间 設定時間 @@ -567,7 +607,7 @@ Wybierz zapalnik Sélectionner un déclencheur Zvolit detonátor - Seleziona un attivatore + Seleziona la spoletta Gyújtóeszköz kiválasztása Selecionar um Gatilho Выберите детонатор @@ -652,7 +692,7 @@ Keine Auslöser für %1 vorhanden Pas de déclencheur disponible pour %1. Žádný detonátor k dispozici pro %1 - Nessun attivatore disponibile per %1 + Nessuna spoletta disponibile per %1 Nincs elérhető gyújtóeszköz ide: %1 Nenhum gatilho disponível para %1 Нет доступных взрывателей для %1 @@ -685,7 +725,7 @@ Magnetfeldsensor (Bodenangriff) Capteur magnétique (par le bas) Magnetický Senzor (Výbuch ze spoda) - Sensore Magnetico di Prossimità (attacco inferiore) + Sensore Magnetico di Prossimità (attacco dal basso) Mágneses mező érzékelő (Bottom Attack) Influência magnética (ataque inferior) Магнитный сенсор (детонация вверх) @@ -738,7 +778,7 @@ Usado para detonar remotamente o explosivo quando solto. Используется для дистанционного подрыва, после смерти оператора. Usato per attivare a distanza esplosivi al momento del rilascio - 点火装置から遠隔から起爆したい時に使います。 + 放した時に爆発物を遠隔で起爆させるためのデッドマンスイッチ。 압력이 해제될때 원격으로 폭발시킵니다. 当放开按钮时,将会引爆炸弹。 當放開按鈕時, 將會引爆炸彈. @@ -789,7 +829,7 @@ Specialisták igénylése? Требуется специалист? Richiedi specialisti? - 特技兵を必須 + 専門兵特性を必須にするか? 전문가가 필요합니까? 需要专家? 需要專家? @@ -805,8 +845,8 @@ Seul un spécialiste peut désamorcer des explosifs. Szükséges-e egy specialista a robbanóanyagok hatástalanításához? Alapértelmezett: Nem Требуется ли специалист по минному делу для обезвреживания взрывчатки? По умолчанию: Нет - Richiedi specialisti esplosivi per disabilitare esplosivi? Default: No - 爆発物を無効化するには特技兵である必要かどうかを設定できます。標準: 無効化 + Richiedi specialisti esplosivi per disabilitare esplosivi? Predefinito: No + 爆発物を無効にするために爆発物専門兵の特性を必要としますか? デフォルト: 不要 폭발물을 해제하기 위해서는 전문가가 필요합니까? 기본설정: 아니요 需要爆破专业兵才能拆除爆炸物? 预设:否 需要炸彈專家才能拆除炸彈? 預設: 否 @@ -823,7 +863,7 @@ Nem-specialisták büntetése? Штраф не-специалистам? Punisci non-specialisti? - 非特技兵へ足かせ + 非専門兵にペナルティを与える? 비전문가에게 불이익을 줍니까? 惩罚非专业人士? 折磨非專業人員? @@ -838,8 +878,8 @@ Augmente le temps nécessaire au désamorçage pour les unités non spécialisées. Nem-specialisták esetén több ideig tartson a cselekvés befejezése? Alapértelmezett: Igen Увеличивать время завершения действий для не-специалистов? По умолчанию: Нет - Aumenta il tempo richiesto per completare azioni per non-specialisti? Default: Si - 非特技兵は動作完了までの時間を増加させますか? 標準: 有効化 + Aumenta il tempo richiesto per completare azioni per non-specialisti? Predefinito: Si + 専門兵以外がアクション完了するのに必要な時間を増加しますか? デフォルト: 有効 비전문가가 폭발물을 해제 시 더욱 많은 시간을 소요합니까? 기본설정: 예 增加非专业人员相关操作的时间? 预设:是 增加非專業人員相關操作的時間? 預設: 是 @@ -854,8 +894,8 @@ Explosion au désamorçage Robbanás hatástalanításkor? Взрыв при разминировании? - Fai esplodere quando disarmato? - 解除中に爆発 + Detona se disarmati? + 解除中に爆発するか? 해제 시 폭발합니까? 拆除时引爆? 拆除時引爆? @@ -870,8 +910,8 @@ Certains explosifs exploseront durant le désamorçage. Valeur par défaut : activé. Meghatározott robbanóanyagok felrobbanjanak-e hatástalanításkor? Alapértelmezett: Igen Разрешить определенным взрывным устройствам взрываться при разминировании? По умолчанию: Да - Abilita alcuni esplosivi per esplosione al disarmo? Default: Si - 特定の爆発物を解除中に爆発させるかどうかを設定できます。? 標準: 有効化 + Permettere ad alcuni esplosivi di esplodere quando si tenta il disinnesco? Predefinito: Si + 特定の爆発物を解除中に爆発可能にしますか? デフォルト: 有効 특정 폭발물이 해제 시 폭발하게 합니까? 기본설정: 예 启用后,某些爆炸物会在拆除时引爆? 预设:是 啟用後, 某些炸彈會在拆除時引爆? 預設: 是 @@ -887,7 +927,7 @@ Этот модуль управляет настройками, связанными со взрывными устройствами Este módulo ajusta las configuraciones relacionadas con explosivos. Questo modulo cambia le impostazioni relative agli esplosivi - モジュールを調節し爆発物に設定を反映させます。 + このモジュールは爆発物に関する設定を調整します。 이 모듈은 폭발물에 관한 설정을 수정할 수 있게합니다. 此模块用来调整炸药的相关设定 此模塊用來調整炸藥的相關設定 @@ -898,7 +938,7 @@ M6-SLAM-Mine (Bodenangriff) Mina M6 SLAM (atak od dołu) Mina M6 SLAM (Ataque Inferior) - Mina M6 SLAM (base) + Mina M6 SLAM (Da Sotto) M6 SLAM (Útok zespoda) Mina M6 SLAM (Ataque Inferior) Мина M6 SLAM (направлена вверх) @@ -913,7 +953,7 @@ M6-SLAM-Mine (Seitenangriff) Mina M6 SLAM (atak od boku) Mina M6 SLAM (Ataque Lateral) - Mina M6 SLAM (Laterale) + Mina M6 SLAM (Dal Lato) M6 SLAM (Útok do strany) Mina M6 SLAM (Ataque Lateral) Мина M6 SLAM (направлена вбок) @@ -928,7 +968,7 @@ Große USBV (Stadt, Druckplatte) Duży IED (miejski, płyta naciskowa) IED Grande (Urbano, Placa de presión) - IED grande (urbano, a pressione) + IED grande (Urbano, a pressione) IED, Velké (Městské, Nášlapné) IED Grande (Urbano, Placa de pressão) Большое СВУ (городское, нажимного действия) @@ -943,7 +983,7 @@ Große USBV (Eingegraben, Druckplatte) Duży IED (zakopany, płyta naciskowa) IED Grande (Enterrado, Placa de presión) - IED grande (interrato, a pressione) + IED grande (Interrato, a pressione) IED, Velké (Zakopané, Nášlapné) IED Grande (Enterrado, Placa de pressão) Большое СВУ (закопанное, нажимного действия) @@ -958,7 +998,7 @@ Kleine USBV (Stadt, Druckplatte) Mały IED (miejski, płyta naciskowa) IED Pequeño (Urbano, Placa de presión) - IED piccolo (urbano, a pressione) + IED piccolo (Urbano, a pressione) IED, Malé (Městské, Nášlapné) IED Pequeno(Urbano, Placa de pressão) Малое СВУ (городское, нажимного действия) @@ -973,7 +1013,7 @@ Kleine USBV (Eingegraben, Druckplatte) Mały IED (zakopany, płyta naciskowa) IED Pequeño (Enterrado, Placa de presión) - IED piccolo (interrato, a pressione) + IED piccolo (Interrato, a pressione) IED, Malé (Zakopané, Nášlapné) IED Pequeno (Enterrado, Placa de pressão) Малое СВУ (закопанное, нажимного действия) @@ -991,7 +1031,7 @@ Podłącz do %1 Connecter %1 Csatlakozás %1 - Collega a %1 + Collega a %1 Conectar à %1 %1 へ接続 %1에 연결 중 @@ -1002,12 +1042,12 @@ Tripwire Flare Сигнальная растяжка - 仕掛け型照明地雷 + 仕掛け線照明地雷 Flara na linkę Stolperdraht-Leuchtrakete 조명지뢰 Fusée éclairante avec fil piège - Cavo d'innesco + Bengala a filo d'inciampo 绊线信号弹 絆線閃光地雷 Tripwire (Sinalizador) @@ -1017,12 +1057,12 @@ Type: Tripwire flare - Ignites a non-lethal flare when triggered.<br />Rounds: 1<br />Used on: Ground Тип: Сигнальная растяжка - При срабатывании выпускает несмертельную сигнальную вспышку.<br />Зарядов: 1<br />Используется на: Земле - 種類: 仕掛け型照明地雷 - 発動したとき、非致死性の照明を発炎します。<br />装填数: 1<br />次で使用: 地表 + 種類: 仕掛け線照明地雷 - 発動したとき、非致死性の照明を発炎します。<br />装填数: 1<br />次で使用: 地表 Typ: Flara na linkę - Wystrzeliwuje nieszkodliwą flarę przy nadepnięciu linki.<br/>Pociski: 1<br/>Używane na: ziemia Typ: Stolperdraht-Leuchtrakete - Schießt bei Auslösung eine nicht-tödliche Leuchtrakete ab.<br />Ladungen: 1<br />Benutzt auf: Boden 종류: 조명지뢰 - 작동시 무해한 조명을 사출합니다.<br />장탄수: 1<br />사용처: 지면 Type : Fusée éclairante avec fil piège - Allume une fusée éclairante lorsque déclenchée.<br />Coups : 1<br />Utilisé sur : le sol - Tipo: Cavo d'innesco - Sfocio un abbaglio non letale quanto attivato. <br />Rimanenti: 1<br />Usato: A terra + Tipo: Bengala a cavo d'innesco - Accende un bengala abbagliante non letale quando innescato. <br />Rimanenti: 1<br />Usato: A terra 类型:绊线信号弹—触发后产生非致命性的强光。<br />发数:1<br />使用于:地面 類型: 絆線閃光地雷 - 觸發後產生非致命性的強光.<br />發數: 1<br />使用於: 地面 Tipo: Flare de Tripwire - Acende um sinalizador não letal quando acionado.<br/>Usos: 1<br/>Usado em: Chão @@ -1064,7 +1104,7 @@ Is EOD Kampfmittelbeseitigung - EOD に + EODにする Spécialiste en explosifs 是EOD 爆破专家 @@ -1074,11 +1114,12 @@ Сапёр ¿Es EOD? 폭발물 처리반 + É EOD Controls whether the unit is an explosive specialist. Steuert, ob die Einheit ein Sprengstoffspezialist ist. - ユニットが何であれ爆発物専門家にします。 + ユニットが爆発物専門兵であるかどうかを定義します。 Définit si l'unité est un spécialiste en explosifs. 控制該單位是否是爆裂物處置專家 控制该单位是否是爆破专家 @@ -1088,72 +1129,85 @@ Определяет, является ли юнит сапёром. Controla si la unidad es un especialista en explosivos 유닛이 폭발물 처리반인지 결정합니다 + Controla se a unidade é um especialista em explosivos. Minimum Time Мин. время Durée minimale - 最短時間 + タイマーの最短時間 Tiempo mínimo Minimalny czas Minimale Zeit + Tempo Minimo 最短时间 최소 시간 + Tempo Mínimo Maximum Time Макс. время Durée maximale - 最長時間 + タイマーの最長時間 Tiempo máximo Maksymalny czas Maximale Zeit + Tempo Massimo 最长时间 최대 시간 + Tempo Máximo Default Time Стандартное время Durée par défaut - 標準時間 + タイマーの標準時間 Tiempo por defecto Domyślny czas Standardmäßige Zeit + Tempo Predefinito 默认时间 기본 시간 + Tempo Padrão Minimum time value (in seconds) for the explosive timer. Минимальное время до взрыва в секундах Définit la durée minimale paramétrable sur le minuteur. - 起爆タイマーの最低時間 (秒) を設定します。 + 起爆タイマーの最短時間 (秒単位) を設定します。 Tiempo mínimo (en segundos) para el temporizador del explosivo. Minimalna wartość czasomierza dla ładunku (w sekundach). Minimale Zeit (in Sekunden) für den Zeitzünder. + Tempo minimo (in secondi) per le spolette a tempo. 定时爆炸的最短时间(单位:秒) 초 단위로, 폭발 타이머의 최소 시간을 정합니다 + Tempo mínimo (em segundos) para o temporizador do explosivo. Maximum time value (in seconds) for the explosive timer. Макисмальное время до взрыва в секундах Définit la durée maximale paramétrable sur le minuteur. - 起爆タイマーの最長時間 (秒) を設定します。 + 起爆タイマーの最長時間 (秒単位) を設定します。 Tiempo máximo (en segundos) para el temporizador del explosivo. Maksymalna wartość czasomierza dla ładunku (w sekundach). Maximale Zeit (in Sekunden) für den Zeitzünder. + Tempo massimo (in secondi) per le spolette a tempo. 定时爆炸的最长时间(单位:秒) 초 단위로, 폭발 타이머의 최대 시간을 정합니다 + Tempo máximo (em segundos) para o temporizador do explosivo. Default time value (in seconds) for the explosive timer. Стандартное время до взрыва в секундах Définit la durée paramétrée par défaut sur le minuteur. - 起爆タイマーの標準時間 (秒) を設定します。 + 起爆タイマーの標準時間 (秒単位) を設定します。 Tiempo por defecto (en segundos) para el temporizador del explosivo. Domyślna wartość czasomierza dla ładunku (w sekundach). Standardmäßige Zeit (in Sekunden) für den Zeitzünder. + Tempo predefinito (in secondi) per le spolette a tempo. 定时爆炸的默认时间(单位:秒) 초 단위로, 기본 폭발 타이머 시간을 정합니다 + Tempo padrão (em segundos) para o temporizador do explosivo. diff --git a/addons/fastroping/XEH_postInit.sqf b/addons/fastroping/XEH_postInit.sqf index 27d3ca4008..0ba9231215 100644 --- a/addons/fastroping/XEH_postInit.sqf +++ b/addons/fastroping/XEH_postInit.sqf @@ -1,17 +1,15 @@ #include "script_component.hpp" -[QGVAR(deployRopes), { - _this call FUNC(deployRopes); -}] call CBA_fnc_addEventHandler; +[QGVAR(deployRopes), LINKFUNC(deployRopes)] call CBA_fnc_addEventHandler; [QGVAR(startFastRope), { - [FUNC(fastRopeServerPFH), 0, _this] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(fastRopeServerPFH), 0, _this] call CBA_fnc_addPerFrameHandler; }] call CBA_fnc_addEventHandler; // Keybinds ["ACE3 Vehicles", QGVAR(fastRope), localize LSTRING(Interaction_fastRope), { if ((vehicle ACE_player) == ACE_player) exitWith {false}; - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; if ([ACE_player, vehicle ACE_player] call FUNC(canFastRope)) then { [ACE_player, vehicle ACE_player] call FUNC(fastRope); true @@ -22,7 +20,7 @@ ["ACE3 Vehicles", QGVAR(cutRopes), localize LSTRING(Interaction_cutRopes), { if ((vehicle ACE_player) == ACE_player) exitWith {false}; - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; if ([vehicle ACE_player] call FUNC(canCutRopes)) then { [vehicle ACE_player] call FUNC(cutRopes); true @@ -45,7 +43,7 @@ if (isServer) then { #ifdef DRAW_FASTROPE_INFO addMissionEventHandler ["Draw3D", { - if (!(cursorObject isKindOf "Helicopter")) exitWith {}; + if !(cursorObject isKindOf "Helicopter") exitWith {}; private _config = configOf cursorObject; private _enabled = getNumber (_config >> QGVAR(enabled)); drawIcon3D ["", [.5,.5,1,1], (ASLtoAGL getPosASL cursorObject), 0.5, 0.5, 0, format ["%1 = %2", typeOf cursorObject, _enabled], 0.5, 0.025, "TahomaB"]; diff --git a/addons/fastroping/XEH_preInit.sqf b/addons/fastroping/XEH_preInit.sqf index 6d6065b323..b750275167 100644 --- a/addons/fastroping/XEH_preInit.sqf +++ b/addons/fastroping/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" if (isServer) then { ["Helicopter", "Deleted", LINKFUNC(unequipFRIES)] call CBA_fnc_addClassEventHandler; diff --git a/addons/fastroping/functions/fnc_cutRopes.sqf b/addons/fastroping/functions/fnc_cutRopes.sqf index cbd01b5661..40d2416049 100644 --- a/addons/fastroping/functions/fnc_cutRopes.sqf +++ b/addons/fastroping/functions/fnc_cutRopes.sqf @@ -34,8 +34,8 @@ private _deployedRopes = _vehicle getVariable [QGVAR(deployedRopes), []]; //Only delete the hook first so the rope falls down. //Note: ropeDetach was used here before, but the command seems a bit broken. deleteVehicle _hook; - [{{deleteVehicle _x} count _this}, [_ropeTop, _ropeBottom, _dummy], 60] call CBA_fnc_waitAndExecute; -} count _deployedRopes; + [{{deleteVehicle _x} forEach _this}, [_ropeTop, _ropeBottom, _dummy], 60] call CBA_fnc_waitAndExecute; +} forEach _deployedRopes; _vehicle setVariable [QGVAR(deployedRopes), [], true]; diff --git a/addons/fastroping/functions/fnc_deployRopes.sqf b/addons/fastroping/functions/fnc_deployRopes.sqf index 71cfbbbc21..eea81a7746 100644 --- a/addons/fastroping/functions/fnc_deployRopes.sqf +++ b/addons/fastroping/functions/fnc_deployRopes.sqf @@ -67,9 +67,7 @@ if (GVAR(requireRopeItems) && {_ropeClass != ""}) then { //deployedRopes format: attachment point, top part of the rope, bottom part of the rope, attachTo helper object, occupied, broken _deployedRopes pushBack [_ropeOrigin, _ropeTop, _ropeBottom, _dummy, _hook, false, false]; - - false -} count _ropeOrigins; +} forEach _ropeOrigins; _vehicle setVariable [QGVAR(deployedRopes), _deployedRopes, true]; _vehicle setVariable [QGVAR(deploymentStage), 3, true]; diff --git a/addons/fastroping/functions/fnc_fastRope.sqf b/addons/fastroping/functions/fnc_fastRope.sqf index 80be870553..430c8d86ca 100644 --- a/addons/fastroping/functions/fnc_fastRope.sqf +++ b/addons/fastroping/functions/fnc_fastRope.sqf @@ -36,4 +36,4 @@ _vehicle setVariable [QGVAR(deployedRopes), _deployedRopes, true]; //Start server PFH asap [QGVAR(startFastRope), [_unit, _vehicle, _usableRope, _usableRopeIndex, false]] call CBA_fnc_serverEvent; moveOut _unit; -[FUNC(fastRopeLocalPFH), 0, [_unit, _vehicle, _usableRope, _usableRopeIndex, diag_tickTime]] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(fastRopeLocalPFH), 0, [_unit, _vehicle, _usableRope, _usableRopeIndex, diag_tickTime]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf b/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf index 92d23715b0..b1fec908a5 100644 --- a/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf +++ b/addons/fastroping/functions/fnc_fastRopeLocalPFH.sqf @@ -20,7 +20,7 @@ _arguments params ["_unit", "", "_rope", "", "_timeToPlayRopeSound"]; _rope params ["", "", "", "_dummy", "_hook"]; //Wait until the unit is actually outside of the helicopter -if (vehicle _unit != _unit) exitWith {}; +if (!isNull objectParent _unit) exitWith {}; // dummy lost hook if (isNull _hook) exitWith { diff --git a/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf b/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf index c3b7fe1ea4..716c0ab43e 100644 --- a/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf +++ b/addons/fastroping/functions/fnc_fastRopeServerPFH.sqf @@ -20,7 +20,7 @@ _arguments params ["_unit", "_vehicle", "_rope", "_ropeIndex", "_hasBeenAttached _rope params ["_attachmentPoint", "_ropeTop", "_ropeBottom", "_dummy", "_hook"]; //Wait until the unit is actually outside of the helicopter -if (vehicle _unit != _unit) exitWith {}; +if (!isNull objectParent _unit) exitWith {}; //Prevent teleport if hook has been deleted due to rope cut if (isNull _hook) exitWith { diff --git a/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf b/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf index 970194ab63..892997bf80 100644 --- a/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf +++ b/addons/fastroping/functions/fnc_moduleEquipFRIES.sqf @@ -22,5 +22,4 @@ private _synchedUnits = synchronizedObjects _module; _x = vehicle _x; }; [_x] call FUNC(equipFRIES); - false -} count _synchedUnits; +} forEach _synchedUnits; diff --git a/addons/fastroping/initSettings.sqf b/addons/fastroping/initSettings.inc.sqf similarity index 78% rename from addons/fastroping/initSettings.sqf rename to addons/fastroping/initSettings.inc.sqf index 844de927a2..cde4a32b47 100644 --- a/addons/fastroping/initSettings.sqf +++ b/addons/fastroping/initSettings.inc.sqf @@ -5,9 +5,7 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(setting_c [LSTRING(setting_requireRopeItems_displayName)], _category, false, // default value - true, // isGlobal - {[QGVAR(requireRopeItems), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // needRestart + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/fastroping/stringtable.xml b/addons/fastroping/stringtable.xml index bc12c23296..10ea50a7c5 100644 --- a/addons/fastroping/stringtable.xml +++ b/addons/fastroping/stringtable.xml @@ -22,7 +22,7 @@ Wyposaża kompatybilne helikoptery w zestaw Fast Rope Insertion Extraction System. Équipe les hélicoptères compatibles avec un FRIES (Fast Rope Insertion Extraction System). Equipar helicoptero compatible con un Sistema de Inserción/Extracción Rápida por Cuerda. - Equipagga l'elicottero compatibile con il Fast Rope Insertion Extraction System + Equipagga elicotteri compatibili con il Fast Rope Insertion Extraction System Vybavit kompatibilní vrtulníky systémem Fast Rope Insertion Extraction (FRIES). Equipa um helicóptero compatível com o Fast Rope Insertion Exctraction System. Снаряжает совместимые вертолеты оборудованием для спуска десанта по канатам. @@ -41,7 +41,7 @@ Připravit systém slaňování Prepara sistema de descida rápida Подготовить канаты - ファスト ロープのシステムを準備 + ファストロープ システムを準備 패스트로프 준비 准备快速绳降系统 準備快速繩降系統 @@ -51,7 +51,7 @@ Stow fast roping system Verstaue "Fast Roping"-System Arrotola le corde - ファスト ロープのシステムを収容 + ファストロープ システムを収容 收起快速繩降系統 收起快速绳降系统 패스트로프 시스템 보관 @@ -89,7 +89,7 @@ SLANIT Descida rápida Спуститься по канату - ファスト ロープをする + ファストロープする 패스트로프 快速绳降 快速繩降 @@ -144,11 +144,11 @@ LET UNITS FAST ROPE EINHEITEN ABSEILEN LASSEN - SCENDI DALLE CORDE + FAI SCENDERE CON FASTROPE Equipa o helicóptero selecionado com o Fast Rope Insertion Extraction System LAISSER LES UNITÉS UTILISER LA CORDE ДЕСАНТИРОВАНИЕ ПО КАНАТУ - ユニットへファスト ロープをさせる + ユニットへファストロープをさせる ZJAZD NA LINACH 让单位快速绳降 讓單位快速繩降 @@ -163,7 +163,7 @@ Wysuń linę o długości 3 m. Выпустить 3 м канат Jogar cordas (3m) - Dispiegamento corde 3m + Dispiega corde da 3m Připravit 3m lana 3m halat sal Desplegar cuerdas de 3m @@ -179,7 +179,7 @@ Wysuń linę o długości 6 m. Выпустить 6 м канат Jogar cordas (6m) - Dispiegamento corde 6m + Dispiega corde da 6m Připravit 6m lana 6m halat sal Desplegar cuerdas de 6m @@ -198,7 +198,7 @@ Jogar cordas (12m) 部屬12公尺長之繩索 部署12米长的绳索 - Dispiegamento corde 12m + Dispiega corde da 12m Připravit 12m lana 12m halat sal Desplegar cuerdas de 12m @@ -214,7 +214,7 @@ Jogar cordas (15m) 部屬15公尺長之繩索 部署15米长的绳索 - Dispiegamento corde 15m + Dispiega corde da 15m Připravit 15m lana 15m halat sal Desplegar cuerdas de 15m @@ -230,7 +230,7 @@ Jogar cordas (18m) 部屬18公尺長之繩索 部署18米长的绳索 - Dispiegamento corde 18m + Dispiega corde da 18m Připravit 18m lana 18m halat sal Desplegar cuerdas de 18m @@ -246,7 +246,7 @@ Jogar cordas (27m) 部屬27公尺長之繩索 部署27米长的绳索 - Dispiegamento corde 27m + Dispiega corde da 27m Připravit 27m lana 27m halat sal Desplegar cuerdas de 27m @@ -262,7 +262,7 @@ Jogar cordas (36m) 部屬36公尺長之繩索 部署36米长的绳索 - Dispiegamento corde 36m + Dispiega corde da 36m Připravit 36m lana 36m halat sal Desplegar cuerdas de 36m @@ -289,13 +289,14 @@ Hélicordage 快速繩降 快速索降 - ファスト ロープ + ファストロープ Cuerdas rápidas Zjazd na linach Halatla Kayma Slaňování Спуск по канату Schnelles-Abseilen + Fast Rope 패스트로프 @@ -319,16 +320,24 @@ Automatycznie Zamontuj FRIES FRIESの自動装備 FRIES automatisch ausrüsten + Auto-Aggiungi FRIES FRIES 로프 자동 장착 Equipement automatique FRIES + Auto-equipar FRIES + Авто-подготовка канатов + Auto-Equipar FRIES Automatically add FRIES to helicopters that support them. Automatycznie dodawaj FRIES do śmigłowców które je wspierają. FRIESをサポートするヘリコプターに自動的にFRIESを追加します。 FRIES automatisch Helikoptern hinzufügen, die es unterstützen + Aggiunge il sistema FRIES in automatico su elicotteri compatibili. 로프를 지원하는 헬기에 자동으로 FRIES 로프를 추가합니다. Ajoute automatiquement des FRIES aux hélicoptères qui les supportent. + Adiciona automaticamente FRIES a helicópteros que os suportam. + Автоматически добавляйте канаты в вертолеты, которые их поддерживают. + Añadir automáticamente el FRIES a los helicópteros que lo soporten. diff --git a/addons/fcs/XEH_postInit.sqf b/addons/fcs/XEH_postInit.sqf index 7693fecb6c..a63b03c5d9 100644 --- a/addons/fcs/XEH_postInit.sqf +++ b/addons/fcs/XEH_postInit.sqf @@ -6,7 +6,7 @@ GVAR(position) = [0,0,0]; if (!hasInterface) exitWith {}; -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" ["ace_infoDisplayChanged", { if (!isNull ((_this select 0) displayCtrl 1713151)) then { diff --git a/addons/fcs/functions/fnc_calculateSolution.sqf b/addons/fcs/functions/fnc_calculateSolution.sqf index 5800068e4b..b0cb2ea1c4 100644 --- a/addons/fcs/functions/fnc_calculateSolution.sqf +++ b/addons/fcs/functions/fnc_calculateSolution.sqf @@ -44,14 +44,13 @@ private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurret if (_x != "this") then { _weaponMagazines append getArray (configFile >> "CfgWeapons" >> _weapon >> _x >> "magazines"); }; - false - } count _muzzles; + } forEach _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 { @@ -62,8 +61,7 @@ private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurret _initSpeed = _initSpeedCoef; }; }; - false - } count (_vehicle weaponsTurret _turret); + } forEach (_vehicle weaponsTurret _turret); private _offset = "ace_fcs" callExtension format ["%1,%2,%3,%4", _initSpeed, _airFriction, _angleTarget, _distance]; _offset = parseNumber _offset; @@ -72,8 +70,7 @@ private _turretConfig = [configOf _vehicle, _turret] call EFUNC(common,getTurret _FCSMagazines pushBack _magazine; _FCSElevation pushBack _offset; }; - false -} count (_vehicle magazinesTurret _turret); +} forEach (_vehicle magazinesTurret _turret); [_vehicle, format ["%1_%2", QGVAR(Distance), _turret], _distance] call EFUNC(common,setVariablePublic); [_vehicle, format ["%1_%2", QGVAR(InitSpeed), _turret], _FCSInitSpeed] call EFUNC(common,setVariablePublic); diff --git a/addons/fcs/functions/fnc_firedEH.sqf b/addons/fcs/functions/fnc_firedEH.sqf index dedef1c74e..e99416593a 100644 --- a/addons/fcs/functions/fnc_firedEH.sqf +++ b/addons/fcs/functions/fnc_firedEH.sqf @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); private _FCSMagazines = _vehicle getVariable [format ["%1_%2", QGVAR(Magazines), _turret], []]; @@ -50,7 +50,7 @@ if (_zeroDistance > 0) then { private _antiOffset = _gunner getVariable QGVAR(lastAntiOffset); _offset = _offset - _antiOffset; - TRACE_4("fired",_gunner, currentZeroing _gunner, _antiOffset, _offset); + TRACE_4("fired",_gunner,currentZeroing _gunner,_antiOffset,_offset); }; [_projectile, (_vehicle getVariable format ["%1_%2", QGVAR(Azimuth), _turret]), _offset, 0] call EFUNC(common,changeProjectileDirection); @@ -72,5 +72,5 @@ if (getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(Airburst)) == 1) then { if (_zeroing < 50) exitWith {}; if (_zeroing > 1500) exitWith {}; - [FUNC(handleAirBurstAmmunitionPFH), 0, [_vehicle, _projectile, _zeroing]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(handleAirBurstAmmunitionPFH), 0, [_vehicle, _projectile, _zeroing]] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/fcs/initKeybinds.sqf b/addons/fcs/initKeybinds.inc.sqf similarity index 100% rename from addons/fcs/initKeybinds.sqf rename to addons/fcs/initKeybinds.inc.sqf diff --git a/addons/fcs/stringtable.xml b/addons/fcs/stringtable.xml index 91c180545a..2f3ae894b1 100644 --- a/addons/fcs/stringtable.xml +++ b/addons/fcs/stringtable.xml @@ -10,7 +10,7 @@ Iluminar objetivo / Medir distancia Подсветить цель / Замерить расстояние Célpont lézerezése / Távolság Bemérése - Misura la distanza + Telemetra bersaglio / Rileva distanza Marcar com laser / Medir Distância レーザー ターゲット / 計測距離 목표까지 거리를 레이저로 취득 @@ -27,7 +27,7 @@ Выставлено на Nullázási táv Fixado em - Azzeramento a + Azzerato a 次にゼロイン 영점 조절 已归零到 @@ -42,9 +42,9 @@ SCT - Augmenter la portée FCS tartomány állítása (Fel) Ajustar distância do FCS (Acima) - Aumentare la distanza dell'FCS + Aumenta la portata dell'FCS Диапазон СУО (выше) - FCS による距離を調節 (上げ) + FCS 距離を調節 (上げ) 사통장치 거리 조정 (위로) 调整火控系统距离(上调) 調整火控系統距離 (上) @@ -58,9 +58,9 @@ SCT - Réduire la portée FCS tartomány állítása (Le) Ajustar distância do FCS (Abaixo) - Ridurre la distanza dell'FCS + Riduci la portata dell'FCS Диапазон СУО (ниже) - FCS による距離を調節 (下げ) + FCS 距離を調節 (下げ) 사통장치 거리 조정 (아래로) 调整火控系统距离(下调) 調整火控系統距離 (下) diff --git a/addons/field_rations/XEH_postInit.sqf b/addons/field_rations/XEH_postInit.sqf index 1ee235ca4f..9fc8406aba 100644 --- a/addons/field_rations/XEH_postInit.sqf +++ b/addons/field_rations/XEH_postInit.sqf @@ -96,10 +96,10 @@ if !(hasInterface) exitWith {}; ] call CBA_fnc_addItemContextMenuOption; // Add water source helpers when interaction menu is opened - ["ace_interactMenuOpened", {call FUNC(addWaterSourceInteractions)}] call CBA_fnc_addEventHandler; + ["ace_interactMenuOpened", LINKFUNC(addWaterSourceInteractions)] call CBA_fnc_addEventHandler; // Add status modifiers - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [0, { if (_this getVariable [QEGVAR(medical,isBleeding), false]) exitWith { 0.5 @@ -134,7 +134,7 @@ if !(hasInterface) exitWith {}; ["CAManBase", "respawn", LINKFUNC(handleRespawn)] call CBA_fnc_addClassEventHandler; // Start update loop - [FUNC(update), CBA_missionTime + MP_SYNC_INTERVAL, 1] call CBA_fnc_waitAndExecute; + [LINKFUNC(update), CBA_missionTime + MP_SYNC_INTERVAL, 1] call CBA_fnc_waitAndExecute; #ifdef DEBUG_MODE_FULL ["ACE_player thirst", {ACE_player getVariable [QXGVAR(thirst), 0]}, [true, 0, 100]] call EFUNC(common,watchVariable); diff --git a/addons/field_rations/XEH_preInit.sqf b/addons/field_rations/XEH_preInit.sqf index a54da0834a..e74e4086ca 100644 --- a/addons/field_rations/XEH_preInit.sqf +++ b/addons/field_rations/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" #define ARSENAL_CATEGORY_ICON QPATHTOF(ui\icon_survival.paa) 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/field_rations/functions/fnc_handleEffects.sqf b/addons/field_rations/functions/fnc_handleEffects.sqf index 1981cc5f99..ad60a743ad 100644 --- a/addons/field_rations/functions/fnc_handleEffects.sqf +++ b/addons/field_rations/functions/fnc_handleEffects.sqf @@ -21,24 +21,21 @@ params ["_player", "_thirst", "_hunger"]; // Kill unit with max thirst or hunger if ((_thirst > 99.9 || {_hunger > 99.9}) && {random 1 < 0.5}) exitWith { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { - [_player, "Hunger/Thirst empty"] call EFUNC(medical_status,setDead); - } else { - _player setDamage 1; - }; + [_player, "Hunger/Thirst empty"] call EFUNC(common,setDead); }; // Exit if unit is not awake, below are animation based consequences if !(_player call EFUNC(common,isAwake)) exitWith {}; // Set unit unconscious (chance based on how high thirst/hunger are) -if ((_thirst > 85 || {_hunger > 85}) && {random 1 < linearConversion [85, 100, _thirst max _hunger, 0.05, 0.1, true]}) exitWith { - if (["ace_medical"] call EFUNC(common,isModLoaded)) then { - [_player, true, 5, true] call EFUNC(medical,setUnconscious); - }; +if ( + GETEGVAR(medical,enabled,false) && + {(_thirst > 85 || {_hunger > 85}) && {random 1 < linearConversion [85, 100, _thirst max _hunger, 0.05, 0.1, true]}} +) exitWith { + [_player, true, 5, true] call EFUNC(medical,setUnconscious); }; // Make unit fall if moving fast -if ((_thirst > 93 || {_hunger > 93}) && {speed _player > 1} && {vehicle _player == _player}) exitWith { +if ((_thirst > 93 || {_hunger > 93}) && {speed _player > 1} && {isNull objectParent _player}) exitWith { [_player, "down"] call EFUNC(common,doGesture); }; diff --git a/addons/field_rations/functions/fnc_update.sqf b/addons/field_rations/functions/fnc_update.sqf index 82b87bcfb6..f66573824b 100644 --- a/addons/field_rations/functions/fnc_update.sqf +++ b/addons/field_rations/functions/fnc_update.sqf @@ -25,7 +25,7 @@ private _player = ACE_player; // Exit if player is not alive or a virtual unit if (!alive _player || {_player isKindOf "VirtualMan_F"}) exitWith { - [FUNC(update), _nextMpSync, 1] call CBA_fnc_waitAndExecute; + [LINKFUNC(update), _nextMpSync, 1] call CBA_fnc_waitAndExecute; QGVAR(hud) cutFadeOut 0.5; }; @@ -73,4 +73,4 @@ if (!EGVAR(common,OldIsCamera) && {_thirst > XGVAR(hudShowLevel) || {_hunger > X QGVAR(hud) cutFadeOut 0.5; }; -[FUNC(update), _nextMpSync, 1] call CBA_fnc_waitAndExecute; +[LINKFUNC(update), _nextMpSync, 1] call CBA_fnc_waitAndExecute; diff --git a/addons/field_rations/initSettings.sqf b/addons/field_rations/initSettings.inc.sqf similarity index 100% rename from addons/field_rations/initSettings.sqf rename to addons/field_rations/initSettings.inc.sqf diff --git a/addons/field_rations/stringtable.xml b/addons/field_rations/stringtable.xml index 264988ae7e..2b443ccc3c 100644 --- a/addons/field_rations/stringtable.xml +++ b/addons/field_rations/stringtable.xml @@ -9,7 +9,7 @@ ACE Rations sur le terrain ACE Feld Rationen ACE Terepi adagok - ACE Razioni di campo + ACE Razioni da Campo ACE フィールド レーション ACE 전투식량 ACE Racje polowe @@ -21,6 +21,7 @@ ACE Field Rations HUD ACE Feldrationen HUD + ACE Razioni da Campo HUD ACE 戰地口糧界面 ACE 野战军粮界面 ACE フィールド レーション HUD @@ -29,6 +30,8 @@ ACE Gıda Göstergesi ACE 전투식량 HUD ACE HUD de Raciones de campo + ACE HUD de Rações de Campo + ACE Rations de terrain HUD Indicates current hunger and thirst status. @@ -38,8 +41,8 @@ Indique l'état actuel de la faim et de la soif. Zeigt den aktuellen Hunger- und Durststatus an. Jelzi az éhínség és a szomjúság állapotát. - Indica lo stato attuale di fame e sete. - 現在の空腹感と渇きの状態を示します。 + Mostra lo stato attuale di fame e sete. + 現在の喉の渇きと空腹度の状態を示します。 굶주림과 갈증 정도를 표시합니다. Wskazuje bieżący status głodu i pragnienia. Indica o status atual de fome e sede. @@ -67,6 +70,7 @@ Eat/Drink Essen/Trinken + Mangia/Bevi Jeść/Pić Есть/Пить Yeme / Içme @@ -74,6 +78,8 @@ 吃/喝 먹기/마시기 Comer/Beber + Comer/Beber + Manger/Boire Enable/Disable Field Rations @@ -83,7 +89,7 @@ Activer / désactiver les rations de champ Feldrationen aktivieren / deaktivieren Terepi adagok engedélyezése / letiltása - Abilita / disabilita le razioni di campo + Abilita / disabilita le razioni da campo フィールド レーションを有効/無効化します 전투식량 활성화/비활성화 Włącz / wyłącz racje polowe @@ -101,7 +107,7 @@ Zeit ohne Wasser Víz nélküli idő Tempo senza acqua - 水なしの時間 + 水分無しでの耐久時間 물 없이 생존 가능 시간 Czas bez wody Tempo sem água @@ -117,8 +123,8 @@ Combien de temps une unité devrait-elle pouvoir se passer d'eau (heures)? Wie lange sollte eine Einheit ohne Wasser auskommen (Stunden)? Mennyi ideig kell egy egység víz nélkül (óra) - Mennyi ideig kell egy egység víz nélkül (óra) - ユニットが水なしでどれくらい時間を過ごすことができるか (一時間単位) + Per quanto tempo ci si può muovere senza acqua (ore) + ユニットが水分無しでどれくらいの時間耐えられるか (一時間単位) 물을 안 마시고 얼마나 생존할 수 있는지 정합니다 (시간) Jak długo jednostka powinna przetrwać bez wody (godziny) Quanto tempo uma unidade pode passar sem água (horas) @@ -135,7 +141,7 @@ Zeit ohne Essen Élelmiszer nélkül Tempo senza cibo - 食べ物なしの時間 + 食事抜きでの耐久時間 밥 없이 생존 가능 시간 Czas bez jedzenia Tempo sem comida @@ -151,8 +157,8 @@ Combien de temps une unité doit-elle pouvoir se passer de nourriture (heures)? Wie lange sollte eine Einheit ohne Essen gehen können (Stunden)? Mennyi ideig kell egy egység élni nélkül (óra) - Per quanto tempo un'unità dovrebbe essere in grado di andare senza cibo (ore) - ユニットが食糧なしでどれくらい時間を過ごすことができるか (一時間単位) + Per quanto tempo ci si può muovere senza cibo (ore) + ユニットが食事抜きでどれくらいの時間耐えられるか (一時間単位) 밥을 안 먹고 얼마나 생존할 수 있는지 정합니다 (시간) Jak długo jednostka powinna przetrwać bez jedzenia (godziny) Quanto tempo uma unidade pode ir sem alimentos (horas) @@ -163,133 +169,167 @@ Thirst Quenched Durst gestillt + Sete placata 止渴程度 解渴程度 - 乾きの満たし + 喉の渇き度の満たされ量 Утоление жажды Pragnienie zaspokojone Susuzluk Giderme Katsayısı 갈증 해소 Sed saciada + Sede saciada + Soif étanchée Coefficient for the amount of thirst quenched from drinking. Koeffizient für die Menge des Dursts, der durch Trinken gestillt wird. + Coefficiente che determina la quantità di sete placata bevendo. 從飲用中能夠攝取多少水份。 通过喝水能够补充多少水份。 - 飲むことによって得られる乾きの満たし量の係数を設定します + 水分補給によって満たされる喉の渇きの量を表す係数。 Коэффициент утоления жажды от питья Współczynnik ilości zaspokojnego pragnienia od picia Bir şey içince, susuzluğunun ne kadar giderileceğini belirler. 마심으로써 갈증이 얼마나 해소되는지를 정합니다 Coeficiente del saciamiento de sed por beber. + Coeficiente para a quantidade de sede saciada por beber. + Coefficient déterminant la quantité de soif étanchée par la boisson. Hunger Satiated Hunger gesättigt + Fame placata 飽足感 饱腹感 - 満腹感 + 空腹度の満たされ量 Утоление голода Głód Zaspokojony Açlık Giderme Katsayısı 배부름 Hambre saciada + Fome saciada + Faim rassasiée Coefficient for the amount of hunger satiated from eating. Koeffizient für die Menge des Hungers, der durch essen gesättigt wird. + Coefficiente che determina la quantità di fame placata mangiando. 從飲食中獲取多少飽食感。 通过饮食能够补充多少能量。 - 食べることによって得られる満腹感の量の係数を設定します + 食事によって満たされる空腹度の量を表す係数。 Коэффициент утоления голода от принятия пищи Współczynnik ilosci zaspokojnego głodu od jedzenia Bir şey yiyince, açlığın ne kadar giderileceğini belirler. 밥을 먹어서 배고픔이 얼마나 해결되는지를 정합니다 Coeficiente del saciamiento del hambre por comer. + Coeficiente para a quantidade de fome saciada por comer. + Coefficient déterminant la quantité de faim satisfaite en mangeant. Water Source Actions Действия с источником воды Akcje przy źrodle wody Su Içme Animasyonu - 水源動作 + 水源でのアクション Wasserquellen-Aktionen + Interazioni su sorgenti d'acqua 水源动作 물 근처 행동 Acciones para suministros de agua + Ações para suprimentos de água + Interactions sur les sources d'eau Controls what actions are available on water sources. Определяет какие действия будут доступны с источником воды. Kontroluje jakie akcje są dostępne przy źrodle wody. Su içerken hangi animasyonu yapacağını belirler - 水源で可能な動作を設定します。 + 水源で可能なアクションを設定します。 Bestimmt, welche Aktionen an Wasserquellen verfügbar sind. + Determina quali azioni sono disponibili presso sorgenti di acqua. 控制对水源可用的动作。 물가에서 어떤 행동을 취할지 정합니다 Controla qué acciones están disponibles para los suministros de agua. + Controla quais ações estão disponíveis para os suprimentos de água. + Déterminer les stocks disponibles dans les sources d'eau. Refill Only Только пополнить Tylko napełnij Sadece içeceği iç - 汲むだけ + 水汲みのみ Nur Befüllen + Solo riempimento 仅限取水 다시 채우기만 가능 Sólo rellenar + Apenas reabastecer + Remplissage uniquement Terrain Object Actions Действия с объектами ландшафта Akcje Objektu terenu Varsayılan Nesne Animasyonu - マップ オブジェクト動作 + 地形オブジェクトでのアクション Geländeobjekt-Aktionen + Interazioni su oggetti del terreno 地形物体动作 지형 물체 상호작용 Acciones sobre objetos del terreno + Ações para objetos do terreno + Actions sur les objets du terrain Enables water source actions for terrain objects. Включает действия с источниками воды для объектов ландшафта. Umożliwia akcje przy źrodle wody na obiektach terenu. Varsayılan nesneler için animasyonu etkinleştir - マップに存在するオブジェクトを水源として動作するよう設定できます。 + 地形に存在するオブジェクトを水源として動作するよう設定できます。 Aktiviert Wasserquellen-Aktionen für Geländeobjekte. + Permette le interazioni da sorgenti d'acqua anche su oggetti del terreno. 为地形物体启用水源动作。 지형 물체에서 물을 얻는 게 가능해집니다. Habilitar acciones de suministros de agua para los objetos en el suelo. + Habilita ações para suprimentos de água para objetos do terreno. + Active les actions relatives aux sources d'eau pour les objets de terrain. Affect Advanced Fatigue Beeinflusst die erweiterte Ausdauer + Influenza la Fatica Avanzata 與進階疲勞聯動 与进阶疲劳联动 - アドバンスド ファティーグへの影響 + アドバンスド疲労への影響 Влияние на продвинутую усталость Wpływ na zaawansowane zmęczenie Gelişmiş Yorgunluk 고급 피로도에 영향을 끼침 Afecta a la Fatiga Avanzada + Afeta a Fadiga Avançada + Affectation Fatigue avancée Controls if thirst and hunger should affect ACE Advanced Fatigue. Bestimmt, ob Durst und Hunger ACE Erweiterte Ausdauer beeinflussen sollen. + Determina se fame e sete influenzano la Fatica Avanzata ACE. 是否讓飲食影響到ACE的進階疲勞。 是否让饮食影响到 ACE 的进阶疲劳。 - 喉の渇きと空腹感が ACE アドバンスド ファティーグへ与える影響を決定します + 喉の渇きと空腹度が ACE アドバンスド疲労へ与える影響を定義します。 Определяет, будет ли жажда и голод влиять на продвинутую усталость ACE. Kontroluje czy pragnienie i głód mają wpływ na zaawansowane zmęczenie ACE. Acıkınca veya susayınca kişinin yorulup yorulmayacağını belirler. 배고픔과 목마름이 고급 피로도에 영향을 끼칠지를 정합니다 Controla si la sed y el hambre afectan a la Fatiga Avanzada de ACE + Controla se a sede e a fome afetam a Fadiga Avançada do ACE. + Contrôle si la soif et la faim doivent affecter la fatigue avancée ACE. HUD Type HUD Typ + Tipo HUD 界面類型 界面类型 HUD タイプ @@ -298,10 +338,13 @@ HUD Tipi HUD 종류 Tipo de HUD + Tipo de HUD + Type de HUD Selects which HUD style will be used. Wählt, welcher HUD Stil benutzt wird. + Seleziona lo stile utilizzato per l'HUD. 選擇妳想使用的界面類型。 选择你想使用的界面类型。 使用する HUD のタイプを選択できます @@ -310,10 +353,13 @@ Hangi HUD sitilini kullanılacağını seçer. 사용될 HUD 스타일을 고르십시오. Selecciona qué estilo de HUD será utilizado. + Seleciona qual estilo de HUD será usado. + Sélectionne le style HUD à utiliser. Colored Icons Farbige Icons + Icone colorate 顏色化圖示 彩色图标 色付きアイコン @@ -322,22 +368,28 @@ Renkli Ikonlar 색깔 아이콘 Iconos coloreados + Ícones coloridos + Icônes de couleur Draining Icons Farblose Icons + Icone non colorate 增減化圖示 渐化图标 - ドレイン アイコン + レベルゲージアイコン Ubywające ikony Исчезающие иконки Içi Boşalan Ikonlar 빠지는 아이콘 Iconos de drenado + Ícones de drenagem + Icônes incolores HUD Show Level HUD zeigen Level + Livello Mostra HUD 界面顯示程度 界面显示程度 HUD 表示レベル @@ -346,18 +398,23 @@ HUD Gösterilme Seviyesi HUD 표시 Mostrar nivel en HUD + Mostrar nível no HUD + Afficher le niveau dans le HUD Automatically show the HUD when either thirst or hunger are above this level. Zeigt automatisch das HUD an, sobald Durst oder Hunger über diesem Level sind. + Mostra le icone HUD in automatico quando fame o sete superano questo livello. 在飲食低於多少程度時顯示界面。 在饮食能量低于多少程度时显示界面。 - この値以上に空腹感か乾きを感じると自動的に HUD を表示します + この値以上に空腹度か喉の渇きを感じると自動的に HUD を表示します Automatycznie pokaż HUD kiedy pragnienie albo głód przekroczy ten poziom Автоматически отображает иконки при достижении определенных уровней голода и жажды. Susuzluk veya açlık belli bir seviyenin altına inince otomatik olarak HUD u göster. 정한 퍼센트 이하로 내려가면 HUD가 나타나게 합니다. Mostrar automáticamente el HUD cuando la sed o el hambre están por encima de este nivel. + Mostrar automaticamente o HUD quando a sede ou a fome estão acima deste nível. + Affiche automatiquement le HUD dès que la soif ou la faim sont au-dessus de ce niveau. Always @@ -379,6 +436,7 @@ Colored Icons - Transparency Farbige Icons - Transparenz + Icone Colorate - Trasparenza 顏色化圖示 - 透明度 彩色图标—透明度 色付きアイコン - 透明度 @@ -387,18 +445,23 @@ Renkli Ikonlar - Şeffaflaşan 색깔 아이콘 - 투명도 Iconos coloreados - Transparencia + Ícones coloridos - Transparência + Icônes de couleur - Transparence Controls the transparency of the Colored Icons HUD. Dynamic setting makes the HUD less transparent as thirst or hunger increase. Bestimmt die Tranzparenz der farbigen HUD Icons. Die Dynamische Einstellung macht das HUD weniger transparent, wenn Hunger oder Durst steigen. + Determina la trasparenza di icone HUD colorate. L'impostazione 'Dinamico' rende l'HUD meno trasparente quando la fame o sete è maggiore. 控制顏色化圖示的透明度。設定為動態使其界面透明度與飲食需求一樣,越透明越需要。 控制彩色图标 HUD 的透明度。动态设置使 HUD 的透明度随着口渴或饥饿的增加而减弱。 Kontroluje transparentność kolorowych ikon HUD. Dynamiczne ustawienie zmniejsza przejrzystość wraz z zwiększeniem głodu czy pragnienia. - 色付きアイコンの透明度を決定できます。動的に設定されると、喉の渇きや空腹感が増すにつれて、アイコンの透明度を下げます。 + 色付きアイコンの透明度を制御できます。動的に設定されると、空腹度や喉の渇きが増すにつれて、アイコンの透明度を下げます。 Настраивает прозрачность цветных иконок. «Динамическая» делает иконки менее прозрачными при увеличении жажды и голода. Renkli Simgeler Gösterge Paneli'nin şeffaflığını kontrol eder. Dinamik ayar, susuzluk veya açlık arttıkça HUD'yi daha az şeffaf hale getirir. 색깔 아이콘의 투명도를 조절합니다. 동적 설정의 경우 배고픔이나 목마름이 해결되면 덜 투명하게 바뀝니다. Controla la transparencia de los Iconos coloreados en el HUD. La opción dinámica muestra el HUD menos transparente cuando la sed o el hambre aumentan. + Controla a transparência dos ícones coloridos no HUD. A configuração dinâmica torna o HUD menos transparente à medida que a sede ou a fome aumentam. + Contrôle la transparence du HUD des icônes colorées. Un réglage dynamique rend le HUD moins transparent lorsque la soif ou la faim augmentent. Dynamic @@ -420,28 +483,35 @@ Water Supply Wasservorrat + Scorta d'acqua 飲用水補給 饮用水补给 - 水資源 + 水資源量 Водные ресурсы Źródło wody 식수 보급량 Suministro de agua + Suprimentos de água + Réserve d'eau The amount of water available for ACE Field Rations water source actions (-1 disabled, -10 infinite) Die Menge des für ACE Feldrationen Wasserquellenaktionen verfügbaren Wassers (-1 ausgeschaltet, -10 unendlich) + La quantità di acqua disponibile per interazioni ACE Razioni da Campo di sorgenti d'acqua (-1 nessuna, -10 infinita) 水源可供補充飲用水的次數(-1為關閉,-10為無限次)。 水源可供取水的次数(-1为关闭,-10为无限次)。 - ACE フィールド レーションで利用できる水源の量を設定できます。(-1で無効化、-10で無限) + ACE フィールド レーションで利用できる水源の資源量を設定できます。(-1で無効化、-10で無限) Количество воды, доступной для использования в ACE Полевые рационы. (-1 - отключено, -10 - бесконечно) Ilość wody dostępnej dla Akcji ACE Źródła wody (-1 wyłączone, -10 nieskończone) ACE 전투식량 물 근처 행동에서 얼마나 물을 얻어 갈 수 있는지를 정합니다 (-1은 비활성화, -10은 무한대) La cantidad de agua disponible para las acciones de suministro de agua de las Raciones de Combate de ACE (-1 deshabilitado, -10 infinito) + A quantidade de água disponível para as ações de suprimentos de água das Rações de Campo do ACE (-1 desativado, -10 infinito) + Quantité d'eau disponible pour les actions relatives aux sources d'eau des rations de campagne ACE (-1 désactivé, -10 infini). Water Source Wasserquelle + Sorgente d'acqua 水源 水源 水源 @@ -450,10 +520,13 @@ Matara 수원지 Suministro de agua + Fonte de água + Source d'eau Check Remaining Water Überprüfe verbleibendes Wasser + Controlla acqua rimanente 檢查剩餘飲用水 检查剩余饮用水 残っている水を確認 @@ -462,10 +535,13 @@ Kalan Suyu Kontrol Et 남은 물 확인 Comprobar agua restante + Verificar água restante + Vérifier l'eau restante Checking remaining water... Überprüfe verbleibendes Wasser... + Controllando acqua rimanente... 檢查剩下的飲用水... 检查剩余饮用水中... 残っている水量を確認中です・・・ @@ -474,34 +550,43 @@ Kalan Su Kontrol Ediliyor... 남은 물 확인 중... Comprobando agua restante... + Verificando água restante... + Vérification de l'eau restante... There are %1 litres left. Es sind %1 Liter übrig. + Ci sono ancora %1 Litri. 那還有 %1 公升 还剩下 %1 升 - 残り %1 リットル残っています。 + あと %1 リットル残っています。 Pozostało %1 litrów. Осталось %1 л воды %1 Litre kaldı. %1 리터의 물이 남아있습니다. Quedan %1 litros. + Ainda há %1 litros. + Il reste %1 litres. There is no water left. Es ist kein Wasser mehr übrig. + Non c'è più acqua rimanente 水已經用完了 水已经喝完了。 - 水はもうありません。 + 水は残っていません。 Nie ma wody Воды больше не осталось Hiç su kalmadı. 물이 한 방울도 없습니다. No queda agua. + Não há mais água. + Il n'y a plus d'eau. Drink From Source Trinke direkt + Bevi da sorgente Выпить из источника Pij z źródła wody Mataradan Iç @@ -509,6 +594,8 @@ 从水源处喝水 수원에서 물 마시기 Beber desde el suministro + Beber da fonte + Boire à la source Refill @@ -518,8 +605,8 @@ Recharge Nachfüllung Utántöltés - Ricarica - 汲む + Riempi + 水を汲む 다시 채우기 Uzupełnij Recarga @@ -535,7 +622,7 @@ Remplissage ... Nachfüllen... Utántöltés ... - Ricarica ... + Riempendo... 汲んでいます・・・ 채우는 중... Uzupełnianie ... @@ -552,7 +639,7 @@ Article rechargé Artikel nachgefüllt Újratöltött tétel - Articolo riempito + Oggetto riempito 中身がいっぱいになりました 아이템 채워짐 Przedmiot uzupełniony @@ -564,6 +651,7 @@ Eating %1... Esse %1... + Mangiando %1... 食用 %1... 食用 %1... %1 を食べています・・・ @@ -572,10 +660,13 @@ %1 Yeniyor... %1 먹는 중... Comiendo %1... + Comendo %1... + Manger %1... Drinking %1... Trinke %1... + Bevendo %1... 飲用自 %1... 饮用 %1... %1 を飲んでいます・・・ @@ -584,10 +675,13 @@ %1 Içiliyor... %1 마시는 중... Bebiendo %1... + Bebendo %1... + Boire %1... Drinking from %1... Trinke von %1... + Bevendo da %1... 飲用%1的水中... 从%1饮用中... %1 から飲んでいます・・・ @@ -596,6 +690,8 @@ %1 den içiliyor... %1 으로 부터 마시는 중... Bebiendo desde %1... + Bebendo de %1... + Boire à %1... Drinking from source... @@ -604,9 +700,12 @@ Mataradan Içiliyor... 水源から飲んでいます・・・ Trinke von Quelle... + Bevendo da sorgente... 从水源处喝水中... 수원에서 마시는 중... Bebiendo desde el suministro... + Bebendo da fonte... + Boire à la source... Water Bottle @@ -617,7 +716,7 @@ Wasserflasche Vizesüveg Bottiglia d'acqua - ウォーターボトル + 水のペットボトル 물병 Butelka wody Garrafa de água @@ -634,7 +733,7 @@ Eine Wasserflasche Egy vizes palackot Una bottiglia d'acqua - ウォーター ボトル + 水入りペットボトル 물병 Butelka wody Uma garrafa de água @@ -651,7 +750,7 @@ Wasserflasche (Hälfte) Vízpalack (fél) Bottiglia d'acqua (metà) - ウォーター ボトル (半分) + 水のペットボトル (半分) 물병 (절반) Butelka wody (połowa) Garrafa de água (meio) @@ -667,8 +766,8 @@ Une bouteille d'eau à moitié pleine Eine halbvolle Wasserflasche Fél-teljes vizes palack - Una mezza bottiglia piena d'acqua - 半分入っているウォーター ボトル + Una bottiglia d'acqua mezza piena o mezza vuota + 半分残っている水入りペットボトル 절반만 차 있는 물병입니다. Pół butelki z wodą Uma garrafa de água meia cheia @@ -685,7 +784,7 @@ Wasserflasche (leer) Vízpalack (üres) Bottiglia d'acqua (vuota) - ウォーター ボトル (空) + 水のペットボトル (空) 물병 (비어 있음) Butelka na wodę (pusta) Garrafa de água (vazia) @@ -702,7 +801,7 @@ Eine leere Wasserflasche Egy üres palack Una bottiglia d'acqua vuota - 空のウォーター ボトル + 空のウォーターボトル 빈 물병입니다 Pusta butelka wody Uma garrafa de água vazia @@ -718,7 +817,7 @@ Cantine Feldflasche Kantin - Mensa + Borraccia 水筒 수통 Manierka @@ -735,7 +834,7 @@ Une cantine remplie d'eau Eine Feldflasche mit Wasser gefüllt Vízzel töltött kantin - Una mensa piena d'acqua + Una borraccia piena d'acqua 水で一杯の水筒 물이 가득찬 수통입니다 Manierka wypełniona wodą @@ -752,7 +851,7 @@ Cantine (Demi) Feldflasche (halb) Étkezés (fél) - Mensa (metà) + Borraccia (metà) 水筒 (半分) 수통 (절반) Manierka (połowa) @@ -769,7 +868,7 @@ Une cantine à moitié remplie d'eau Eine Feldflasche zur Hälfte mit Wasser gefüllt A vízzel töltött kantin - Una mensa riempita per metà di acqua + Una borraccia riempita per metà di acqua 半分入っている水筒 반이 차 있는 수통입니다 Manierka w połowie wypełniona wodą @@ -786,7 +885,7 @@ Cantine (Vide) Feldflasche (leer) Étkezde (üres) - Mensa (vuota) + Borraccia (vuota) 水筒 (空) 수통 (비어 있음) Manierka (pusta) @@ -803,7 +902,7 @@ Une cantine vide Eine leere Feldflasche Egy üres kantin - Una mensa vuota + Una borraccia vuota 空の水筒 빈 수통입니다 Pusta manierka @@ -815,6 +914,7 @@ Refreshing lemon and lime flavored soft drink Ein erfrischender Softdrink mit Zitronen- und Limettengeschmack. + Una bibita rinfrescante con gusto di limoni e lime. 清新檸檬以及有著酸橙味的汽水 清爽的柠檬和青柠味汽水 新鮮なレモンとライムの風味を味わえるソフトドリンク @@ -823,10 +923,13 @@ Limon Ve Yeşil Limondan Yapılmış Gazlı Bir Içecek 상쾌한 레몬라임향의 탄산음료 Bebida refrescante de sabor lima y limón + Bebida refrescante de sabor limão e lima + Une boisson gazeuse rafraîchissante au goût de citron et de citron vert. Orange flavored soft drink with a tingly, fruity taste Ein nach Orange schmeckender Softdrink mit einem prickelndem und fruchtigem Geschmack + Una bibita frizzante con gusto di arancia 有著微微的橘子水果味的汽水 橙子味汽水,有刺鼻的水果味 口いっぱいに果物を感じるオレンジ風味のソフトドリンク @@ -835,18 +938,23 @@ Gazlı Portakallı Bir Içecek 오렌지 향의 톡쏘는 탄산음료 Bebida refrescante de sabor naranja, con un chispeante y afrutado sabor. + Bebida refrescante de sabor laranja, com um sabor frutado e formigante. + Une boisson gazeuse aromatisée à l'orange Red Gull gives you wings Red Gull verleiht Flügel + Red Gull mette le ali 紅鷹讓你猛虎添翼 红鹰让你猛虎添翼 - レッドガル 翼をさずける + レッドガル 翼を授ける Red Gull doda ci skrzydeł Рэд Гулл окрыляет! Red Gull kanatlandırrrrr 레드굴은 날개를 달아줘요 Red Gull te da alas + Red Gull te dá asas + Red Gull vous donne des ailes MRE Lamb Curry @@ -856,7 +964,7 @@ MRE Curry d'agneau EPA Lamm Curry MRE bárány Curry - MRE Curry di agnello + MRE Agnello al curry MRE ラムカレー MRE 양고기 카레 MRE jagnięcina Curry @@ -873,7 +981,7 @@ Un MRE contenant du Curry d'agneau. Chaleur pour le meilleur effet Eine EPA mit Lamm Curry. Für den besten Geschmack erhitzen. Egy MRE, amely Lamb Curry-t tartalmaz. Hő a legjobb hatás érdekében - Un MRE contenente Lamb Curry. Calore per il miglior effetto + Un MRE contenente Agnello al Curry. Riscalda per un sapore migliore. ラム(羊肉)カレーの MRE。温めるとなお美味しい 양고기 카레가 들어있는 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 MRE zawierające jagnięcine Curry. Podgrzej dla najlepszego efektu @@ -885,6 +993,7 @@ MRE Beef Stew EPA Rindereintopf + MRE Zuppa di bovino 軍糧 牛肉燉湯 军粮炖牛肉汤 MRE ビーフシチュー @@ -893,10 +1002,13 @@ MRE Dana Yahni MRE 비프스튜 MRE Estofado de ternera + MRE ensopado de carne + MRE Ragoût de bœuf An MRE containing Beef Stew. Heat for best effect Eine EPA, welche Rindereintopf beeinhaltet. Für den besten Geschmack erhitzen. + Un MRE contenente zuppa di bovino. Riscalda per un sapore migliore. 含有牛肉燉湯的軍用口糧。加熱以達到最佳效果 含有牛肉炖汤的军粮。加热以达到最佳效果 ビーフ シチューの MRE。温めるとなお美味しい @@ -905,6 +1017,8 @@ Sığır Yahni içeren bir MRE. 비프스튜가 들어있는 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 Un MRE que contiene estofado de ternera. Calentar para mejor efecto. + Um MRE contendo ensopado de carne. Aquecer para melhor efeito + Un MRE contenant du ragoût de bœuf. Chauffer pour un meilleur effet MRE Cream Tomato Soup @@ -914,7 +1028,7 @@ MRE Soupe de tomate crème EPA Cremige Tomatensuppe MRE krémes paradicsomleves - MRE Crema di pomodoro + MRE Zuppa di pomodoro MRE クリームトマトスープ MRE 크림 토마토 수프 MRE Kremowa Zupa Pomidorowa @@ -931,7 +1045,7 @@ Un MRE contenant de la soupe à la tomate et à la crème. Mélanger avec de l'eau et chauffer pour obtenir le meilleur effet Eine EPA mit Creme Tomatensuppe. Für beste Wirkung mit Wasser und Hitze mischen. Egy krémes paradicsomleveset tartalmazó MRE. Keverjük össze vízzel és hővel a legjobb hatás érdekében - Un MRE contenente zuppa di pomodoro crema. Mescolare con acqua e calore per ottenere il massimo effetto + Un MRE contenente zuppa di pomodoro cremosa. Mescolare con acqua e riscaldare per il sapore migliore クリームトマトスープの MRE。水と混ぜて温めるとなお美味しい 크림 토마토 수프가 들어 있는 MRE입니다. 물과 섞어 뜨겁게 먹을 때 가장 좋습니다 MRE zawierające śmietanową zupę pomidorową. Wymieszaj z wodą i podgrzej, aby uzyskać najlepszy efekt @@ -948,7 +1062,7 @@ MRE Soupe à la crème au poulet EPA Cream Hühnersuppe MRE krémes csirke leves - MRE Zuppa di pollo crema + MRE Zuppa di pollo MRE クリームチキンスープ MRE 크림 치킨 수프 MRE Kremowy Rosół @@ -965,7 +1079,7 @@ Un MRE contenant une soupe au poulet. Mélanger avec de l'eau et chauffer pour obtenir le meilleur effet Eine EPA mit Hühnersuppe. Für beste Wirkung mit Wasser und Hitze mischen. A csirke leves tartalmú MRE. Keverjük össze vízzel és hővel a legjobb hatás érdekében - Un MRE contenente zuppa di pollo. Mescolare con acqua e calore per ottenere il massimo effetto + Un MRE contenente zuppa di pollo. Mescolare con acqua e riscaldare per il sapore migliore クリームチキンスープの MRE。水と混ぜて温めるとなお美味しい 치킨 수프가 들어 있는 MRE입니다. 물과 섞어 뜨겁게 먹을 때 가장 좋습니다 MRE zawierające rosół. Wymieszaj z wodą i podgrzej, aby uzyskać najlepszy efekt @@ -982,7 +1096,7 @@ MRE Poulet Tikka Masala EPA Huhn Tikka Masala MRE csirke Tikka Masala - MRE pollo Tikka Masala + MRE Pollo Tikka Masala MRE チキン ティッカ マサラ MRE 치킨 티카 마살라 MRE kurczak Tikka Masala @@ -999,7 +1113,7 @@ Un MRE avec du poulet Tikka Masala. Chaleur pour le meilleur effet Eine EPA mit Hühnchen Tikka Masala. Für den besten Geschmack erhitzen. Egy MRE csirkével Tikka Masala. Hő a legjobb hatás érdekében - Un MRE con pollo Tikka Masala. Calore per effetto migliore + Un MRE con pollo Tikka Masala. Riscaldare per il sapore migliore チキン ティッカ マサラの MRE。温めるとなお美味しい 치킨 티카 마살라 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 MRE z kurczakiem Tikka Masala. Podgrzej dla najlepszego efektu @@ -1016,7 +1130,7 @@ MRE Steak légumes EPA Steak Gemüse MRE Steak zöldségek - MRE Verdura di bistecca + MRE Bistecca con verdure MRE 野菜添えステーキ MRE 스테이크 야채 MRE Stek Warzywny @@ -1033,7 +1147,7 @@ Un MRE contenant du bifteck et des légumes. Chaleur pour le meilleur effet Eine EPA mit Steak und Gemüse. Für den besten Geschmack erhitzen. Egy MRE, amely Steak és Zöldségeket tartalmaz. Hő a legjobb hatás érdekében - Un MRE contenente bistecche e verdure. Calore per il miglior effetto + Un MRE contenente bistecca e verdure. Riscaldare per il sapore migliore 野菜とステーキの MRE。温めるとなお美味しい 스테이크와 채소가 들어 있는 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 MRE zawierający stek i warzywa. Podgrzej dla najlepszego efektu @@ -1067,7 +1181,7 @@ Un MRE contenant des boulettes de viande et des pâtes. Chaleur pour le meilleur effet Eine EPA mit Fleischbällchen und Pasta. Für den besten Geschmack erhitzen. Húsgombócokat és tésztát tartalmazó MRE. Hő a legjobb hatás érdekében - Un MRE contenente polpette e pasta. Calore per il miglior effetto + Un MRE contenente pasta con polpette. Riscaldare per il sapore migliore ミートボールとパスタの MRE。温めるとなお美味しい 미트볼과 파스타가 들어 있는 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 MRE zawierające klopsiki i makaron. Podgrzej dla najlepszego efektu @@ -1101,7 +1215,7 @@ Un MRE contenant du poulet et des dumplings aux fines herbes. Chaleur pour le meilleur effet Eine EPA mit Hühnchen mit Kräuterknödeln. Für den besten Geschmack erhitzen. Egy MRE, amely csirkét és fűszeres gombócokat tartalmaz. Hő a legjobb hatás érdekében - Un MRE contenente pollo con gnocchi alle erbe. Calore per il miglior effetto + Un MRE contenente pollo con gnocchi alle erbe. Riscaldare per il sapore migliore チキンとハーブ団子のMRE。温めるとなお美味しい 허브 치킨 만두 MRE입니다. 뜨겁게 먹을 때 가장 좋습니다 MRE z kurczakiem i pierogamii ziołowymi. Podgrzej dla najlepszego efektu @@ -1134,8 +1248,8 @@ Une ration humanitaire destinée à servir d'approvisionnement alimentaire en cas de crise Eine humanitäre Ration, die dazu bestimmt ist, in Krisenzeiten als Nahrung für eine Person zu dienen Humanitárius eloszlás, amelynek célja az ember élelmezési ellátottsága a válság idején - Una razione umanitaria destinata a servire come riserva di cibo di una persona durante le crisi - 人道危機を救う為に配布された食料品 + Una razione umanitaria destinata a fungere come riserva di cibo di una persona in caso di crisi umanitarie + 危機に瀕した人々の供給食としての使用を目的とした人道配給食 재난 상황에 식량으로 쓸 수 있는 인도주의 차원의 배급식량입니다 Racja humanitarna, która ma służyć jako żywność dla danej osoby podczas kryzysów Uma Ração Humanitária destinada a servir como alimento alimentar de uma pessoa durante as crises @@ -1145,22 +1259,28 @@ Sunflower Seeds Sonnenblumenkerne + Semi di girasole 해바라기씨 Nasiona Słonecznika ヒマワリの種 葵花籽 Семечки подсолнуха Pipas de girasol + Sementes de girassol + Graines de tournesol Roasted And Salted Geröstet und Gesalzen + Tostati e salati 굽고 간을 했습니다 Pieczone i Solone 炒って塩で味付け済 焙烤盐焗 Поджаренные и солёные Tostadas y saladas + Torradas e salgadas + Grillé et salé diff --git a/addons/fieldmanual/CfgHints.hpp b/addons/fieldmanual/CfgHints.hpp index 8164bd7943..6f5b0c8efe 100644 --- a/addons/fieldmanual/CfgHints.hpp +++ b/addons/fieldmanual/CfgHints.hpp @@ -37,7 +37,7 @@ class CfgHints { }; class ACE_BodyBag: ACE_FieldManual_Base { logicalOrder = 2; - arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_BodyBag' call FUNC(getItemName))}; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_BodyBag' call FUNC(getItemName)), MEDICAL_MENU_KEYBIND}; displayName = "%14"; displayNameShort = CSTRING(Items_BodyBag_ShortName); description = CSTRING(Items_BodyBag_Description); @@ -122,7 +122,7 @@ class CfgHints { }; class ACE_FortifyTool: ACE_FieldManual_Base { logicalOrder = 13; - arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_FortifyTool' call FUNC(getItemName))}; + arguments[] = {BASE_ARGUMENTS, QUOTE('ACE_Fortify' call FUNC(getItemName))}; displayName = "%14"; displayNameShort = CSTRING(Items_FortifyTool_ShortName); description = CSTRING(Items_FortifyTool_Description); diff --git a/addons/fieldmanual/stringtable.xml b/addons/fieldmanual/stringtable.xml index 3056ff5168..12e34d0e34 100644 --- a/addons/fieldmanual/stringtable.xml +++ b/addons/fieldmanual/stringtable.xml @@ -9,7 +9,7 @@ Rations sur le terrain Feld Rationen Terepi adagok - Razioni di campo + Razioni da campo フィールド レーション 전투식량 Racje polowe @@ -22,135 +22,263 @@ Hunger Głód 허기 + Fome + Fame Hunger + 空腹 + Голод + Faim + Hambre %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. %3Głód%4 zwiększa się liniowo wraz z prędkością ruchu. Odnawiany przez spożywanie jedzenia.<br/><br/>%3Użycie:%4<br/>%2Podnieś jedzenie.<br/>%2Użyj [%3%12%4] i wybierz %3Surwiwal%4.<br/>%2Wybierz pokarm do zjedzenia %3허기%4는 병사의 이동속도에 따라 선형적으로 증가합니다. 음식을 섭취하여 회복하십시오.<br/><br/>%3사용 방법:%4<br/>%2음식을 집으십시오.<br/>%2[%3%12%4]를 사용하여 %3생존%4을 선택하십시오.<br/>%2섭취할 아이템을 선택하십시오. + %3A fome%4 aumenta linearmente com a velocidade de movimento do soldado. Restaure comendo comida.<br/><br/>%3Uso:%4<br/>%2Pegue comida.<br/>%2Use [%3%12%4] e selecione %3Sobrevivência%4.<br/>%2Escolha um item para consumir. %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Выберите продукт для потребления. + %3La faim%4 augmente linéairement avec la vitesse de déplacement du soldat. Il se régénère en consommant de la nourriture.<br/><br/>%3Utilisation:%4<br/>%2Ramasser la nourriture.<br/>%2Utilisez [%3%12%4] et sélectionnez %3Survie%4.<br/>%2Choisissez un article à consommer. + El %3Hambre%4 aumenta linealmente con los movimientos del soldado. Se reestablece comiendo comida.<br/><br/>%3Uso:%4<br/>%2Coger comida.<br/>%2Usar [%3%12%4] y seleccionar %3Sobrevivir%4.<br/>%2Elegir un objeto para consumir. Thirst Pragnienie 갈증 + Sede + Sete Durst + 渇き + Жажда + Soif + Sed %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. %3Pragnienie%4 zwiększa się liniowo wraz z prędkością ruchu. Odnawiane przez spożywanie napojów.<br/><br/>%3Użycie:%4<br/>%2Podnieś napój.<br/>%2Użyj [%3%12%4] i wybierz %3Surwiwal%4.<br/>%2Wybierz napój do wypicia. - %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섭취할 아이템을 선택하십시오. + %3A sede%4 aumenta linearmente com a velocidade de movimento do soldado. Restaure bebendo líquidos.<br/><br/>%3Uso:%4<br/>%2Pegue uma bebida.<br/>%2Use [%3%12%4] e selecione %3Sobrevivência%4.<br/>%2Escolha um item para consumir. %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Выберите напиток для потребления. + %3La soif%4 augmente linéairement avec la vitesse de déplacement du soldat. Elle se régénère en buvant des liquides.<br/><br/>%3Utilisez [%3%12%4] et choisissez %3survival%4.<br />%2Choisissez un article à boire. + La %3Sed%4 aumenta linealmente con la velocidad de movimiento del soldado. Se restaura bebiendo líquidos.<br/><br/>%3Uso:%4<br/>%2Selecciona una bebida.<br/>%2Usar [%3%12%4] y seleccionar %3Sobrevivir%4.<br/>%2Elegir un objeto para consumir. Medical Treatment Opieka Medyczna 의료 치료법 + Tratamento médico Medizinische Behandlung + Cure Mediche + 治療 + Медицинское лечение + Traitement médical + Tratamiento Médico Decrease Heart Rate Obniża Tętno 심박수를 낮춥니다 + Diminuir a frequência cardíaca Verringere Herzfrequenz + Rallenta ritmo cardiaco + 心拍数を下げる + Уменьшить частоту сердечных сокращений + Diminution de la fréquence cardiaque + Disminuir Ritmo Cardíaco %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. %3Adenozyna%4 jest używana do obniżenia tętna.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz kończynę.<br/>%2Wstrzyknij %3Adenozynę%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을 주사하십시오. + %3Adenosina%4 é usada para diminuir a frequência cardíaca.<br/><br/>%3Uso:%4<br/>%2Use [%3%13%4] ou [%3%14%4] e selecione um apêndice.<br/>%2Injete %3Adenosina%4. %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. + L'%3adénosine%4 est utilisée pour réduire la fréquence cardiaque.<br/><br/>%3Utilisation:%4<br/>%2Utilisez [%3%13%4] ou [%3%14%4] et sélectionnez un membre.<br/>%2Injectez l'%3Adénosine%4. + La %3Adenosina%4 se usa para disminuir el ritmo cardíaco.<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y selecciona una extremidad.<br/>%2Inyectar %3Adenosina%4. Bandages Bandaże 붕대 + Bandagens Bandagen + Bende + 包帯 + Бинты + Pansements + Vendas Close Wounds Zamykają Rany 상처를 막습니다 + Fechar Feridas Wunden schließen + Chiudi ferite + 傷口をふさぐ + Закрыть раны + Fermer les plaies + Cerrar Heridas %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. %3Bandaże%4 zatrzymają krwawienie i zamykają rany. W zależności od twoich ustawień, bandaże mogą się otwierać, jeżeli rany nie są zaszyte. <br/><br/>%2%3Bandaż Jałowy:%4<br/>%11<t color='#D9D900'>Przeciętne</t> We wszystkich kategoriach<br/>%2%3Bandaż Uciskowy: %4<br/>%11<t color='#D9D900'>Przeciętne</t> Leczenie<br/>%11<t color='#E60000'>Wyższa</t> Szansa Otwarcia<br/>%11<t color='#00CC00'>Dłuższe</t> Opóźnienie Otwarcia<br/>%2%3Bandaż Elastyczny: %4<br/>%11<t color='#00CC00'>Lepsze</t> Leczenie<br/>%11<t color='#E60000'>Wyższa</t> Szansa Otwarcia<br/>%11<t color='#E60000'>Krótsze</t> Opóźnienie Otwarcia<br/>%2%3Quickclot: %4<br/>%11<t color='#E60000'>Gorsze</t> Leczenie<br/>%11<t color='#00CC00'>Niższa</t> Szansa Otwarcia<br/>%11<t color='#00CC00'>Dłuższe</t> Opóźnienie Otwarcia<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz zranioną część ciała. <br/>%2Zabandażuj ranę wybierając typ %3Bandażu%4. - %3붕대%4는 출혈을 멈추고 상처를 치료합니다.설정에 따라 수술을 하지 않을 경우 붕대가 다시 풀릴 수 있습니다.<br/><br/>%2%3붕대(기본):%4<br/>모든 카테고리에 대해 %11<tcolor='#D9D900'>평균</t>적임<br/>%2%3붕대(거즈):%4<br/><br/>%11<t color='#D9D900'>평균</t>적인 치료 효과<br/>%11<t color='#E60000'>높은</t> 풀림 확률<br/>%11<t color='#00CC00'>긴</t> 풀림 딜레이<br/>%2%3붕대(압박):%4<br/>%11<t color='#00CC00'>높은</t> 치료 효과<br/>%11<t color='#E60000'>높은</t> 풀림 확률<br/>%11<t color='#E60000'>짧은</t> 풀림 딜레이<br/>%2%3붕대(퀵 클롯):%4<br/>%11<t color='#E60000'>낮은</t> 치료 효과<br/>%11<t color='#00CC00'>낮은</t> 풀림 확률<br/>%11<t color='#00CC00'>긴</t> 풀림 딜레이<br/><br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하고 부상당한 신체부위를 선택하십시오.<br/>%2원하는 종류의 %3붕대%4를 선택하여 신체부위에 붕대를 감으십시오. + %3붕대%4는 출혈을 멈추고 상처를 치료합니다.설정에 따라 수술을 하지 않을 경우 붕대가 다시 풀릴 수 있습니다.<br/><br/>%2%3붕대(기본):%4<br/>모든 카테고리에 대해 %11<t color='#D9D900'>평균</t>적임<br/>%2%3붕대(거즈):<br/>%11<t color='#D9D900'>평균</t>적인 치료 효과<br/>%11<t color='#E60000'>높은</t> 풀림 확률<br/>%11<t color='#00CC00'>긴</t> 풀림 딜레이<br/>%2%3붕대(압박):%4<br/>%11<t color='#00CC00'>높은</t> 치료 효과<br/>%11<t color='#E60000'>높은</t> 풀림 확률<br/>%11<t color='#E60000'>짧은</t> 풀림 딜레이<br/>%2%3붕대(퀵 클롯):%4<br/>%11<t color='#E60000'>낮은</t> 치료 효과<br/>%11<t color='#00CC00'>낮은</t> 풀림 확률<br/>%11<t color='#00CC00'>긴</t> 풀림 딜레이<br/><br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하고 부상당한 신체부위를 선택하십시오.<br/>%2원하는 종류의 %3붕대%4를 선택하여 신체부위에 붕대를 감으십시오. + %3Bandagens%4 interrompem o sangramento e fecham feridas. A depender das suas configurações, as bandagens podem reabrir se não for feita a cirurgia.<br/><br/>%2%3Curativo de Campo:%4<br/>%11<t color='#D9D900'>Mediano</t> em todas as categorias<br/>%2%3Bandagem de Compressão:%4<br/>%11<t color='#D9D900'>Mediana</t> em tratamento<br/>%11<t color='#E60000'>Maior</t> chance de reabertura<br/>%11<t color='#00CC00'>Mais longo</t> atraso na reabertura<br/>%2%3Bandagem Elástica:%4<br/>%11<t color='#00CC00'>Melhor</t> em tratamento<br/>%11<t color='#E60000'>Maior</t> chance de reabertura<br/>%11<t color='#E60000'>Mais curto</t> atraso na reabertura<br/>%2%3QuikClot:%4<br/>%11<t color='#E60000'>Pior</t> em tratamento<br/>%11<t color='#00CC00'>Menor</t> chance de reabertura<br/>%11<t color='#00CC00'>Mais longo</t> atraso na reabertura<br/><br/>%Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione uma parte do corpo ferida.<br/>%2Suture a parte do corpo selecionando o tipo desejado de %3Bandagem%4. %3Verbände%4 stoppen Blutungen und schließen Wunden. Abhängig von Ihren Einstellungen können sich Verbände wieder öffnen, wenn keine Operation durchgeführt wird.<br/><br/>%2%3Einfache Bandage:%4<br/>%11<t color='#D9D900'>Durchschnittlich</t> In allen Kategorien<br/>%2%3Mullbinde:%4<br/>%11<t color='#D9D900'>Durchschnittliche</t> Behandlung<br/>%11<t color='#E60000' >Höhere</t> Wiedereröffnungswahrscheinlichkeit<br/>%11<t color='#00CC00'>Längere</t> Wiedereröffnungsverzögerung<br/>%2%3Elastischer Verband:%4<br/>%11<t color='#00CC00'>Längere</t> Behandlung<br/>%11<t color='#E60000'>Höhere</t> Chance auf Wiedereröffnung<br/>%11<t color='#E60000'> Kürzere</t> Wiedereröffnungsverzögerung<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Kürzere</t> Behandlung<br/>%11<t color=' #00CC00'>Geringere</t> Wiedereröffnungswahrscheinlichkeit<br/>%11<t color='#00CC00'>Längere</t> Wiedereröffnungsverzögerung<br/><br/>%3Verwende:%4<br/> %2Verwenden Sie [%3%13%4] oder [%3%14%4] und wähle ein verletztes Körperteil aus.<br/>%2Verbinde ein Körperteil, indem der gewünschte %3Bandagen%4-Typ ausgewählt wurde. + %3Bende%4 fermano emorragie e chiudono ferite. A seconda delle tue impostazioni, ferite bendate potrebbero riaprirsi se non suturate.<br/><br/>%2%3Bendaggio Basico:%4<br/>%11<t color='#D9D900'>Media</t> In tutte le categorie<br/>%2%3Bendaggio Compressivo:%4<br/>%11<t color='#D9D900'>Media</t> Trattamenti<br/>%11<t color='#E60000'>Alta</t> Probabilità di riapertura<br/>%11<t color='#00CC00'>Lungo</t> Tempo di riapertura<br/>%2%3Bendaggio Elastico:%4<br/>%11<t color='#00CC00'>Alto</t> Trattamento<br/>%11<t color='#E60000'>Alto</t> Probabilità di riapertura<br/>%11<t color='#E60000'>Breve</t> Tempo di riapertura<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Basso</t> Trattamento<br/>%11<t color='#00CC00'>Basso</t> Probabilità di riapertura<br/>%11<t color='#00CC00'>Lungo</t> Tempo di riapertura<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] seleziona una parte del corpo ferita.<br/>%2Benda la parte del corpo ferita selezionando la %3Benda%4 desiderato. + %3包帯%4は傷口をとじて出血を止めます。設定によっては、手術を行わないと包帯が解けて傷が再開放し出血が再開する場合があります。<br/><br/>%2%3緊急圧迫包帯:%4<br/>%11<t color='#D9D900'>平均的な</t> 全体性能を持っています<br/>%2%3弾性包帯:%4<br/>%11<t color='#D9D900'>平均的な</t> 治療効果<br/>%11<t color='#E60000'>高い</t> 再解放の可能性<br/>%11<t color='#00CC00'>長い</t> 再解放の再計算間隔<br/>%2%3伸縮包帯:%4<br/>%11<t color='#00CC00'>高い</t> 治療効果<br/>%11<t color='#E60000'>高い</t> 再解放の可能性<br/>%11<t color='#E60000'>短い</t> 再解放の再計算間隔<br/>%2%クイッククロット:%4<br/>%11<t color='#E60000'>低い</t> 治療効果<br/>%11<t color='#00CC00'>低い</t> 再解放の可能性<br/>%11<t color='#00CC00'>長い</t> 再解放の再計算間隔<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って身体の負傷個所を選択します。<br/>%2希望の%3包帯%4の種類を選択して部位に包帯を巻きます。 + Las %3Vendas%4 paran el sangrado y cierran las heridas. Dependiendo de las opciones configuradas, las heridas pueden reabrirse si no se realiza cirugía.<br/><br/>%2%3Vendaje de campaña:%4<br/>%11<t color='#D9D900'>Medio</t> en todas las categorias<br/>%2%3Vendaje compresivo:%4<br/>%11<t color='#D9D900'>Medio</t> Tratamiento<br/>%11<t color='#E60000'>Alto</t> Probabilidad de Reapertura<br/>%11<t color='#00CC00'>Larga</t> Retardo en reapertura<br/>%2%3Vendaje elástico:%4<br/>%11<t color='#00CC00'>Alto</t> Tratamiento<br/>%11<t color='#E60000'>Alto</t> Probabilidad de reapertura<br/>%11<t color='#E60000'>Corto</t> Retardo en reapertura<br/>%2%3Quickclot:%4<br/>%11<t color='#E60000'>Bajo</t> Tratamiento<br/>%11<t color='#00CC00'>Bajo</t> Probabilidad de Reapertura<br/>%11<t color='#00CC00'>Larga</t> Retardo en reapertura<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y selecciona una parte del cuerpo herida.<br/>%2Venda la parte del cuerpo seleccionada eligiendo el tipo de %3Venda%4. IV Fluids Płyny IV IV 수액 + Fluidos IV IV-Flüssigkeiten + Fluidi EV + IV 輸液 + IV Fluides + Fluidos IV Restore Blood Volume Przywracają Krew 혈액량을 회복합니다 + Restaurar o volume de sangue Blutvolumen wiederherstellen + Ristorano Volume di Sangue + 血液量を回復する + Внутривенные жидкости + Restaurer le volume sanguin + Reestablece el volumen de sangre %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. %3Płyny IV%4 przywracają poziom krwi. Krew, Osocze, i Sól Fizjologiczna są takie same pod względem funkcjonalności.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz kończynę.<br/>%2Przywróć poziom krwi przez podanie wybrego %3Płynu IV%4. %3수액용기%4는 손실된 혈액량을 보충합니다. 혈액, 혈장 및 생리식염수는 기능적으로 동일합니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하고 부위를 선택하십시오.<br/>%2원하는 %3수액용기%4 종류를 선택하여 혈액량을 보충하십시오. + %3Fluidos IV%4 restauram o volume de sangue perdido. Sangue, Plasma e Soro fisiológico são funcionalmente equivalentes.<br/><br/>%3Uso:%4<br/>%Utilize [%3%13%4] ou [%3%14%4] e selecione um apêndice.<br/>%2Restaure o volume de sangue selecionando o tipo desejado de %3Fluido IV%4. %3IV-Flüssigkeiten%4 stellen das verlorene Blutvolumen wieder her. Blut, Plasma und Kochsalzlösung sind funktionell gleich.<br/><br/>%3Verwende:%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus..<br/>%2Stelle das Blutvolumen wieder her, indem der gewünschte %3IV Flüssigkeitstyp%4 ausgewählt wird. + %3Fluidi EV%4 ristorano volume di sangue perso. Sangue, Plasma, e Salina sono funzionalmente identiche.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto.<br/>%2Ristora il volume di sangue selezionando il tipo di %3Fluido EV%4 desiderato. + %3IV 輸液%4は失われた血液を回復します。血液、血漿、生理食塩水は機能的には同じです。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2希望の%3IV 輸液%4の種類を選択して、血液量を復元します。 + %%3Внутривенные жидкости%4восстанавливают потерянный объем крови. Кровь, плазма и физраствор функционально идентичны.<br/><br/>%3 Использование:%4<br/>%2 Используйте [%3%13%4] или [%3%14%4] и выберите добавку.<br/>%2 Восстановите объем крови выбрав желаемый %4тип %3жидкости + Los %3Fluidos IV%4 restauran el volumen de sangre. Sangre, Plasma, y Salino funcionan de manera similar.<br/><br/>%3Uso:%4<br/>%2Uso [%3%13%4] o [%3%14%4] y seleccionar una extremidad.<br/>%2Restaura el volumen de sangre seleccionando el tipo de %3Fluido IV%4 elegido. Increase Heart Rate | Wake Up Faster Zwiększ Tętno | Obudź się Szybciej 심박수 상승 | 더 빨리 일어남 + Aumentar a frequência cardíaca | Acordar mais rápido Herzfrequenz erhöhen | Wache schneller auf + Aumenta ritmo cardiaco | Accelera rinvenimento + 心拍数を上げる | はやく起こす + Увеличьте частоту сердечных сокращений | просыпайтесь быстрее + Augmentation de la fréquence cardiaque - Réveil plus rapide + Incrementa el ritmo cardíaco | Despierta más rápido %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. %3Adrenalina%4 zwiększa tętno pacjenta, zmniejszając czas pomiędzy sprawdzeniami przytomności (efektywnie redukując czas potrzebny do przebudzenia się pacjenta).<br/><br/>%3Użycie%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz kończynę.<br/>%2Wstrzyknij %3Adrenalinę%4. - %3에피네프린%4는 환자의 맥박을 증가시킬 뿐만 아니라 의식 검사 사이의 시간을 감소시킬 수 있습니다(환자가 깨어나는 데 필요한 시간을 효과적으로 단축).<br>%3t사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 선택하고 부위를 선택하십시오.<br/>%2%3에피네프린%4을 주사하십시오. + %3에피네프린%4는 환자의 맥박을 증가시킬 뿐만 아니라 의식 검사 사이의 시간을 감소시킬 수 있습니다(환자가 깨어나는 데 필요한 시간을 효과적으로 단축).<br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 선택하고 부위를 선택하십시오.<br/>%2%3에피네프린%4을 주사하십시오. + %Epinefrina%4 aumenta o pulso do paciente, bem como potencialmente diminui o tempo entre os exames de consciência (reduzindo efetivamente o tempo necessário para que o paciente acorde).<br/><br/>%3Uso%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione um apêndice.<br/>%2Injete %3Epinefrina%4. %3Epinephrine%4 erhöht den Puls eines Patienten und verkürzt möglicherweise die Zeit zwischen Bewusstseinskontrollen (wodurch die Zeit, die der Patient zum Aufwachen benötigt, effektiv verkürzt wird).<br/><br/>%3Verwendung%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus.<br/>%2Injiziere %3Epinephrine%4. + %3Epinefrina%4 aumenta il ritmo cardiaco di un paziente e riduce potenzialmente gli intervalli tra verifiche di coscienza (effettivamente riducendo il tempo necessario che questo paziente si svegli).<br/><br/>%3Utilizzo%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto.<br/>%2Inietta %3Epinefrina%4. + %3アドレナリン%4は、患者の脈拍を増加させるだけでなく、意識チェックの間隔を短縮する可能性があります。 (患者が目覚めるまでに必要な時間を効果的に短縮します)<br/><br/>%3使用方法%4<br/>%2[%3%13%4] または [%3%14%4] を使って四肢を選択します。<br/>%2%3アドレナリン%4を注射します。 + La %3Epinefrina%4 aumenta el pulso del paciente así como potencialmente disminuye el tiempo entre las comprobaciones sobre consciencia (reduciendo de manera efectiva el tiempo de despertar del paciente).<br/><br/>%3Uso%4<br/>%2Usa [%3%13%4] o [%3%14%4] y selecciona una extremidad.<br/>%2Inyecta %3Epinefrina%4. Restore Like New Jak Nowo Narodzony 신체 완치 + Restaurar como novo Wie neu wiederherstellen + Cura completa + 生まれたてのように回復する + Лечение тела + Remettre comme neuf + Restaurar como nuevo 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. %3Apteczka Osobista%4 jest przedmiotem pozwalającym na pełne uleczenie gracza. Niezależnie od %3Ustawień ACE%4, wymagane jest, aby pacjent był w%3Stanie Stabilnym%4 przed jej użyciem.<br/><br/>%3Stan Stabilny%4 występuje gdy:<br/>%2Jednostka jest %3Żywa%4.<br/>%2Jednostka jest %3Przytomna%4.<br/>%2Jednostka nie%3Krwawu%4.<br/>%2Tętno>= 40. <br/>%2Ciśnienie Skurczowe >= 60.<br/>%2Ciśnienie Rozkurczowe >= 50.<br/><br/>%3Użycie:%4<br/>%2Udaj się do właściwej lokacji żależnej od %3Ustawień ACE%4.<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz %3Zaawansowane Zabiegi%4.<br/>%2Wybierz %3Użyj Apteczki Osobistej%4. - %3개인응급키트%4는 병사를 완치시킬 수 있는 아이템입니다. %3ACE 설정%4과 무관하게 사용 전에 환자가 %3안정된 상태%4로 있어야 합니다.<br/><br/>%3안정된 상태%4는 다음 조건이 필요합니다:<br/>%2유닛이 %3살아있어야%4 합니다.<br/>%2유닛은 %3의식이 있어야%4 합니다.<br/>%2유닛은 %3출혈이 일어나지 않은 상태%4여야 합니다.<br/>%2심박수가 40 이상이어야 합니다.<br/>%2수축 혈압이 60 이상이어야 합니다.<br/>이완 혈압이 50 이상이어야 합니다.<br/><br/>%3사용 방법:%4<br/>%2%3ACE 설정%4에 따라 적절한 위치로 이동하십시오.<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하여 %3고급 치료%4를 선택하십시오.<br/>%2%3개인응급키트 사용%4을 선택하십시오. + %3개인응급키트%4는 병사를 완치시킬 수 있는 아이템입니다. %3ACE 설정%4과 무관하게 사용 전에 환자가 %3안정된 상태%4로 있어야 합니다.<br/><br/>%3안정된 상태%4는 다음 조건이 필요합니다:<br/>%2유닛이 %3살아있어야%4 합니다.<br/>%2유닛은 %3의식이 있어야%4 합니다.<br/>%2유닛은 %3출혈이 일어나지 않은 상태%4여야 합니다.<br/>%2심박수가 40 이상이어야 합니다.<br/>%2수축 혈압이 60 이상이어야 합니다.<br/>%2이완 혈압이 50 이상이어야 합니다.<br/><br/>%3사용 방법:%4<br/>%2%3ACE 설정%4에 따라 적절한 위치로 이동하십시오.<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하여 %3고급 치료%4를 선택하십시오.<br/>%2%3개인응급키트 사용%4을 선택하십시오. + O %3Kit De Primeiros Socorros Pessoal%4 é um item que permite a cura completa de um combatente. Independente das %3Configurações do ACE%4, é necessário que o paciente esteja em %3Condições Estáveis%4 antes do uso.<br/><br/>%3Condições estáveis%4 qualificam-se como:<br/>%2Unidade está %3Viva%4.<br/>%2Unidade está %3Consciente%4.<br/>%2Unidade não está %3Sangrando%4.<br/>%2Frequência Cardíaca >= 40.<br/>%2PA Sistólica >= 60.<br/>%2PA Diastólica >= 50.<br/><br/>%3Uso:%4<br/>%2Mover-se a uma localização apropriada, a depender das %3Configurações do ACE%4.<br/>%2Utilizar [%3%13%4] ou [%3%14%4] e selecionar %3Tratamentos Avançados%4<br/>%2Selecionar %3Usar o kit de primeiros socorros%4. Das %3Persönliche Erste Hilfe Kit%4 ist ein Gegenstand, der es einem Soldaten ermöglicht, vollständig geheilt zu werden. Unabhängig von den %3ACE-Einstellungen%4 ist es erforderlich, dass sich der Patient vor der Verwendung in einem %3stabilen Zustand%4 befindet.<br/><br/>%3Stabiler Zustand%4 gilt wenn:<br/>%2Einheit ist %3am Leben%4 .<br/>%2Einheit ist %3Bei Bewusstsein%4.<br/>%2Einheit hat keine aktive %3Blutung%4.<br/>%2Herzfrequenz >= 40.<br/>%2Systolischer Blutdruck >= 60.< br/>%2Diastolischer Blutdruck >= 50.<br/><br/>%3Verwende:%4<br/>%2Bewege den Patienten je nach %3ACE-Einstellungen%4 an den entsprechenden Ort.<br/>%2Verwende [%3% 13%4] oder [%3%14%4] und wähle %3Erweiterte Behandlungen%4<br/>%2Wähle %3Persönliche Erste Hilfe Kit verwenden%4. + Il %3Kit di Pronto Soccorso%4 è un oggetto che permette di curare completamente un soldato, indipendentemente da %3impostazioni ACE%4, richiede che il paziente sia in %3condizione stabile%4 prima dell'utilizzo.<br/><br/>%3Condizione stabile%4 significa:<br/>%2Paziente è %3Vivo%4.<br/>%2Paziente è %3Conscio%4.<br/>%2Paziente non sta %3Sanguinando%4.<br/>%2Ritmo cardiaco >= 40.<br/>%2Sistolico BC >= 60.<br/>%2Diastolico BC >= 50.<br/><br/>%3Utilizzo:%4<br/>%2Sposta in luogo specifico a seconda delle %3impostazioni ACE%4.<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona %3Trattamenti avanzati%4<br/>%2Seleziona %3Usa Kit di Pronto Soccorso%4. + %3個人用治療キット%4は、兵士を完全に回復できるアイテムです。使用時には%3ACE 設定%4と関係なく、対象の患者が%3安定状態%4である必要があります。<br/><br/>%3安定状態%4とは次の状態です:<br/>%2ユニットが %3生存%4している。<br/>%2ユニットが %3覚醒状態%4である。<br/>%2ユニットが %3出血状態%4ではない。<br/>%2心拍数が40以上。<br/>%2収縮期血圧が60以上。<br/>%2拡張期血圧が50以上。<br/><br/>%3使用方法:%4<br/>%2%3ACE 設定%4で使用が許可された場所へ移動する。<br/>%2[%3%13%4] または [%3%14%4] を使って%3高度な治療%4を選択する。<br/>%2%3個人用治療キットを使う%4を選択して使用します。 + El %3Kit de Primeros Auxilios%4 es un objeto que permite al soldado ser curado totalmente. Independientemente de las %3Opciones de ACE%4, requiere que el paciente esté en %3Condición Estable%4 antes de usarse.<br/><br/>%3Condición Estable%4 significa que:<br/>%2La unidad está %3Viva%4.<br/>%2La unidad está %3Consciente%4.<br/>%2La unidad no está %3Sangrando%4.<br/>%2Ritmo Cardíaco >= 40.<br/>%2Presión Sistólica >= 60.<br/>%2Presión Diastólica >= 50.<br/><br/>%3Uso:%4<br/>%2Mover al lugar adecuado dependiendo de las%3Opciones de ACE%4.<br/>%2Uso [%3%13%4] o [%3%14%4] y seleccionar %3Tratamientos Avanzados%4<br/>%2Seleccionar %3Usar Kit de Primeros Auxilios%4. Fix Fractures Opatrywanie Złamań 골절을 치료합니다 + Consertar Fraturas Brüche richten + Risolvi frattura + 骨折を治す + Исправлять переломы + Réparation des fractures + Curar Fracturas 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. %3Szyna%4 jest używana do leczenie złamań. %3Szyna%4 jest zużywana po wykorzystaniu.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz kończynę, na którą ma być założona.<br/>%2Wybierz %3Załóż Szynę%4. %3부목%4은 골절을 치료하는 데 사용되며 %3부목%4은 사용 시 소모됩니다.<br/><br/>%3사용 방법%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하여 해당 부위를 선택하십시오.<br/>%2%3부목 대기%4를 선택하십시오. + A %3Tala%4 é utilizada para consertar fraturas. Ela é consumida quando utilizada.<br/><br/>%Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione um membro afetado.<br/>%2Selecione %3Aplicar Tala%4. Ein %3Splint%4 wird zur Fixierung von Frakturen verwendet. Der %3Splint%4 wird bei Verwendung verbraucht.<br/><br/>%3Verwendung:%4<br/>%2Verwende [%3%13%4] oder [%3%14%4] und wählen ein Körperteil aus.<br/>%2Wähle %3Schiene verwenden%4. + Una %3Gessatura%4 è usata per risolvere fratture. La %3Gessatura%4 è consumata quando usata.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto afflitto.<br/>%2Seleziona %3Applica Gessatura%4. + %3添え木%4は骨折の治療に使います。%3添え木%4は使用時に消費します。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って使用したい四肢を選択します。<br/>%2%3添え木を当てる%4を選択して使用します。 + La %3Férula%4 se utiliza para curar fracturas. La %3Férula%4 se consume cuando es usada.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar la extremidad adecuada.<br/>%2Seleccionar %3Aaplicar Férula%4. Prevent Wounds From Reopening Zapobiegaj Ponownemu Otwieraniu się Ran 상처가 재발하지 않도록 방지합니다 + Prevenir Reabertura de Feridas + Impedisce la riapertura di ferite + 傷口が開くのを防ぐ + Предотвратить повторное открытие ран + Empêcher la réouverture des plaies + Verhindert, dass sich Wunden wieder öffnen + Prevenir la reapertura de heridas 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. %3Zestaw do Szycia%4 jest używany do zapobiegania otwieraniu się ran po ich zabandażowaniu. W zależności od ustawień może także je leczyć.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz %3Zaawansowane Zabiegi%4.<br/>%2Wybierz %3Użyj Zestawu do Szycia%4. %3봉합 키트%4는 붕대를 감은 후 상처가 다시 열리는 것을 방지하기 위해 사용됩니다. 설정에 따라 외상을 치료할 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하여 %3고급 치료%4를 선택하십시오.<br/>%2%3봉합 키트%4를 선택하십시오. + O %3Kit Cirúrgico%4 é utilizado para prevenir a reabertura de feridas após a aplicação de bandagens. A depender das configurações, ele também pode remover traumas e pode requerir %3Suturas%4 adicionais para fechar feridas. Suturas são consumíveis, tal como as bandagens, e não são substituem o Kit Cirúrgico.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione %3Tratamento Avançado%4.<br/>%2Selecione %3Usar Kit Cirúrgico%4. + Un %3Kit Chirurgico%4 è usato per impedire che ferite bendate si riaprano. A seconda delle impostazioni, può anche azzerare danni o potrebbe richiedere %3Suture%4 aggiuntive per chiudere ferite. Suture sono consumabili proprio come bende, non sono un sostituto per un Kit Chirurgico.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona %3Trattamenti Avanzati%4.<br/>%2Seleziona %3Usa Kit Chirurgico%4. + %3手術キット%4は包帯を巻いた傷口が再度開いて出血するのを防ぎます。設定によっては、負傷を取り除いたり、傷口を閉じるのに%3糸付縫合針%4を必要としたりします。糸付縫合針は消耗品で包帯のように使用され、手術キットを代替するものではありません。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って%3高度な治療%4を選択する。<br/>%2%3手術キット%4を選択して使用します。 + Ein %3Chirurgisches Kit%4 wird verwendet, um zu verhindern, dass sich Wunden nach dem Verbinden wieder öffnen. Abhängig von den Einstellungen kann es auch Traumata beseitigen und erfordert möglicherweise zusätzliche %3Nähte%4, um Wunden zu schließen. Nahtmaterial ist, ähnlich wie Bandagen, Verbrauchsmaterial und kein Ersatz für das Chirurgie-Set.<br/><br/>%3Verwendung:%4<br/>%2Verwenden Sie [%3%13%4] oder [%3% 14%4] und wählen Sie %3Erweiterte Behandlung%4.<br/>%2Wählen Sie %3Chirurgisches Kit verwenden%4. + El %3Kit Quirúrgico%4 se usa para prevenir la reapertura de heridas despues de ser vendadas. Dependiendo de las opciones, tambien puede curar traumatismos y puede requerir %3Sutura%4 adicional para cerrar las heridas. Las Suturas son consumibles, al igual que las vendas, y no son un reemplazo para el Kit Quirúgico.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar %3Tratamientos Avanzados%4.<br/>%2Seleccionar %3Usar Kit Quirúgico%4. Stop Bleeding Zatamuj Krwawienie 피를 멈추게 합니다 + Parar o Sangramento + Ferma emorragia + 出血を止める + Остановить кровотечение + Arrêter les saignements + Stoppt Blutung + Parar Sangrado 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. %3Staza%4 czasowo zatrzymuje krwawienie pozwalając na zabandażowanie ran. Może być użyta tylko na kończynach.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz kończynę.<br/>%2Wybierz %3Załóż Stazę%4. %3지혈대%4는 출혈을 일시적으로 멈춰 상처(들)에 붕대를 감을 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하여 해당 부위를 선택하십시오.<br/>%2%3지혈대 적용%4를 선택하십시오. + O %3Torniquete%4 interrompe o sangramento temporariamente, para que feridas possam ser enfaixadas. Seu uso é restrito aos membros.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%13%4] ou [%3%14%4] e selecione um membro afetado.<br/>%2Selecione %3Aplicar Torniquete%4. + Un %3Laccio Emostatico%4 ferma emorragie temporaneamente in modo da poter bendare ferite con calma. Utilizzabile su arti.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%13%4] o [%3%14%4] e seleziona un arto afflitto.<br/>%2Seleziona %3Applica Laccio Emostatico%4. + %3止血帯%4は一時的に出血を止め、その間に傷に包帯を巻くことができます。四肢にのみ使用できます。<br/><br/>%3使用方法:%4<br/>%2[%3%13%4] または [%3%14%4] を使って使用したい四肢を選択します。<br/>%2%3止血帯を巻く%4を選択して使用します。 + Ein %3Tourniquet%4 stoppt die Blutung vorübergehend, sodass eine oder mehrere Wunden verbunden werden können. Kann nur an Gliedmaßen verwendet werden.<br/><br/>%3Verwendung:%4<br/>%2Verwenden Sie [%3%13%4] oder [%3%14%4] und wählen Sie ein betroffenes Glied aus.< br/>%2Wählen Sie %3Tourniquet anwenden%4. + El %3Torniquete%4 para temporalmente el sangrado hasta que la herida sea vendada. Sólo puede ser usado en extremidades.<br/><br/>%3Uso:%4<br/>%2Usar [%3%13%4] o [%3%14%4] y seleccionar la extremidad afectada.<br/>%2Seleccionar %3Aplicar Torniquete%4. Medical Menu @@ -162,7 +290,7 @@ Zdravotnická nabídka Menù Medico Menu médical - 治療メニュー + 医療メニュー 의료 메뉴 医疗菜单 醫療選單 @@ -171,282 +299,518 @@ Treatment, Simplified Leczenie, Uproszczone - 치료, 단순화 + 치료를 단순화 + Cure, Semplificato + Tratamento, Simplificado + 治療を簡略化する + Traitement, simplifié + Tratamiento, Simplificado The %3Medical Menu%4 is a dedicated %3interface%4 to facilitate %3medical treatment%4. The %3R%4 and %3L%4 letters indicate the side of the patient's body being treated.<br/><br/>%3Usage:%4<br/>%2Use [%3%14%4] while looking at a patient to open the Medical Menu. Opening the menu without a patient allows for self-treatment.<br/>%2Alternatively, use [%3%12%4] or [%3%13%4] and select %3Medical Menu%4.<br/><br/>%3Keybinds:%4<br/>%2Use [%3W, A, S, D, X, and Z%4] to select body parts.<br/>%2Use your %3number keys%4 to select treatment categories. %3Menu Medyczne%4 jest dedykowanym %3interfejsem%4 ułatwiającym %3zabiegi medyczne%4. Litery %3P%4 i %3L%4 wskazują, która część ciała pacjenta jest opatrywana.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%14%4] podczas patrzenia na pacjenta aby otworzyć Menu Medyczne. Otwarcie menu bez patrzenia na pacjenta otwiera menu leczenia własnej postaci.<br/>%2Alternatywnie, użyj [%3%12%4] lub [%3%13%4] i wybierz %3Menu Medyczne%4.<br/><br/>%3Przypisanie Klawiszy:%4<br/>%2Użyj [%3W, A, S, D, X, i Z%4] aby wybrać części ciała.<br/>%2Użyj %3klawiszy numerycznych%4 do wybrania kategorii leczenia. - %3의료 메뉴%4는 %3의료%4를 용이하게 사용하기 위한 전용 %3인터페이스%4입니다. %3우%4 및 %3좌%4 문자는 치료 중인 환자의 신체 측면을 나타냅니다.<br/><br/>%3사용 방법:%4<br/>%2환자를 보고 [%3%13%4]를 사용하여 의료 메뉴를 여십시오. 환자 없이 메뉴를 열면 자가 치료가 됩니다.<br/>%2아니면 [%3%12%4] 또는 [%3%13%4]를 사용하고 %3의료 메뉴%4를 선택하십시오.<br/><br/>%3키 설정%4<ㅠㄱ/>%2[%3W, A, S, D, X와 ㅋ%4]를 사용하여 신체 부위를 선택하십시오.<br/>%2%3번호판 키%4를 사용하여 치료 카테고리를 선택하십시오. + %3의료 메뉴%4는 %3의료%4를 용이하게 사용하기 위한 전용 %3인터페이스%4입니다. %3우%4 및 %3좌%4 문자는 치료 중인 환자의 신체 측면을 나타냅니다.<br/><br/>%3사용 방법:%4<br/>%2환자를 보고 [%3%13%4]를 사용하여 의료 메뉴를 여십시오. 환자 없이 메뉴를 열면 자가 치료가 됩니다.<br/>%2아니면 [%3%12%4] 또는 [%3%13%4]를 사용하고 %3의료 메뉴%4를 선택하십시오.<br/><br/>%3키 설정%4<br/>%2[%3W, A, S, D, X와 Z%4]를 사용하여 신체 부위를 선택하십시오.<br/>%2%3번호판 키%4를 사용하여 치료 카테고리를 선택하십시오. + O %3Menu Médico%4 é uma %3interface%4 dedicada a facilitar o %3tratamento médico%4. As letras %3R%4 e %3L%4 indicam o lado do corpo do paciente que está recebendo o tratamento.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%14%4] enquanto olha o paciente para abrir o Menu Médico. Se não houver paciente, o menu será de auto-tratamento.<br/>%2Alternativamente, utilize [%3%12%4] ou [%3%13%4] e selecione %3Menu Médico%4.<br/><br/>%3Atalhos de teclado:%4<br/>%2Utilize [%3W, A, S, D, X, e Z%4] para selecionar partes do corpo.<br/>%2Utilize as %3teclas numéricas%4 para selecionar as categorias de tratamento. + Il %3Menù Medico%4 è un'%3interfaccia%4 dedicata a facilitare %3trattamenti medici%4. Le lettere %3Dx%4 e %3Sx%4 contrassegnano i lati del corpo del paziente che si stanno medicando.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%14%4] guardando il paziente per aprire il Menù Medico. Aprire il menù senza paziente di fronte permette l'automedicazione.<br/>%2In alternativa, usa [%3%12%4] o [%3%13%4] e seleziona %3Menù Medico%4.<br/><br/>%3Comandi:%4<br/>%2Usa [%3W, A, S, D, X, and Z%4] per selezionare parti del corpo.<br/>%2Usa %3tasti numerici%4 per selezionare categorie di cure. + %3医療メニュー%4は%3治療%4をしやすくするための専用%3インタフェース%4です。%3右%4と%3左%4の文字は治療を受ける患者の向きを表しています。<br/><br/>%3使用方法:%4<br/>%2[%3%14%4] を患者に視点を合わせながら押すことで患者の医療メニューを開けます。視点を合わせないで押すと、自分の医療メニューを開くことが出来ます。<br/>%2もしくは [%3%12%4] または [%3%13%4] を使って%3医療メニュー%4を選択します。<br/><br/>%3キーバインド:%4<br/>%2[%3W, A, S, D, X, と Zキー%4] を使って身体の部位を選択できます。<br/>%2%3数字キー%4を使って治療項目を選択できます。 + El %3Menú Médico%4 es una %3interfaz%4 dedicada para facilitar el %3tratamiento médico%4. Las letras %3R%4 and %3L%4 indican el lado del paciente siendo tratado.<br/><br/>%3Uso:%4<br/>%2Usar [%3%14%4] mientras se mira al paciente para abrir el Menú Médico. Abrir el menú sin mirar a un paciente permite el tratamiento a uno mismo. <br/>%2Alternativamente, usar [%3%12%4] o [%3%13%4] y seleccionar %3Menú Médico%4.<br/><br/>%3Teclas asociadas:%4<br/>%2Usar [%3W, A, S, D, X, and Z%4] para seleccionar las partes del cuerpo.<br/>%2Usar las %3teclas numéricas%4 para seleccionar las categorías de tratamiento. Portable, Precise, Rugged Przenośny, Precyzyjny, Wytrzymały 휴대성 있고, 정밀하며, 견고합니다 + Portátil, Preciso e Robusto + Leggero, Preciso, Robusto + 高機動、高精度、高耐久 + Portable, précis, robuste + Portable, Preciso, Robusto The %3Horus ATragMX%4 considers atmospheric conditions, gun data, ammunition, range, speed, and muzzle velocity to calculate precise aiming solutions with %3Come-Up%4 results - and even accounts for %3Coriolis%4 and %3Spin Drift%4 effects. %3ATragMX%4, loaded on a handheld computer made by %3TDS Recon%4, is easy to use and lightning fast. The %3Recon%4 meets the rigorous %3MIL-STD-810F%4 military standard for drops, vibration, humidity, altitude and extreme temperatures.<br/><br/>%3Usage:%4<br/>Please visit the wiki page for more information. %3Horus ATragMX%4 uwzględnia warunki atmosferyczne, dane broni, amunicję, zasięg, prędkość wylotową do wyliczenia precyzyjnych nastaw - ponadto uwzględnia %3Efekt Coriolisa%4 oraz %3Efekt Spinowy%4. %3ATragMX%4, załadowany na komputer przenośny wyprodukowany przez %3TDS Recon%4, jest łatwy i prosty w użyciu. %3Recon%4 spełnia rygorystyczne wymagania %3MIL-STD-810F%4 pod względem odporności na upadek, wibracje, wilgotność, wyskość oraz ekstremalne temperatury.<br/><br/>%3Użycie:%4<br/>Wejdź na wiki po więcej informacji. %3호러스 ATragMX%4는 대기 상태, 총기 데이터, 탄약, 사거리, 탄속 그리고 총구 속도를 고려하여 %3나타나는 결과%4로 정확한 해결책을 계산하고 %3코리올리 효과%4와 %3스핀 드리프트 효과%4도 설명합니다. %3TDS Recon%4 사에서 제작한 휴대용 컴퓨터에 탑재된 %3ATragMX%4는 사용하기 쉽고 매우 빠릅니다. %3Recon%4 사는 낙하, 진동, 습도, 고도 및 극한 온도에 대해 엄격한 %3%4MIL-STD-810F%4 군사 표준을 충족합니다.<br/><br/>%3사용 방법:%4<br/>자세한 내용은 위키 페이지를 참조하십시오. + O %3Horus ATragMX%4 considera condições atmosféricas, dados de armas, munição, alcance, e velocidade do projétil - e até os efeitos Coriolis e Spin - para calcular as configurações necessárias da mira. O %3ATragMX%4, carregado em um computador portátil feito pela %3TDS Recon%4, é rápido e fácil de usar. O %3Recon%4 satisfaz os rigorosos padrões militares %3MIL-STD-810F%4 para quedas, vibrações, umidade, altitude e temperaturas extremas.<br/><br/>%3Uso:%4<br/>Por favor, visite a wiki para mais informações. + L'%3Horus ATragMX%4 tiene conto di condizioni atmosferiche, caratteristiche del fucile, munizioni, portata e velocità alla volata per calcolare precise impostazioni di mira con risultati %3Come-Up%4 - considerando anche effetti %3Coriolis%4 e %3Magnus%4. L'%3ATragMX%4, caricato su un computer portabile %3TDS Recon%4, è facile da usare e molto rapido nei calcoli. Il %3Recon%4 soddisfa i rigorosi standard militari %3MIL-STD-810F%4 per cadute, vibrazioni, umidità, altitudine e temperature estreme.<br/><br/>%3Utilizzo:%4<br/>Visitate la pagina wiki per ulteriori informazioni. + %3ホルス ATragMX%4は、大気条件、銃のデータ、弾薬、射程、速度、および初速を考慮した%3最適な結果が得られる%4正確な照準のための計算とその解法を提供します。さらに、%3コリオリ効果%4および%3スピン ドリフト効果%4も考慮します。%3ATragMX%4は%3TDS Recon製%4の携帯コンピュータに読み込まれており、使いやすく、超高速です。%3Recon%4はは、落下、振動、湿度、高度、極端な温度に関する厳格な%3MIL-STD-810F%4軍事規格を満たしています。<br/><br/>%3使用方法:%4<br/>詳細については、Wiki ページを参照してください。 + El %3Horus ATragMX%4 tiene en cuenta las condiciones atmosféricas, datos del arma, munición, distancia, velocidad y velocidad en boca para calcular con precisión soluciones de tiro precisas con %3Resultados%4 - e incluso tiene en cuenta los efectos %3Coriolis%4 y %3Movimiento Giroscópico%4. %3ATragMX%4, cargado en un ordenador portátil fabricado por %3TDS Recon%4, es facil de usar y muy rápido. El %3Recon%4 cumple con los rigurosos estándares militares %3MIL-STD-810F%4 en cuanto a caidas, vibraciones, humedad, altitud y temperaturas extremas.<br/><br/>%3Uso:%4<br/>Por favor, visita la página de la Wiki para más información. Bring Out Your Dead Przyprowadź Swoich Zmarłych 죽은 사람을 끌어냅니다 + Retorne os Abatidos + Recupera i tuoi morti + 死者を連れ出す + Récupérez vos morts + Trae de vuelta a los muertos - %3Body Bags%4 are used to transport dead bodies. They can be dragged and loaded into vehicles.<br/><br/>%3Usage:%4<br/>%2Approach a dead body.<br/>%2Use [%3%13%4] or [%3%14%4] and select %3Place Body In Bodybag%4. - %3Worki na Zwłoki%4 są używane do transportu ciał. Worki mogą być przeciągane i ładowanie do pojazdów.<br/><br/>%3Użycie:%4<br/>%2Podejdź do martwego ciała.<br/>%2Użyj [%3%13%4] lub [%3%14%4] i wybierz %3Umieść Ciało w Worku na Zwłoki%4. - %3시체 운반용 부대%4는 시체를 운반하는 데 사용되며, 차량으로 끌고 가서 적재할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2시체에 접근하십시오.<br/>%2[%3%13%4] 또는 [%3%14%4]를 사용하여 %3시체 운반용 부대에 담기%4를 선택하십시오. + %3Body Bags%4 are used to transport dead bodies. They can be dragged and loaded into vehicles.<br/><br/>%3Usage:%4<br/>%2Approach a dead body.<br/>%2Use [%3%13%4] or [%3%15%4] and select %3Place Body In Bodybag%4. + %3Worki na Zwłoki%4 są używane do transportu ciał. Worki mogą być przeciągane i ładowanie do pojazdów.<br/><br/>%3Użycie:%4<br/>%2Podejdź do martwego ciała.<br/>%2Użyj [%3%13%4] lub [%3%15%4] i wybierz %3Umieść Ciało w Worku na Zwłoki%4. + %3시체 운반용 부대%4는 시체를 운반하는 데 사용되며, 차량으로 끌고 가서 적재할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2시체에 접근하십시오.<br/>%2[%3%13%4] 또는 [%3%15%4]를 사용하여 %3시체 운반용 부대에 담기%4를 선택하십시오. + OS %3Sacos de Cadáver%4 são utilizados para transportar cadáveres. Eles podem ser arrastados e embarcados em veículos.<br/><br/>%3Uso:%4<br/>%2Aproxime-se de um cadáver.<br/>%2Utilize [%3%13%4] ou [%3%15%4] e selecione %3Colocar cadáver dentro do saco%4. + %3Sacche per cadaveri%4 sono usate per trasportare i morti. Possono essere trascinate e caricate su veicoli.<br/><br/>%3Utilizzo:%4<br/>%2Avvicinati ad un morto.<br/>%2Usa [%3%13%4] o [%3%15%4] e seleziona %3Metti il corpo nella sacca per cadaveri%4. + %3遺体袋%4は、遺体の輸送に使用されます。引きずって車両に積み込むことができます。<br/><br/>%3使用方法:%4<br/>%2遺体に近寄る。<br/>%2[%3%13%4] または [%3%15%4] を使って%3遺体袋に入れる%4を選択して使用します。 + Las %3Bolsas para Cadáveres%4 se usan para transportar cadáveres. Pueden ser arrastradas y cargadas en vehículos. <br/><br/>%3Uso:%4<br/>%2Acercarse a un cadáver.<br/>%2Usar [%3%13%4] o [%3%15%4] y seleccionar %3Colocar cuerpo en la Bolsa para Cadáveres%4. Take Prisoners Weź Więźniów 포로를 데려갑니다 + Faça Prisioneiros + Prendi prigionieri + 捕虜の捕り方 + Faire des prisonniers + Tomar prisioneros %3Cable Ties%4 enable a soldier to capture and detain another soldier. Once apprehended, the captor gains the ability to inspect the prisoner's belongings, set them free, or accompany them to an alternate area. Transporting escorted prisoners is also possible, including loading them into vehicles if needed. Depending on your settings, units may need to surrender before being taken captive.<br/><br/>%3Usage:%4<br/>%2Approach the unit and use the [%3%13%4].<br/>%2The interaction is located around the hands in the form of a handcuffs icon.<br/>%2Repeat to release. %3Opaski Zaciskowe%4 umożliwiają żołnierzowi pojmanie i zatrzymanie innego żołnierza, a po zatrzymaniu pozwalają na sprawdzenia ekwipunku więźnia, uwolnienia go lub przeniesienia w inne miejsce, a także załadowania go do pojazdu, jeśli zajdzie taka potrzeba. W zależności od ustawień, jednostka może wymagać poddania się przed wzięciem do niewoli.<br/><br/>%3Użycie:%4<br/>%2Podejdź do jednostki i użyj [%3%13%4].<br/>%2Interakcja jest zlokalizowana na rękach pod postacią ikony kajdanek.<br/>%2Użyj ponownie aby uwolnić. - %3게이블 타이%4를 사용하면 병사가 다른 병사를 포로로 잡고 구금할 수 있습니다. 체포되면 포로는 포로의 소지품을 검사하여 석방하거나 대체 지역으로 동행시킬 수 있습니다. 필요하면 차량에 싣는 것을 포함하여 죄수를 호송할 수도 있습니다. 설정에 따라 유닛은 포로가 되기 전에 항복해야 할 수도 있습니다.<br/><br/>%3사용 방법:%4%2유닛에 접근하여 [%3%13%4]를 사용하십시오.<br/>%2상호작용은 수갑 아이콘의 형태로 손 부분에 위치합니다.<br/>%2해제 하려면 같은 행동을 반복하십시오. + %3케이블 타이%4를 사용하면 병사가 다른 병사를 포로로 잡고 구금할 수 있습니다. 체포되면 포로는 포로의 소지품을 검사하여 석방하거나 대체 지역으로 동행시킬 수 있습니다. 필요하면 차량에 싣는 것을 포함하여 죄수를 호송할 수도 있습니다. 설정에 따라 유닛은 포로가 되기 전에 항복해야 할 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2유닛에 접근하여 [%3%13%4]를 사용하십시오.<br/>%2상호작용은 수갑 아이콘의 형태로 손 부분에 위치합니다.<br/>%2해제 하려면 같은 행동을 반복하십시오. + As %3Algema Plásticas%4 permitem a captura e detenção de soldados. Quando apreendidos, o captor se torna capaz de inspecionar os pertences do prisioneiro, liberá-los, ou acompanhá-los a outro local. Transportes mais longos também são possíveis, podendo colocá-los em veículos, se necessário. A depender das configurações, pode ser necessário que as unidades estejam rendidas antes de serem detidas.<br/><br/>%3Uso:%4<br/>%2Aproxime-se da unidade e use [%3%13%4].<br/>%2A interação encontra-se próxima às mãos simbolizada por uma algema.<br/>%2Faça o mesmo para liberar. + %3Fascette%4 permettono a soldati di catturare e ammanettare altri soldati. Una volta catturati è possibile ispezionare il loro inventario, liberarli o scortarli altrove. È inoltre possibile caricarli su veicoli se necessario. A seconda delle impostazioni, potrebbe essere necessaria la resa di unità prima di poterle ammanettare.<br/><br/>%3Uso:%4<br/>%2Avvicinati all'unità e usa [%3%13%4].<br/>%2L'interazione è localizzata intorno alle mani con l'icona di manette.<br/>%2Ripeti per liberare. + %3ケーブル タイ%4は兵士が他の兵士を拘束できるようにします。一度拘束すれば、拘束者は捕虜の所持品を検査したり、釈放したり、別の場所に移送することができるようになります。必要に応じて車両に積み込むなどして捕虜の輸送や護送も可能です。設定によっては、ユニットは捕虜になる前に降伏する必要がある場合があります。<br/><br/>%3使用方法:%4<br/>%2対象に近づいて [%3%13%4] を使います。<br/>%2インタラクションは、手錠アイコンの形で手のあたりに表示されます。<br/>%2同様の方法で解放できます。 + Las %3Bridas%4 permiten a un soldado capturar y detener a otro soldado. Una vez atado, el capturador tiene la habilidad de inspeccionar las pertenencias del prisionero, liberarles de nuevo o transportarles a otro área diferente. Transportar prisioneros escoltados tambien es posible, incluído montarles en vehículos si es necesario. Dependiendo de las opciones, puede requerirse que las unidades se rindan antes de ser capturados.<br/><br/>%3Uso:%4<br/>%2Acercarse a la unidad y usar el [%3%13%4].<br/>%2El punto de interacción se situa sobre las manos en forma de un icono de unas esposas.<br/>%2Repetir el paso para liberar. Phone In An Explosion Zadzwoń po Eksplozję 기폭 전화입니다 + Celular Explosivo + Cellulare per esplosivi + 電話でドカン + Explosifs téléphone portable + Teléfono explosivo The %3Cellphone%4 is functionally a %3Clacker%4. Use it to connect and detonate an explosive device. Multiple devices can be linked to the cellphone and called within the phonebook.<br/><br/>%3Usage:%4<br/>%2Place an explosive.<br/>%2Use [%3%13%4], select %3Explosives%4, and select %3Cellphone%4.<br/>%2Open the cellphone interface with [%3%12%4].<br/>%2Navigate the phone book with the arrows and select your calling number.<br/>%2Call the number to detonate. %3Telefon%4 jest funkcjonalnie %3Detonatorem%4. Użyj go, aby podłączyć i zdetonować ładunek wybuchowy. Wiele urządzeń może być połączonych z jednym telefonem komórkowym i wywoływanych za pomocą książki telefonicznej.<br/><br/>%3Użycie:%4<br/>%2Połóż ładunek wybuchowy<br/>%2Użyj [%3%13%4], wybierz %3Ładunki Wybuchowe%4, i wybierz %3Telefon%4. <br/>%2Otwórz interfejs telefonu za pomocą [%3%12%4].<br/>%2Nawiguj po książce telefonicznej za pomocą strzałek i wybierz żądany numer.<br/>%2Zadzwoń pod niego aby wywołać wybuch. - %3휴대전화%4는 기능적으로는 %3격발기%4입니다. 폭발물 장치를 연결하여 폭발물을 터뜨릴 때 사용합니다. 여러 장치를 휴대전화와 연결하여 전화번호부 내에서 호출할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2폭발물을 놓으십시오.<br/>%2[%313%4]를 사용하고, %3폭발물%4을 선택하고, %3휴대전화%4를 선택하십시오.<br/%2[%3%12%4]로 휴대전화 인터페이스를 여십시오.<br/>%2기폭시킬 전화번호를 선택하십시오. + %3휴대전화%4는 기능적으로는 %3격발기%4입니다. 폭발물 장치를 연결하여 폭발물을 터뜨릴 때 사용합니다. 여러 장치를 휴대전화와 연결하여 전화번호부 내에서 호출할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2폭발물을 놓으십시오.<br/>%2[%3%13%4]를 사용하고, %3폭발물%4을 선택하고, %3휴대전화%4를 선택하십시오.<br/%2[%3%12%4]로 휴대전화 인터페이스를 여십시오.<br/>%2기폭시킬 전화번호를 선택하십시오. + O %3Celular%4 serve como dispositivo de detonação ao explosivo. Utilize-o para conectar e detonar dispositivos explosivos. Múltiplos dispositivos podem estar conectados ao celular e aparecerão na lista telefônica.<br/><br/>%3Uso:%4<br/>%2Plante o explosivo.<br/>%2Utilize [%3%13%4], selecione %3Explosivos%4, e selecione %3Celular%4.<br/>%2Abra a interface do celular com [%3%12%4].<br/>%2Navegue pela lista telefônica utilizando as setas e selecione o número desejado.<br/>%2Ligue para o número para detonar. + Il %3Cellulare%4 è essenzialmente una %3spoletta%4. Usalo per collegare e detonare esplosivi. Molteplici esplosivi possono essere collegati ad un cellulare e detonati chiamando numeri nella rubrica.<br/><br/>%3Utilizzo:%4<br/>%2Piazza un esplosivo.<br/>%2Usa [%3%13%4], seleziona %3Esplosivi%4, seleziona %3Cellulare%4.<br/>%2Apri l'interfaccia del telefono con [%3%12%4].<br/>%2Naviga la rubrica con le freccette e seleziona il numero da chiamare.<br/>%2Chiama il numero del dispositivo da detonare. + %3携帯電話%4は%3点火装置%4として機能します。爆破装置を接続して起爆するために使用します。複数のデバイスを携帯電話に繋ぎ、電話帳から呼び出すことができます。<br/><br/>%3使用方法:%4<br/>%2爆発物を設置。<br/>%2[%3%13%4] を使い、%3爆発物%4を選択して、%3携帯電話%4を選択します。<br/>%2[%3%12%4] を使って携帯電話インタフェースを開きます。<br/>%2矢印ボタンで電話帳に移動し、発信番号を選択します。<br/>%2電話を掛けることで起爆します。 + El %3Teléfono%4 es funcionalmente un %3Detonador%4. Úsalo para conectarlo y detonar un dispositivo explosivo. Múltiples dispositivos pueden ser conectados al teléfono y llamados desde la agenda de contactos.<br/><br/>%3Uso:%4<br/>%2Colocar un explosivo.<br/>%2Usar [%3%13%4], seleccionar %3Explosivos%4, y seleccionar %3Teléfono%4.<br/>%2Abrir la interfaz del teléfono con [%3%12%4].<br/>%2Navegar por la agenda de contactos con las flechas y selecciona el número a llamar.<br/>%2Llamar al número para detonarlo. Portable Reading Lights Przenośne Lampki do Czytania 휴대용 조명입니다 + Luzes de Leitura Portáteis + Luci da Lettura Portabili + 携帯読書灯 + Lampes de lecture portables + Luces de Lectura Portátiles %3Chemlight Shields%4 give you the ability to read your map, even in dark environments. However, when using %3Chemlight Shields%4, you will have a slight glow around you.<br/><br/>%3Usage:%4<br/>%2Use [%3%12%4] and select %3Equipment%4.<br/>%2elect %3Chemlights%4 and %3Prepare Chemlight Shield (Color)%4.<br/>%2Open %3Map%4.<br/>%2Use [%3%12%4] and select %3Flashlights%4 where you will find your chemlight shield. %3Osłony na Świetliki%4 dają ci możliwość czytania mapy nawet w najciemniejszym otoczeniu. Jednak podczas korzystania z %3Świetlików%4, wokół ciebie będzie widoczna lekka poświata<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4. <br/>%2Wybierz %3Świetlik%4 i %3Przygotuj Osłonę Świetlika (Kolor)%4.<br/>%2Otwórz%3Mapę%4.<br/>%2Użyj [%3%12%4] i wybierz %3Latarki%4 gdzie znajdziesz twoją osłonę na świetlik. %3화학조명 가림막%4은 어두운 환경에서도 지도를 읽을 수 있는 기능을 제공합니다. 단, %3화학조명 가림막%4을 사용하면 주변에 약간 빛이 납니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3화학조명%4을 선택하고 %화학조명 가림막 준비%4를 선택하십시오.<br/>%2%3지도%4를 열고 [%3%12%4]를 사용하고 화학조명 가림막을 찾을 수 있는 %3손전등%4을 선택하십시오. + Os %3Protetores de Bastão de Luz%4 possibilitam a leitura de mapas em ambientes escuros. Todavia, quando utilizados, eles iluminam parcialmente os seus arredores.<br/><br/>%3Uso:%4<br/>%2Utilize [%3%12%4] e selecione %3Equipamento%4.<br/>%2Selecione %3Bastões de Luz%4 e %Preparar Protetor de Bastão de Luz (Cor)%4.<br/>%2Abrir %3Mapa%4.<br/>%2Utilize [%3%12%4] e selecione %3Lanternas%4 onde você encontrará o seu bastão de luz. + %3Scudi per Luci Chimiche%4 permettono di leggere la mappa anche in ambienti bui. Il loro utilizzo comporta però un leggero effetto di luminosità intorno alla testa del giocatore.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Eqipaggiamenti%4.<br/>%2Seleziona %3Luce Chimica%4 e %3Prepara Scudo Luce Chimica (Colore)%4.<br/>%2Apri %3Mappa%4.<br/>%2Usa [%3%12%4] e seleziona %3Torcia%4 dove troverai il tuo scudo per luce chimica. + %3ケミライト シールド%4を使用すると、暗い環境でも地図を読み取ることができます。ただし、%3ケミライト シールド%4を使用すると、周囲がわずかに光ります。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3ケミライト%4を選択し%3ケミライト シールドを使う (色)%4を選択します。<br/>%2%3マップ%4を開きます。<br/>%2[%3%12%4] を使って%3フラッシュライト%4を選択し、ケミライト シールドを選択します。 + Los %3Protectores de Luz Química%4 proveen la habilidad de poder leer mapas en entornos oscuros. No obstante, cuando se usan los, %3Protectores de Luz Química%4, tendrás un ligero brillo alrededor tuyo.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Luces químicas%4 y %3Preparar Protector de Luz Química (Color)%4.<br/>%2Abrir %3Mapa%4.<br/>%2Usar [%3%12%4] y seleccionar %3Linternas%4 donde encontrarás el protector de luz química. Remote Detonation Zdalna Detonacja 원격 격발기입니다 + Detonação Remota + Detonazione da remoto + リモコン爆弾 + Détonation à distance + Detonación Remota Use %3Clackers%4 to connect and detonate an explosive device. Multiple devices can be linked to a clacker and detonated on different channels.<br/><br/>%3Usage:%4<br/>%2Place an explosive.<br/>%2Use [%3%13%4], select %3Explosives%4, and select the %3Clacker%4 you wish to link to.<br/>%2Open the ACE interface with [%3%12%4].<br/>%2Select %3Explosives%4 and select a %3Clacker%4.<br/>%2Select the %3Explosive%4 you wish to detonate. Użyj%3Detonatora%4 do podłączenia i wysadzenia ładunku. Do jednego ładunku może być podłączonych wiele ładunków na różnych kanałach.<br/><br/>%3Użycie:%4<br/>%2Połóż ładunek wybuchowy.<br/>%2Użyj [%3%13%4], wybierz%3Mat. Wybuchowe%4, i wybierz %3Detonator%4, do którego chcesz go podłączyć.<br/>%2Otwórz menu interakcji ACE [%3%12%4].<br/>%2Wybierz %3Mat. Wybuchowe%4 i wybierz %3Detonator%4.<br/>%2Wybierz %3Ładunek%4 który chcesz wysadzić. %3격발기%4를 사용하여 폭발물을 연결하고 폭발시킬 수 있습니다. 여러 폭발물을 다른 채널에 연결하여 폭발시킬 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2폭발물을 설치합니다.<br/>%2[%3%13%4]를 사용하여 %3폭발물%4을 선택하고 연결할 %3격발기%4를 선택하십시오.<br/>%2[%3%12%4] 키로 ACE 인터페이스를 여십시오.<br/>%2%3폭발물%4을 선택하고 %3격발기%4를 선택하십시오.<br/>%2%3폭발물%4을 선택하면 폭발합니다. + Usa %3Spolette%4 per collegare e detonare dispositivi esplosivi. Molteplici dispositivi possono essere collagati a una spoletta e detonati individualmente come vari canali.<br/><br/>%3Utilizzo:%4<br/>%2Piazza esplosivo.<br/>%2Usa [%3%13%4], seleziona %3Esplosivo%4, seleziona la %3Spoletta%4 a cui intendi collegarlo.<br/>%2Apri l'interfaccia ACE con [%3%12%4].<br/>%2Seleziona %3Esplosivi%4 e scegli una %3Spoletta%4.<br/>%2Seleziona un %3Explosivo%4 da detonare. + %3点火装置%4を爆破装置に接続し使用することで起爆することが出来ます。複数の爆破装置を接続しそれぞれ違うチャンネルから起爆することもできます。<br/><br/>%3使用方法:%4<br/>%2爆発物を設置。<br/>%2[%3%13%4] を使い、%3爆発物%4を選択して、接続したい%3点火装置%4を選択します。<br/>%2ACEインタフェースを [%3%12%4] で開きます。<br/>%2%3爆発物%4を選択し、%3点火装置%4を選びます。<br/>%2起爆したい%3爆破装置%4を選択します。 + Utiliza los %3Detonadores%4 para conectar y detonar un explosivo. Múltiple dispositivos pueden ser conectados a un detonador y detonados en diferentes canales.<br/><br/>%3Uso:%4<br/>%2 Coloca un explosivo.<br/>%2Usar [%3%13%4], seleccionar %3Explosivos%4, y selecciona el %3Detonador%4 al que quieres conectarlo.<br/>%2Abre la interfaz de ACE con [%3%12%4].<br/>%2Selecciona %3Explosivos%4 y selecciona un %3Detonador%4.<br/>%2Selecciona el %3Explosivo%4 que quieres detonar. Navigate Nawigacja 내비게이션입니다 + Naviga + 測位 + Навигация + Naviguer + Navegar 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 %3DAGR%4 jest uproszczoną wersją%3MicroDAGR GPS%4. Posiada podobne funkcje, ale brakuje mu map dostępnych w %3MicroDAGR GPS%4.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3DAGR%4.<br/>%2Użyj [%3%12%4] i wybierz %3Konfiguruj%4 lub %3Przełącz%4.<br/><br/>Poniższe menu są dostępne podczas konfiguracji %3DAGR:%4<br/>%11%2Widok Danych: WIP<br/>%11%2GoTo WP: Wybierz waypoint do śledzenia.<br/>%11%2WP List: Dodaj/Edytuj/Usuń waypointy.<br/>%11%2Połącz do: Połącz %3DAGR%4 do dalmierza %3Vector 21%4.<br/>%11%2Opcje %3DAGR%4은 %3마이크로DAGR GPS%4의 단순화 버전입니다. 유사한 기능을 가지고 있지만 %3마이크로DAGR GPS%4의 지형 및 위성 이미지 기능이 없습니다.<br/><br/>%3사용 방법:%4<br/>%2%3DAGR%4를 장착하십시오.<br/>%2[%3%12%4를 사용하고 %3DAGR 설정%4 또는 %3DAGR 토글%4을 선택하십시오.<br/><br/>%3DAGR%4을 구성할 때 다음 메뉴를 사용할 수 있습니다:<br/>%11%2Data View: 제작 중<br/>%11%2GoTo WP: 추적할 웨이포인트를 선택합니다.<br/>%11%2WP List: 경유지를 추가/편집/제거합니다.<br/>%11%2Connect To: %3DAGR%4을 %3벡터 21%4 거리계에 연동시킵니다.<br/>%11%2옵션입니다 + Il %3DAGR%4 è una versione più semplice del %3GPS MicroDAGR%4. Ha funzioni simili, gli manca però la capacità di visualizzare informazioni topografiche e satellitari come il %3GPS MicroDAGR%4.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia il %3DAGR%4.<br/>%2Usa [%3%12%4] e seleziona %3Configura%4 o %3Apri%4.<br/><br/>I seguenti Menù sono disponibili durante la configurazione del tuo %3DAGR:%4<br/>%11%2Pagina Dati: WIP<br/>%11%2VaiA WP: Seleziona un waypoint da tracciare.<br/>%11%2Lista WP: Aggiungi/Modifica/Rimuovi waypoint.<br/>%11%2Collega A: Collega il %3DAGR%4 al %3Telemetro Vector 21%4.<br/>%11%2Opzioni + %3DAGR%4はシンプルなバージョンの%3MicroDAGR GPS%4です。同様の機能を備えていますが、%3MicroDAGR GPS%4のような地形および衛星画像機能はありません。<br/><br/>%3使用方法:%4<br/>%2%3DAGR%4を装備する。<br/>%2[%3%12%4] を使って%3設定%4 もしくは %3表示切替%4を選択します。<br/><br/>%3DAGR%4の設定には次のメニューを使用できます:<br/>%11%2Data View: WIP<br/>%11%2GoTo WP: 追跡するウェイポイントを選択します。<br/>%11%2WP List: ウェイポイントを追加/編集/削除します。<br/>%11%2Connect To: %3DAGR%4を%3ベクター 21 レンジファインダー%4に接続できます。<br/>%11%2Options + El %3DAGR%4 es una versión simplificada del %3MicroDAGR GPS%4. Tiene unas funcionalidades similares pero le faltan las funciones de los mapas topográficos e imágenes satelitales del %3MicroDAGR GPS%4.<br/><br/>%3Usage:%4<br/>%2Equip a %3DAGR%4.<br/>%2Usar [%3%12%4] y seleccionar %3Configurar%4 o %3Activar%4.<br/><br/>Los siguientes menús están disponibles cuando configuras el %3DAGR:%4<br/>%11%2Vista de Datos: WIP<br/>%11%2Ir a WP: Selecciona un Punto de Ruta para seguir.<br/>%11%2Lista de WP: Añadir/Editar/Suprimir puntos de ruta.<br/>%11%2Conectar A: Conectar %3DAGR%4 a %3Telémetro Vector 21%4.<br/>%11%2Opciones Explosive Revenge Wybuchowa Zemsta '폭발'적인 복수입니다 + Vendetta Esplosiva + 爆発的な復讐 + Взрывная месть + Homme mort + Venganza Explosiva 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. %3Czuwak%4 jest urządzeniem pozwalającym wysadzić %3Ładunek Wybuchowy%4 gdy żołnierz zginie.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Mat. Wybuchowe%4.<br/>%2Wybierz %3Czuwak%4 i połącz wybrany %3Ładunek Wybuchowy%4.<br/>%2W celu odłączenia powtórz czynności i wybierz odłącz. %3자폭 장치%4는 병사가 사망했을 때 병사가 %3폭발물%4을 폭발시킬 수 있는 장치입니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3폭발물%4을 선택하십시오.<br/>%2%3자폭 장치%4를 선택하고 원하는 %3폭발물%4에 연결하십시오.<br/>%2반대로 해제하고 싶다면 같은 행동을 반복하십시오. + Il %3Detonatore a rilascio%4 è un dispositivo che permette a soldati di detonare un %3Esplosivo%4 quando perdono i sensi.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Esplosivi%4.<br/>%2Seleziona %3Detonatore a rilascio%4 e collega l'%3Esplosivo%4 desiderato.<br/>%2Ripeti il processo e scollega per disarmare il detonatore. + %3自爆装置%4は、兵士の死亡時に%3爆発物%4を起爆させることができる装置です。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3爆発物%4を選択します。<br/>%2%3自爆装置%4を選択し、接続したい%3爆発物%4を選びます。<br/>%2同様の手順を逆に行うことで接続を解除できます。 + El %3Detonador de Hombre Muerto%4 es un dispositivo que permite a un soldado detonar un %3Explosivo%4 cuando el soldado muere.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Explosivos%4.<br/>%2Seleccionar %3Detonador de Hombre Muerto%4 y conectar el %3Explosivo%4.<br/> deseado%2Repetir el proceso y desconectar para revertirlo. The %3Defusal Kit%4 allows defusal of explosives.<br/><br/>%3Usage:%4<br/>%2Equip a %3Defusal Kit%4.<br/>%2Safely approach an %3Explosive%4.<br/>%2Use [%3%13%4] and select %3Defuse%4. %3Zestaw do Rozbrajania%4 pozwala rozbrajać ładunki wybuchowe.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Zestaw do Rozbrajania%4.<br/>%2Ostrożnie podejdź pod %3Ładunek Wybuchowy%4.<br/>%2Użyj [%3%13%4] i wybierz %3Rozbrój%4. %3해체 장비%4를 사용하면 폭발물을 제거할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3해체 장비%4를 장착하십시오.<br/>%2%3폭발물%4에 안전하게 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3해체%4를 선택하십시오. + The %3Kit E.O.D.%4 permette il disinnesco di esplosivi.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Kit E.O.D.%4.<br/>%2Avvicinati in modo sicuro ad un %3Esplosivo%4.<br/>%2Usa [%3%13%4] e seleziona %3Disinnesca%4. + %3解除キット%4は爆発物の無力化を行うことができます。<br/><br/>%3使用方法:%4<br/>%2%3解除キット%4を装備。<br/>%2慎重に%3爆発物%4に接近します。<br/>%2[%3%13%4] を使って%3無力化%4を選択します。 + El %3Kit de Desactivación%4 permite la desactivación de explosivos.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Kit de Desactivación%4.<br/>%2Aproxímate al %3Explosivo%4<br/> de forma segura.%2Usa [%3%13%4] y selecciona %3Desactivar%4. Defuse Explosives Rozbrajanie Ładunków 폭발물을 해체합니다 + Disinnesca Esplosivi + 爆発物の解除 + Обезвреживание взрывчатки + Désamorcer les explosifs + Desactivar Explosivos Protect Your Hearing Dbaj o Swój Słuch 청력을 보호합니다 + Proteggi il tuo Udito + 聴覚の保護 + Защитите свой слух + Protéger votre audition + Protege tus oídos %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. %3Stopery do Uszu%4 zapobiegają uszkodzeniom słuchu na skutek wybuchów i strzałów w pobliżu żołnierza. Włóż %3Stopery do Uszu%4 w celu wyciszenia otoczenia i uniknięcia %3Głuchoty Bojowej%4.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Włóż %3Stopery do Uszu%4. + %3Tappi auricolari%4 aiutano a prevenire danni all'udito da ripetuti rumori forti in prossimità del soldato. Inserisci %3Tappi auricolari%4 per ridurre il volume dell'ambiente per il soldato e impedire %3Assordamento%4.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Indossa %3Tappi Auricolari%4. %3귀마개%4는 병사 주변에서 반복되는 시끄러운 소리로 인한 청력 손상을 방지하는 데 도움이 됩니다. %3귀마개%4를 끼워서 병사가 있는 환경의 소리 크기를 낮추고 %3전투로 인한 청력손상%4을 방지하십시오.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3귀마개%4를 삽입하십시오. + %3耳栓%4は、兵士の近くで繰り返される大きな騒音による聴覚障害を防ぐのに役立ちます。%3耳栓%4を耳に挿入することで兵士の環境の音量を下げ、%3戦闘難聴%4を防ぎます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3耳栓を着ける%4ことで使用できます。 + Los %3Tapones de oídos%4 ayudan a prevenir el daño auditivo de ruidos altos repetidos cerca de un soldado. Inserta los %3Tapones de oídos%4 para reducir el volumen del entorno del soldado y prevenir la %3Sordera de Combate%4.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Insertar %3Tapones de oídos%4. Get To Cover Łap Osłonę 엄폐하십시오 + Mettiti in Copertura + 遮蔽を造り出す + Добраться до укрытия + Se mettre à couvert + Ponerse A Cubierto 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. %3Saperka%4 pozwala żołnierzowi kopać okopy w celu obrony swoich pozycji. Żołnierz musi być na glebie, aby wykopać okop.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Saperkę%4.<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Wybierz rodzaj okopu, który chcesz wykopać. - %3야전삽%4을 사용하면 병사들의 진지 방어를 위한 참호를 팔 수 있습니다. 병사가 참호를 파려면 흙 위에 있어야 합니다.<br/><br/>%3사용 방법:%4<br/>%2%3야전삽%4을 장비하십시오.<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>짓고 싶은 종류의 참호를 선택하십시오. + La %3Pala da Trincea%4 permette a soldati di scavare trincee per difendere meglio la loro posizione. Il soldato deve trovarsi su suolo scavabile per poter creare trincee.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Pala da Trincea%4.<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona il tipo di trincea che vuoi costruire. + %3야전삽%4을 사용하면 병사들의 진지 방어를 위한 참호를 팔 수 있습니다. 병사가 참호를 파려면 흙 위에 있어야 합니다.<br/><br/>%3사용 방법:%4<br/>%2%3야전삽%4을 장비하십시오.<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2짓고 싶은 종류의 참호를 선택하십시오. + %3塹壕ツール%4を使用すると、兵士は自分の陣地を守るために塹壕を掘ることができます。塹壕を掘るには、兵士は土の上にいる必要があります。<br/><br/>%3使用方法:%4<br/>%2%3塹壕ツール%4を装備します。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2構築する塹壕の種類を選択します。 + La %3Pala de Trincheras%4 permite a los soldados excavar trincheras para ayudarles a defender su posición. El soldado debe estar sobre tierra para poder excavar una trinchera.<br/><br/>%3Uso:%4<br/>%2Equipar la %3Pala de Trincheras%4.<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar el tipo de trinchera que quieres construir. Flashlights Latarki + Torce 손전등 + フラッシュライト + Фонари + Lampes de poche + Linternas Illuminate Your Map Rozświetlij Swoją Mapę + Illumina la tua Mappa 지도를 밝혀줍니다 + 地図に光あれ + Осветите свою карту + Éclairer votre carte + Ilumina Tu Mapa %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. %3Latarki%4 pozwalają czytać mapę, nawet w ciemnościach. Jednakże podczas używani %3Latarki%4, będziesz miał wokół siebie delikatną poświatę.<br/><br/>%3Użycie:%4<br/>%2W widoku mapy użyj [%3%12%4] i wybierz %3Latarki%4.<br/>%2Wybierz %3Latarkę%4, którą chcesz użyć i wybierz %3Włącz%4.<br/><br/>%3Dostępne latarki%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTE:%4<br/>Stan latarki jest trwały. - %3손전등%4은 어두운 환경에서도 지도를 읽을 수 있는 기능을 제공합니다. 단, %3손전등%4을 사용할 때 주변에 약간 빛이 납니다.<br/><br/>%3사용 방법:%4<br/>%2지도 화면에서 [%3%12%4]를 사용하고 %3손전등%4을 선택하십시오.<br/>%2사용할 %3손전등%4을 선택하고 %3켜기%4를 선택하십시오.<br/><br/>%3사용 가능한 손전등 아이템%4:<br/>% 2풀턴 MX-991<br/>%2 KSF-1<br/>%2 매그라이트 XL50<br/><br/>%3참고:%4<br/>손전등 상태는 영구적입니다. + %3Torce%4 permettono di leggere la tua mappa anche in ambienti bui. Però quando le utilizzi avrai un leggero effetto luminoso intorno a te.<br/><br/>%3Utilizzo:%4<br/>%2Sulla mappa usa [%3%12%4] e seleziona %3Torcia%4.<br/>%2Seleziona la %3Torcia%4 che vuoi usare e seleziona %3Accendi%4.<br/><br/>%3Oggetti Torcia Disponibili%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTE:%4<br/>Lo stato di una torcia è persistente. + %3손전등%4은 어두운 환경에서도 지도를 읽을 수 있는 기능을 제공합니다. 단, %3손전등%4을 사용할 때 주변에 약간 빛이 납니다.<br/><br/>%3사용 방법:%4<br/>%2지도 화면에서 [%3%12%4]를 사용하고 %3손전등%4을 선택하십시오.<br/>%2사용할 %3손전등%4을 선택하고 %3켜기%4를 선택하십시오.<br/><br/>%3사용 가능한 손전등 아이템%4:<br/>%2풀턴 MX-991<br/>%2 KSF-1<br/>%2 매그라이트 XL50<br/><br/>%3참고:%4<br/>손전등 상태는 영구적입니다. + %3フラッシュライト%4を使用すると、暗い環境でも地図を読むことができます。ただし、%3フラッシュライト%4を使用すると、周囲がわずかに光ります。<br/><br/>%3使用方法:%4<br/>%2マップ画面で [%3%12%4] を使用し、%3フラッシュライト%4を選択します。<br/>%2%3フラッシュライト%4を選択し、使用したいライトを%3点ける%4。<br/><br/>%3使用可能なフラッシュライトのアイテム%4:<br/>%2 フルトン MX-991<br/>%2 KSF-1<br/>%2 マグライト XL50<br/><br/>%3備考:%4<br/>フラッシュライトの状態は継続します。 + Las %3Linternas%4 proveen la habilidad para leer tu mapa, incluso en entornos oscuros. No obstante, cuando se usen las %3Linternas%4, aparecerá un ligero brillo alrededor tuya.<br/><br/>%3Uso:%4<br/>%2En la pantalla del mapa, utilizar [%3%12%4] y seleccionar %3Linternas%4.<br/>%2Seleccionar la %3Linterna%4 Que quieres utilizar y selecciona %3On%4.<br/><br/>%3Objetos de Linternas disponibles%4:<br/>%2 Fulton MX-991<br/>%2 KSF-1<br/>%2 Maglite XL50<br/><br/>%3NOTA:%4<br/>Los estados de las Linternas son persistentes. Observe From The Skies Obserwuj Świat z Góry + Osserva dal Cielo 하늘에서 관측합니다 + 空から戦場を見てみよう + Наблюдайте с Небес + Observer depuis le ciel + Observar Desde El 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. %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 przeznaczony jest do wystrzeliwania z granatnika. Po wystrzeleniu, wbudowany spadochron zostanie otwarty i uruchomi się kamera IR CMOS, zapewniająca obraz wideo do momentu zetknięcia się z ziemią lub zestrzelenia.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Monitor HuntIR%4 i kompatybilną amunicję.<br/>%2Wystrzel %3Pocisk HuntIR%4 najwyżej jak to tylko możliwe nad teren, który chcesz obserwować.<br/>%2Otwórz%3Monitor HuntIR%4.<br/>%2Użyj [%3%12%4], wybierz %3Ekwipunek%4.<br/>%2Wybierz %3Aktywuj Monitor HuntIR%4. + Il %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 è progettato per essere sparato da un lanciagranate. Dopo essere stato sparato verso l'alto, verrà aperto un paracadute incorporato e attivata una videocamera IR CMOS, inviando una diretta video finché toccherà terra o verrà abbattuto.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Monitor HuntIR%4 e munizioni compatibili.<br/>%2Spara un %3Colpo HuntIR%4 il più alto possibile sopra l'area che vuoi osservare.<br/>%2Apri il %3Monitor HuntIR%4.<br/>%2Usa [%3%12%4], seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Attiva Monitor HuntIR%4. %3고고도 유닛 탐색용 전술 영상화 탄약 (HuntIR)%4은 유탄발사기에서 발사될 수 있도록 설계되었습니다.공주에서 발사된 후 내장된 낙하산이 전개되고 적외선 CMOS 카메라가 작동하여 지상에 닿거나 격추될 때까지 비디오 스트림이 제공됩니다.<br/><br/>%3사용 방법:%4<br/>%2%3헌트IR 모니터%4와 호환 탄약을 장착하십시오.<br/>%2%3헌트IR 유탄%4을 발사하려는 구역에서 가능한 한 높게 발사하십시오.<br/>%2%3헌트IR 모니터%4를 여십시오.<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3헌트IR 모니터 활성화%4를 선택하십시오. + %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4はグレネードランチャーから発射されるように設計されています。空中で発射された後、内蔵のパラシュートが展開され、IR CMOS カメラが起動し、地面に着くか撃墜されるまでビデオ ストリームを提供します。<br/><br/>%3使用方法:%4<br/>%2%3HuntIR モニター%4と互換性のある弾薬を装備します。<br/>%2観測したいエリアに向けてできるだけ高く%3HuntIR 弾頭%4を発射します。<br/>%2%3HuntIR モニター%4を開きます。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3HuntIRを起動する%4からモニターを起動します。 + El %3High-Altitude Unit Navigated Tactical Imaging Round (HuntIR)%4 está diseñado para ser disparado desde un lanzagranadas. Despues de ser disparada al aire, desplegará su paracaídas integrado y activará su cámara IR CMOS integrada, proveyendo de un flujo de video hasta que toque el suelo o sea derribado.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Monitor HuntIR%4 y la munición compatible.<br/>%2Dispara la %3Munición HuntIR%4 tan alto como sea posible sobre el área que quieres observar.<br/>%2Abre el %3Monitor HuntIR%4.<br/>%2Usar [%3%12%4], seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Activar Monitor HuntIR%4. Track Your Team With Stealth Śledź Swój Zespół w Ciszy + Traccia la tua squadra con discrezione 은신하여 팀을 찾아냅니다 + 自分の部隊を追う + Следите за своей командой незаметно + Suivez votre équipe en toute discrétion + Sigue A Tu Equipo Con Sigilo 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. %3Stroboskop IR%4 jest rzucanym przedmiotem emitującym pulsujące światło podczerwone. %3Stroboskop IR%4 może być także przypięty do munduru, tworząc z niego użyteczne urządzenie do śledzenia żołnierzy z użyciem noktowizji.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Wybierz %3Przyczep%4 i wybierz %3Stroboskop IR%4. + La %3Strobo IR%4 è un lanciabile che emette un impulso intermittente di luce IR. La %3Strobo IR%4 può anche essere attaccata ad un soldato, facilitando l'identificazione di alleati con visori notturni.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Attacca%4 e scegli la %3Strobo IR%4. %3적외선 스트로브%4는 던질 수 있는 적외선 광펄스를 간헐적으로 방출하는 투척형 아이템입니다. %3적외선 스트로브%4는 병사에게도 부착 가능하기 때문에 야간투시장치로 팀원을 추적할 때 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하여 %3장비%4를 선택하십시오.<br/>%2%3아이템 부착%4을 선택하고 %3적외선 스트로브%4를 선택하십시오. + %3赤外線ストロボ%4は、赤外線光パルスを断続的に放射します。投擲可能です。%3赤外線ストロボ%4は兵士に取り付けることもできるため、暗視装置の下でチームメイトを追跡するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3アイテムを取り付ける%4を選択して%3赤外線ストロボ%4を選び使用します。 + El %3Estroboscópico IR%4 es un objeto lanzable que emite un pulso intermitente de luz IR. El %3Estroboscópico IR%4 tambien puede ser sujeto a un soldado, haciéndolo útil para el seguimiento de los compañeros utilizando gafas de visión nocturna.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Sujetar%4 y seleccionar el %3Estroboscópico IR%4. Pocket Weatherstation Przenośna Pogodynka + Stazione Meteo Tascabile 휴대용 기상 관측 장비입니다 + 携帯気象予報所 + Карманная метеостанция + Station météo de poche + Estación Climática de Bolsillo - 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. + 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. %3Kestrel 4500 Pocket Weather Tracker%4 jest przenośną stacją pogodową pozwalającą zbierać takie dane jak: <br/>%2Kurs i kierunek wiatru<br/>%2Wiatr boczny i czołowy<br/>%2Wysokość i ciśnienie barometryczne<br/>%2Temperatua mokrego termometru<br/>%2Wilgotność i punkt rosy<br/>%2Gęstość powietrza<br/>%2Temperatura i temperatura odczuwalna<br/>%2Czas i data<br/>%2Wartości minimalne, maksymalne oraz średnie<br/><br/>%3Użycie: %4<br/>%2Wyekwipuj %3Kestrela%4. <br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Wybierz %3Otwórz%4. - %3케스트렐 4500 휴대용 기상 추적 장비%4는 다음 날씨 데이터들을 수집하는 데 유용한 소형 기상 관측 장비입니다:<br/>%2바람이 오는 방향과 가는 방향<br/>%2옆바람과 맞바람<br/>%2고도 및 기압<br/>%2습구온도<br/>%2습도 및 이슬점<br/>%2밀도고도<br/>%2체감온도<br/>%2시간 및 날짜<br/>%2최소, 최대, 평균값<br/>%3사용 방법:%4<br/>%2%3케스트렐 4500NV%4를 장착하십시오.<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3열기%4를 선택하십시오. + Il %3Kestrel 4500 Indicatore Meteorologico Tascabile%4 è una mini-stazione meteo utile per ricavare le seguenti informazioni meteorologiche:<br/>%2Prua e direzione del vento<br/>%2Vento di traverso e frontale<br/>%2Altitudine and pressione barometrica<br/>%2Temperatura di bulbo umido<br/>%2Umidità e punto di rugiada<br/>%2Density altitude<br/>%2Temperatura e gelo del vento<br/>%2Data e Ora<br/>%2Valori minimi, massimi, e medi<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia %3Kestrel%4.<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Apri%4. + %3케스트렐 4500 휴대용 기상 추적 장비%4는 다음 날씨 데이터들을 수집하는 데 유용한 소형 기상 관측 장비입니다:<br/>%2바람이 오는 방향과 가는 방향<br/>%2옆바람과 맞바람<br/>%2고도 및 기압<br/>%2습구온도<br/>%2습도 및 이슬점<br/>%2밀도고도<br/>%2체감온도<br/>%2시간 및 날짜<br/>%2최소, 최대, 평균값<br/><br/>%3사용 방법:%4<br/>%2%3케스트렐 4500NV%4를 장착하십시오.<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3열기%4를 선택하십시오. + %3ケストレル 4500 携帯気象計%4は、次の気象データの収集に役立つミニ気象ステーションです:<br/>%2方位と風向<br/>%2横風と向かい風<br/>%2高度と気圧<br/>%2湿球温度<br/>%2湿度と露点<br/>%2密度高度<br/>%2ウィンドチルと温度<br/>%2日付と時刻<br/>%2最小値、最大値、平均値<br/><br/>%3使用方法:%4<br/>%2%3ケストレル%4を装備します。<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3ケストレルを開く%4で使用できます。 + La %3Estación Climática de Bolsillo Kestrel 4500%4 es una pequeña estación climática portátil para recolectar la siguiente información del tiempo:<br/>%2Dirección y Sentido del Viento<br/>%2VIento cruzado y Viento en cola<br/>%2Altitud y presión barométrica<br/>%2Temperatura húmeda<br/>%2Humedad y punto de condensación<br/>%2Densidad de altitud<br/>%2Sensación térmica y temperatura<br/>%2Hora y fecha<br/>%2Valores mínimos, máximos y medios<br/><br/>%3Uso:%4<br/>%2Equipa un %3Kestrel%4.<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Abrir%4. Triangulate Your Position Trianguluj Swoją Pozycję + Triangola la tua posizione 위치를 삼각측량합니다 + 三角測量で位置を特定 + Передавайте свое местоположение + Trianguler votre position + Triangular Tu Posición 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]. %3Narzędzia Nawigacyjne%4 są zestawem narzędzi pozwalającym mierzyć dystans i kąt. Użyteczne do wyliczania parametrów strzałów dla artylerii.<br/><br/>%3Użycie:%4<br/>%2Otwórz%3Mapę%4.<br/>%2Użyj [%3%12%4] i wybierz %3Narzędzia Nawigacyjne%4.<br/>%2 Narzędzia mogą być przeciągane za pomocą [%3LPM%4] trzymając [%3ALT%4]. + Gli %3Strumenti Cartografici%4 permettono al soldato di misurare distanze e angoli sulla mappa. Utile a terra e per calculare direzioni di tiro per artiglieria.<br/><br/>%3Utilizzo:%4<br/>%2Apri %3Mappa%4.<br/>%2Usa [%3%12%4] e seleziona %3Strumenti Cartografici%4.<br/>%2 Lo strumento può essere spostato trascinandolo con [%3Click-Sinistro%4] premendo [%3ALT%4]. %3독도용 도구%4는 병사가 거리와 각도를 측정할 수 있는 도구 세트입니다. 지상에서 유용하며 포병 사격 솔루션 계산에 유용합니다,<br/><br/>%3사용 방법:%4<br/>%2%3지도%4를 여십시오.<br/>%2[%3%12%4]를 사용하여 %3독도용 도구%4를 선택하십시오.<br/>%2도구는 [%3Alt 키%4]를 누른 상태에서 [%3마우스 왼쪽 클릭%4]으로 드래그하여 이동할 수 있습니다. + %3マップ ツール%4は、兵士が距離と角度を測定できるようにするツールのセットです。陸上や大砲の射撃工程の計算を解くのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2%3マップ%4を開きます。<br/>%2[%3%12%4] を使って%3マップ ツール%4を選択します。<br/>%2 [%3ALT%4] を押しながら [%3左クリック%4] でドラッグするとツールを移動できます。 + Les %3Outils cartographiques%4 sont un ensemble d'outils permettant au soldat de mesurer des distances et des angles. Utile pour la terre et le calcul des solutions de tir pour l'artillerie.<br/><br/>%3Utilisation:%4<br/>%2Ouvrir la%3Carte%4.<br/>%2Utiliser [%3%12%4] et sélectionner %3Outils cartographiques%4.<br/>%2 L'outil peut être déplacé en le faisant glisser avec [%3Clic gauche%4] tout en maintenant [%3ALT%4]. + Las %3Herramientas de mapa%4 son un conjunto de herramientas que permiten a un soldado medir distancias y ángulos. Util para terrenos, y para calcular soluciones de tiro para artillería.<br/><br/>%3Uso:%4<br/>%2Abrir %3Mapa%4.<br/>%2Usar [%3%12%4] y seleccionar %3Herramientas de Mapa%4.<br/>%2 La herramienta puede ser movida siendo arrastrada con [%3CLick-Izquierdo%4] mientras se pulsa [%3ALT%4]. Advanced DAGR Zaawansowany DAGR + DAGR Avanzato 고급형 DAGR입니다 + より高度なDAGR + Продвинутый DAGR + DAGR avancé + DAGR Avanzado 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. %3MicroDAGR GPS%4 jest zaawansowaną wersją %3DAGR%4. Dostarcza dane oparte o pozycję, nawigację, i czas (PNT): <br/>%2Kompas i kierunek<br/>%2Datę i godzinę zsynchronizowaną z misją<br/>%2Elewację (relatywną do poziomu morza)<br/>%2Obecną prędkość<br/>%2GPS z widokiem topograficznym i satelitarnym<br/>%2Tworzenie, nazywanie oraz usuwanie waypointów<br/>%2Identyfikację sojuszników (Wymaga ACE BLUFOR Tracker)<br/>Połączenie do dalmierza Vector-21 w celu importu danych (waypointy i współrzędne zmierzonego celu)<br/><br/>%3Użycie: %4<br/>%2Po instrukcję użycia odwiedź %3MicroDAGR%4 wiki. + Il %3GPS MicroDAGR%4 è una versione avanzata del %3DAGR%4. Esso mostra dati su posizione, navigazione e tempismo (PNT), includendo:<br/>%2Bussola e azimut<br/>%2Data e ora sincronizzate con la missione<br/>%2Elevazione (dal livello del mare)<br/>%2Velocità attuale<br/>%2GPS con visuale topografica e satellitare<br/>%2Creazione, rinomina e rimozione di waypoint<br/>%2Identificazione di alleati (Richiede Impostazioni ACE BLUFOR Tracker)<br/>Connessione al Telemetro Vector-21 per importazione di dati (creazione waypoint e indicazione di griglia su bersagli puntati)<br/><br/>%3Utilizzo:%4<br/>%2Per informazioni sull'utilizzo sei pregato di visitare la pagina wiki dedicata al %3MicroDAGR%4. %3마이크로DAGR GPS%4는 %3DAGR%4의 고급 버전입니다. 다음과 같이 위치, 내비게이션 및 타이밍(PNT) 데이터를 제공합니다:<br/>%2나침반 및 방향<br/>%2임무와 동기화된 날짜 및 시간<br/>%2고도 (해수면 기준)<br/>%2현재 속도<br/>%2지형 및 위성 시점 기능이 있는 GPS<br/>%2웨이포인트 생성, 작명 및 삭제<br/>%2아군 식별 (ACE의 GPS 피아식별기 켜기 체크 필요)<br/>%2데이터를 가져오기 위한 벡터-21 거리계에 연결(원거리 대상의 웨이포인트 생성 및 좌표 참조)<br/><br/>%3사용 방법:%4<br/>%2사용 방법을 보려면 전용 %3마이크로DAGR%4의 위키를 방문하십시오. + %3MicroDAGR GPS%4は%3DAGR%4のより高度なバージョンです。測位、航法、計時(PNT)データが提供されます。これには以下の情報を含みます:<br/>%2コンパスと方位<br/>%2ミッションに同期された日付と時間<br/>%2標高 (海面に対する相対値)<br/>%2現在の速度<br/>%2地形図と衛星ビューを備えたGPS<br/>%2ウェイポイントの作成、名前付け、および削除<br/>%2友軍の識別 (ACE ブルーフォーストラッキング設定が必要)<br/>ベクター21レンジファインダーへの接続とデータのインポート (ウェイポイントの作成と遠距離ターゲットのグリッド参照)<br/><br/>%3使用方法:%4<br/>%2使用手順については、専用の %3MicroDAGR%4 wiki を参照してください。 + El %3GPS MicroDAGR%4 es una versión avanzada del %3DAGR%4. Provee de posicionamiento, navegación y datos de temporización (PNT) que incluye:<br/>%2Brújula y dirección<br/>%2Fecha y hora sincronizada con la misión<br/>%2Elevación (relativa al nivel del mar)<br/>%2Velocidad actual<br/>%2GPS con vista topográfica y satelital<br/>%2Creación, nombrado y borrado de puntos de ruta<br/>%2Identificación de aliados (Requiere la opción de ACE BLUFOR Tracker)<br/>Conexión con el telémetro Vector-21 para importación de datos (creación de puntos de ruta y referenciado en eje de coordenada para objetivos a distancia)<br/><br/>%3Uso:%4<br/>%2Para instrucciones de uso, por favor visita la Wiki dedicada de %3MicroDAGR%4. Range Tables Tabele Strzelnicze + Tavole di Tiro 사거리표 + 射表 + Таблицы диапазонов + Tables de tir + Tablas de Distancia Get A Firing Solution Strzelaj Celnie + Per una soluzione di tiro 사격 솔루션을 제공합니다 + 撃ち方の解を得る + Получите расчёт + Obtenir une solution de tir + Obtener Una Solución de 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. %3Tabele Strzelnicze%4 pozwalają żołnierzowi oszacować dokładne rozmieszczenie strzałów na cele bezpośrednie lub pośrednie (w zależności od zasobu). %3Tabele Strzelnicze%4 wypełnią się automatycznie w zależności od wybranej broni/pojazdu.<br/><br/>%3Użycie:%4%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4<br/>.<br/>%2Wybierz żądaną%3Tabelę Strzelniczą%4. + %3Tavole di tiro%4 permettono al soldato di stimare piazzamenti accurati di colpi mediante fuoco diretto o indiretto (a seconda dell'arma). La %3Tavola di tiro%4 si modificherà in automatico a seconda dell'arma/veicolo del soldato.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] and seleziona %3Equipaggiamento%4.<br/>%2Seleziona la portata desiderata sulla %3Tavola di tiro%4. %3사거리표%4를 사용하면 병사가 직접 또는 간접 표적(자산에 따라 다름)에 대한 정확한 사격 배치를 추정할 수 있습니다. %3사거리표%4는 선택한 병사의 무기/차량에 따라 자동으로 작성됩니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2원하는 %3사거리표%4를 선택하십시오. + %3射表%4 を使用すると、兵士は (手段に応じて) 直接的または間接的なターゲットへの正確な射撃位置を推定できます。%3射表%4は、兵士が選択した武器/車両に応じて自動的に入力されます。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2目的の%3射表%4を選択します。 + La %3Tabla de distancias%4 permite a un soldado estimar con precisión el posicionamiento de un disparo sobre un objetivo de manera directa o indirecta (dependiendo del dispositivo). La %3Tabla de distancias%4 se autorellena dependiendo del arma o vehículo seleccionado por el soldado.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Selecciona la %3Tabla de distancias%4 deseada. Ropes Liny + Corde 로프 + ロープ + Канаты + Corde + Cuerdas Tow With Ease Holowanie bez Wysiłku + Rimorchia con facilità 쉽게 견인을 할 수 있습니다 + 楽々けん引 + Буксируйте с легкостью + Remorquer avec facilité + Remolcar Con Facilidad %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 %3Liny%4 mają wiele zastosowań, takich jak %3Holowanie%4 pojazdów czy %3Zjeżdżanie na Linach%4 z helikopterów.<br/><br/>%3Holowanie:%4<br/>%2Podejdź pod pojazd.<br/>%2Użyj [%3%13%4] i wybierz %3Holowanie%4.<br/>%2Wybierz długość liny. <br/>%2Wybierz punkt zaczepu liny na holującym pojeździe.<br/>%2Wybierz punkt zaczepu liny na holowanym pojeździe.<br/><br/>%3Dostępne Długości Liny:%4<br/>%2 3.2 metera<br/>%2 6.2 metera<br/>%2 12.2 metera<br/>%2 15.2 metera<br/>%2 18.3 metera<br/>%2 27.4 metera<br/>%2 36.6 metera + %3Corde%4 hanno molteplici utilizzi, come %3Trainare%4 veicoli e %3Fast Roping%4 da elicotteri.<br/><br/>%3Traino:%4<br/>%2Avvicinati a un veicolo.<br/>%2Usa [%3%13%4] e seleziona %3Traina%4.<br/>%2Seleziona lunghezza corda.<br/>%2Seleziona punto di attacco su veicolo trainante.<br/>%2Seleziona attacco su veicolo trainato.<br/><br/>%3Lunghezze corde a disposizione:%4<br/>%2 3.2 metri<br/>%2 6.2 metri<br/>%2 12.2 metri<br/>%2 15.2 metri<br/>%2 18.3 metri<br/>%2 27.4 metri<br/>%2 36.6 metri %3로프%4는 차량 %3견인%4 및 헬기의 %3패스트로프%4 등 여러 용도로 사용됩니다.<br/><br/>%3견인 방법:%4<br/>%2차량에 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3견인%4을 선택하십시오.<br/>%2로프 길이를 선택하십시오.<br/>%2견인할 차량의 부착 지점을 선택하십시오.<br/>%2견인될 차량의 부착 지점을 선택하십시오.<br/><br/>%3사용 가능한 로프 길이:%4<br/>%2 3.2m<br/>%2 6.2m<br/>%2 12.2m<br/>%2 15.2m<br/>%2 18.3m<br/>%2 27.4m<br/>%2 36.6m + %3ロープ%4には、車両の%3けん引%4やヘリコプターからの%3ファストロープ%4など、複数の用途があります。<br/><br/>%3けん引方法:%4<br/>%2車両に近づきます。<br/>%2[%3%13%4] を使って%3けん引%4を選択します。<br/>%2ロープの長さを選択します。<br/>%2けん引する車両のロープ取付位置を選択します。<br/>%2けん引される車両のロープ取付位置を選択します。<br/><br/>%3利用可能なロープの長さ:%4<br/>%2 3.2 メートル<br/>%2 6.2 メートル<br/>%2 12.2 メートル<br/>%2 15.2 メートル<br/>%2 18.3 メートル<br/>%2 27.4 メートル<br/>%2 36.6 メートル + Las %3Cuerdas%4 tienen múltiples usos incluyendo el %3Remolcado%4 de vehículos y el %3Descenso con Cuerda%4 desde helicópteros.<br/><br/>%3Remolcado:%4<br/>%2Acércate a un vehículo.<br/>%2Usar [%3%13%4] y seleccionar %3Remolcado%4.<br/>%2Selecciona la longitud de la cuerda.<br/>%2Selecciona un punto de anclaje en el vehículo de remolcado.<br/>%2Selecciona una sujección en el vehículo remolcado.<br/><br/>%3Longitudes de Cuerda Disponibles:%4<br/>%2 3.2 metros<br/>%2 6.2 metros<br/>%2 12.2 metros<br/>%2 15.2 metros<br/>%2 18.3 metros<br/>%2 27.4 metros<br/>%2 36.6 metros Expand Your Fortifications Powiększ Swoje Fortyfikacje + Espandi le tue Fortificazioni 당신의 요새를 확장합니다 + 要塞を拡張する + Расширить свои укрепления + Élargissez vos fortifications + Expande Tus Fortificaciones %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. %3Worki z Piaskiem%4 to worki wykonane z mocnego materiału, wypełnione piaskiem, używane do różnych celów, takich jak tworzenie barier lub zapewnianie stabilności w projektach budowlanych. Przydatne przy tworzeniu większych fortyfikacji.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Worek z Piaskiem (Pusty%4.<br/>%2Use [%3%12%4] i wybierz %3Rozłóż Worek z Piaskiem%4.<br/>%2Podążaj za instrukcjami na ekranie. + %3Sacchi di Sabbia%4 sono sacchi di un materiale robusto, riempiti di sabbia, usati per una varietà di utilizzi come creare barriere o aumentare la stabilità di fortificazioni.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Sacco di Sabbia (Vuoto)%4.<br/>%2Usa [%3%12%4] e seleziona %3Posiziona Sacco di Sabbia%4.<br/>%2Segui le istruzioni sullo schermo per il piazzamento. %3모래주머니%4는 튼튼한 재료로 만든 주머니로 모래를 채워 장벽을 만들거나 건설 작업에서 안정성을 제공하는 등 다양한 용도로 사용되며, 더 큰 요새를 확장하는 데 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2%3모래주머니(비어있음)%4을 장착하십시오.<br/>%2[%3%12%4]를 사용하고 %3모래주머니 배치%4를 선택하십시오.<br/>%2화면의 지시에 따라 배치하십시오. + %3土のう%4は、砂が詰められた頑丈な素材で作られた袋で、建設プロジェクトでの障壁の作成や安定性の提供など、さまざまな目的に使用されます。より大きな配置の要塞を拡張するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2%3土のう (空)%4を装備します。<br/>%2[%3%12%4] を使って%3土のうを作る%4を選択します。<br/>%2画面上の指示に従って配置します。 + Los %3Sacos de tierra%4 son sacos hechos de un material resistente, rellenados de tierra, usados para una diversa variedad de propósitos como la construcción de barreras o proveer estabilidad en los proyectos de construcción. Son útiles en la expansión de proyectos de construcción más grandes.<br/><br/>%3Uso:%4<br/>%2Equipa un %3Saco de tierra (Vacío)%4.<br/>%2Usar [%3%12%4] y seleccionar %3Desplegar Saco de tierra%4.<br/>%2Seguir las instrucciones en pantalla para su colocación. Lower Firearm Temperature Niższa Temperatura twojej Broni + Raffredda l'Arma 총기의 온도를 낮춥니다 + 銃の熱を冷ます + Понизьте температуру оружия + Refroidir l'arme + Bajar la Temperatura del 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. %3Zapasowa Lufa%4 pozwala żołnierzowi znacznie zmniejszyć ciepło broni. Po krótkim czasie lufa broni zostanie zamieniona, a jej temperatura zostanie zmniejszona. Żołnierz może również sprawdzić temperaturę każdej lufy w swoim ekwipunku. Nie wszystkie bronie obsługują zamianę luf.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Wybierz %3Zmień Lufę%4.<br/>%2. + %3Canne di Ricambio%4 permettono ai soldati di raffreddare la loro arma notevolmente. Dopo una breve attesa, la canna dell'arma verrà sostituita e la temperatura ridotta. Un soldato può anche controllare la temperatura di canne di ricambio presenti nel proprio inventario. Non tutte le armi consentono lo scambio canna.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Sostituisci Canna%4.<br/>%2Continua l'ingaggio dopo sostituzione avvenuta. %3예비 총열%4을 사용하면 병사의 무기의 발열을 크게 줄일 수 있습니다. 잠시 뒤에 무기의 총신이 교체되고 발열이 감소합니다. 군인은 소지품에 있는 총열의 온도도 확인할 수 있습니다. 모든 무기가 총열 교환을 지원하는 것은 아닙니다.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4]를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3총열 교체%4를 선택하십시오.<br/>%2총열 교체가 완료된 후 작전을 계속하십시오. + %3予備銃身%4を使用すると、兵士は武器の熱を大幅に下げることができます。少し経つと、武器の銃身が交換され熱が下がります。兵士はインベントリ内の銃身の温度を確認することもできます。すべての武器が銃身の交換をサポートしているわけではありません。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3銃身を交換%4を選択します。<br/>%2銃身交換が完了すると、再度射撃することが出来ます。 + El %3Cañón de Repuesto%4 permite a un soldado reducir el calor del arma significativamente. Tras un pequeño periodo, el cañón del arma habrá sido sustituido y el calor reducido. Un soldado puede tambien comprobar la temperatura de cualquier cañón en su inventario. No todas las armas soportan el cambio de cañón.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Cambiar Cañón%4.<br/>%2Continuar con la operación una vez se haya cambiado el cañón. Spray Paint Farba w Sprayu + Bomboletta Spray 스프레이 페인트 + ペイントスプレー + Аэрозольная краска + Bombe de peinture + Pintura En Spray Tag Your Territory Zaznacz Swój Teren + Marca il tuo territorio 당신의 영역을 지정합니다 + 自分のテリトリーをマーキング + Пометьте свою территорию + Marquez votre territoire + Marca Tu 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 %3Farba w Sprayu%4 jest używana do oznaczania powierzchni różnymi symbolami.<br/><br/>%3Użycie:%4<br/>%2Podejdź blisko powierzchni (ściany, pojazdu, ziemi, etc). <br/>%2Użyj [%3%12%4] i wybierz %3Malowanie%4.<br/>%2Wybierz Symbol.<br/><br/>%3Dostępne Kolory:%4<br/>%2Czarny<br/>%2Niebieski<br/>%2Zielony<br/>%2Czerwony + %3Bombolette Spray%4 vengono usate per marcare superfici con vari simboli.<br/><br/>%3Utilizzo:%4<br/>%2Muoviti vicino a una superfice (muro, veicolo, suolo, etc).<br/>%2Usa [%3%12%4] e seleziona %3Marca%4.<br/>%2Seleziona un simbolo.<br/><br/>%3Colori disponibili:%4<br/>%2Nero<br/>%2Blu<br/>%2Verde<br/>%2Rosso %3스프레이 페인트%4다양한 기호로 표면에 태그를 지정하는 데 사용됩니다.<br/><br/>%3사용 방법:%4<br/>%2표면(벽, 차량, 지면 등)에 가까이 가십시오.<br/>%2[%3%12%4]를 사용하고 %3태그%4를 선택하십시오.<br/>%2모양을 고르십시오.<br/><br/>%3사용 가능 색상:%4<br/>%2검정<br/>%2파랑<br/>%2초록<br/>%2빨강 + %3ペイントスプレー%4は、地面や壁、車両の表面などに様々な図形のタグを付けるために使えます。<br/><br/>%3使用方法:%4<br/>%2塗りたい面に近づきます。(壁、車両、地面など)<br/>%2[%3%12%4] を使って%3タグ (スプレーペイント)%4を選択します。<br/>%2図形を選びます。<br/><br/>%3利用可能な色:%4<br/>%2黒<br/>%2白<br/>%2赤<br/>%2青<br/>%2緑<br/>%2黄 + La %3Pintura en Spray%4 se usa para marcar superficies con varios símbolos.<br/><br/>%3Uso:%4<br/>%2Acércate a una superficie (pared, vehículo, suelo, etc).<br/>%2Usar [%3%12%4] y seleccionar %3Tag%4.<br/>%2Elige un símbolo.<br/><br/>%3Colores disponibles:%4<br/>%2Negro<br/>%2Azul<br/>%2Verde<br/>%2Rojo Brace From Anywhere Zawsze Stabilny + Stabilizzati Ovunque 어느 곳에나 지지대를 배치할 수 있습니다 + どこでも支持器 + Опора может быть установлена в любом месте + Stabilisé partout + Apoyarte En Cualquier Lugar 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. %3Trójnóg Snajperski%4 jest to rozkładany statyw, który pozwala żołnierzowi dokładnie przycelować, gdy jest rozłożony. Używaj go, gdy potrzebujesz stabilnej pozycji strzeleckiej, a wokół nie ma innych obiektów.<br/><br/>%3Użycie:%4<br/>%2Użyj [%3%12%4] i wybierz %3Ekwipunek%4.<br/>%2Wybierz %3Trójnóg Snajperski%4 i podążaj za instrukcjami wyświetlanymi na ekranie. + Il %3Kit SSWT%4 è un treppiede piazzabile che permette al soldato di appoggiare la sua arma. Usalo quando ti serve una posizione di tiro rialzata e non ci sono altri oggetti utili nelle vicinanze.<br/><br/>%3Utilizzo:%4<br/>%2Usa [%3%12%4] e seleziona %3Equipaggiamento%4.<br/>%2Seleziona %3Kit SSWT%4 e segui le indicazioni di piazzamento. %3SSWT 키트%4는 병사가 배치 시 조준력을 상승시킬 수 있는 배치 가능한 삼각대입니다. 높이 조절이 된 사격 위치가 필요하고 주위에 다른 물체가 없을 때 사용하십시오.<br/><br/>%3사용 방법:%4<br/>%2[%3%12%4] 를 사용하고 %3장비%4를 선택하십시오.<br/>%2%3SSWT 키트%4를 선택하고 화면의 지시에 따라 배치하십시오. + %3SSWT キット%4は展開可能な三脚で、展開時に兵士が狙いを定めることができます。高い射撃位置が必要で、周囲に他の物体がない場合に使用してください。<br/><br/>%3使用方法:%4<br/>%2[%3%12%4] を使って%3装備%4を選択します。<br/>%2%3SSWT キット%4を選択し、画面上の指示に従って配置します。 + El %3Kit SSWT%4 es un trípode desplegable que permite a un soldado apoyarse para apuntar cuando está desplegado. Úsalo cuando necesites una posición de tiro elevada y no hay ningún otro objeto alrededor.<br/><br/>%3Uso:%4<br/>%2Usar [%3%12%4] y seleccionar %3Equipamiento%4.<br/>%2Seleccionar %3Kit SSWT%4 y sigue las indicaciones en pantalla para colocarlo. Keep Eyes In The Sky Trzymaj Głowę w Górze + Tieni gli occhi nel cielo 하늘에서 계속 내려다봅니다 + 空の目を維持する + Не Отрывай Глаз От Неба + Gardez les yeux au ciel + Gardez les yeux au ciel + Manten Tus Ojos En El 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. %3Baterie UAV%4 są używane do zasilania UAV. Zwłaszcza tych małych.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Baterię UAV%4<br/>%2Podejdź pod %3UAV%4 z %3Wyłączonym Silnikiem%4.<br/>%2Użyj [%3%13%4] i wybierz %3Naładuj%4. + %3Batteria UAV%4 vengono usate per ricaricare gli UAV. Molto utile per piccoli UAV.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Batteria UAV%4<br/>%2Avvicinati al %3UAV%4 con il %3Motore Spento%4.<br/>%2Usa [%3%13%4] e seleziona %3Ricarica%4. %3무인기 배터리%4는 무인기의 에너지 저장소를 재충전하는 데 사용됩니다. 소형 무인기에 특히 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2%3무인기 배터리%4를 장착하십시오.<br/>%2%3엔진을 끄고%4 %3무인기%4에 접근하십시오.<br/>%2[%3%13%4]를 사용하고 %3재충전%4을 선택하십시오. + %3UAVバッテリー%4は、UAVの電源容量を充電するために使用されます。<br/><br/>%3使用方法:%4<br/>%2%3UAV バッテリー%4を装備します。<br/>%2%3エンジンをオフ%4にした%3UAV%4に近づきます。<br/>%2[%3%13%4] を使って%3充電%4を選択します。 + La %3Batería de VANT%4 se utilizan para recargar el almacenamiento de energía de un VANT. Especialmente útiles para pequeños VANTs.<br/><br/>%3Uso:%4<br/>%2Equipa una %3Batería de VANT%4<br/>%2Acércate a un %3VANT%4 con su %3Motor Apagado%4.<br/>%2Usa [%3%13%4] y selecciona %3Recargar%4. Making An Entrance Robienie Własnego Wejścia + Fai un'entrata 진입로를 만듭니다 + 堂々入場する + Создание собственного входа + Faire son entrée + Abriendo Una Entrada %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. %3Nożyce do Cięcia Drutu%4 są narzędziem pozwalającym pokonywać zapory z siatki oraz drutu. Użyteczne przy tworzenia tylnego wejścia do pilnownej strefy.<br/><br/>%3Użycie:%4<br/>%2Podejdź pod ogrodzenie.<br/>%2Użyj[%3%12%4] i wybierz %3Przetnij Płot%4. + La %3Trancia%4 è un utensile che permette ai soldati di sorpassare filo spinato e recinzioni. Utile per creare punti di accesso nel retro di zone protette.<br/><br/>%3Utilizzo:%4<br/>%2Avvicinati a una barriera.<br/>%2Usa [%3%12%4] e seleziona %3Taglia%4. %3절단기%4는 병사가 철조망을 통과할 수 있게 해주는 도구입니다. 보안 구역에 뒷입구를 만드는 데 유용합니다.<br/><br/>%3사용 방법:%4<br/>%2철조망에 가까이 가십시오.<br/>%2[%3%13%4]를 사용하고 %3철조망 자르기%4를 선택하십시오. + %3ワイヤーカッター%4は、兵士が有線フェンスを回避できるようにするツールです。安全にエリアへの裏口を作成するのに役立ちます。<br/><br/>%3使用方法:%4<br/>%2フェンスの近くに移動します。<br/>%2[%3%12%4] を使って%3フェンスを切断する%4を選択します。 + La %3Cizalla%4 es una herramienta que permite a un soldado atravesar una valla de alambre. Es útil para crear entradas traseras en áreas seguras.<br/><br/>%3Uso:%4<br/>%2Acércate a una valla.<br/>%2Usar [%3%12%4] y seleccionar %3Cortar Valla%4. Items @@ -467,42 +831,83 @@ ACE3 ACE3 + ACE3 ACE3 + ACE 3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 + ACE3 Build Fortifications Budowanie Fortyfikacji + Costruisci Fortificazioni 요새를 건설합니다 + 要塞を構築する + Стройте укрепления + Construire des fortifications + Construir Fortificaciones - The %3Fortify Tool%4 allows soldiers to build fortifications provided by their mission creator.<br/><br/>%3Usage:%4<br/>%2Pick up a %3FortifyTool%4.<br/>%2Use [%3%12%4] and select %3Fortify%4.<br/>%2Select an available fortification and follow the on screen prompts for placement. + 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. %3Narzędzie do fortyfikowania%4 pozwala żołnierzom budować fortyfikacje wybrane przez twórcę misji.<br/><br/>%3Użycie:%4<br/>%2Podnieś %3Narzędzie do fortyfikowania%4.<br/>%2Użyj [%3%12%4] i wybierz %3Fortyfikuj%4.<br/>%2Wybierz dostępną fortyfikację i postępuj zgodnie ze wskazówkami na ekranie. + L'%3Attrezzo di Fortificazione%4 permette ai soldati di costruire fortificazioni permesse dal creatore della missione.<br/><br/>%3Utilizzo:%4<br/>%2Raccogli un %3Attrezzo di Fortificazione%4.<br/>%2Usa [%3%12%4] e seleziona %3Fortifica%4.<br/>%2Seleziona una fortificazione disponibile e segui le indicazioni di piazzamento sullo schermo. %3요새화 도구%4를 사용하면 병사들이 임무 생성자가 제공한 요새를 구축할 수 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3요새화 도구%4를 가지십시오.<br/>%2[%3%12%4]를 사용하고 %3요새화%4를 선택하십시오.<br/>%2사용 가능한 요새를 선택하고 화면의 지시에 따라 배치하십시오. + %3築城ツール%4を使用すると、兵士はミッション作成者が提供した要塞を構築できます。<br/><br/>%3使用方法:%4<br/>%2%3築城ツール%4を持つ。<br/>%2[%3%12%4] を使って%3野戦築城%4を選択します。<br/>%2利用可能な構造物を選択し、画面上の指示に従って配置します。 + La %3Herramienta de Fortificación%4 permite a los soldados construir fortificaciones provistas por su creador de mision.<br/><br/>%3Uso:%4<br/>%2Coge una %3Herramienta de Fortificación%4.<br/>%2Usar [%3%12%4] y seleccionar %3Fortificar%4.<br/>%2Selecciona una fortificación disponible y sigue las instrucciones en pantalla para su colocación. Breaking and Entering Włamywanie i Otwieranie + Effrazione 침입용 도구입니다 + 破壊して乗り込む + Взлом и проникновение + Entrée par effraction + Romper y Entrar %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. %3Wytrychy%4 są używane w celu uzyskania dostępu do zablokowanych pojazdów.<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Wytrych%4.<br/>%2Podejdź do %3Zablokowanego%4 pojazdu. <br/>Użyj [%3%13%4] i wybierz %3Otwórz Zamek%4.<br/><br/><t underline='1'>%3Uwaga:%4</t> Klucze i wytrychy są dostępne tylko przy zastosowaniu skryptów lub użyciu modułu ACE Zamknięcie Pojazdu + I %3Grimaldelli%4 sono usati per forzare l'accesso a veicoli bloccati.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia un %3Grimaldello%4.<br/>%2Avvicinati a un veicolo %3Bloccato%4 vehicle.<br/>Usa [%3%13%4] e seleziona %3Scassina Veicolo%4.<br/><br/><t underline='1'>%3Note:%4</t> Grimaldelli e chiavi sono solo reperibili mediante scripting o moduli ACE di assegnazione Chiavi Veicoli. %3해정도구%4는 잠긴 차량에 들어가는 데 사용됩니다.<br/><br/>%3사용 방법:%4<br/>%2%3해정도구%4를 장착하십시오.<br/>%2%3잠긴%4 차량에 접근하십시오.<br/>[%3%13%4]를 사용하고 %3차량 잠금해제%4를 선택하십시오.<br/><br/><t underline='1'>%3참고:%4</t> 해정도구와 열쇠는 스크립팅 또는 ACE 차량 열쇠 모듈에서만 사용할 수 있습니다. + %3Lockpick%4は、ロックされた車両にアクセスするために使用されます。<br/><br/>%3使用方法:%4<br/>%2%3Lockpick%4を装備します。<br/>%2%3鍵の掛かった%4車両に近づきます。<br/>[%3%13%4] を使って%3鍵をこじ開ける%4を選択します。<br/><br/><t underline='1'>%3備考:%4</t> ロックピックとキーは、スクリプトまたは ACE Vehicle Key モジュールを介してのみ使用できます。 + La %3Ganzúa%4 es usada para lograr acceso a vehículos bloqueados.<br/><br/>%3Uso:%4<br/>%2Equipar %3Ganzúa%4.<br/>%2Acércate a un vehículo %3Bloqueado%4.<br/>Usar [%3%13%4] y seleccionar %3Ganzuar Vehículo%4.<br/><br/><t underline='1'>%3Nota:%4</t>Ganzúas y Llaves sólo están disponibles mediante scripting o módulos de Llaves de Vehículos ACE. Vehicle Keys Kluczyki od Pojazdu + Chiavi dei Veicoli 차량 열쇠 + 車両キー + Взлом и проникновение + Clés de véhicule + Llaves de Vehículos Lock/Unlock Vehicles Zablokuj/Odblokuj Pojazdy + Blocco/Sblocco di Veicoli 차량을 잠그거나 해제합니다 + 車両のロック/ロック解除 + Взлом и проникновение + Verrouiller/déverrouiller un véhicule + Bloquear/Desbloquear vehículos %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. %3Kluczyki od Pojazdów%4 są używane w celu ich zablokowania/odblokowania. Kluczyki mogą istnieć dla całej strony, lub być tworzone tylko dla wybranych pojazdów<br/><br/>%3Użycie:%4<br/>%2Wyekwipuj %3Kluczyk do Pojazdu%4.<br/>%2Podejdź do samochodu, do którego pasuje kluczyk. <br/>Użyj [%3%13%4] i wybierz %3Zablokuj/Odblokuj Pojazd%4.<br/><br/><t underline='1'>%3Uwaga:%4</t> Klucze i wytrychy są dostępne tylko przy zastosowaniu skryptów lub użyciu modułu ACE Zamknięcie Pojazdu + Le %3Chiavi di Veicoli%4 vengono usate per bloccare/sbloccare i propri veicoli. Chiavi di veicoli possono esistere per un'intera fazione, oppure per un veicolo particolare.<br/><br/>%3Utilizzo:%4<br/>%2Equipaggia una %3Chiave di Veicolo%4.<br/>%2Avvicinati al veicolo a cui appartiene la chiave.<br/>Usa [%3%13%4] e seleziona %3Blocca/Sblocca Veicolo%4.<br/><br/><t underline='1'>%3Note:%4</t> Grimaldelli e chiavi sono solo disponibili mediante scripting o moduli ACE Chiavi Veicoli. %3차량 열쇠%4는 차량을 잠그거나 잠금해제하는 데 사용됩니다. 차량 열쇠는 모든 세력에게 존재할 수도 있고, 특정 차량 자체에 대해 열쇠를 생성할 수도 있습니다.<br/><br/>%3사용 방법:%4<br/>%2%3차량 열쇠%4를 장착하십시오.<br/>%2해당 열쇠에 속한 차량에 접근하십시오.<br/>[%3%13%4]를 사용하고 %3차량 잠금/잠금해제%4를 선택하십시오.<br/><br/><t underline='1'>%3참고:%4</t> 해정도구와 열쇠는 스크립팅 또는 ACE 차량 열쇠 모듈에서만 사용할 수 있습니다. + %3Vehicle Key%4は、車両のロック/ロック解除に使用されます。車両キーは陣営全体に存在することも、特定の車両だけに対してキーを作成することもできます。<br/><br/>%3使用方法:%4<br/>%2%3Vehicle Key%4を装備します。<br/>%2鍵の対応している車両に近づきます。<br/>[%3%13%4] を使って%3鍵を解錠/施錠%4します。<br/><br/><t underline='1'>%3備考:%4</t> ロックピックとキーは、スクリプトまたは ACE Vehicle Key モジュールを介してのみ使用できます。 + Las %3Llaves de Vehículos%4 son usadas para bloquear/desbloquear tus vehículos. Las Llaves de Vehículos existen para un bando entero o para un vehículo concreto.<br/><br/>%3Uso:%4<br/>%2Equipa una %3Llave de Vehículo%4.<br/>%2Acércate a un vehículo cuya llave corresponda.<br/>Usar [%3%13%4] y selecciona %3Bloquear/Desbloquear Vehículo%4.<br/><br/><t underline='1'>%3Nota:%4</t> Ganzúas y Llaves sólo están disponibles mediante scripting o módulos de Llaves de Vehículos ACE diff --git a/addons/finger/XEH_postInit.sqf b/addons/finger/XEH_postInit.sqf index caa2ab54e8..6a44a5ae79 100644 --- a/addons/finger/XEH_postInit.sqf +++ b/addons/finger/XEH_postInit.sqf @@ -4,14 +4,14 @@ if (!hasInterface) exitWith {}; ["CBA_settingsInitialized", { //If not enabled, dont't bother adding eventhandler - TRACE_1("CBA_settingsInitialized eh", GVAR(enabled)); + TRACE_1("CBA_settingsInitialized eh",GVAR(enabled)); if (!GVAR(enabled)) exitWith {}; GVAR(lastFPTime) = -1; GVAR(fingersHash) = createHashMap; GVAR(pfeh_id) = -1; - [QGVAR(fingered), {_this call FUNC(incomingFinger)}] call CBA_fnc_addEventHandler; + [QGVAR(fingered), LINKFUNC(incomingFinger)] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; //Add Keybind: diff --git a/addons/finger/XEH_preInit.sqf b/addons/finger/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/finger/XEH_preInit.sqf +++ b/addons/finger/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/finger/functions/fnc_incomingFinger.sqf b/addons/finger/functions/fnc_incomingFinger.sqf index fb65d8eac9..4509a270db 100644 --- a/addons/finger/functions/fnc_incomingFinger.sqf +++ b/addons/finger/functions/fnc_incomingFinger.sqf @@ -25,12 +25,12 @@ private _fingerPos = if (_sourceUnit == ACE_player) then { _fingerPosPrecise vectorAdd ([random (2 * FP_RANDOMIZATION_X) - FP_RANDOMIZATION_X, random (2 * FP_RANDOMIZATION_X) - FP_RANDOMIZATION_X, random (2 * FP_RANDOMIZATION_Y) - FP_RANDOMIZATION_Y] vectorMultiply _distance) }; -TRACE_3("incoming finger:", _sourceUnit, _fingerPosPrecise, _fingerPos); +TRACE_3("incoming finger:",_sourceUnit,_fingerPosPrecise,_fingerPos); private _data = [diag_tickTime, _fingerPos, ([_sourceUnit, false, true] call EFUNC(common,getName)), _sourceUnit]; GVAR(fingersHash) set [hashValue _sourceUnit, _data]; if (GVAR(pfeh_id) == -1) then { GVAR(pfeh_id) = [DFUNC(perFrameEH), 0, []] call CBA_fnc_addPerFrameHandler; - TRACE_1("Started PFEH", GVAR(pfeh_id)); + TRACE_1("Started PFEH",GVAR(pfeh_id)); }; diff --git a/addons/finger/functions/fnc_keyPress.sqf b/addons/finger/functions/fnc_keyPress.sqf index 59405b57a5..2445986d15 100644 --- a/addons/finger/functions/fnc_keyPress.sqf +++ b/addons/finger/functions/fnc_keyPress.sqf @@ -42,7 +42,7 @@ private _sendFingerToPlayers = []; private _nearbyMen = (ACE_player nearObjects ["CAManBase", (GVAR(maxRange) + 2)]); { _nearbyMen append (crew _x); -} count (ACE_player nearObjects ["StaticWeapon", (GVAR(maxRange) + 2)]); +} forEach (ACE_player nearObjects ["StaticWeapon", (GVAR(maxRange) + 2)]); { if ((((eyePos _x) vectorDistance _playerEyePosASL) < GVAR(maxRange)) && {alive _x} && @@ -53,8 +53,7 @@ private _nearbyMen = (ACE_player nearObjects ["CAManBase", (GVAR(maxRange) + 2)] _sendFingerToPlayers pushBack _x; }; - true -} count _nearbyMen; +} forEach _nearbyMen; TRACE_1("sending finger to",_sendFingerToPlayers); diff --git a/addons/finger/functions/fnc_perFrameEH.sqf b/addons/finger/functions/fnc_perFrameEH.sqf index e499ff8808..4af4f6b643 100644 --- a/addons/finger/functions/fnc_perFrameEH.sqf +++ b/addons/finger/functions/fnc_perFrameEH.sqf @@ -44,7 +44,7 @@ private _iconBaseSize = GVAR(sizeCoef) * BASE_SIZE * 0.10713 * (call EFUNC(commo } forEach GVAR(fingersHash); if (GVAR(fingersHash) isEqualTo createHashMap) then { - TRACE_1("Ending PFEH", GVAR(pfeh_id)); + TRACE_1("Ending PFEH",GVAR(pfeh_id)); [GVAR(pfeh_id)] call CBA_fnc_removePerFrameHandler; GVAR(pfeh_id) = -1; }; diff --git a/addons/finger/initSettings.sqf b/addons/finger/initSettings.inc.sqf similarity index 100% rename from addons/finger/initSettings.sqf rename to addons/finger/initSettings.inc.sqf diff --git a/addons/finger/stringtable.xml b/addons/finger/stringtable.xml index 51e73e101e..bdb0c835b6 100644 --- a/addons/finger/stringtable.xml +++ b/addons/finger/stringtable.xml @@ -44,8 +44,8 @@ Показывает пальцем и рисует виртуальный маркер в направлении взгляда ближайшим игрокам. Можно удерживать. Señala y muestra un marcador virtual donde ustás apuntando para las unidades cercanas. Puede ser mantenido. Ukazuje virtuální značku kruhu ve směru, kterým se díváte pro všechny blízké jednotky. - Punta e mostra un marker virtuale di dove stai guardando alle unità vicine. Può essere tenuto premuto. - 指差し表記は自ユニットの近くにいる人のみに表記されます。また押しっぱなしにできます。 + Punta e mostra un indicatore virtuale di dove stai guardando alle unità vicine. Può essere tenuto premuto. + 近くのユニットに対して、今見ている場所に向けて指を差し、仮想のマーカーを表示して指示することが出来る。 押し続けることも可能。 당신이 보는 것을 가상의 마커로 표시함으로서 다른 인원이 볼 수 있게 합니다. 누른 채로 유지할 수 있습니다. 当按下此按键后,你附近的单位即可看见一个虚拟图示,标明你正在指向的位置。此按键可以被按住来持续显示。 當按下此按鍵後,你附近的單位即可看見一個虛擬圖示,標明你正在指向的位置。此按鍵可以被按住來持續顯示。 @@ -78,8 +78,8 @@ Максимальная дальность между игроками для отображения индикатора указания пальцем [по умолчанию: 4 метра] Distancia máxima entre los jugadores para mostrar el indicador que señala [por defecto: 4 metros] Maximální vzdálenost mezi hráči pro ukázání směru [výchozí: 4 metry] - Distanza massima tra giocatori per mostrare l'indicatore di puntamento [default: 4 metri] - 指差し表記が他のプレイヤーに表示される範囲を決定できます。(標準 4 メートル) + Distanza massima tra giocatori per mostrare l'indicatore di puntamento [Predefinito: 4 metri] + 指差しのマーカー表示が他のプレイヤーに表示される最大範囲 [デフォルト: 4メートル] 플레이어 사이에서 가리키기 표시를 보이게 하는 최대거리를 설정합니다[기본설정: 4 미터] 设定指向标记最大显示距离。[预设:4米] 設定指向指示器最大顯示距離。[預設: 4公尺] @@ -88,28 +88,33 @@ Visual Marker Size Coefficient Visueller Markergrößenkoeffizient + Coefficiente di dimensione puntatore 보이는 마커 크기 계수 Współczynnik wielkości wirtualnego znacznika - 指さし表記大きさ係数 + 指差しマーカーの大きさ係数 屏幕标记大小系数 Коэф. размера маркера Coeficiente del tamaño del marcador visual Coefficient taille des marqueurs visuels + Coeficiente de tamanho do marcador visual Adjusts the size of the visual marker. Passt die Größe der visuellen Markierung an. + Modifica la dimensione del puntatore virtuale. 눈에 보이는 마커의 크기를 조정합니다. Dostosowuje rozmiar wirtualnego znacznika. - 指さし表記の大きさを調整します。 + 指差しマーカーの大きさを調整します。 调整屏幕上显示的标记大小 Настраивает размер визуального маркера Ajusta el tamaño del marcador visual. Ajuste la taille des marqueurs visuels + Ajusta o tamanho do marcador visual Proximity Scaling Näherungsskalierung + Scalaggio di prossimità 근접 스케일링 Skalowanie odległościowe 近接性スケーリング @@ -117,17 +122,20 @@ Масштабирование от дальности Escalado de cercanía Mise à l'échelle + Escala por proximidade Scales the size of the visual marker based on the distance between the player observing and the player pointing. Skaliert die Größe der visuellen Markierung basierend auf der Entfernung zwischen dem beobachtenden Spieler und dem zeigenden Spieler. + Scala la dimensione del puntatore a seconda della distanza tra il giocatore osservatore e quello che punta. 관찰하는 플레이어와 가리키는 플레이어 사이의 거리에 따라 보이는 마커의 크기를 조정합니다. Skaluje rozmiar wirtualnego znacznika, na podstawie odległości między graczem obserwującym a graczem wskazującym. - 見ているプレーヤーと指さししたプレーヤーの距離に基づいて、指さし表記の大きさを調整します。 + 見ているプレーヤーと指差ししたプレーヤーの距離に基づいて、指差しマーカーの大きさを調整します。 根据观察的玩家和在指出方向的的玩家之间的距离调整视觉标记的大小。 Масштабирует размер визуального маркера в зависимости от дальности от игрока до точки указания. Escala el tamaño del marcador visual dependiendo de la distancia entre el jugador observador y el jugador que señala. Modifie la taille du marqueur visuel en fonction de la distance entre le joueur qui observe et le joueur qui pointe. + Redimensiona o tamanho do marcador visual baseado na distância entre o jogador observador e o jogador que aponta. Show pointing indicator to self @@ -140,7 +148,7 @@ Mostrar el indicador de señalado a uno mismo Zobrazit ukázání směru pro sebe Mostra puntatore per te stesso - 自分に指差し表記を表示する + 指差しマーカーを自分で見る 자신이 가리키는곳을 보여줍니다 在自己身边显示指向标记 顯示指向指示器給自己 @@ -156,8 +164,8 @@ Renderizar o indicador para o jogador que está apontando. Esta opção não afeta se os outros jogadores verão ou não o indicador Muestra el indicador para el jugador que apunta. Esta opción no afecta si los otros jugadores verían el indicador Zobrazit infikátor, když ukážete prstem. Tato volba nemá vliv, zda ostatní hráči uvidí indikátor nebo ne. - Mostra puntatore per il giocatore indicato. Questa opzione non influisce la possibilità che gli altri giocatori vedano il puntatore - プレイヤーへ指差し表記を描画します。これは他のプレイヤーの表記に影響しません。 + Mostra indicatore per il giocatore che punta. Questa opzione non influisce sulla visibilità del puntatore per gli altri giocatori + 指差ししたプレーヤーが自身の指差しマーカーを描画して確認できるようにします。 このオプションは、他のプレイヤーが指差しマーカーを表示出来るかどうかには影響しません。 대상이 가리키는곳을 보이게 합니다. 显示指向标记给玩家自己。此选项设定并不影响其他玩家能否看到指示标记 顯示指向指示器給玩家自己。此選項設定並不影響其他玩家能否看到指示器 @@ -174,7 +182,7 @@ Indicador de señalado Ukazování směru Indicatore di puntamento - 指差し表記 + 指差しマーカー 가리키기 표시기 指向标记 指向指示器 @@ -191,7 +199,7 @@ Color del círculo indicador que señala Barva kruhu pro ukázání směru Colore del cerchio dell'indicatore di puntamento - 指差し表記の円の色 + 指差しマーカーの円の色 가리키기의 원형 색상 指向标记颜色 指向指示器顏色 @@ -208,7 +216,7 @@ Acción "apuntar con el dedo a" Akce "ukázat prstem na" Azione "punta il dito a" - "指差し"キー + アクション "指を差す" "손가락으로 가리키기" 행동 使"手指指向在" 使"手指指向在" @@ -224,8 +232,8 @@ Показывает пальцем и рисует виртуальный маркер в направлении взгляда ближайшим игрокам. Можно удерживать. Señala y muestra un marcador virtual donde ustás apuntando para las unidades cercanas. Puede ser mantenido. Ukazuje virtuální značku kruhu ve směru, kterým se díváte pro všechny blízké jednotky. - Punta e mostra un marker virtuale di dove stai guardando alle unità vicine. Può essere tenuto premuto. - 指差し表記は自ユニットの近くにいる人のみに表記されます。また押しっぱなしにできます。 + Punta e mostra un indicatore virtuale di dove stai guardando alle unità vicine. Può essere tenuto premuto. + 近くのユニットに対して、今見ている場所に向けて指を差し、仮想のマーカーを表示して指示することが出来る。 押し続けることも可能。 당신이 보는 것을 가상의 마커로 표시함으로서 다른 인원이 볼 수 있게 합니다. 누른 채로 유지할 수 있습니다. 当按下此按键后,你附近的单位即可看见一个虚拟图示,标明你正在指向的位置。此按键可以被按住来持续显示。 當按下此按鍵後,你附近的單位即可看見一個虛擬圖示,標明你正在指向的位置。此按鍵可以被按住來持續顯示。 @@ -241,7 +249,7 @@ Настройки указания пальцем Ajustes de señalado Nastavení ukázování směru - Impostazioni puntamento + Impostazioni Puntamento 指差し設定 가리키기 설정 指向设定 diff --git a/addons/fire/CfgSounds.hpp b/addons/fire/CfgSounds.hpp index b83ce9b91a..76fb0e64f7 100644 --- a/addons/fire/CfgSounds.hpp +++ b/addons/fire/CfgSounds.hpp @@ -1,10 +1,10 @@ // weird ass concatenation syntax. PBO Project complains otherwise... #define CONCAT(a,b) a####b #define CREATE_SCREAM(no)\ -class GVAR(DOUBLES(scream,no)) { \ - name = QUOTE(GVAR(CONCAT(scream,no)));\ - sound[] = {QUOTE(PATHTOF(CONCAT(sounds\scream,no).ogg)), QUOTE(db+8), 1};\ - titles[] = {}; \ +class GVAR(DOUBLES(scream,no)) {\ + name = QGVAR(CONCAT(scream,no));\ + sound[] = {QPATHTOF(CONCAT(sounds\scream,no).ogg), QUOTE(db+8), 1};\ + titles[] = {};\ } class CfgSounds { diff --git a/addons/fire/CfgVehicles.hpp b/addons/fire/CfgVehicles.hpp new file mode 100644 index 0000000000..0ed16faff7 --- /dev/null +++ b/addons/fire/CfgVehicles.hpp @@ -0,0 +1,7 @@ +class CfgVehicles { + class Static; + class GVAR(logic): Static { + scope = 1; + displayName = ""; + }; +}; diff --git a/addons/fire/XEH_PREP.hpp b/addons/fire/XEH_PREP.hpp index d9eacfdee0..a352cdf2aa 100644 --- a/addons/fire/XEH_PREP.hpp +++ b/addons/fire/XEH_PREP.hpp @@ -1,10 +1,10 @@ PREP(burn); -PREP(isBurning); -PREP(isPlant); +PREP(burnEffects); PREP(burnIndicator); PREP(burnReaction); +PREP(burnSimulation); PREP(fireManagerPFH); - +PREP(isBurning); +PREP(medical_canPatDown); PREP(medical_progress); PREP(medical_success); -PREP(medical_canPatDown); diff --git a/addons/fire/XEH_postInit.sqf b/addons/fire/XEH_postInit.sqf index 125cb59140..1050d75753 100644 --- a/addons/fire/XEH_postInit.sqf +++ b/addons/fire/XEH_postInit.sqf @@ -1,38 +1,89 @@ #include "script_component.hpp" -[QGVAR(burn), FUNC(burn)] call CBA_fnc_addEventHandler; -[QGVAR(playScream), { - params ["_scream", "_source"]; - // only play sound if enabled in settings - if (GVAR(enableScreams)) then { - _source say3D _scream; - }; -}] call CBA_fnc_addEventHandler; +["CBA_settingsInitialized", { + TRACE_1("settingsInitialized",GVAR(enabled)); -["ace_settingsInitialized", { - TRACE_1("settingsInit", GVAR(enabled)); if (!GVAR(enabled)) exitWith {}; - if (isServer) then { - [QGVAR(addFireSource), { - params ["_source", "_radius", "_intensity", "_key", ["_condition", { true }], ["_conditionArgs", []]]; - private _fireLogic = createVehicle ["ACE_LogicDummy", [0, 0, 0], [], 0, "NONE"]; - if (_source isEqualType objNull) then { - _fireLogic attachTo [_source]; - } else { - _fireLogic setPosASL _source; - }; + [QGVAR(burn), LINKFUNC(burn)] call CBA_fnc_addEventHandler; + [QGVAR(burnEffects), LINKFUNC(burnEffects)] call CBA_fnc_addEventHandler; + [QGVAR(burnSimulation), LINKFUNC(burnSimulation)] call CBA_fnc_addEventHandler; - [GVAR(fireSources), _key, [_fireLogic, _radius, _intensity, _condition, _conditionArgs]] call CBA_fnc_hashSet; - }] call CBA_fnc_addEventHandler; + [QGVAR(playScream), { + params ["_scream", "_source"]; - [QGVAR(removeFireSource), { - params ["_key"]; - [GVAR(fireSources), _key] call CBA_fnc_hashRem; - }] call CBA_fnc_addEventHandler; + // 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; - [{ _this call FUNC(fireManagerPFH) }, FIRE_MANAGER_PFH_DELAY, []] call CBA_fnc_addPerFrameHandler; - GVAR(fireSources) = [[], nil] call CBA_fnc_hashCreate; - }; + if (!isServer) exitWith {}; + + GVAR(fireSources) = createHashMap; + + [QGVAR(addFireSource), { + params [ + ["_source", objNull, [objNull, []]], + ["_radius", 0, [0]], + ["_intensity", 0, [0]], + ["_key", ""], + ["_condition", {true}, [{}]], + ["_conditionArgs", []] + ]; + + private _isObject = _source isEqualType objNull; + + // Check if the source is valid + if !(_isObject || {_source isEqualTypeParams [0, 0, 0]}) exitWith {}; + + if (_isObject && {isNull _source}) exitWith {}; + if (_radius == 0 || _intensity == 0) exitWith {}; + if (_key isEqualTo "") exitWith {}; // key can be many types + + // hashValue supports more types than hashmaps do by default, but not all (e.g. locations) + private _hashedKey = hashValue _key; + + if (isNil "_hashedKey") exitWith { + ERROR_2("Unsupported key type used: %1 - %2",_key,typeName _key); + }; + + // If a position is passed, create a static object at said position + private _sourcePos = if (_isObject) then { + getPosATL _source + } else { + ASLToATL _source + }; + + private _fireLogic = createVehicle [QGVAR(logic), _sourcePos, [], 0, "CAN_COLLIDE"]; + + // If an object was passed, attach logic to the object + if (_isObject) then { + _fireLogic attachTo [_source]; + }; + + // To avoid issues, remove existing entries first before overwriting + if (_hashedKey in GVAR(fireSources)) then { + [QGVAR(removeFireSource), _key] call CBA_fnc_localEvent; + }; + + GVAR(fireSources) set [_hashedKey, [_fireLogic, _radius, _intensity, _condition, _conditionArgs]]; + }] call CBA_fnc_addEventHandler; + + [QGVAR(removeFireSource), { + params ["_key"]; + + private _hashedKey = hashValue _key; + + if (isNil "_hashedKey") exitWith { + ERROR_2("Unsupported key type used: %1 - %2",_key,typeName _key); + }; + + (GVAR(fireSources) deleteAt _hashedKey) params [["_fireLogic", objNull]]; + + detach _fireLogic; + deleteVehicle _fireLogic; + }] call CBA_fnc_addEventHandler; + + [LINKFUNC(fireManagerPFH), FIRE_MANAGER_PFH_DELAY, []] call CBA_fnc_addPerFrameHandler; }] call CBA_fnc_addEventHandler; - diff --git a/addons/fire/XEH_preInit.sqf b/addons/fire/XEH_preInit.sqf index e69c115927..894773534a 100644 --- a/addons/fire/XEH_preInit.sqf +++ b/addons/fire/XEH_preInit.sqf @@ -6,8 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" - -GVAR(burningPlants) = []; +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/fire/ACE_Medical_Treatment_Actions.hpp b/addons/fire/compat_medical_engine/ACE_Medical_Treatment_Actions.hpp similarity index 100% rename from addons/fire/ACE_Medical_Treatment_Actions.hpp rename to addons/fire/compat_medical_engine/ACE_Medical_Treatment_Actions.hpp diff --git a/addons/fire/compat_medical_engine/config.cpp b/addons/fire/compat_medical_engine/config.cpp new file mode 100644 index 0000000000..cc4431b18f --- /dev/null +++ b/addons/fire/compat_medical_engine/config.cpp @@ -0,0 +1,20 @@ +#include "script_component.hpp" + +class CfgPatches { + class SUBADDON { + name = COMPONENT_NAME; + units[] = {}; + weapons[] = {}; + requiredVersion = REQUIRED_VERSION; + requiredAddons[] = {"ace_medical_engine"}; + skipWhenMissingDependencies = 1; + author = ECSTRING(common,ACETeam); + authors[] = {}; + url = ECSTRING(main,URL); + VERSION_CONFIG; + + addonRootClass = QUOTE(ADDON); + }; +}; + +#include "ACE_Medical_Treatment_Actions.hpp" diff --git a/addons/fire/compat_medical_engine/script_component.hpp b/addons/fire/compat_medical_engine/script_component.hpp new file mode 100644 index 0000000000..b2ce8adc8d --- /dev/null +++ b/addons/fire/compat_medical_engine/script_component.hpp @@ -0,0 +1,3 @@ +#define SUBCOMPONENT medical_engine +#define SUBCOMPONENT_BEAUTIFIED Medical Engine +#include "..\script_component.hpp" diff --git a/addons/fire/config.cpp b/addons/fire/config.cpp index da8cd0091c..7a13dd079b 100644 --- a/addons/fire/config.cpp +++ b/addons/fire/config.cpp @@ -1,20 +1,12 @@ #include "script_component.hpp" -#pragma hemtt flag pe23_ignore_has_include -#if __has_include("\z\ace\addons\nomedical\script_component.hpp") -#define PATCH_SKIP "No Medical" -#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[] = {"ace_common", "ace_medical_engine"}; + requiredAddons[] = {"ace_common"}; author = ECSTRING(common,ACETeam); authors[] = {"commy2", "tcvm"}; url = ECSTRING(main,URL); @@ -24,7 +16,5 @@ class CfgPatches { #include "CfgEventHandlers.hpp" #include "CfgSounds.hpp" -#include "ACE_Medical_Treatment_Actions.hpp" +#include "CfgVehicles.hpp" #include "RscTitles.hpp" - -#endif diff --git a/addons/fire/functions/fnc_burn.sqf b/addons/fire/functions/fnc_burn.sqf index 08d52bd05c..1cf0fc6759 100644 --- a/addons/fire/functions/fnc_burn.sqf +++ b/addons/fire/functions/fnc_burn.sqf @@ -1,13 +1,12 @@ #include "..\script_component.hpp" /* - * Author: tcvm - * Makes object catch fire. Only call from events. Local effects only. - * Arbitrary values to ignite people. Assumed maximum is "10". + * Author: johnb43 + * Makes a unit catch fire. Only call from targeted events, is applied globally. * * Arguments: - * 0: Vehicle - * 1: Intensity of fire - * 2: Instigator of fire (default: objNull) + * 0: Unit + * 1: Fire intensity + * 2: Fire instigator (default: objNull) * * Return Value: * None @@ -18,322 +17,62 @@ * Public: No */ -#define INTENSITY_LOSS 0.03 -#define INTENSITY_UPDATE 3 -#define BURN_PROPOGATE_UPDATE 1 -#define BURN_PROPOGATE_DISTANCE 2 -#define BURN_PROPOGATE_COUNTER_MAX 5 - -params ["_unit", "_intensity", ["_instigator", objNull]]; +if (!EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [LINKFUNC(burn), _this]; +}; if (!GVAR(enabled)) exitWith {}; -private _isBurning = [_unit] call FUNC(isBurning); -if (_isBurning) exitWith {}; +params ["_unit", "_intensity", ["_instigator", objNull]]; +TRACE_3("burn",_unit,_intensity,_instigator); -[{ - // looped function - (_this getVariable "params") params ["_unit", "", "_instigator"]; - private _unitPos = getPosASL _unit; +if (BURN_MIN_INTENSITY > _intensity) exitWith { + TRACE_3("intensity is too low",_unit,_intensity,BURN_MIN_INTENSITY); +}; - _intensity = _unit getVariable [QGVAR(intensity), 0]; +// Check if unit is remote (objNull is remote) +if (!local _unit) exitWith { + TRACE_1("unit is null or not local",_unit); +}; - if (surfaceIsWater _unitPos && {(_unitPos#2) < 1}) then { - _intensity = 0; +// Check if the unit can burn (takes care of spectators and curators) +if (getNumber (configOf _unit >> "isPlayableLogic") == 1 || {!(_unit isKindOf "CAManBase")}) exitWith { + TRACE_1("unit is virtual or not a man",_unit); +}; + +// If unit is invulnerable, don't burn the unit +if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith { + TRACE_1("unit is invulnerable",_unit); +}; + +private _eyePos = eyePos _unit; + +// Check if unit is mostly submerged in water +if (surfaceIsWater _eyePos && {(_eyePos select 2) < 0.1}) exitWith { + TRACE_1("unit is in water",_unit); +}; + +// If unit is already burning, update intensity, but don't add another PFH +if (_unit call FUNC(isBurning)) exitWith { + // Only allow intensity to be increased + if (_intensity <= (_unit getVariable [QGVAR(intensity), 0])) exitWith { + TRACE_2("unit already burning, no intensity update",_unit,_intensity); }; - _fireParticle setDropInterval (0.01 max linearConversion [BURN_MAX_INTENSITY, BURN_MIN_INTENSITY, _intensity, 0.03, 0.1, false]); - _fireParticle setParticleParams [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 10, 32], // sprite sheet values - "", // animation name - "Billboard", // particle type - 1, // timer period - 0.7, // lifetime - "destructionEffect2", // position - [0, 0, 1], // move velocity - 0, // rotation velocity - 10, // weight - 7.9, // volume - 1, // rubbing - [0.3, 0.3], // size - [ - [1, 1, 1, -0], - [1, 1, 1, -1], - [1, 1, 1, -1], - [1, 1, 1, -1], - [1, 1, 1, -0] - ], // colour - [0.5, 1], // animation speed - 1, // random dir period - 0, // random dir intensity - "", // on timer script - "", // before destroy script - _unit, // particle source - 0, - false, - 0, - [[0.8, 0.6, 0.2, 1]] // emissive color - ]; - _fireParticle setParticleRandom [ - 0.04 * _intensity, // life time - [0.05, 0.05, 2], // position - [0.05 * _intensity, 0.05 * _intensity, 0.05 * _intensity], // move velocity - 0, // rotation velocity - 0.06 * _intensity, // size - [0, 0, 0, 0], // color - 0, // random direction period - 0 // random direction intensity - ]; + TRACE_2("unit already burning, updating intensity",_unit,_intensity); - _smokeParticle setParticleCircle [0, [0, 0, 0]]; - _smokeParticle setParticleRandom [ - 0, // life time - [0.25, 0.25, 0], // position - [0.2, 0.2, 0], // move velocity - 0, // rotation velocity - 0.25, // size - [0, 0, 0, 0.1], // color - 0, // random direction period - 0 // random direction intensity - ]; - _smokeParticle setParticleParams [ - ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 7, 48], // sprite sheet values - "", // animation name - "Billboard", // particle type - 1, // timer period - 8, // lifetime - [0, 0, 1.1], // position - [0, 0, 1], // move velocity - 0, // rotation velocity - 10, // weight - 7.9, // volume - 0.066, // rubbing - [1, 3, 6], // size - [ - [0.5, 0.5, 0.5, 0.15], - [0.75, 0.75, 0.75, 0.075], - [1, 1, 1, 0] - ], // colour - [0.125], // animation speed - 1, // random dir period - 0, // random dir intensity - "", // on timer script - "", // before destroy script - _unit // particle source - ]; - _smokeParticle setDropInterval 0.15; + _unit setVariable [QGVAR(intensity), _intensity, true]; +}; - _fireLight setLightBrightness ((_intensity * 3) / 10); - _lightFlare setLightBrightness (_intensity / 30); +TRACE_2("setting unit ablaze",_unit,_intensity); - private _distanceToUnit = (_unit distance ace_player); - _fireLight setLightAttenuation [1, 10 max (5 min (10 - _intensity)), 0, 15]; - _lightFlare setLightFlareSize (_intensity * (3 / 4)) * FLARE_SIZE_MODIFIER; +_unit setVariable [QGVAR(intensity), _intensity, true]; - if (!GVAR(enableFlare)) then { - _lightFlare setLightFlareSize 0; - }; +// Fire simulation (fire sources are handled differently) +[QGVAR(burnSimulation), [_unit, _instigator], _unit] call CBA_fnc_targetEvent; - // always keep flare visible to perceiving unit as long as it isnt the player - if (_unit isNotEqualTo ace_player) then { - private _relativeAttachPoint = [0, 0, 0.3]; - if (_distanceToUnit > 1.5) then { - _relativeAttachPoint = (vectorNormalized (_unit worldToModelVisual (getPos ace_player))) vectorMultiply linearConversion [5, 30, _distanceToUnit, 0.5, 1.5]; - _relativeAttachPoint set [2, 0.3 + ((_unit selectionPosition "pelvis") select 2)]; - }; - _lightFlare attachTo [_unit, _relativeAttachPoint]; - }; +// Spawn effects for unit +private _burnEffectsJipID = [QGVAR(burnEffects), _unit] call CBA_fnc_globalEventJIP; +[_burnEffectsJipID, _unit] call CBA_fnc_removeGlobalEventJIP; - if (!isGamePaused) then { - // If the unit goes to spectator alive _unit == true and they will be on fire and still take damage - // Only workaround I could think of, kinda clunky - if (_isThisUnitAlive) then { - _isThisUnitAlive = (alive _unit) && { getNumber ((configOf _unit) >> "isPlayableLogic") != 1 }; - }; - - // propagate fire - if ((CBA_missionTime - _lastPropogateUpdate) >= BURN_PROPOGATE_UPDATE) then { - _lastPropogateUpdate = CBA_missionTime; - if !([ace_player] call FUNC(isBurning)) then { - if ((vehicle _unit) isEqualTo (vehicle ace_player)) then { - if (0.5 > random 1) then { - [QGVAR(burn), [ace_player, _intensity * (7 / 8), _instigator]] call CBA_fnc_globalEvent; - }; - } else { - if ((ace_player isKindOf "Man") && {_unit isNotEqualTo ace_player} && {isDamageAllowed ace_player && {ace_player getVariable [QEGVAR(medical,allowDamage), true]}}) then { - private _burnCounter = _unit getVariable [QGVAR(burnCounter), 0]; - if (_distanceToUnit < BURN_PROPOGATE_DISTANCE) then { - if (_burnCounter < BURN_PROPOGATE_COUNTER_MAX) then { - _burnCounter = _burnCounter + 1; - } else { - [QGVAR(burn), [ace_player, _intensity * (3 / 4), _instigator]] call CBA_fnc_globalEvent; - }; - } else { - _burnCounter = 0; - }; - _unit setVariable [QGVAR(burnCounter), _burnCounter]; - }; - }; - }; - }; - - // update intensity/fire reactions - if ((CBA_missionTime - _lastIntensityUpdate) >= INTENSITY_UPDATE) then { - _lastIntensityUpdate = CBA_missionTime; - _intensity = _intensity - INTENSITY_LOSS - (rain / 10); - if (local _unit) then { - if (_isThisUnitAlive) then { - if !(IS_UNCONSCIOUS(_unit)) then { - if !(isPlayer _unit) then { - private _sdr = _unit getVariable [QGVAR(stopDropRoll), false]; - if ((_unit isEqualTo vehicle _unit) && (_sdr || ({ 0.05 > random 1 }))) then { - _unit setVariable [QGVAR(stopDropRoll), true]; - if !(_sdr) then { - TRACE_1("stop, drop, roll!", _unit); - _unit setUnitPos "DOWN"; - doStop _unit; - }; - // queue up a bunch of animations - for "_i" from 0 to 2 do { - [_unit, selectRandom ["amovppnemstpsnonwnondnon_amovppnemevasnonwnondl", "amovppnemstpsnonwnondnon_amovppnemevasnonwnondr"], 0] call EFUNC(common,doAnimation); - }; - _intensity = _intensity - (1 / _intensity); - } else { - private _group = (group _unit); - private _vehicle = vehicle _unit; - - if (_vehicle != _unit) then { - TRACE_1("Ejecting", _unit); - _unit leaveVehicle _vehicle; - unassignVehicle _unit; - _unit action ["eject",_vehicle]; - }; - _unit disableAI "TARGET"; - _unit disableAI "AUTOTARGET"; - - // Run away - if (leader _group != _unit) then { - [_unit] join grpNull; - }; - _unit doMove ((getPosATL _unit) getPos [20 + random 35, floor (random 360)]); - _unit setSpeedMode "FULL"; - _unit setSuppression 1; - }; - } else { - if ((animationState _unit) in PRONE_ROLLING_ANIMS) then { - // decrease intensity of burn - _intensity = _intensity * INTENSITY_DECREASE_MULT_ROLLING; - }; - }; - - [_unit] call FUNC(burnReaction); - }; - - // Common burn areas are the hands and face https://www.ncbi.nlm.nih.gov/pubmed/16899341/ - private _woundSelection = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.77, 0.5, 0.8, 0.8, 0.3, 0.3]; - if (GET_PAIN_PERCEIVED(_unit) < (PAIN_UNCONSCIOUS + random 0.2)) then { - // keep pain around unconciousness limit to allow for more fun interactions - [_unit, _intensity / BURN_MAX_INTENSITY, _woundSelection, "burn", _instigator] call EFUNC(medical,addDamageToUnit); - } else { - [_unit, 0.15, _woundSelection, "burn", _instigator] call EFUNC(medical,addDamageToUnit); - }; - }; - _unit setVariable [QGVAR(intensity), _intensity, true]; // globally sync intensity across all clients to make sure simulation is deterministic - }; - }; - - private _burnIndicatorPFH = _unit getVariable [QGVAR(burnUIPFH), -1]; - if (_unit isEqualTo ace_player && { _isThisUnitAlive } && { _burnIndicatorPFH < 0 }) then { - _burnIndicatorPFH = [FUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler; - _unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH]; - }; - }; -}, 0, [_unit, _intensity, _instigator], { - TRACE_1("burn init",GVAR(enableFlare)); - // init function - private _params = _this getVariable "params"; - _params params ["_unit", "_startingIntensity"]; - - _intensity = _startingIntensity; - private _unitPos = getPos _unit; - - _fireParticle = "#particlesource" createVehicleLocal _unitPos; - _fireParticle attachTo [_unit, [0, 0, 0]]; - _fireParticle setDropInterval 0.03; - - _smokeParticle = "#particlesource" createVehicleLocal _unitPos; - - _fireLight = "#lightpoint" createVehicleLocal _unitPos; - _fireLight setLightIntensity 0; - _fireLight setLightAmbient [0.8, 0.6, 0.2]; - _fireLight setLightColor [1, 0.5, 0.4]; - _fireLight attachTo [_unit, [0, 0, 0]]; - _fireLight setLightDayLight false; - - _lightFlare = "#lightpoint" createVehicleLocal _unitPos; - _lightFlare setLightIntensity 0; - _lightFlare setLightColor [1, 0.8, 0.8]; - _lightFlare setLightUseFlare true; - _lightFlare setLightFlareMaxDistance 100; - _lightFlare setLightFlareSize 0; - - if (_unit isNotEqualTo ace_player) then { - private _relativeAttachPoint = (vectorNormalized (_unit worldToModelVisual (getPos ace_player))) vectorMultiply 1; - _relativeAttachPoint set [2, 0.5]; - _lightFlare attachTo [_unit, _relativeAttachPoint]; - } else { - _lightFlare attachTo [_unit, [0, 0, 0.3]]; - }; - - if (isServer) then { - _fireSound = createSoundSource ["Sound_Fire", _unitPos, [], 0]; - _fireSound attachTo [_unit, [0, 0, 0], "Head"]; - }; - - _unit setVariable [QGVAR(burning), true]; - _unit setVariable [QGVAR(intensity), _intensity]; - _unit setVariable [QGVAR(burnUIPFH), -1]; - - if (local _unit) then { - if (_unit isEqualTo ace_player) then { - private _burnIndicatorPFH = [FUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler; - _unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH]; - }; - - [_unit, false] call FUNC(burnReaction); - }; - - _lastIntensityUpdate = 0; - _lastPropogateUpdate = 0; - - _isThisUnitAlive = true; -}, { - (_this getVariable "params") params ["_unit"]; - - // deinit function - deleteVehicle _fireParticle; - deleteVehicle _smokeParticle; - deleteVehicle _fireLight; - deleteVehicle _lightFlare; - deleteVehicle _fireSound; - - if (local _unit) then { - if (!isPlayer _unit) then { - _unit setUnitPos "AUTO"; - _unit setVariable [QGVAR(stopDropRoll), false]; - }; - }; - _unit setVariable [QGVAR(burning), false]; - _unit setVariable [QGVAR(burnCounter), 0]; -}, { - // run condition - true -}, { - // exit condition - (_this getVariable "params") params ["_unit"]; - - private _unitAlive = (alive _unit) && { getNumber ((configOf _unit) >> "isPlayableLogic") != 1 }; - private _unitIsUnit = { (_unit != vehicle _unit) && { isNull vehicle _unit } }; - - !_unitAlive || _unitIsUnit || { _intensity <= BURN_MIN_INTENSITY } || { !([_unit] call FUNC(isBurning)) } -}, ["_intensity", "_fireParticle", "_smokeParticle", "_fireLight", "_fireSound", "_lightFlare", "_lastIntensityUpdate", "_lastPropogateUpdate", "_isThisUnitAlive"]] call CBA_fnc_createPerFrameHandlerObject; +_unit setVariable [QGVAR(jipID), _burnEffectsJipID, true]; diff --git a/addons/fire/functions/fnc_burnEffects.sqf b/addons/fire/functions/fnc_burnEffects.sqf new file mode 100644 index 0000000000..4dadda8526 --- /dev/null +++ b/addons/fire/functions/fnc_burnEffects.sqf @@ -0,0 +1,191 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Spawns particle effects for a burning unit. + * + * Arguments: + * 0: Unit + * + * Return Value: + * None + * + * Example: + * player call ace_fire_fnc_burnEffects + * + * Public: No + */ + +params ["_unit"]; + +// Spawn particles +private _unitPos = getPos _unit; +private _fireParticle = objNull; +private _smokeParticle = objNull; +private _fireLight = objNull; +private _lightFlare = objNull; + +if (hasInterface) then { + _fireParticle = createVehicleLocal ["#particlesource", _unitPos, [], 0, "CAN_COLLIDE"]; + _fireParticle attachTo [_unit]; + _fireParticle setDropInterval 0.03; + + _smokeParticle = createVehicleLocal ["#particlesource", _unitPos, [], 0, "CAN_COLLIDE"]; + + _fireLight = createVehicleLocal ["#lightpoint", _unitPos, [], 0, "CAN_COLLIDE"]; + _fireLight setLightIntensity 0; + _fireLight setLightAmbient [0.8, 0.6, 0.2]; + _fireLight setLightColor [1, 0.5, 0.4]; + _fireLight attachTo [_unit]; + _fireLight setLightDayLight false; + + _lightFlare = createVehicleLocal ["#lightpoint", _unitPos, [], 0, "CAN_COLLIDE"]; + _lightFlare setLightIntensity 0; + _lightFlare setLightColor [1, 0.8, 0.8]; + _lightFlare setLightUseFlare true; + _lightFlare setLightFlareMaxDistance 100; + _lightFlare setLightFlareSize 0; + + if (_unit != ACE_player) then { + private _relativeAttachPoint = vectorNormalized (_unit worldToModelVisual (getPos ACE_player)); + _relativeAttachPoint set [2, 0.5]; + _lightFlare attachTo [_unit, _relativeAttachPoint]; + } else { + _lightFlare attachTo [_unit, [0, 0, 0.3]]; + }; +}; + +private _fireSound = objNull; + +if (isServer) then { + _fireSound = createSoundSource ["Sound_Fire", _unitPos, [], 0]; + _fireSound attachTo [_unit, [0, 0, 0], "Head"]; +}; + +[{ + params ["_args", "_pfhID"]; + _args params ["_unit", "_fireParticle", "_smokeParticle", "_fireLight", "_lightFlare", "_fireSound"]; + + if (isNull _unit || {!(_unit call FUNC(isBurning))}) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + + deleteVehicle _fireParticle; + deleteVehicle _smokeParticle; + deleteVehicle _fireLight; + deleteVehicle _lightFlare; + deleteVehicle _fireSound; + }; + + // Display burn indicators + if (_unit == ACE_player && {alive _unit} && {isNil {_unit getVariable QGVAR(burnUIPFH)}}) then { // This accounts for player remote controlled a new unit + private _burnIndicatorPFH = [LINKFUNC(burnIndicator), 1, _unit] call CBA_fnc_addPerFrameHandler; + _unit setVariable [QGVAR(burnUIPFH), _burnIndicatorPFH]; + }; + + if (!hasInterface) exitWith {}; + + private _intensity = _unit getVariable [QGVAR(intensity), 0]; + + _fireParticle setDropInterval (0.01 max linearConversion [BURN_MAX_INTENSITY, BURN_MIN_INTENSITY, _intensity, 0.03, 0.1, false]); + _fireParticle setParticleParams [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 10, 32], // sprite sheet values + "", // animation name + "Billboard", // particle type + 1, // timer period + 0.7, // lifetime + "destructionEffect2", // position + [0, 0, 1], // move velocity + 0, // rotation velocity + 10, // weight + 7.9, // volume + 1, // rubbing + [0.3, 0.3], // size + [ + [1, 1, 1, -0], + [1, 1, 1, -1], + [1, 1, 1, -1], + [1, 1, 1, -1], + [1, 1, 1, -0] + ], // colour + [0.5, 1], // animation speed + 1, // random dir period + 0, // random dir intensity + "", // on timer script + "", // before destroy script + _unit, // particle source + 0, + false, + 0, + [[0.8, 0.6, 0.2, 1]] // emissive color + ]; + _fireParticle setParticleRandom [ + 0.04 * _intensity, // life time + [0.05, 0.05, 2], // position + [0.05, 0.05, 0.05] vectorMultiply _intensity, // move velocity + 0, // rotation velocity + 0.06 * _intensity, // size + [0, 0, 0, 0], // color + 0, // random direction period + 0 // random direction intensity + ]; + + _smokeParticle setDropInterval 0.15; + _smokeParticle setParticleCircle [0, [0, 0, 0]]; + _smokeParticle setParticleParams [ + ["\A3\data_f\ParticleEffects\Universal\Universal", 16, 7, 48], // sprite sheet values + "", // animation name + "Billboard", // particle type + 1, // timer period + 8, // lifetime + [0, 0, 1.1], // position + [0, 0, 1], // move velocity + 0, // rotation velocity + 10, // weight + 7.9, // volume + 0.066, // rubbing + [1, 3, 6], // size + [ + [0.5, 0.5, 0.5, 0.15], + [0.75, 0.75, 0.75, 0.075], + [1, 1, 1, 0] + ], // colour + [0.125], // animation speed + 1, // random dir period + 0, // random dir intensity + "", // on timer script + "", // before destroy script + _unit // particle source + ]; + _smokeParticle setParticleRandom [ + 0, // life time + [0.25, 0.25, 0], // position + [0.2, 0.2, 0], // move velocity + 0, // rotation velocity + 0.25, // size + [0, 0, 0, 0.1], // color + 0, // random direction period + 0 // random direction intensity + ]; + + _fireLight setLightBrightness ((_intensity * 3) / 10); + _fireLight setLightAttenuation [1, 10 max (5 min (10 - _intensity)), 0, 15]; + + _lightFlare setLightBrightness (_intensity / 30); + _lightFlare setLightFlareSize (_intensity * (3 / 4)) * FLARE_SIZE_MODIFIER; + + if (!GVAR(enableFlare)) then { + _lightFlare setLightFlareSize 0; + }; + + // Always keep flare visible to perceiving unit as long as it isn't the player + if (_unit != ACE_player) then { + private _distanceToUnit = _unit distance ACE_player; + private _relativeAttachPoint = [0, 0, 0.3]; + + if (_distanceToUnit > 1.5) then { + _relativeAttachPoint = (vectorNormalized (_unit worldToModelVisual (getPos ACE_player))) vectorMultiply linearConversion [5, 30, _distanceToUnit, 0.5, 1.5]; + _relativeAttachPoint set [2, 0.3 + ((_unit selectionPosition "pelvis") select 2)]; + }; + + _lightFlare attachTo [_unit, _relativeAttachPoint]; + }; +}, 0, [_unit, _fireParticle, _smokeParticle, _fireLight, _lightFlare, _fireSound]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/fire/functions/fnc_burnIndicator.sqf b/addons/fire/functions/fnc_burnIndicator.sqf index 13db8862c9..5dbc1a8cbf 100644 --- a/addons/fire/functions/fnc_burnIndicator.sqf +++ b/addons/fire/functions/fnc_burnIndicator.sqf @@ -11,26 +11,30 @@ * None * * Example: - * [player, 4] call ace_fire_fnc_burnIndicator + * [player, _pfhID] call ace_fire_fnc_burnIndicator * * Public: No */ -params ["_unit", "_pfhHandle"]; +params ["_unit", "_pfhID"]; -if !(IS_UNCONSCIOUS(_unit)) then { - private _iteration = _unit getVariable [QGVAR(indicatorIteration), 0]; - if (_iteration == 0) then { - QGVAR(indicatorLayer) cutRsc [QGVAR(onFire1), "PLAIN"]; - _iteration = 1; - } else { - QGVAR(indicatorLayer) cutRsc [QGVAR(onFire2), "PLAIN"]; - _iteration = 0; - }; - _unit setVariable [QGVAR(indicatorIteration), _iteration]; +if (!alive _unit || {!(_unit call FUNC(isBurning))}) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + + _unit setVariable [QGVAR(burnUIPFH), nil]; }; -if (!([_unit] call FUNC(isBurning)) || { !alive _unit }) then { - [_pfhHandle] call CBA_fnc_removePerFrameHandler; - _unit setVariable [QGVAR(burnUIPFH), -1]; +// Don't show burn overlay if unconscious or dead +if !(_unit call EFUNC(common,isAwake)) exitWith {}; + +private _iteration = _unit getVariable [QGVAR(indicatorIteration), 0]; + +if (_iteration == 0) then { + QGVAR(indicatorLayer) cutRsc [QGVAR(onFire1), "PLAIN"]; + _iteration = 1; +} else { + QGVAR(indicatorLayer) cutRsc [QGVAR(onFire2), "PLAIN"]; + _iteration = 0; }; + +_unit setVariable [QGVAR(indicatorIteration), _iteration]; diff --git a/addons/fire/functions/fnc_burnReaction.sqf b/addons/fire/functions/fnc_burnReaction.sqf index 748fbbd60e..5a9b75d48c 100644 --- a/addons/fire/functions/fnc_burnReaction.sqf +++ b/addons/fire/functions/fnc_burnReaction.sqf @@ -5,7 +5,6 @@ * * Arguments: * 0: Unit - * 1: Should unit throw its current weapon * * Return Value: * None @@ -13,19 +12,15 @@ * Public: No */ -params ["_unit", ["_throwWeapon", true]]; +params ["_unit"]; if ( - _throwWeapon - && {GVAR(dropWeapon) > 0} - && {_unit in _unit && {(currentWeapon _unit) isNotEqualTo ""}} - && {!isPlayer _unit || GVAR(dropWeapon) >= 2} + GVAR(dropWeapon) > 0 && + {isNull objectParent _unit} && + {(currentWeapon _unit) != ""} && + {!isPlayer _unit || GVAR(dropWeapon) == 2} ) then { - [_unit] call EFUNC(common,throwWeapon); + _unit call EFUNC(common,throwWeapon); }; -if (_unit isKindOf "CAManBase") then { - private _soundID = floor (1 + random 15); - private _sound = format [QGVAR(scream_%1), _soundID]; - [QGVAR(playScream), [_sound, _unit]] call CBA_fnc_globalEvent; -}; +[QGVAR(playScream), [format [QGVAR(scream_%1), floor (1 + random 15)], _unit]] call CBA_fnc_globalEvent; diff --git a/addons/fire/functions/fnc_burnSimulation.sqf b/addons/fire/functions/fnc_burnSimulation.sqf new file mode 100644 index 0000000000..ac98de5dda --- /dev/null +++ b/addons/fire/functions/fnc_burnSimulation.sqf @@ -0,0 +1,175 @@ +#include "..\script_component.hpp" +/* + * Author: tcvm, johnb43 + * Simulates fire intensity over time on burning units. + * Arbitrary values to ignite people. Assumed maximum is "10". + * + * Arguments: + * 0: Unit + * 1: Instigator + * + * Return Value: + * None + * + * Example: + * [player, player] call ace_fire_fnc_burnSimulation + * + * Public: No + */ + +params ["_unit", "_instigator"]; + +[{ + params ["_args", "_pfhID"]; + _args params ["_unit", "_instigator"]; + + if (isNull _unit) exitWith { + TRACE_1("unit is null",_unit); + + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + // Locality has changed + if (!local _unit) exitWith { + TRACE_1("unit is no longer local",_unit); + + _pfhID call CBA_fnc_removePerFrameHandler; + + [QGVAR(burnSimulation), [_unit, _instigator], _unit] call CBA_fnc_targetEvent; + }; + + // If the unit is invulnerable, in water or if the fire has died out, stop burning the unit + if ( + !(_unit call FUNC(isBurning)) || + {!(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]})} || + {private _eyePos = eyePos _unit; surfaceIsWater _eyePos && {(_eyePos select 2) < 0.1}} + ) exitWith { + TRACE_3("unit is no longer burning, invulnerable or in water",_unit,_unit call FUNC(isBurning),isDamageAllowed _unit && {_unit getVariable [ARR_2(QEGVAR(medical,allowDamage),true)]}); + + // Remove global effects + (_unit getVariable [QGVAR(jipID), ""]) call CBA_fnc_removeGlobalEventJIP; + + // Update globally that the unit isn't burning anymore + _unit setVariable [QGVAR(intensity), nil, true]; + + _pfhID call CBA_fnc_removePerFrameHandler; + + if (!isNil {_unit getVariable QGVAR(stopDropRoll)} && {!isPlayer _unit}) then { + _unit setUnitPos "AUTO"; + + _unit setVariable [QGVAR(stopDropRoll), nil, true]; + }; + }; + + if (isGamePaused) exitWith {}; + + private _intensity = _unit getVariable [QGVAR(intensity), 0]; + + // Propagate fire to other units (alive or dead) if it's intense + if (_intensity >= BURN_THRESHOLD_INTENSE) then { + TRACE_2("check for other units",_unit,_intensity); + + { + private _distancePercent = 1 - ((_unit distance _x) / BURN_PROPAGATE_DISTANCE); + private _adjustedIntensity = _intensity * _distancePercent; + + // Don't burn if intensity is too low or already burning with higher intensity + if (BURN_MIN_INTENSITY > _adjustedIntensity || {(_x getVariable [QGVAR(intensity), 0]) > _adjustedIntensity}) then { + continue; + }; + + [QGVAR(burn), [_x, _adjustedIntensity, _instigator], _x] call CBA_fnc_targetEvent; + + TRACE_3("propagate fire",_x,_intensity,_adjustedIntensity); + } forEach nearestObjects [_unit, ["CAManBase"], BURN_PROPAGATE_DISTANCE]; + }; + + // Update intensity/fire reactions + if (CBA_missionTime >= _unit getVariable [QGVAR(intensityUpdate), 0]) then { + TRACE_2("update intensity",_unit,_intensity); + + _unit setVariable [QGVAR(intensityUpdate), CBA_missionTime + INTENSITY_UPDATE]; + + _intensity = _intensity - INTENSITY_LOSS - (rain / 10); + + if (_unit call EFUNC(common,isAwake)) then { + if (_unit call EFUNC(common,isPlayer)) then { + // Decrease intensity of burn if rolling around + if ((animationState _unit) in PRONE_ROLLING_ANIMS) then { + _intensity = _intensity * INTENSITY_DECREASE_MULT_ROLLING; + }; + } else { + private _sdr = _unit getVariable [QGVAR(stopDropRoll), false]; + + private _vehicle = objectParent _unit; + + if (isNull _vehicle && {_sdr || {0.05 > random 1}}) then { + _unit setVariable [QGVAR(stopDropRoll), true, true]; + + if (!_sdr) then { + TRACE_1("stop, drop, roll!",_unit); + + _unit setUnitPos "DOWN"; + doStop _unit; + }; + + // Queue up a bunch of animations + for "_i" from 0 to 2 do { + [_unit, selectRandom ["amovppnemstpsnonwnondnon_amovppnemevasnonwnondl", "amovppnemstpsnonwnondnon_amovppnemevasnonwnondr"], 0] call EFUNC(common,doAnimation); + }; + + _intensity = _intensity - (1 / _intensity); + } else { + // Make the unit leave the vehicle + if (_vehicle != _unit) then { + TRACE_1("Ejecting",_unit); + + _unit leaveVehicle _vehicle; + unassignVehicle _unit; + + _unit action ["Eject", _vehicle]; + }; + + _unit disableAI "TARGET"; + _unit disableAI "AUTOTARGET"; + + // Run away, erraticly + if (leader group _unit != _unit) then { + [_unit] join grpNull; + }; + + _unit doMove ((getPosATL _unit) getPos [20 + random 35, floor (random 360)]); + _unit setSpeedMode "FULL"; + _unit setSuppression 1; + }; + }; + + // Play screams and throw weapon (if enabled) + _unit call FUNC(burnReaction); + }; + + // Keep pain around unconsciousness limit to allow for more fun interactions + private _damageToAdd = [0.15, _intensity / BURN_MAX_INTENSITY] select (!alive _unit || {GET_PAIN_PERCEIVED(_unit) < (PAIN_UNCONSCIOUS + random 0.2)}); + + if (GETEGVAR(medical,enabled,false)) then { + if (!isNull _instigator) then { + _unit setVariable [QEGVAR(medical,lastDamageSource), _instigator]; + _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; + }; + + // Common burn areas are the hands and face https://www.ncbi.nlm.nih.gov/pubmed/16899341/ + private _bodyPart = ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"] selectRandomWeighted [0.77, 0.5, 0.8, 0.8, 0.3, 0.3]; + + // Use event directly, as ace_medical_fnc_addDamageToUnit requires unit to be alive + [QEGVAR(medical,woundReceived), [_unit, [[_damageToAdd, _bodyPart, _damageToAdd]], _instigator, "burn"]] call CBA_fnc_localEvent; + } else { + private _bodyParts = [["HitFace", "HitNeck", "HitHead"], ["HitPelvis", "HitAbdomen", "HitDiaphragm", "HitChest", "HitBody"], ["HitArms", "HitHands"], ["HitLegs"]] selectRandomWeighted [0.77, 0.5, 0.8, 0.3]; + + { + _unit setHitPointDamage [_x, (_unit getHitPointDamage _x) + _damageToAdd, true, _instigator, _instigator]; + } forEach _bodyParts; + }; + + _unit setVariable [QGVAR(intensity), _intensity, true]; // Globally sync intensity across all clients to make sure simulation is deterministic + }; +}, BURN_PROPAGATE_UPDATE, [_unit, _instigator]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/fire/functions/fnc_fireManagerPFH.sqf b/addons/fire/functions/fnc_fireManagerPFH.sqf index fa8e7fb789..924279e3c8 100644 --- a/addons/fire/functions/fnc_fireManagerPFH.sqf +++ b/addons/fire/functions/fnc_fireManagerPFH.sqf @@ -1,43 +1,48 @@ #include "..\script_component.hpp" /* - * Author: tcvm - * Handles various fire objects and determines if local units deserves to get burned. - * Used to handle external burning objects, not used internally because internal methods are more performant. + * Author: tcvm, johnb43 + * Handles various objects on fire and determines if units close to objects deserve to get burned. * * Arguments: - * 0: Unit on fire - * 1: PFH Handle + * None * * Return Value: * None * * Example: - * [ace_fire_fnc_fireManagerPFH, 0.25, [_unit]] call CBA_fnc_addPerFrameHandler + * ace_fire_fnc_fireManagerPFH call CBA_fnc_addPerFrameHandler * * Public: No */ -params ["_args", "_handle"]; +{ + _y params ["_fireLogic", "_radius", "_intensity", "_condition", "_conditionArgs"]; + TRACE_2("fireManagerPFH loop",_x,_y); -[GVAR(fireSources), { - _value params ["", "", "", "_condition", "_conditionArgs"]; - _conditionArgs call _condition; -}] call CBA_fnc_hashFilter; + // Remove when condition is no longer valid + if !(_conditionArgs call _condition) then { + TRACE_2("condition no longer valid, deleting",_x,_y); -[GVAR(fireSources), { - _value params ["_source", "_radius", "_intensity"]; - private _attachedObject = attachedTo _source; - private _sourcePos = getPosATL _source; - if (_attachedObject isNotEqualTo objNull) then { - _sourcePos = getPosATL _attachedObject; + detach _fireLogic; + deleteVehicle _fireLogic; + + GVAR(fireSources) deleteAt _x; + + continue; }; - private _nearEntities = _sourcePos nearEntities ["Man", _radius]; + // Burn units (alive or dead) close to the fire { - private _burning = [_x] call FUNC(isBurning); - if !(_burning) then { - private _distancePercent = 1 - ((_sourcePos distance _x) / _radius); - [QGVAR(burn), [_x, _intensity * _distancePercent]] call CBA_fnc_globalEvent; + private _distancePercent = 1 - ((_fireLogic distance _x) / _radius); + private _adjustedIntensity = _intensity * _distancePercent; + + // Don't burn if intensity is too low or already burning with higher intensity + if (BURN_MIN_INTENSITY > _adjustedIntensity || {(_x getVariable [QGVAR(intensity), 0]) > _adjustedIntensity}) then { + continue; }; - } forEach _nearEntities; -}] call CBA_fnc_hashEachPair; + + [QGVAR(burn), [_x, _adjustedIntensity], _x] call CBA_fnc_targetEvent; + + TRACE_3("propagate fire",_x,_intensity,_adjustedIntensity); + } forEach nearestObjects [_fireLogic, ["CAManBase"], _radius]; +} forEach GVAR(fireSources); diff --git a/addons/fire/functions/fnc_isBurning.sqf b/addons/fire/functions/fnc_isBurning.sqf index 3bdbe560be..04a57c29e6 100644 --- a/addons/fire/functions/fnc_isBurning.sqf +++ b/addons/fire/functions/fnc_isBurning.sqf @@ -1,10 +1,10 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Check if object is burning. + * Check if an object is burning. * * Arguments: - * 0: Vehicle + * 0: Object * * Return Value: * None @@ -15,9 +15,6 @@ * Public: Yes */ -params [["_unit", objNull, [objNull]]]; +params [["_object", objNull, [objNull]]]; -_unit getVariable [QGVAR(burning), false] || { - GVAR(burningPlants) = GVAR(burningPlants) select {!isNull _x}; - _unit in GVAR(burningPlants) -} +(_object getVariable [QGVAR(intensity), 0]) > BURN_MIN_INTENSITY diff --git a/addons/fire/functions/fnc_isPlant.sqf b/addons/fire/functions/fnc_isPlant.sqf deleted file mode 100644 index f132fc72be..0000000000 --- a/addons/fire/functions/fnc_isPlant.sqf +++ /dev/null @@ -1,20 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Check if object is a map placed bush or tree. - * - * Arguments: - * 0: Object - * - * Return Value: - * Is bush or tree? - * - * Example: - * cursorObject call ace_fire_fnc_isPlant - * - * Public: No - */ - -params [["_object", objNull, [objNull]]]; - -_object in nearestTerrainObjects [_object, ["TREE", "SMALL TREE", "BUSH"], 0.1] diff --git a/addons/fire/functions/fnc_medical_canPatDown.sqf b/addons/fire/functions/fnc_medical_canPatDown.sqf index b7efc262b2..758b83b922 100644 --- a/addons/fire/functions/fnc_medical_canPatDown.sqf +++ b/addons/fire/functions/fnc_medical_canPatDown.sqf @@ -18,4 +18,4 @@ params ["", "_patient"]; -[_patient] call FUNC(isBurning) +_patient call FUNC(isBurning) diff --git a/addons/fire/functions/fnc_medical_progress.sqf b/addons/fire/functions/fnc_medical_progress.sqf index 07d99958d6..fd64b5c27d 100644 --- a/addons/fire/functions/fnc_medical_progress.sqf +++ b/addons/fire/functions/fnc_medical_progress.sqf @@ -5,8 +5,8 @@ * * Arguments: * 0: Arguments - * 0: Medic - * 1: Patient + * - 0: Medic (not used) + * - 1: Patient * * Return Value: * Continue pat down @@ -18,6 +18,6 @@ */ params ["_args"]; -_args params ["_medic", "_patient"]; +_args params ["", "_patient"]; -[_patient] call FUNC(isBurning) +_patient call FUNC(isBurning) diff --git a/addons/fire/functions/fnc_medical_success.sqf b/addons/fire/functions/fnc_medical_success.sqf index 78e119a8fa..ca569e1280 100644 --- a/addons/fire/functions/fnc_medical_success.sqf +++ b/addons/fire/functions/fnc_medical_success.sqf @@ -2,10 +2,13 @@ /* * Author: tcvm * Decreases burning intensity on successful medical action. + * The medical action is looped until the user stops the interaction or the unit is no longer burning. * * Arguments: * 0: Medic * 1: Patient + * 2: Body Part + * 3: Treatment * * Return Value: * None @@ -20,17 +23,21 @@ params ["_medic", "_patient", "_bodyPart", "_classname"]; private _intensity = _patient getVariable [QGVAR(intensity), 0]; _intensity = _intensity * INTENSITY_DECREASE_MULT_PAT_DOWN; + _patient setVariable [QGVAR(intensity), _intensity, true]; -if (_intensity > BURN_MIN_INTENSITY) then { - TRACE_1("patient still burning, looping",_this); - - if (EGVAR(medical_gui,pendingReopen)) then { - LOG("temporarily blocking medical menu reopen"); - - EGVAR(medical_gui,pendingReopen) = false; - [{EGVAR(medical_gui,pendingReopen) = true}] call CBA_fnc_execNextFrame; - }; - - [_medic, _patient, _bodyPart, _classname] call EFUNC(medical_treatment,treatment); +// If the unit is still burning, loop the medical action +if !(_patient call FUNC(isBurning)) exitWith { + TRACE_1("patient no longer burning, quitting",_this); }; + +TRACE_1("patient still burning, looping",_this); + +if (EGVAR(medical_gui,pendingReopen)) then { + TRACE_1("temporarily blocking medical menu reopen",_this); + + EGVAR(medical_gui,pendingReopen) = false; + [{EGVAR(medical_gui,pendingReopen) = true}] call CBA_fnc_execNextFrame; +}; + +[_medic, _patient, _bodyPart, _classname] call EFUNC(medical_treatment,treatment); diff --git a/addons/fire/initSettings.sqf b/addons/fire/initSettings.inc.sqf similarity index 50% rename from addons/fire/initSettings.sqf rename to addons/fire/initSettings.inc.sqf index 97963f3e32..d9649c2ad9 100644 --- a/addons/fire/initSettings.sqf +++ b/addons/fire/initSettings.inc.sqf @@ -1,40 +1,40 @@ [ - QGVAR(enabled), "CHECKBOX", + QGVAR(enabled), + "CHECKBOX", [ELSTRING(common,Enabled), LSTRING(Setting_Description)], LSTRING(Category_DisplayName), - true, // default value - true, // isGlobal - {[QGVAR(fireEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true, + 1, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, true // Needs mission restart ] call CBA_fnc_addSetting; [ - QGVAR(enableFlare), "CHECKBOX", + QGVAR(enableFlare), + "CHECKBOX", [LSTRING(Setting_FlareEnable), LSTRING(Setting_FlareDescription)], LSTRING(Category_DisplayName), - false, // default value - true, // isGlobal - {[QGVAR(flareEnabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true // Needs mission restart + false, + 1 ] call CBA_fnc_addSetting; [ - QGVAR(dropWeapon), "LIST", + QGVAR(dropWeapon), + "LIST", [LSTRING(Setting_DropWeapon), LSTRING(Setting_DropWeapon_Description)], LSTRING(Category_DisplayName), [ - [0,1,2], - [localize "STR_A3_OPTIONS_DISABLED", ELSTRING(common,aiOnly), ELSTRING(common,playersAndAI)], + [0, 1, 2], + ["STR_A3_OPTIONS_DISABLED", ELSTRING(common,aiOnly), ELSTRING(common,playersAndAI)], 1 ], - true // isGlobal + 1 ] call CBA_fnc_addSetting; [ - QGVAR(enableScreams), "CHECKBOX", + QGVAR(enableScreams), + "CHECKBOX", [LSTRING(Setting_EnableScreams), LSTRING(Setting_EnableScreams_Description)], LSTRING(Category_DisplayName), - true, - false // isGlobal + true ] call CBA_fnc_addSetting; - diff --git a/addons/fire/script_component.hpp b/addons/fire/script_component.hpp index 86ef159aae..d79ca0d490 100644 --- a/addons/fire/script_component.hpp +++ b/addons/fire/script_component.hpp @@ -16,7 +16,14 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#pragma hemtt flag pe23_ignore_has_include +#if __has_include("\z\ace\addons\medical_engine\script_macros_medical.hpp") #include "\z\ace\addons\medical_engine\script_macros_medical.hpp" +#else +#define GET_PAIN_PERCEIVED(var) 0 +#define PAIN_UNCONSCIOUS 1 +#endif #define FIRE_MANAGER_PFH_DELAY 0.25 #define FLARE_SIZE_MODIFIER 5 @@ -31,9 +38,14 @@ "amovppnemstpsoptwbindnon_amovppnemevasoptwbindr"\ ] - #define BURN_MAX_INTENSITY 10 #define BURN_MIN_INTENSITY 1 #define INTENSITY_DECREASE_MULT_PAT_DOWN 0.8 #define INTENSITY_DECREASE_MULT_ROLLING INTENSITY_DECREASE_MULT_PAT_DOWN + +#define INTENSITY_LOSS 0.02 +#define INTENSITY_UPDATE 2 +#define BURN_PROPAGATE_UPDATE 1 +#define BURN_PROPAGATE_DISTANCE 2 +#define BURN_THRESHOLD_INTENSE 3 diff --git a/addons/fire/stringtable.xml b/addons/fire/stringtable.xml index 494a21265d..dc93a88c2b 100644 --- a/addons/fire/stringtable.xml +++ b/addons/fire/stringtable.xml @@ -7,10 +7,12 @@ ACE Feu ACE Возгорание ACE Feuer + ACE Fuoco ACE Ogień ACE Fuego ACE 火 ACE 불 + ACE Fogo Pat Down Fire @@ -18,10 +20,12 @@ Éteindre le feu Потушить Feuer löschen + Estingui Fuoco Zgaś ogień Extingir el fuego 灭火 불 끄기 + Apagar Fogo Patting down fire... @@ -29,10 +33,12 @@ Feu en cours d'extinction... Тушение... Feuer wird gelöscht... + Estinguendo Fuoco... Gaszenie ognia... Extinguiendo el fuego... 正在灭火... 불 끄는 중... + Apagando Fogo... Allow units to catch fire @@ -40,10 +46,12 @@ Définit si les unités peuvent prendre feu ou non. Включает возгорание Erlaubt, dass Einheiten Feuer fangen können + Permette che unità possono prendere fuoco Zezwól jednostkom na zapalenie się Permitir que las unidades se incendien 允许单位着火 유닛에 불이 붙게합니다 + Permitir que as unidades peguem fogo Enable fire-flare at night @@ -51,10 +59,12 @@ Halo lumineux la nuit Включает сверкание пламени Aktiviert Feuerschein bei Nacht. + Ability luce-fuoco di notte Włącza efekt flary od ognia w nocy Habilitar bengalas de fuego por la noche 在夜间启用耀斑效果 밤에 불로 인한 조명 활성화 + Ativar brilho do fogo à noite Uses a flare effect to increase fire intensity at night @@ -62,10 +72,12 @@ Ajoute un effet de halo lumineux afin d'accroitre l'intensité du feu durant la nuit. Включает ореол пламени для большей интенсивности ночью Benutzt einen Feuerschein-Effekt um die Intensität des Feuers bei Nacht zu verstärken. + Usa un effetto flare per mettere in mostra fuochi di notte Używa efektu flary, aby zwiększyć jasność w nocy Utiliza un efecto de bengala para aumentar la intensidad del fuego por la noche 启用耀斑效果,增加夜间火焰的强度。 야간에 불로 인한 조명을 극대화 시킵니다 + Usa um efeito de brilho para aumentar a intensidade do fogo à noite Enable screams by units on fire @@ -73,10 +85,12 @@ 启用着火单位发出惨叫声 불 붙은 유닛 비명 Schreie von brennenden Einheiten aktivieren + Grida di unità a fuoco Włącz krzyki podpalonych jednostek 炎上中の悲鳴を有効 Вкл. крики от горения Activer les cris des unités en feu + Habilita os gritos das unidades em chamas Enables if units on fire will play the screaming sound @@ -84,10 +98,12 @@ 启用着火的单位是否会发出惨叫声。 불이 붙은 유닛이 소리를 지르게 합니다 Aktiviert, ob brennende Einheiten den Schrei-Ton abspielen + Abilita le grida di unità andate a fuoco Włącza, czy płonące jednostki będą odtwarzać dźwięk krzyku 有効化すると炎上しているユニットが悲鳴を上げます Включает воспроизведение криков когда юнит загорается Active un son de hurlement si les unités sont en feu + Define se as unidades em chamas reproduzirão o som de grito Drop Weapons When on Fire @@ -96,9 +112,11 @@ 着火时扔掉武器 불 붙을 경우 무기 내려놓음 Waffen fallen lassen, wenn in Brand geraten. + Fai cadere armi quando a fuoco 炎上時に武器を落とす Бросать оружие из-за горения Lâche les armes si en feu + Soltar Armas Quando em Chamas Controls whether units drop their weapons when on fire. @@ -107,9 +125,11 @@ 控制单位在着火时是否丢掉武器。 유닛이 불에 붙이면 무기를 떨굴지를 결정합니다. Steuert, ob Einheiten ihre Waffen fallen lassen, wenn sie brennen. + Determina se le unità fanno cadere le proprie armi quando cominciano a bruciare. ユニットが炎上時に武器を落とすかどうかを定義します。 Должны ли юниты выбрасывать оружие когда загораются. Contrôle si les unités lâchent leurs armes lorsqu'elles sont en feu. + Controla se as unidades soltam suas armas quando estão em chamas. diff --git a/addons/flashlights/stringtable.xml b/addons/flashlights/stringtable.xml index 8ca985cf34..2afaa1aacf 100644 --- a/addons/flashlights/stringtable.xml +++ b/addons/flashlights/stringtable.xml @@ -127,6 +127,7 @@ Maglite ML300L Maglite ML300L 매그라이트 ML300L + Maglite ML300L Powerful LED flashlight. @@ -134,7 +135,7 @@ Mocna latarka LED. 強大的LED手電筒 强光 LED 手电筒。 - Torcia a LED ad alta potenza + Torcia a LED molto luminosa Silná LED svítilna. Puissante lampe torche à LED. 強力な LED のフラッシュライト。 @@ -142,6 +143,7 @@ Linterna LED potente Мощный светодиодный фонарь. 고휘도 LED 손전등. + Potente lanterna LED. diff --git a/addons/flashsuppressors/stringtable.xml b/addons/flashsuppressors/stringtable.xml index 51db6008f2..2591ee5398 100644 --- a/addons/flashsuppressors/stringtable.xml +++ b/addons/flashsuppressors/stringtable.xml @@ -5,7 +5,7 @@ Flash Suppressor (6.5 mm) Lángrejtő (6,5 mm) Mündungsfeuerdämpfer (6,5 mm) - Soppressore di fiamma (6.5mm) + Rompifiamma (6.5mm) Supressor de Clarão (6,5mm) Tłumik płomienia (6,5 mm) Tlumič plamene (6,5 mm) @@ -22,7 +22,7 @@ Flash Suppressor (7.62 mm) Lángrejtő (7,62 mm) Mündungsfeuerdämpfer (7,62 mm) - Soppressore di fiamma (7.62mm) + Rompifiamma (7.62mm) Supressor de Clarão (7,62mm) Tłumik płomienia (7,62 mm) Tlumič plamene (7,62 mm) @@ -39,7 +39,7 @@ Flash Suppressor (5.56 mm) Lángrejtő (5,56 mm) Mündungsfeuerdämpfer (5,56 mm) - Soppressore di fiamma (5.56mm) + Rompifiamma (5.56mm) Supressor de Clarão (5,56mm) Tłumik płomienia (5,56 mm) Tlumič plamene (5,56 mm) @@ -56,7 +56,7 @@ Flash Suppressor (.45 ACP) Lángrejtő (.45 ACP) Mündungsfeuerdämpfer (.45 ACP) - Soppressore di fiamma (.45 ACP) + Rompifiamma (.45 ACP) Supressor de Clarão (.45 ACP) Tłumik płomienia (.45 ACP) Tlumič plamene (.45 ACP) @@ -73,7 +73,7 @@ Flash Suppressor (9 mm) Lángrejtő (9 mm) Mündungsfeuerdämpfer (9 mm) - Soppressore di fiamma (9 mm) + Rompifiamma (9mm) Supressor de Clarão (9mm) Tłumik płomienia (9 mm) Tlumič plamene (9 mm) @@ -90,7 +90,7 @@ Flash Suppressor (.338) Lángrejtő (.338) Mündungsfeuerdämpfer (.338) - Soppressore di fiamma (.338) + Rompifiamma (.338) Supressor de Clarão (.338) Tłumik płomienia (.338) Tlumič plamene (.338) @@ -107,7 +107,7 @@ Flash Suppressor (9.3 mm) Lángrejtő (9,3 mm) Mündungsfeuerdämpfer (9,3 mm) - Soppressore di fiamma (9.3mm) + Rompifiamma (9.3mm) Supressor de Clarão (9,3mm) Tłumik płomienia (9,3 mm) Tlumič plamene (9,3 mm) diff --git a/addons/fortify/XEH_preInit.sqf b/addons/fortify/XEH_preInit.sqf index a28aee8445..382fc80566 100644 --- a/addons/fortify/XEH_preInit.sqf +++ b/addons/fortify/XEH_preInit.sqf @@ -13,6 +13,6 @@ GVAR(locations) = []; // Custom deploy handlers GVAR(deployHandlers) = []; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/fortify/functions/fnc_createObjectMarker.sqf b/addons/fortify/functions/fnc_createObjectMarker.sqf index 185ae640eb..ce6fd279b0 100644 --- a/addons/fortify/functions/fnc_createObjectMarker.sqf +++ b/addons/fortify/functions/fnc_createObjectMarker.sqf @@ -29,7 +29,7 @@ private _direction = getDir _object; // Marker name unique to this object private _markerNameStr = format [QGVAR(marker_%1), hashValue _object]; -private _channel = if (GVAR(markObjectsOnMap) == 2) then { 0 } else { 1 }; +private _channel = parseNumber (GVAR(markObjectsOnMap) != 2); private _marker = createMarkerLocal [_markerNameStr, _object, _channel, _unit]; TRACE_2("created",_marker,_channel); 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_deployObject.sqf b/addons/fortify/functions/fnc_deployObject.sqf index 4895b261bc..f7e9e6dbad 100644 --- a/addons/fortify/functions/fnc_deployObject.sqf +++ b/addons/fortify/functions/fnc_deployObject.sqf @@ -70,6 +70,7 @@ private _mouseClickID = [_player, "DefaultAction", {GVAR(isPlacing) == PLACE_WAI [_unit, _object] call FUNC(deployConfirm); } else { TRACE_1("deleting object",_object); + [QGVAR(onDeployStop), [_unit, _object, _cost]] call CBA_fnc_localEvent; deleteVehicle _object; }; }; 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/fortify/functions/fnc_setupModule.sqf b/addons/fortify/functions/fnc_setupModule.sqf index f032d98ebe..1215393a46 100644 --- a/addons/fortify/functions/fnc_setupModule.sqf +++ b/addons/fortify/functions/fnc_setupModule.sqf @@ -48,10 +48,10 @@ if IS_NUMBER(_preset) then { // Legacy support }; private _budget = _logic getVariable ["Budget", -1]; -if (!(_budget isEqualType 0)) then {_budget = -1}; +if !(_budget isEqualType 0) then {_budget = -1}; private _addToolItem = _logic getVariable ["AddToolItem", false]; -if (!(_addToolItem isEqualType false)) then {_addToolItem = false}; +if !(_addToolItem isEqualType false) then {_addToolItem = false}; private _objects = [_preset] call FUNC(getPlaceableSet); diff --git a/addons/fortify/initSettings.sqf b/addons/fortify/initSettings.inc.sqf similarity index 100% rename from addons/fortify/initSettings.sqf rename to addons/fortify/initSettings.inc.sqf diff --git a/addons/fortify/stringtable.xml b/addons/fortify/stringtable.xml index 8e524fbdfd..028cfbd9b2 100644 --- a/addons/fortify/stringtable.xml +++ b/addons/fortify/stringtable.xml @@ -4,8 +4,9 @@ Fortify Verstärken - 要塞 + 野戦築城 요새화 + Fortifica 要塞 设防 Fortyfikowanie @@ -13,11 +14,13 @@ Inşa Etme Fortificar Fortification + Fortificação Fortify Tool Bauwerkzeug - 要塞ツール + Attrezzo di Fortificazione + 築城ツール 요새화 도구 要塞工具 设防工具 @@ -26,11 +29,13 @@ Inşa Etme Aleti Herramienta de Fortificar Outil de fortification + Ferramenta de Fortificação Budget Budget 予算 + Budget 예산 預算 预算 @@ -39,11 +44,13 @@ Bütçe Presupuesto Budget + Provisão Auto add fortify item Füge das Bauwerkzeug automatisch hinzu - 自動的に要塞ツールを追加 + 自動的に築城ツールを追加 + Auto-aggiungi attrezzo di fortificazione 요새화 도구 자동으로 추가 自動增加要塞物品 自动增加设防物品 @@ -52,18 +59,21 @@ Otomatik olarak inşa etme aletini ekle Añadir objeto de Fortificar automáticamente Ajout automatique de l'outil de fortification + Adicionar item de fortificação automaticamente Initializes the Fortify system, with some basic parameters.<br/>Presets are pulled from configFile and missionConfigFile, see wiki for format. Inicjalizuje system fortyfikacji, z podstawowymi parametrami.<br/>Domyślne ustawienia są załadowane z configFile oraz missionConfigFile, odwiedź wiki aby znaleźć format + Inizializza il sistema di fortificazione con alcuni parametri di base.<br/>Preset vengono presi da configFile and missionConfigFile, leggi la wiki per il formato richiesto. Инициализирует систему фортификации с некоторыми базовыми параметрами.<br/>Предустановки взяты из configFile и missionConfigFile, формат смотри на wiki. Inşa etme sistemini bazı temel parametrelerle başlatır. <br/> Ön ayarlar configFile ve missionConfigFile'dan alınır, format için wiki'ye bakın. - 要塞システムを初期設定に戻します。<br/>プリセットは configfile と missionConfigFile から参照されます。詳細は wiki を参照してください。 + 野戦築城システムを初期設定に戻します。<br/>プリセットは configfile と missionConfigFile から参照されます。詳細は wiki を参照してください。 Initialisiert das Verstärken-System, mit grundlegenden Einstellungen <br/>Vorseinstellungen werden aus der configFile und der missionConfigFile gezogen, für mehr Informationen: siehe das ACE Wiki. 使用一些基本参数初始化设防系统。<br/>预设从 configFile 和 missionConfigFile 中提取,参见 wiki 的格式。 기본 파라미터와 함께 요새화 시스템을 활성화합니다<br/>configFile 과 missionConfigFile에서 프리셋을 뽑아옵니다, 포맷은 위키를 참조하십시오. Inicializa el sistema deFortificación con los parámetros básicos. .<br/>Los presets son importados de configFile y de missionConfigFile, consultar la wiki para ver el formato. Initialise le système de fortification, avec quelques paramètres de base.<br/>Les presets sont tirés du configFile et du missionConfigFile, consulter le wiki pour les formats. + Inicializa o sistema de fortificação, com alguns parâmetros básicos.<br/>Os presets são retirados do configFile e do missionConfigFile, consulte a wiki para o formato. Rotate @@ -93,7 +103,7 @@ Conferma Posizionamento Lerak Confirmar implantação - ここで作る + 配置を確定 설치 확인 确认部署 確認佈署 @@ -102,8 +112,9 @@ Fortify: Limit Build Area Verstärken: Beschränke Baubereich - 要塞: 構築制限エリア + 野戦築城: 構築制限エリア 要塞: 限制建造區 + Fortificazione: Limita Area 设防:限制建造区 Fortyfikowanie: Limituj strefe budowania Фортификация: Ограничить зону постройки @@ -111,49 +122,57 @@ 요새화: 건설 영역 제한 Fortificar: Limitar área de construcción Fortification : limiter la zone de construction + Fortificação: Limitar área de construção ACE Fortify ACE Verstärken + ACE Fortificazione ACE 要塞 ACE 设防 - ACE 要塞 + ACE 野戦築城 ACE Fortyfikowanie ACE Фортификация ACE Inşa Etme ACE 요새화 ACE Fortificar ACE Fortification + ACE Fortificação Show budget updates Zeige Budgetveränderungen + Mostra aggiornamenti di budget 顯示預算更新 显示预算更新 - 予算の更新を表示 + 予算更新を表示 Pokaż aktualizacje budżetu Показывать обновления бюджета Bütçe güncellenmelerini göster 비용 업데이트 표시 Mostrar actualizaciones de presupuesto Afficher les changements de budget + Mostrar as atualizações de previsão Controls when budget update hints are shown Bestimmt wann Budgetveränderungen angezeigt werden 決定預算變更時是否會顯示提示 决定预算变更时是否会显示提示 - 予算が更新されヒント表示時の操作を決定します + Controlla se vengono mostrati avvisi di aggiornamento del budget + 予算更新のヒントが表示される場面を制御します Kontroluje kiedy aktualizacje budżetu są wyświetlane Настраивает сообщения об обновлении бюджета Bütçe güncellenince bilgi verilip verilmeyeceğini kontrol eder. 어떤 행동을 취할 때 비용이 표시되는지를 결정합니다 Controla cuándo los avisos de actualizaciones de presupuesto se muestran Détermine quand les modifications de budget sont affichées + Controla quando as atualizações de previsão são mostradas Never show Niemals anzeigen + Non mostrare 永不顯示 永不显示 非表示 @@ -163,23 +182,27 @@ 안 보여줌 No mostrar nunca Ne jamais afficher + Nunca mostrar Has fortify tool Hat Bauewerkzeug + Ha l'attrezzo di fortificazione 有要塞工具 有设防工具 - 要塞ツール所持の時 + 築城ツール所持時 Posiada narzędzie do fortyfikowania Если имеется инструмент Insa Etme Aleti Olanlara Göster 요새화 도구를 들고 있을 때 Tiene herramienta de Fortificar Dispose d'un outil de fortification + Tem ferramenta de fortificação Always show Immer anzeigen + Mostra sempre 總是顯示 总是显示 常に表示 @@ -189,83 +212,98 @@ 항상 보여줌 Mostrar siempre Toujours afficher + Sempre mostrar Time-Cost Coefficient 时间—成本系数 시간-가격 계수 Zeit-Kosten-Koeffizient - 時間コスト係数 + Coefficiente tempo/costo + タイム-コスト係数 Współczynnik Czas-Koszt Коэф. время-цена Coeficiente Tiempo-Coste Coefficient de temps/coût + Coeficiente de Tempo/Custo Coefficient used to determine time to build structure.\nA in Ax + b where x is cost of object 用于确定建造建筑所需时间的系数。\nA是 Ax+b中的一个参数,其中x是物体的成本 건축물을 지을 때 걸리는 시간을 계수를 적용하여 계산합니다. Koeffizient zur Bestimmung der Bauzeit \nA in Ax + b, wobei x die Kosten des Objekts sind. - 建造する時間を決定するために使用される係数。\n計算式はAx + bです。この係数はAであり、xは建造物のコストです。 + Il coefficiente 'C' che determina il tempo di costruzione.\nTempo Totale = Costo * C + Tempo Minimo + 構築する時間を定義するために使用される係数。\n計算式はAx + bです。この係数はAであり、xは構築物のコストです。 Współczynnik używany do określenia czasu budowy konstrukcji.\nA w Ax + b gdzie x jest kosztem obiektu Коэффициент используемый для указания времени необходимого для возведения постройки.\nA в формуле Ax + b, где x - это цена объекта Coeficiente usado para determinar el tiempo de construcción de una estructura.\nA en Ax + b donde x es el coste del objeto Coefficient utilisé pour déterminer le temps de construction d'une structure.\nA dans Ax + b où x est le coût de l'objet. + Coeficiente usado para determinar o tempo para construir uma estrutura.\nA em Ax + b, onde x é o custo do objeto Minimum Build Time 最短建造时间 최소 건축 시간 Minimale Bauzeit - 建造に掛かる最小の時間 + Tempo di costruzione minimo + 最短構築時間 Minimalny czas budowy Мин. время возведения Tiempo mínimo de construcción Temps de construction minimum + Tempo Mínimo de Construção Minimum time to build any structure.\nb in Ax + b where x is cost of object 建造任何建筑的最短时间。\nb是 Ax+b中的一个参数,其中x是物体的成本 건축물을 지을 때 걸리는 최소 시간을 계수를 적용하여 계산합니다. Mindestzeit für den Bau eines beliebigen Bauwerks.\nb in Ax + b, wobei x die Kosten des Objekts sind. - 建造に掛かる最小の時間。\n計算式はAx + bです。この時間はbであり、xは建造物のコストです。 + Tempo minimo necessario per costruire una qualsiasi fortificazione.\nTempo Totale = Costo * CoefT/C + Tempo Minimo + 構築に掛かる最短時間。\n計算式はAx + bです。この時間はbであり、xは構築物のコストです。 Minimalny czas do zbudowania dowolenj konstrukcji.\nb w Ax + b gdzie x jest kosztem obiektu Минимальное время для возведения любой постройки.\nb в формуле Ax + b, где x - это цена объекта Tiempo mínimo para construir una estructura.\nb en Ax + b donde x es el coste del objeto Temps minimum pour construire une structure.\nb dans Ax + b où x est le coût de l'objet. + Tempo mínimo para construir uma estrutura.\nb em Ax + b, onde x é o custo do objeto Building 建造 건설 중 Bauwerk - 建造 + Costruendo + 構築中 Budowanie Возведение Construyendo Construction + Construindo Create map markers 创建地图标记 지도에 마커 생성 Kartenmarkierungen erstellen + Crea marker sulla mappa マップマーカーを生成する Twórz znaczniki na mapie Создавать маркера на карте Crear marcadores de mapa Créer des marqueurs sur carte + Criar marcadores de mapa Create map markers that look like terrain buildings when static fortifications are placed 在放置静态防御工事时,创建看起来像地形建筑的地图标记 건축물을 건설하고 나서 지도에 마커를 생성합니다 Erstellen von Kartenmarkierungen, die wie Gebäude im Gelände aussehen, wenn statische Befestigungen platziert werden - 静的な建築物が配置されたときに地形の建物のように見えるマップマーカーを生成します + Crea marker che appaiono come edifici sulla mappa lì dove vengono costruite fortificazioni + 静的な構築物が配置されたときに地形の建物のように見えるマップマーカーを生成します Utwórz znaczniki mapy, które wyglądają jak obiekty terenu, gdy umieszczane są statyczne fortyfikacje Создавать маркера от статических фортификаций как от зданий на карте Crear marcadores de mapa que tienen la apariencia de edificios del terreno cuando las fortificaciones estáticas son colocadas Créer des marqueurs sur carte qui ressemblent à des bâtiments sur le terrain lorsque des fortifications statiques sont placées + Criar marcadores de mapa que parecem edifícios do terreno quando fortificações estáticas são colocadas Never @@ -288,11 +326,13 @@ 对放置者友军单位 아군 유닛이 지은 건물만 Für, zum Erbauer, verbündete Einheiten. + Per unità alleate al costruttore 設置者の友軍に Dla jednostek sojuszniczych wobec stawiającego Для союзников Para unidades aliadas de quien coloca la fortificación Pour les unités alliées du placeur + Para unidades aliadas do autor da fortificação For everyone @@ -316,11 +356,13 @@ Малый Küçük 小型 + Piccola Klein 小型 소형 Pequeña Petit + Pequena Small (Green) @@ -329,10 +371,12 @@ Küçük (Yeşil) 小型 (グリーン) Klein (Grün) + Piccola (Verde) 小型(绿色) 소형 (초목) Pequeña (Verde) Petit (Vert) + Pequena (Verde) Medium @@ -341,10 +385,12 @@ Orta 中型 Mittel + Media 中型 중형 Mediana Moyen + Média Medium (Green) @@ -353,10 +399,12 @@ Orta (Yeşil) 中型 (グリーン) Mittel (Grün) + Media (Verde) 中型(绿色) 중형 (초목) Mediana (Verde) Moyen (Vert) + Média (Verde) Big @@ -364,11 +412,13 @@ Большой Büyük 大型 + Grande Groß 大型 대형 Grande Grand + Grande Big (Green) @@ -377,10 +427,12 @@ Büyük (Yeşil) 大型 (グリーン) Groß (Grün) + Grande (Verde) 大型(绿色) 대형 (초목) Grande (Verde) Grand (Vert) + Grande (Verde) Big (Both) @@ -389,10 +441,12 @@ Büyük (İkisi de) 大型 (両方) Groß (Beide) + Grande (Entrambe) 大型(两方) 대형 (둘 다) Grande (Ambos) Grand (les deux) + Grande (Ambos) diff --git a/addons/frag/XEH_postInit.sqf b/addons/frag/XEH_postInit.sqf index ecebd793ce..cc58e1d15b 100644 --- a/addons/frag/XEH_postInit.sqf +++ b/addons/frag/XEH_postInit.sqf @@ -2,7 +2,7 @@ if (isServer) then { GVAR(lastFragTime) = -1; - [QGVAR(frag_eh), {_this call FUNC(frago);}] call CBA_fnc_addEventHandler; + [QGVAR(frag_eh), LINKFUNC(frago)] call CBA_fnc_addEventHandler; }; ["CBA_settingsInitialized", { @@ -18,7 +18,7 @@ if (isServer) then { }] call CBA_fnc_addEventHandler; // Cache for ammo type configs -GVAR(cacheRoundsTypesToTrack) = [false] call CBA_fnc_createNamespace; +GVAR(cacheRoundsTypesToTrack) = createHashMap; // Debug stuff: diff --git a/addons/frag/XEH_preInit.sqf b/addons/frag/XEH_preInit.sqf index f4f59e681a..dc616917b8 100644 --- a/addons/frag/XEH_preInit.sqf +++ b/addons/frag/XEH_preInit.sqf @@ -20,6 +20,6 @@ GVAR(lastIterationIndex) = 0; GVAR(objects) = []; GVAR(arguments) = []; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/frag/functions/fnc_addPfhRound.sqf b/addons/frag/functions/fnc_addPfhRound.sqf index 7c2b5d1681..358a9ee71e 100644 --- a/addons/frag/functions/fnc_addPfhRound.sqf +++ b/addons/frag/functions/fnc_addPfhRound.sqf @@ -67,7 +67,7 @@ if (alive _round) then { getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(force)), getNumber (configFile >> "CfgAmmo" >> _type >> "indirecthit") * (sqrt (getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange"))) ]; - TRACE_1("Initializing track", _round); + TRACE_1("Initializing track",_round); GVAR(objects) pushBack _round; GVAR(arguments) pushBack _args; 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_doReflections.sqf b/addons/frag/functions/fnc_doReflections.sqf index 023a283e81..70c7471181 100644 --- a/addons/frag/functions/fnc_doReflections.sqf +++ b/addons/frag/functions/fnc_doReflections.sqf @@ -22,5 +22,5 @@ if (_depth <= 2) then { private _indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"); private _indirectHit = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirectHit"); private _testParams = [_pos, [_indirectHitRange, _indirectHit], [], [], -4, _depth, 0]; - [DFUNC(findReflections), 0, _testParams] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(findReflections), 0, _testParams] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/frag/functions/fnc_doSpall.sqf b/addons/frag/functions/fnc_doSpall.sqf index 8b5a06d812..b206c701b2 100644 --- a/addons/frag/functions/fnc_doSpall.sqf +++ b/addons/frag/functions/fnc_doSpall.sqf @@ -25,7 +25,7 @@ private _hpData = (_hitData select 1) select _hitPartDataIndex; private _objectHit = _hpData param [0, objNull]; TRACE_1("",_objectHit); if ((isNil "_objectHit") || {isNull _objectHit}) exitWith {WARNING_1("Problem with hitPart data - bad object [%1]",_objectHit);}; -_objectHit removeEventHandler ["hitPart", _hpId]; +_objectHit removeEventHandler ["HitPart", _hpId]; private _caliber = getNumber (configFile >> "CfgAmmo" >> _roundType >> "caliber"); private _explosive = getNumber (configFile >> "CfgAmmo" >> _roundType >> "explosive"); diff --git a/addons/frag/functions/fnc_findReflections.sqf b/addons/frag/functions/fnc_findReflections.sqf index b0ae161597..a753934fe8 100644 --- a/addons/frag/functions/fnc_findReflections.sqf +++ b/addons/frag/functions/fnc_findReflections.sqf @@ -65,7 +65,7 @@ if (_zIndex < 5) then { while {count _nlos != count _excludes && {_c < (count _nlos)}} do { scopeName "mainSearch"; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x; @@ -74,7 +74,7 @@ if (_zIndex < 5) then { }; } forEach _nlos; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { _testPos = _x; if (_testPos vectorDistanceSqr _bucketPos <= 30) then { _bucketList pushBack _x; @@ -120,7 +120,7 @@ if (_zIndex < 5) then { // _dirvec = _pos vectorFromTo ((player modelToWorldVisualWorld (player selectionPosition "Spine3"))); // _dirvec = _dirvec vectorMultiply 100; // _can setVelocity _dirvec; - [DFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler; [_pfhID] call CBA_fnc_removePerFrameHandler; }; END_COUNTER(fnc_findReflections); diff --git a/addons/frag/functions/fnc_fired.sqf b/addons/frag/functions/fnc_fired.sqf index 355da901c6..03d2fab609 100644 --- a/addons/frag/functions/fnc_fired.sqf +++ b/addons/frag/functions/fnc_fired.sqf @@ -17,9 +17,9 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -private _shouldAdd = GVAR(cacheRoundsTypesToTrack) getVariable _ammo; +private _shouldAdd = GVAR(cacheRoundsTypesToTrack) get _ammo; if (isNil "_shouldAdd") then { TRACE_1("no cache for round",_ammo); @@ -40,7 +40,7 @@ if (isNil "_shouldAdd") then { }; TRACE_6("Setting Cache",_skip,_explosive,_indirectRange,_force,_fragPower,_shouldAdd); - GVAR(cacheRoundsTypesToTrack) setVariable [_ammo, _shouldAdd]; + GVAR(cacheRoundsTypesToTrack) set [_ammo, _shouldAdd]; }; if (_shouldAdd) then { diff --git a/addons/frag/functions/fnc_frago.sqf b/addons/frag/functions/fnc_frago.sqf index f2700654c3..8fd77dbc73 100644 --- a/addons/frag/functions/fnc_frago.sqf +++ b/addons/frag/functions/fnc_frago.sqf @@ -127,7 +127,7 @@ if (_objects isNotEqualTo []) then { if (_currentCount < 10) then { private _count = ceil (random (sqrt (_m / 1000))); private _vecVar = FRAG_VEC_VAR; - if (!(_target isKindOf "Man")) then { + if !(_target isKindOf "Man") then { ADD(_vecVar,(sqrt _cubic) / 2000); if ((crew _target) isEqualTo [] && {_count > 0}) then { _count = 0 max (_count / 2); @@ -144,7 +144,7 @@ if (_objects isNotEqualTo []) then { private _vel = _vec vectorMultiply _fp; private _fragObj = (selectRandom _fragTypes) createVehicleLocal [0,0,10000]; - // TRACE_4("targeted",_fp, typeOf _fragObj,_lastPos vectorDistance _targetPos,typeOf _x); + // TRACE_4("targeted",_fp,typeOf _fragObj,_lastPos vectorDistance _targetPos,typeOf _x); _fragObj setPosASL _lastPos; _fragObj setVectorDir _vec; _fragObj setVelocity _vel; diff --git a/addons/frag/functions/fnc_masterPFH.sqf b/addons/frag/functions/fnc_masterPFH.sqf index 6e75e80951..004af9a9ce 100644 --- a/addons/frag/functions/fnc_masterPFH.sqf +++ b/addons/frag/functions/fnc_masterPFH.sqf @@ -34,7 +34,7 @@ while {_objectCount > 0 && {_iter < (GVAR(maxTrackPerFrame) min _objectCount)}} if (!isNil "_object") then { private _args = GVAR(arguments) select GVAR(lastIterationIndex); - if (!(_args call FUNC(pfhRound))) then { + if !(_args call FUNC(pfhRound)) then { _gcIndex pushBack GVAR(lastIterationIndex); // Add it to the GC if it returns false }; }; @@ -45,7 +45,7 @@ while {_objectCount > 0 && {_iter < (GVAR(maxTrackPerFrame) min _objectCount)}} // Clean up dead object references private _deletionCount = 0; { - TRACE_1("GC Projectile", _x); + TRACE_1("GC Projectile",_x); private _deleteIndex = _x - _deletionCount; GVAR(objects) deleteAt _deleteIndex; GVAR(arguments) deleteAt _deleteIndex; diff --git a/addons/frag/functions/fnc_pfhRound.sqf b/addons/frag/functions/fnc_pfhRound.sqf index bd5a229f0e..0c261dcffb 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); @@ -41,7 +41,7 @@ if (!alive _round) exitWith { TRACE_1("doSpall",_foundObjectHPIds); { if (!isNil "_x") then { - _x removeEventHandler ["hitPart", _foundObjectHPIds select _forEachIndex]; + _x removeEventHandler ["HitPart", _foundObjectHPIds select _forEachIndex]; }; } forEach _spallTrack; }; diff --git a/addons/frag/functions/fnc_spallTrack.sqf b/addons/frag/functions/fnc_spallTrack.sqf index 43dae8afcb..50ca64b6ec 100644 --- a/addons/frag/functions/fnc_spallTrack.sqf +++ b/addons/frag/functions/fnc_spallTrack.sqf @@ -31,7 +31,7 @@ if (_intersectsWith isEqualTo []) exitWith {}; { // diag_log text format ["Adding HP: %1", _x]; private _index = count GVAR(spallHPData); - private _hpId = _x addEventHandler ["hitPart", compile format ["[%1, _this] call " + QFUNC(spallHP), _index]]; + private _hpId = _x addEventHandler ["HitPart", compile format ["[%1, _this] call " + QFUNC(spallHP), _index]]; _foundObjects pushBack _x; _foundObjectHPIds pushBack _hpId; private _data = [_hpId, _x, typeOf _round, _round, _curPos, _velocity, 0, _foundObjects, _foundObjectHPIds]; diff --git a/addons/frag/initSettings.sqf b/addons/frag/initSettings.inc.sqf similarity index 100% rename from addons/frag/initSettings.sqf rename to addons/frag/initSettings.inc.sqf diff --git a/addons/frag/stringtable.xml b/addons/frag/stringtable.xml index 1ece6a973e..f88877448d 100644 --- a/addons/frag/stringtable.xml +++ b/addons/frag/stringtable.xml @@ -90,7 +90,7 @@ Simulation de la réflexion des explosions Simulação de reflexo de explosão Cимуляция отражения взрывов ACE - 爆発による飛翔シミュレーション + 爆発反射シミュレーション 폭발 반사 시뮬레이션 模拟爆炸反射 模擬爆炸反射 @@ -105,7 +105,7 @@ Active la simulation de la réflexion des explosions ACE. Ativa a simulação de reflexo de explosão do ACE Включить симуляцию отражения взрывов ACE - 爆発による飛翔シミュレーションを有効化 + ACE 爆発反射シミュレーションを有効化 ACE 폭발 반사 시뮬레이션을 적용합니다. 启用 ACE 模拟爆炸反射 啟用ACE模擬爆炸反射 @@ -122,7 +122,7 @@ Maximum követett repeszek Макс. количество отслеживаемых снарядов Numero massimo di Proiettili Tracciati - 最大弾頭追跡数 + 飛翔体最大追跡数 최대 발사체 추적수 最大破片粒子追踪数量 最大碎片/剝落粒子追蹤數量 @@ -136,9 +136,9 @@ 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 одновременно летящих снарядов) - Questo parametro controlla il numero massimo di proiettili che la frammentazione e il sistema di spalling tracciano in ogni momento. Se più proiettili sono sparati, non verranno tracciati. Abbassa questo parametro se non vuoi cali di FPS in scenari con molti proiettili (>200 proiettili in aria contemporaneamente) - 時間が許すかぎり、破片と剥離システムの最大数を設定できます。設定数以上の弾丸が発射された場合、それは対象になりません。もし多い弾数による FPS の低下を望まない場合は、低い数へ設定にします。( &gt;一度に空中内で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개 이하) 设定在指定时间内,系统最大可追踪的破片粒子数量。如有更多的碎片在这之后产生,这些粒子将不会被追踪。如果你想要维持好的帧数,此设定勿调的过高。( >一次200颗粒子) 設定在指定時間內,系統最大可追蹤的碎片/剝落粒子數量。如有更多的碎片在這之後產生,這些粒子將不會被追蹤。如果你想要維持好的幀數,此設定勿調的過高。( >一次200顆粒子) @@ -154,7 +154,7 @@ Maximum repesz/képkocka Макс. количество снарядов за кадр Numero massimo di proiettili per Frame - フレームごとの最大弾頭数 + フレームごとの飛翔体最大数 프레임 당 최대 발사체 수 每帧最大破片粒子数量 每一幀數(FPS)最大碎片/剝落粒子數量 @@ -169,8 +169,8 @@ Le nombre de calculs de suivi à effectuer pour chaque image. Cela aide à répartir l'impact des calculs sur plusieurs images, limitant ainsi encore davantage l'impact sur les FPS. A lepattogzási útvonalak számításának darabjai képkockánként. Ez eloszlatja az FPS-megszakadást több képkockára, ezzel csökkentve a súlyosságát. Число обрабатываемых осколков за кадр. Это позволяет распределить нагрузку по отслеживанию осколков между несколькими кадрами, чтобы предотвратить падение FPS. - Il numero di calcoli per tracciamento di spalling ad ogni frame. Questo aiuta a distribuire l'impatto del tracciamento dello spalling su più frame, limitando ancora di più l'impatto. - 与えられたフレームごとに追跡する剥離の数を決定します。FPS に影響をあたえないよう、剥離を複数のフレームで追跡し、分散させています。 + Il numero di calcoli per tracciamento di spalling ad ogni frame. Questo aiuta a distribuire l'impatto del tracciamento dello spalling su più frame, riducendolo ulteriormente. + 任意のフレームごとに追跡される剥離飛翔体の数。剥離による飛翔体を追跡することによるFPSへの影響を複数フレームに分散させ抑えることが出来ます。 가능한 프레임마다 파편을 추적 및 계산합니다. 여러 프레임에 걸쳐 파편난 발사체를 추적하여 FPS에 도움을 줍니다. 이를 제한함으로써 더욱 큰 효과를 볼 수 있습니다. 设定在每一帧数内,系统最大可追踪的破片粒子数量。此设定可有效帮助系统减低计算压力。 設定在每一幀數內,系統最大可追蹤的碎片/剝落粒子數量。此設定可有效幫助系統減低計算壓力 @@ -202,7 +202,7 @@ (Csak SP) Küldetés/Editor újraindítás szükséges. Engedélyezi a repeszek és pattogzó lövedékek vizuális nyomkövetését, csak egyjátékos módok alatt. (Только для одиночной игры) Требует перезапуска миссии/редактора. Включает визуальные следы от осколков и обломков в режиме одиночной игры. (Solo SP) Richiede un restart editor/missione. Abilita il tracciamento visivo di schegge da frammentazione/spalling in modalità Giocatore Singolo. - (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の弾頭が見えるようになります。 + (SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の飛翔体が見えるようになります。 (仅单人)激活后,只有在单人模式下才可观察到破片粒子的移动轨迹。 (僅在單人模式) 讓你在單人模式下可觀察到碎片/剝落粒子的移動軌跡 (SP 전용) 임무 / 편집자가 다시 시작해야합니다. SP 게임 모드에서만 파편화 및 탄환파편의 시각적 추적을 가능하게 합니다. diff --git a/addons/gestures/XEH_postInit.sqf b/addons/gestures/XEH_postInit.sqf index 935b81aa61..5133f48c41 100644 --- a/addons/gestures/XEH_postInit.sqf +++ b/addons/gestures/XEH_postInit.sqf @@ -31,9 +31,7 @@ if (!hasInterface) exitWith {}; [_key, [false, (_key != -1), false]], false ] call CBA_fnc_addKeybind; - - false -} count [ +} forEach [ ["Freeze", 80], // Numpad 2 ["Cover", 81], // Numpad 3 ["Forward", 75], // Numpad 4 diff --git a/addons/gestures/XEH_preInit.sqf b/addons/gestures/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/gestures/XEH_preInit.sqf +++ b/addons/gestures/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/gestures/initSettings.sqf b/addons/gestures/initSettings.inc.sqf similarity index 100% rename from addons/gestures/initSettings.sqf rename to addons/gestures/initSettings.inc.sqf diff --git a/addons/gestures/stringtable.xml b/addons/gestures/stringtable.xml index 8d77e28a83..0f483e17a2 100644 --- a/addons/gestures/stringtable.xml +++ b/addons/gestures/stringtable.xml @@ -12,7 +12,7 @@ ACE Gestos ACE Жесты ACE Gestos - ACE ジェスチャー + ACE ジェスチャ ACE 수신호 ACE 手势 ACE 手勢 @@ -29,7 +29,7 @@ ACE Gestos ACE Жесты ACE Gestos - ACE ジェスチャー + ACE ジェスチャ ACE 수신호 ACE 手势 ACE 手勢 @@ -46,7 +46,7 @@ Kézjelek Gestos Gesti - ジェスチャー + ジェスチャ 수신호 手势 手勢 @@ -63,7 +63,7 @@ Előre Avançar Avanzare - 警戒 + 前進 전진 前进 前進 @@ -80,7 +80,7 @@ Mozgás Mover-se Muoversi - 進め + 行け 이동 出发 出發 @@ -114,7 +114,7 @@ Fel Acima Alzarsi - 立ち上がれ + 立て 起立 起立 @@ -195,7 +195,7 @@ Собраться Reagrupar Přeskupit - Raggruppare + Raggrupparsi Reunirse 集合 집결 @@ -243,7 +243,7 @@ Показать направление Ponta Ukázat - Puntare + Punta Señalar 指示 가리키기 @@ -288,12 +288,12 @@ Zeige Gesten im Interaktionsmenü Zobrazit posunky v interakčním menu Pokaż gesty w menu interakcji - Mostra Gesti su Menù Interazione + Mostra Gesti nel Menù Interazione Mostrar gestos en el menú de interacción Afficher les gestes dans le menu d'interaction Mostrar gestos no menu de interação Показать жесты в меню взаимодействия - インタラクション メニュー上でジェスチャー表示 + ジェスチャのアクションを表示 수신호를 상호작용 메뉴에서 보여줍니다 显示手势互动菜单 顯示手勢互動選單 @@ -309,7 +309,7 @@ Afficher les gestes dans le menu d'interaction personnel, ou utiliser uniquement les touches, ou désactiver complètement. Mostra gestos no menu de interação, ou utilize um dos atalhos de teclado ou desative completamente Показать жесты в меню взамиодейтсвия с собой или только использовать горячие клавиши, или полностью отключить - キー操作や同時使用を無効化している場合はセルフ インタラクション メニュ上でジェスチャーを表示します + セルフ・インタラクション メニューにジェスチャのアクションを表示するか、キーバインドのみを使用するか、完全に無効にします 수신호를 상호작용 메뉴에서 보여주거나 혹은 단축키를 지정하거나 아니면 아예 사용하지 않습니다. 显示手势选项在自己的互动菜单上,或只利用键盘来使用手势,或完全禁用 顯示手勢選項在自己的互動選單上,或只利用鍵盤來使用手勢,或完全禁用 @@ -341,7 +341,7 @@ Touches + menu d'interaction Atalhos + Menu de Interação Клавиши + Меню взаимодействия - キー操作とインタラクション メニュ + キー操作とメニュー 단축키 및 상호작용 메뉴 键盘 + 互动菜单 鍵盤 + 互動選單 diff --git a/addons/gforces/XEH_postInit.sqf b/addons/gforces/XEH_postInit.sqf index a2f69dd608..d0d58488d3 100644 --- a/addons/gforces/XEH_postInit.sqf +++ b/addons/gforces/XEH_postInit.sqf @@ -12,8 +12,7 @@ GVAR(playerIsVirtual) = false; ["unit", { // Add unit changed EH to check if player is either virtual (logic) or a UAV AI params ["_unit"]; - GVAR(playerIsVirtual) = ((getNumber (configOf _unit >> "isPlayableLogic")) == 1) || - {(getText (configOf _unit >> "simulation")) == "UAVPilot"}; + GVAR(playerIsVirtual) = unitIsUAV _unit || {(getNumber (configOf _unit >> "isPlayableLogic")) == 1}; TRACE_3("unit changed",_unit,typeOf _unit,GVAR(playerIsVirtual)); }, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/gforces/XEH_preInit.sqf b/addons/gforces/XEH_preInit.sqf index 4987bcc61d..55e142c18b 100644 --- a/addons/gforces/XEH_preInit.sqf +++ b/addons/gforces/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(GForces) = []; GVAR(GForces_Index) = 0; diff --git a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf index 13d08f833b..487ba15b2a 100644 --- a/addons/gforces/functions/fnc_pfhUpdateGForces.sqf +++ b/addons/gforces/functions/fnc_pfhUpdateGForces.sqf @@ -71,13 +71,13 @@ private _suitCoef = if ((uniform ACE_player) != "") then { private _gBlackOut = MAXVIRTUALG / _classCoef + MAXVIRTUALG / _suitCoef - MAXVIRTUALG; // Unconsciousness -if ((_average > _gBlackOut) && {["ACE_Medical"] call EFUNC(common,isModLoaded) && {!(ACE_player getVariable ["ACE_isUnconscious", false])}}) then { +if (_average > _gBlackOut && {GETEGVAR(medical,enabled,false) && {ACE_player call EFUNC(common,isAwake)}}) then { [ACE_player, true, (10 + floor(random 5)), true] call EFUNC(medical,setUnconscious); }; GVAR(GForces_CC) ppEffectAdjust [1,1,0,[0,0,0,1],[0,0,0,0],[1,1,1,1],[10,10,0,0,0,0.1,0.5]]; -if !(ACE_player getVariable ["ACE_isUnconscious", false]) then { +if (ACE_player call EFUNC(common,isAwake)) then { if (_average > 0.30 * _gBlackOut) then { private _strength = ((_average - 0.30 * _gBlackOut) / (0.70 * _gBlackOut)) max 0; GVAR(GForces_CC) ppEffectAdjust [1,1,0,[0,0,0,1],[0,0,0,0],[1,1,1,1],[2 * (1 - _strength),2 * (1 - _strength),0,0,0,0.1,0.5]]; diff --git a/addons/gforces/initSettings.sqf b/addons/gforces/initSettings.inc.sqf similarity index 100% rename from addons/gforces/initSettings.sqf rename to addons/gforces/initSettings.inc.sqf diff --git a/addons/gforces/stringtable.xml b/addons/gforces/stringtable.xml index 524e456899..b84bcb01f1 100644 --- a/addons/gforces/stringtable.xml +++ b/addons/gforces/stringtable.xml @@ -10,8 +10,10 @@ ACE G-Kuvveti ACE Fuerza G ACE G-Kräfte + ACE Forze-G ACE G力 ACE 중력가속도 + ACE Força G Gforces Effects @@ -24,7 +26,7 @@ G による効果 Efekty przeciążeń 중력가속도 효과 - Effetti forza G + Effetti Forze-G G力影响 G力影響 G-Kuvveti Efekti @@ -49,13 +51,13 @@ G-force reduction G-Kräfte Reduzierung Réduction des Gs - 耐 G 性 + 耐G性 减少G力 減少G力 - Riduzione forza G + Riduzione forze-G Redukcja przeciążenia Уменьшение перегрузок - Redução de Força-G + Redução de Força G Redukce G Force Reducción de fuerzas G G-Kuvvetinde azalma @@ -66,24 +68,28 @@ Współczynnk przeciążenia Coefficient de force gravitationnelle Коэф. перегрузки - G 効果係数 + G効果係数 G-Kuvvet Katsayısı Coeficiente de Fuerza G G-Kräfte-Koeffizient + Coefficiente Forze-G G力系数 중력가속도 계수 + Coeficiente de Força G Controls strength of G-Force affecting players. Wpływa na siłe przeciążeń oddziałujących na graczy Coefficient permettant d'ajuster le niveau de force gravitationnelle affectant les joueurs. Определяет силу перегрузок, влияющих на игроков. - G 効果がプレイヤーに与える影響量を設定できます。 + G効果がプレイヤーに与える影響量を設定できます。 Oyuncuları etkileyen G-Force'un gücünü kontrol eder. Controla la intensidad de fuerza G que afecta a los jugadores. Bestimmt, wie stark G-Kräfte Spieler beeinflussen. + Controlla quanto fortemente i giocatori sono influenzati da Forze-G. 控制影响玩家的G力的强度。 플레이어에게 영향을 끼칠 중력가속도의 계수를 조절합니다. + Controla a intensidade da Força G que afeta os jogadores. diff --git a/addons/goggles/XEH_postInit.sqf b/addons/goggles/XEH_postInit.sqf index 7700d4cc81..e5a6bf5d1c 100644 --- a/addons/goggles/XEH_postInit.sqf +++ b/addons/goggles/XEH_postInit.sqf @@ -88,10 +88,10 @@ if (!hasInterface) exitWith {}; if (GVAR(effects) in [2, 3]) then { // Register fire event handler - ["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; //Add Explosion XEH - ["CAManBase", "explosion", FUNC(handleExplosion)] call CBA_fnc_addClassEventHandler; + ["CAManBase", "explosion", LINKFUNC(handleExplosion)] call CBA_fnc_addClassEventHandler; GVAR(PostProcessEyes) = ppEffectCreate ["ColorCorrections", 1992]; GVAR(PostProcessEyes) ppEffectAdjust [1, 1, 0, [0, 0, 0, 0], [0, 0, 0, 1], [1, 1, 1, 0]]; diff --git a/addons/goggles/XEH_preInit.sqf b/addons/goggles/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/goggles/XEH_preInit.sqf +++ b/addons/goggles/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/goggles/functions/fnc_applyRainEffect.sqf b/addons/goggles/functions/fnc_applyRainEffect.sqf index 3332db536a..0058209acd 100644 --- a/addons/goggles/functions/fnc_applyRainEffect.sqf +++ b/addons/goggles/functions/fnc_applyRainEffect.sqf @@ -22,7 +22,7 @@ if (!alive _unit) exitWith {}; private _fnc_underCover = { params ["_unit"]; - if (vehicle _unit != _unit && {!isTurnedOut _unit}) exitWith {true}; + if (!isNull objectParent _unit && {!isTurnedOut _unit}) exitWith {true}; // looking up and no roof over head private _position = eyePos _unit; diff --git a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf index 3513eb191a..85b7e60934 100644 --- a/addons/goggles/functions/fnc_applyRotorWashEffect.sqf +++ b/addons/goggles/functions/fnc_applyRotorWashEffect.sqf @@ -23,7 +23,7 @@ if (!alive _unit) exitWith {}; GVAR(FrameEvent) set [0, !(GVAR(FrameEvent) select 0)]; if (GVAR(FrameEvent) select 0) exitWith { - if (vehicle _unit != _unit && {!isTurnedOut _unit}) exitWith { + if (!isNull objectParent _unit && {!isTurnedOut _unit}) exitWith { (GVAR(FrameEvent) select 1) set [0, false]; }; diff --git a/addons/goggles/functions/fnc_canWipeGlasses.sqf b/addons/goggles/functions/fnc_canWipeGlasses.sqf index ef9d961bc1..cb24b4137a 100644 --- a/addons/goggles/functions/fnc_canWipeGlasses.sqf +++ b/addons/goggles/functions/fnc_canWipeGlasses.sqf @@ -15,4 +15,4 @@ * Public: No */ -GVAR(effects) in [2, 3] && {!GETVAR(ACE_player,ACE_isUnconscious,false)} // return +GVAR(effects) in [2, 3] && {ACE_player call EFUNC(common,isAwake)} // return diff --git a/addons/goggles/functions/fnc_handleFired.sqf b/addons/goggles/functions/fnc_handleFired.sqf index ea3455dcee..0c711169ef 100644 --- a/addons/goggles/functions/fnc_handleFired.sqf +++ b/addons/goggles/functions/fnc_handleFired.sqf @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); // no dust in rain if (rain > 0.1) exitWith {true}; diff --git a/addons/goggles/functions/fnc_isInRotorWash.sqf b/addons/goggles/functions/fnc_isInRotorWash.sqf index 8c3b29723d..6784e9db12 100644 --- a/addons/goggles/functions/fnc_isInRotorWash.sqf +++ b/addons/goggles/functions/fnc_isInRotorWash.sqf @@ -36,7 +36,6 @@ private _rotorWash = [false, 0]; _rotorWash set [1, _distance]; }; }; - false -} count (position _unit nearEntities [["Helicopter"], _radius]); +} forEach (position _unit nearEntities [["Helicopter"], _radius]); _rotorWash diff --git a/addons/goggles/initSettings.sqf b/addons/goggles/initSettings.inc.sqf similarity index 100% rename from addons/goggles/initSettings.sqf rename to addons/goggles/initSettings.inc.sqf diff --git a/addons/goggles/stringtable.xml b/addons/goggles/stringtable.xml index 34c02cbdab..233ac3e6ca 100644 --- a/addons/goggles/stringtable.xml +++ b/addons/goggles/stringtable.xml @@ -101,8 +101,8 @@ Effects - эффекты - 効果 + Эффекты + エフェクト Efekty Effekte 효과 @@ -118,7 +118,7 @@ Tint + Effects Тонировка + эффекты - 色彩 + 効果 + 色彩 + エフェクト Winieta + Efekty Tönung + Effekte 색조+효과 @@ -137,7 +137,7 @@ Pokaż interakcję Wyczyść Gogle Mostra interazione automatica per la pulizia degli occhiali Ukaž Vyčistit brýle v menu Interakce (vlastní) - ゴーグル拭き取りをセルフ インタラクションに表示 + ゴーグル拭き取りのアクションを表示 在自我互動中顯示擦拭護目鏡的動作 在自我互动中显示擦拭护目镜的动作 Afficher l'interaction "Essuyer les lunettes" diff --git a/addons/grenades/CfgAmmo.hpp b/addons/grenades/CfgAmmo.hpp index 5082dd432d..2b0849d2f7 100644 --- a/addons/grenades/CfgAmmo.hpp +++ b/addons/grenades/CfgAmmo.hpp @@ -1,4 +1,3 @@ - class CfgAmmo { class Default; class Grenade: Default { @@ -153,7 +152,7 @@ class CfgAmmo { class ACE_G_M14: SmokeShell { GVAR(incendiary) = 1; model = QPATHTOF(models\ace_anm14th3_armed.p3d); - hit = 5; + hit = 10; indirectHit = 4; indirectHitRange = 1.1; dangerRadiusHit = 50; diff --git a/addons/grenades/CfgEventHandlers.hpp b/addons/grenades/CfgEventHandlers.hpp index 6c29240403..f6503c2479 100644 --- a/addons/grenades/CfgEventHandlers.hpp +++ b/addons/grenades/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/grenades/CfgMagazines.hpp b/addons/grenades/CfgMagazines.hpp index ea4641ab7f..2ff86c443d 100644 --- a/addons/grenades/CfgMagazines.hpp +++ b/addons/grenades/CfgMagazines.hpp @@ -1,4 +1,3 @@ - class CfgMagazines { class HandGrenade; class ACE_HandFlare_Base: HandGrenade { diff --git a/addons/grenades/CfgVehicles.hpp b/addons/grenades/CfgVehicles.hpp index f9ac60d9fe..34cf4196e6 100644 --- a/addons/grenades/CfgVehicles.hpp +++ b/addons/grenades/CfgVehicles.hpp @@ -1,4 +1,3 @@ - class CfgVehicles { class NATO_Box_Base; class Box_NATO_Grenades_F: NATO_Box_Base { diff --git a/addons/grenades/CfgWeapons.hpp b/addons/grenades/CfgWeapons.hpp index 842862f7f9..683ec7532b 100644 --- a/addons/grenades/CfgWeapons.hpp +++ b/addons/grenades/CfgWeapons.hpp @@ -1,4 +1,3 @@ - class CfgWeapons { class GrenadeLauncher; class Throw: GrenadeLauncher { diff --git a/addons/grenades/Effects.hpp b/addons/grenades/Effects.hpp index 95c3f12ba8..b4a16c6412 100644 --- a/addons/grenades/Effects.hpp +++ b/addons/grenades/Effects.hpp @@ -1,4 +1,3 @@ - class ACE_M84FlashbangEffect { // empty }; diff --git a/addons/grenades/XEH_PREP.hpp b/addons/grenades/XEH_PREP.hpp index 6b5fb57801..06ceebc6b4 100644 --- a/addons/grenades/XEH_PREP.hpp +++ b/addons/grenades/XEH_PREP.hpp @@ -1,8 +1,8 @@ - +PREP(addChangeFuseItemContextMenuOptions); +PREP(damageEngineAndWheels); PREP(flare); PREP(flashbangExplosionEH); PREP(flashbangThrownFuze); PREP(incendiary); PREP(nextMode); PREP(throwGrenade); -PREP(addChangeFuseItemContextMenuOptions); diff --git a/addons/grenades/XEH_postInit.sqf b/addons/grenades/XEH_postInit.sqf index 7f67e181cc..c13bc81b43 100644 --- a/addons/grenades/XEH_postInit.sqf +++ b/addons/grenades/XEH_postInit.sqf @@ -1,13 +1,15 @@ // by commy2 #include "script_component.hpp" +#include "\a3\ui_f\hpp\defineDIKCodes.inc" -["ace_flashbangExploded", {_this call FUNC(flashbangExplosionEH)}] call CBA_fnc_addEventHandler; +["ace_flashbangExploded", LINKFUNC(flashbangExplosionEH)] call CBA_fnc_addEventHandler; +[QGVAR(damageEngineAndWheels), LINKFUNC(damageEngineAndWheels)] call CBA_fnc_addEventHandler; // Register fired event handlers -["ace_firedPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; -["ace_firedPlayerNonLocal", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; -["ace_firedNonPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedPlayerNonLocal", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedNonPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; if (!hasInterface) exitWith {}; @@ -15,20 +17,45 @@ GVAR(flashbangPPEffectCC) = ppEffectCreate ["ColorCorrections", 4265]; GVAR(flashbangPPEffectCC) ppEffectForceInNVG true; // Add keybinds -["ACE3 Weapons", QGVAR(switchGrenadeMode), localize LSTRING(SwitchGrenadeMode), { +["ACE3 Weapons", QGVAR(switchGrenadeMode), LLSTRING(SwitchGrenadeMode), { // Conditions: canInteract - if !([ACE_player, objNull, ["isNotEscorting"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, objNull, ["isNotEscorting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {false}; + // Don't change mode or show hint if advanced throwing is active if (ACE_player getVariable [QEGVAR(advanced_throwing,inHand), false]) exitWith {false}; // Statement - [] call FUNC(nextMode); -}, {false}, [9, [false, false, false]], false] call CBA_fnc_addKeybind; //8 Key + call FUNC(nextMode) // return +}, {}, [DIK_8, [false, false, false]], false] call CBA_fnc_addKeybind; // 8 Key ["CBA_settingsInitialized", { if (GVAR(convertExplosives)) then { - [] call FUNC(addChangeFuseItemContextMenuOptions); + call FUNC(addChangeFuseItemContextMenuOptions); }; }] call CBA_fnc_addEventHandler; + +["vehicle", { + private _currentThrowable = currentThrowable ACE_player; + + // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) + if !( + GVAR(currentThrowMode) == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } + ) exitWith {}; + + // If the player can't use throwables, don't change it + if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; + + // Force the user into the normal throw mode + // Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly... + [format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured); + + GVAR(currentThrowMode) = 0; + GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; +}, true] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/grenades/XEH_preInit.sqf b/addons/grenades/XEH_preInit.sqf index 9361d05015..9456dc9c9f 100644 --- a/addons/grenades/XEH_preInit.sqf +++ b/addons/grenades/XEH_preInit.sqf @@ -6,6 +6,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +GVAR(currentThrowMode) = 0; +GVAR(throwModePFEH) = -1; + +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf b/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf index d778ca3349..c0b5c9dc80 100644 --- a/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf +++ b/addons/grenades/functions/fnc_addChangeFuseItemContextMenuOptions.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: Cyruz - * Allows conversion of explosive charges in to throwable versions + * Allows conversion of explosive charges into throwable versions. * * Arguments: * None @@ -14,7 +14,8 @@ * * Public: No */ - TRACE_1("addChangeFuseItemContextMenuOptions",_this); + +LOG("addChangeFuseItemContextMenuOptions"); { _x params ["_mag", "_throwableMag"]; @@ -29,21 +30,25 @@ {true}, { params ["", "", "_item", "", "_magArr"]; - _item isEqualTo (_magArr select 0); + + _item == (_magArr select 0) } ], { params ["_unit", "", "", "_slot", "_magArr"]; - private _container = ""; - switch _slot do { + + private _container = switch (_slot) do { case "UNIFORM_CONTAINER": { - _container = "uniform"; + "uniform" }; case "VEST_CONTAINER": { - _container = "vest"; + "vest" }; case "BACKPACK_CONTAINER": { - _container = "backpack"; + "backpack" + }; + default { + "" }; }; @@ -54,7 +59,7 @@ false }, true, - [_mag,_throwableMag] + [_mag, _throwableMag] ] call CBA_fnc_addItemContextMenuOption; [ @@ -67,21 +72,25 @@ {true}, { params ["", "", "_item", "", "_magArr"]; - _item isEqualTo (_magArr select 1); + + _item == (_magArr select 1) } ], { params ["_unit", "", "", "_slot", "_magArr"]; - private _container = ""; - switch _slot do { + + private _container = switch (_slot) do { case "UNIFORM_CONTAINER": { - _container = "uniform"; + "uniform" }; case "VEST_CONTAINER": { - _container = "vest"; + "vest" }; case "BACKPACK_CONTAINER": { - _container = "backpack"; + "backpack" + }; + default { + "" }; }; @@ -92,7 +101,7 @@ false }, true, - [_mag,_throwableMag] + [_mag, _throwableMag] ] call CBA_fnc_addItemContextMenuOption; } forEach [ ["SatchelCharge_Remote_Mag", "ACE_SatchelCharge_Remote_Mag_Throwable"], diff --git a/addons/grenades/functions/fnc_damageEngineAndWheels.sqf b/addons/grenades/functions/fnc_damageEngineAndWheels.sqf new file mode 100644 index 0000000000..ab95ecbe6a --- /dev/null +++ b/addons/grenades/functions/fnc_damageEngineAndWheels.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: commy2, johnb43 + * Damage a vehicle's wheels and engine. + * + * Arguments: + * 0: Vehicle + * 1: Incendiary position AGL + * + * Return Value: + * None + * + * Example: + * [cursorObject, position cursorObject] call ace_grenades_fnc_damageEngineAndWheels + * + * Public: No + */ + +params ["_vehicle", "_position"]; +TRACE_2("damageWheelsAndEngine",_vehicle,_position); + +// Vehicle needs to be local and vulnerable +if !(local _vehicle && {isDamageAllowed _vehicle}) exitWith {}; + +{ + // If wheel is close enough to incendiary, burn it + if (_position distance (_vehicle modelToWorld (_vehicle selectionPosition _x)) < EFFECT_SIZE * 2) then { + _vehicle setHit [_x, 1]; + }; +} forEach ((_vehicle call EFUNC(common,getWheelHitPointsWithSelections)) select 1); + +// Burn car engines only +if (_vehicle isKindOf "Wheeled_APC_F") exitWith {}; + +private _engineSelection = getText (configOf _vehicle >> "HitPoints" >> "HitEngine" >> "name"); +private _enginePosition = _vehicle modelToWorld (_vehicle selectionPosition _engineSelection); + +if (_position distance _enginePosition < EFFECT_SIZE * 2) then { + _vehicle setHit [_engineSelection, 1]; + + if (["ace_cookoff"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; + }; +}; diff --git a/addons/grenades/functions/fnc_flare.sqf b/addons/grenades/functions/fnc_flare.sqf index 8214a5600d..2db6335a77 100644 --- a/addons/grenades/functions/fnc_flare.sqf +++ b/addons/grenades/functions/fnc_flare.sqf @@ -4,7 +4,7 @@ * Makes flare shine. * * Arguments: - * 0: The flare + * 0: Flare * 1: Color of flare * 2: Intensity of flare * 3: Flare lifetime @@ -34,6 +34,5 @@ _light setLightFlareMaxDistance 1000; _light setLightDayLight true; _light lightAttachObject [_projectile, [0,0,0]]; -//_light attachTo [_projectile, [0,0,0]]; [{deleteVehicle _this}, _light, _timeToLive] call CBA_fnc_waitAndExecute; diff --git a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf index cc87f492d7..33c4bdffc2 100644 --- a/addons/grenades/functions/fnc_flashbangExplosionEH.sqf +++ b/addons/grenades/functions/fnc_flashbangExplosionEH.sqf @@ -4,7 +4,7 @@ * Creates the flashbang effect and knock out AI units. * * Arguments: - * 0: The flashBang position ASL + * 0: Flashbang position ASL * * Return Value: * None @@ -18,149 +18,148 @@ params ["_grenadePosASL"]; TRACE_1("params",_grenadePosASL); -// Create flash to illuminate environment -if (hasInterface) then { - private _light = "#lightpoint" createVehicleLocal ASLtoAGL _grenadePosASL; - _light setPosASL _grenadePosASL; - - _light setLightBrightness 20; - _light setLightAmbient [1,1,1]; - _light setLightColor [1,1,1]; - _light setLightDayLight true; - _light setLightAttenuation [0, 1, 5, 1000, 0, 20]; - - // Reduce the light after 0.1 seconds - [{ - params ["_light"]; - _light setLightBrightness 5; - // Delete the light after 0.2 more seconds - [{ - params ["_light"]; - deleteVehicle _light; - }, [_light], 0.2] call CBA_fnc_waitAndExecute; - }, [_light], 0.1] call CBA_fnc_waitAndExecute; -}; - -// Affect local AI +// Affect local AI (players are not local, except for ACE_player) // @todo: Affect units in static weapons, turned out, etc -private _affected = (ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20]; -_affected = _affected - [ACE_player]; +private _affected = ((ASLtoAGL _grenadePosASL) nearEntities ["CAManBase", 20]) - [ACE_player]; + { - if (local _x && {alive _x}) then { - private _unit = _x; - private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 20; + private _unit = _x; + private _strength = 1 - (((eyePos _unit) vectorDistance _grenadePosASL) min 20) / 20; - TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength); + TRACE_3("FlashBangEffect Start",_unit,((getPosASL _unit) vectorDistance _grenadePosASL),_strength); - [_unit, true] call EFUNC(common,disableAI); + [_unit, true] call EFUNC(common,disableAI); - // Make AI try to look away - private _dirToFlash = _unit getDir _grenadePosASL; - _unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]); + // Make AI try to look away + private _dirToFlash = _unit getDir _grenadePosASL; + _unit setDir (_dirToFlash + linearConversion [0.2, 1, _strength, 40, 135] * selectRandom [-1, 1]); + + private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0]; + _unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))]; + + if (_flashReactionDebounce < CBA_missionTime) then { + // Not used internally 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; + + [{ + CBA_missiontime >= _this getVariable [QGVAR(flashReactionDebounce), 0] + }, { + params ["_unit"]; + + _unit setVariable [QGVAR(flashStrength), 0, true]; + + // Make sure we don't enable AI for unconscious units + if (_unit call EFUNC(common,isAwake)) then { + [_unit, false] call EFUNC(common,disableAI); + }; - private _flashReactionDebounce = _unit getVariable [QGVAR(flashReactionDebounce), 0]; - _unit setVariable [QGVAR(flashReactionDebounce), _flashReactionDebounce max (CBA_missionTime + (7 * _strength))]; - if (_flashReactionDebounce < CBA_missionTime) then { - // Not used interally but could be useful for other mods - _unit setVariable [QGVAR(flashStrength), _strength, true]; { - _unit setSkill [_x, (_unit skill _x) / 50]; + _unit setSkill [_x, (_unit skill _x) * 50]; } forEach SUBSKILLS; - [{ - params ["_unit"]; - CBA_missiontime >= _unit getVariable [QGVAR(flashReactionDebounce), 0] - },{ - params ["_unit"]; - - _unit setVariable [QGVAR(flashStrength), 0, true]; - - // Make sure we don't enable AI for unconscious units - if !(_unit getVariable ["ace_isUnconscious", false]) then { - [_unit, false] call EFUNC(common,disableAI); - }; - { - _unit setSkill [_x, (_unit skill _x) * 50]; - } forEach SUBSKILLS; - }, [_unit]] call CBA_fnc_waitUntilAndExecute; - }; + }, _unit] call CBA_fnc_waitUntilAndExecute; }; -} count _affected; +} forEach (_affected select {local _x && {_x call EFUNC(common,isAwake)}}); + +if (!hasInterface) exitWith {}; + +// Create flash to illuminate environment +private _light = "#lightpoint" createVehicleLocal ASLtoAGL _grenadePosASL; +_light setPosASL _grenadePosASL; + +_light setLightBrightness 20; +_light setLightAmbient [1,1,1]; +_light setLightColor [1,1,1]; +_light setLightDayLight true; +_light setLightAttenuation [0, 1, 5, 1000, 0, 20]; + +// Reduce the light after 0.1 seconds +[{ + _this setLightBrightness 5; + + // Delete the light after 0.2 more seconds + [{deleteVehicle _this}, _this, 0.2] call CBA_fnc_waitAndExecute; +}, _light, 0.1] call CBA_fnc_waitAndExecute; + +// Ignore dead and placeable logic (zeus / spectator) +if (!alive ACE_player || {(getNumber (configOf ACE_player >> "isPlayableLogic")) == 1}) exitWith {}; // Affect local player, independently of distance -if (hasInterface && {!isNull ACE_player} && {alive ACE_player}) then { - if ((getNumber (configOf ACE_player >> "isPlayableLogic")) == 1) exitWith { - TRACE_1("skipping playable logic",typeOf ACE_player); // VirtualMan_F (placeable logic zeus / spectator) - }; - // Do effects for player - // is there line of sight to the grenade? - private _eyePos = eyePos ACE_player; //PositionASL - _grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground +// Check for line of sight to the grenade +private _eyePos = eyePos ACE_player; // PositionASL +_grenadePosASL set [2, (_grenadePosASL select 2) + 0.2]; // compensate for grenade glitching into ground - private _strength = 1 - ((_eyePos vectorDistance _grenadePosASL) min 20) / 20; +private _strength = 1 - ((_eyePos vectorDistance _grenadePosASL) min 20) / 20; - // Check for line of sight (check 4 points in case grenade is stuck in an object or underground) - private _losCoefficient = 1; - private _losCount = { - !lineIntersects [_grenadePosASL vectorAdd _x, _eyePos, ACE_player] - } count [[0,0,0], [0,0,0.2], [0.1, 0.1, 0.1], [-0.1, -0.1, 0.1]]; - TRACE_1("Line of sight count (out of 4)",_losCount); - if (_losCount <= 1) then { - _losCoefficient = 0.1; - }; - _strength = _strength * _losCoefficient; +// Check for line of sight (check 4 points in case grenade is stuck in an object or underground) +private _losCount = { + !lineIntersects [_grenadePosASL vectorAdd _x, _eyePos, ACE_player] +} count [[0, 0, 0], [0, 0, 0.2], [0.1, 0.1, 0.1], [-0.1, -0.1, 0.1]]; +TRACE_1("Line of sight count (out of 4)",_losCount); - // Add ace_hearing ear ringing sound effect - if (["ACE_Hearing"] call EFUNC(common,isModLoaded) && {_strength > 0 && {EGVAR(hearing,damageCoefficent) > 0.25}}) then { - private _earringingStrength = 40 * _strength; - [_earringingStrength] call EFUNC(hearing,earRinging); - TRACE_1("Earringing Strength",_earringingStrength); - }; +private _losCoefficient = [1, 0.1] select (_losCount <= 1); +_strength = _strength * _losCoefficient; - // add ace_medical pain effect: - if (["ACE_Medical"] call EFUNC(common,isModLoaded) && {_strength > 0.1}) then { - [ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel); - }; - - // Effect on vision has a wider range, with a higher falloff - _strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4; - _strength = _strength * _losCoefficient; - // Account for people looking away by slightly reducing the effect for visual effects. - private _eyeDir = ((AGLtoASL positionCameraToWorld [0,0,1]) vectorDiff (AGLtoASL positionCameraToWorld [0,0,0])); - private _dirToUnitVector = _eyePos vectorFromTo _grenadePosASL; - private _angleDiff = acos (_eyeDir vectorDotProduct _dirToUnitVector); - TRACE_2("",_angleDiff,((1 - (_angleDiff - 45) / (120 - 45)) max 0)); - // from 0-45deg, full effect - if (_angleDiff > 45) then { - _strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0); - }; - - // Blind player - if (_strength > 0.1) then { - private _blend = [[1,1,1,0], [0.3,0.3,0.3,1]] select EGVAR(common,epilepsyFriendlyMode); - - GVAR(flashbangPPEffectCC) ppEffectEnable true; - GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, (0.8 + _strength) min 1, _blend, [0,0,0,1], [0,0,0,0]]; - GVAR(flashbangPPEffectCC) ppEffectCommit 0.01; - - //PARTIALRECOVERY - start decreasing effect over time - [{ - params ["_strength"]; - - GVAR(flashbangPPEffectCC) ppEffectAdjust [1,1,0,[1,1,1,0],[0,0,0,1],[0,0,0,0]]; - GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength); - }, [_strength], 7 * _strength] call CBA_fnc_waitAndExecute; - - //FULLRECOVERY - end effect - [{ - GVAR(flashbangPPEffectCC) ppEffectEnable false; - }, [], 17 * _strength] call CBA_fnc_waitAndExecute; - }; - - // Make player flinch - if (_strength <= 0.2) exitWith {}; - private _minFlinch = linearConversion [0.2, 1, _strength, 0, 60, true]; - 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); +// Add ace_hearing ear ringing sound effect +if (["ace_hearing"] call EFUNC(common,isModLoaded) && {_strength > 0} && {EGVAR(hearing,damageCoefficent) > 0.25}) then { + private _earringingStrength = 40 * _strength; + [_earringingStrength] call EFUNC(hearing,earRinging); + TRACE_1("Earringing Strength",_earringingStrength); }; -true + +// Add ace_medical pain effect +if (GETEGVAR(medical,enabled,false) && {_strength > 0.1} && {isDamageAllowed _unit} && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) then { + [ACE_player, _strength / 2] call EFUNC(medical,adjustPainLevel); +}; + +// Effect on vision has a wider range, with a higher falloff +_strength = 1 - (((_eyePos vectorDistance _grenadePosASL) min 25) / 25) ^ 0.4; +_strength = _strength * _losCoefficient; + +// Account for people looking away by slightly reducing the effect for visual effects. +private _eyeDir = ((AGLtoASL positionCameraToWorld [0, 0, 1]) vectorDiff (AGLtoASL positionCameraToWorld [0, 0, 0])); +private _dirToUnitVector = _eyePos vectorFromTo _grenadePosASL; +private _angleDiff = acos (_eyeDir vectorDotProduct _dirToUnitVector); +TRACE_2("",_angleDiff,((1 - (_angleDiff - 45) / (120 - 45)) max 0)); + +// From 0-45deg, full effect +if (_angleDiff > 45) then { + _strength = _strength * ((1 - (_angleDiff - 45) / (120 - 45)) max 0); +}; + +// Blind player +if (_strength > 0.1) then { + private _blend = [[1, 1, 1, 0], [0.3, 0.3, 0.3, 1]] select EGVAR(common,epilepsyFriendlyMode); + + GVAR(flashbangPPEffectCC) ppEffectEnable true; + GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, (0.8 + _strength) min 1, _blend, [0, 0, 0, 1], [0, 0, 0, 0]]; + GVAR(flashbangPPEffectCC) ppEffectCommit 0.01; + + // PARTIALRECOVERY - start decreasing effect over time + [{ + params ["_strength", "_blend"]; + + GVAR(flashbangPPEffectCC) ppEffectAdjust [1, 1, 0, _blend, [0, 0, 0, 1], [0, 0, 0, 0]]; + GVAR(flashbangPPEffectCC) ppEffectCommit (10 * _strength); + }, [_strength, _blend], 7 * _strength] call CBA_fnc_waitAndExecute; + + // FULLRECOVERY - end effect + [{ + GVAR(flashbangPPEffectCC) ppEffectEnable false; + }, [], 17 * _strength] call CBA_fnc_waitAndExecute; +}; + +// Make player flinch +if (_strength <= 0.2) exitWith {}; + +private _minFlinch = linearConversion [0.2, 1, _strength, 0, 60, true]; +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; diff --git a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf index 7f1a52417c..89020842d2 100644 --- a/addons/grenades/functions/fnc_flashbangThrownFuze.sqf +++ b/addons/grenades/functions/fnc_flashbangThrownFuze.sqf @@ -4,7 +4,7 @@ * Waits for the flashbang grenade fuze to trigger and 'explode' * * Arguments: - * 0: projectile - Flashbang Grenade + * 0: Flashbang grenade * * Return Value: * None @@ -18,8 +18,17 @@ params ["_projectile"]; TRACE_1("params",_projectile); -if (alive _projectile) then { - playSound3D ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_01.wss", _projectile, false, getPosASL _projectile, 5, 1.2, 400]; +if (!alive _projectile) exitWith {}; - ["ace_flashbangExploded", [getPosASL _projectile]] call CBA_fnc_globalEvent; -}; +private _posASL = getPosASL _projectile; +private _sounds = getArray (_projectile call CBA_fnc_getObjectConfig >> QGVAR(flashbangExplodeSound)); + +(if (_sounds isEqualTo []) then { + [format ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_0%1.wss", floor (random 4) + 1], 5, 1.2, 400] +} else { + selectRandom _sounds +}) params ["_file", "_volume", "_pitch", "_distance"]; + +playSound3D [_file, _projectile, false, _posASL, _volume, _pitch, _distance]; + +["ace_flashbangExploded", [_posASL]] call CBA_fnc_globalEvent; diff --git a/addons/grenades/functions/fnc_incendiary.sqf b/addons/grenades/functions/fnc_incendiary.sqf index 11d89d4ca5..f0caf82ed8 100644 --- a/addons/grenades/functions/fnc_incendiary.sqf +++ b/addons/grenades/functions/fnc_incendiary.sqf @@ -1,11 +1,12 @@ #include "..\script_component.hpp" /* * Author: commy2 - * Makes incendiary burn. + * Makes an incendiary grenade burn. * * Arguments: - * 0: The grenade + * 0: Incendiary grenade * 1: Incendiary lifetime + * 2: Instigator's side * * Return Value: * None @@ -30,11 +31,11 @@ #define PARTICLE_SMOKE_LIFTING 1 #define PARTICLE_SMOKE_WIND_EFFECT 1 -#define EFFECT_SIZE 1 #define ORIENTATION 5.4 #define EXPANSION 1 #define DESTRUCTION_RADIUS 1.8 +#define SEARCH_RADIUS 5 params ["_projectile", "_timeToLive", "_center"]; @@ -42,16 +43,16 @@ if (isNull _projectile) exitWith {TRACE_1("null",_projectile);}; private _position = position _projectile; -// --- AI +// Alert nearby hostile AI private _nearLocalEnemies = []; { { - if (local _x && {[_center, side _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECTS SIDE HERE! + if (local _x && {[_center, side group _x] call BIS_fnc_sideIsEnemy}) then { // WE WANT THE OBJECT'S SIDE HERE! _nearLocalEnemies pushBackUnique _x; }; } forEach crew _x; -} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); +} forEach (_position nearObjects ALERT_NEAR_ENEMY_RANGE); //@todo replace with nearEntities in 2.18 { if (behaviour _x in ["SAFE", "AWARE"]) then { @@ -59,7 +60,7 @@ private _nearLocalEnemies = []; }; } forEach _nearLocalEnemies; -// --- fire +// Fire particles private _fire = "#particlesource" createVehicleLocal _position; _fire setParticleParams [ @@ -99,7 +100,7 @@ _fire setParticleRandom [PARTICLE_LIFE_TIME / 4, [0.15 * EFFECT_SIZE, 0.15 * EFF _fire setParticleFire [1.2,1.0,0.1]; _fire setDropInterval (1 / PARTICLE_DENSITY); -// --- smoke +// Smoke particles private _smoke = "#particlesource" createVehicleLocal _position; _smoke setParticleParams [ @@ -137,7 +138,7 @@ _smoke setParticleParams [ _smoke setParticleRandom [PARTICLE_SMOKE_LIFE_TIME / 2, [0.5 * EFFECT_SIZE, 0.5 * EFFECT_SIZE, 0.2 * EFFECT_SIZE], [0.3,0.3,0.5], 1, 0, [0,0,0,0.06], 0, 0]; _smoke setDropInterval (1 / PARTICLE_SMOKE_DENSITY); -// --- light +// Light private _light = "#lightpoint" createVehicleLocal (_position vectorAdd [0,0,0.5]); _light setLightBrightness 1.0; @@ -150,92 +151,72 @@ _light setLightDayLight false; _light lightAttachObject [_projectile, [0,0,0]]; -// --- sound +// Sound private _sound = objNull; if (isServer) then { _sound = createSoundSource ["Sound_Fire", _position, [], 0]; private _radius = 1.5 * getNumber (configOf _projectile >> "indirectHitRange"); private _intensity = getNumber (configOf _projectile >> "hit"); - [QEGVAR(fire,addFireSource), [_projectile, _radius, _intensity, _projectile, {CBA_missionTime < _this}, CBA_missionTime + _timeToLive]] call CBA_fnc_serverEvent; + + [QEGVAR(fire,addFireSource), [_projectile, _radius, _intensity, _projectile, { + params ["_endTime", "_projectile"]; + + // If incendiary no longer exists, exit + if (isNull _projectile) exitWith { + false // return + }; + + // Need to get the position every time, as grenade might have been moved + private _position = position _projectile; + + { + // Damage vehicles + [QGVAR(damageEngineAndWheels), [_x, _position], _x] call CBA_fnc_targetEvent; + } forEach (_position nearEntities ["Car", SEARCH_RADIUS]); + + CBA_missionTime < _endTime // return + }, [CBA_missionTime + _timeToLive, _projectile]]] call CBA_fnc_serverEvent; }; [{ {deleteVehicle _x} forEach _this; }, [_fire, _smoke, _light, _sound], _timeToLive] call CBA_fnc_waitAndExecute; -// --- damage +// Damage { - if (local _x) then { - //systemChat format ["burn: %1", _x]; + // Inflame fireplace, barrels etc. + _x inflame true; - // --- destroy nearby static weapons and ammo boxes - if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { + // Destroy nearby static weapons and ammo boxes + if (_x isKindOf "StaticWeapon" || {_x isKindOf "ACE_RepairItem_Base"}) then { + _x setDamage 1; + + continue; + }; + + if (_x isKindOf "ReammoBox_F") then { + if ( + (["ace_cookoff"] call EFUNC(common,isModLoaded)) && + {EGVAR(cookoff,enableAmmobox)} && + {EGVAR(cookoff,ammoCookoffDuration) != 0} && + {_x getVariable [QEGVAR(cookoff,enableAmmoCookoff), true]} + ) then { + [QEGVAR(cookOff,cookOffBoxServer), _box] call CBA_fnc_serverEvent; + } else { _x setDamage 1; }; - if (_x isKindOf "ReammoBox_F") then { - if ( - "ace_cookoff" call EFUNC(common,isModLoaded) && - {GETVAR(_x,EGVAR(cookoff,enableAmmoCookoff),EGVAR(cookoff,enableAmmobox))} - ) then { - _x call EFUNC(cookoff,cookOffBox); - } else { - _x setDamage 1; - }; - }; - // --- delete nearby ground weapon holders - if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then { - deleteVehicle _x; - }; - - // --- inflame fireplace, barrels etc. - _x inflame true; + continue; }; -} forEach (_position nearObjects DESTRUCTION_RADIUS); -// --- damage local vehicle -private _vehicle = _position nearestObject "Car"; - -if (!local _vehicle) exitWith {}; - -private _config = configOf _vehicle; - -// --- burn tyres -private _fnc_isWheelHitPoint = { - params ["_selectionName"]; - - // wheels must use a selection named "wheel_X_Y_steering" for PhysX to work - _selectionName select [0, 6] == "wheel_" && { - _selectionName select [count _selectionName - 9] == "_steering" - } // return -}; + // Delete nearby ground weapon holders + if (_x isKindOf "WeaponHolder" || {_x isKindOf "WeaponHolderSimulated"}) then { + deleteVehicle _x; + }; +} forEach ((_position nearObjects DESTRUCTION_RADIUS) select {local _x && {isDamageAllowed _x}}); { - private _wheelSelection = getText (_config >> "HitPoints" >> _x >> "name"); - - if (_wheelSelection call _fnc_isWheelHitPoint) then { - private _wheelPosition = _vehicle modelToWorld (_vehicle selectionPosition _wheelSelection); - - if (_position distance _wheelPosition < EFFECT_SIZE * 2) then { - _vehicle setHit [_wheelSelection, 1]; - }; - }; -} forEach (getAllHitPointsDamage _vehicle param [0, []]); - -// --- burn car engine -if (_vehicle isKindOf "Wheeled_APC_F") exitWith {}; - -private _engineSelection = getText (_config >> "HitPoints" >> "HitEngine" >> "name"); -private _enginePosition = _vehicle modelToWorld (_vehicle selectionPosition _engineSelection); - -if (_position distance _enginePosition < EFFECT_SIZE * 2) then { - _vehicle setHit [_engineSelection, 1]; - - if ("ace_cookoff" call EFUNC(common,isModLoaded)) then { - private _enabled = _vehicle getVariable [QEGVAR(cookoff,enable), EGVAR(cookoff,enable)]; - if (_enabled in [2, true] || {_enabled isEqualTo 1 && {fullCrew [_vehicle, "", false] findIf {isPlayer (_x select 0)} != -1}}) then { - _vehicle call EFUNC(cookoff,engineFire); - }; - }; -}; + // Damage vehicles (locality is checked in FUNC(damageEngineAndWheels)) + [_x, _position] call FUNC(damageEngineAndWheels); +} forEach (_position nearEntities ["Car", SEARCH_RADIUS]); diff --git a/addons/grenades/functions/fnc_nextMode.sqf b/addons/grenades/functions/fnc_nextMode.sqf index 1a64cf9f7b..f33fa7a5a5 100644 --- a/addons/grenades/functions/fnc_nextMode.sqf +++ b/addons/grenades/functions/fnc_nextMode.sqf @@ -7,27 +7,31 @@ * None * * Return Value: - * Handeled + * Handled * * Example: - * [] call ace_grenades_fnc_nextMode + * call ace_grenades_fnc_nextMode * * Public: No */ -private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; +// _mode is 0-4, don't overflow +private _mode = (GVAR(currentThrowMode) + 1) % 5; -if (_mode == 4) then { - _mode = 0; -} else { +private _currentThrowable = currentThrowable ACE_player; + +// Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) +if ( + _mode == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } +) then { _mode = _mode + 1; }; -// ROLL GRENADE DOESN'T WORK RIGHT NOW -if (_mode == 3) then { - _mode = 4; -}; - private _hint = localize ([ LSTRING(NormalThrow), LSTRING(HighThrow), @@ -38,6 +42,37 @@ private _hint = localize ([ [_hint] call EFUNC(common,displayTextStructured); +GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; GVAR(currentThrowMode) = _mode; +// If in rolling mode, check every frame if current throwable is rollable +if (GVAR(currentThrowMode) == 3) then { + GVAR(currentThrowable) = _currentThrowable; + + GVAR(throwModePFEH) = { + private _currentThrowable = currentThrowable ACE_player; + + if (GVAR(currentThrowable) isEqualTo _currentThrowable) exitWith {}; + + GVAR(currentThrowable) = _currentThrowable; + + // Make sure grenade can be rolled if in roll mode (detonation time has to be >= 1 second and player isn't in a vehicle) + if !( + GVAR(currentThrowMode) == 3 && + {_currentThrowable isNotEqualTo []} && + { + !isNull objectParent ACE_player || + {getNumber (configFile >> "CfgAmmo" >> getText (configFile >> "CfgMagazines" >> _currentThrowable select 0 >> "ammo") >> "explosionTime") < MIN_EXPLOSION_TIME_FOR_ROLL} + } + ) exitWith {}; + + // Force the user into the normal throw mode + // Next throw mode after roll would be drop, which isn't ideal if the user tries to throw unknowingly... + [format [LLSTRING(RollGrenadeDisabled), LLSTRING(NormalThrow)], 2] call EFUNC(common,displayTextStructured); + + GVAR(throwModePFEH) call CBA_fnc_removePerFrameHandler; + GVAR(currentThrowMode) = 0; + } call CBA_fnc_addPerFrameHandler; +}; + true diff --git a/addons/grenades/functions/fnc_throwGrenade.sqf b/addons/grenades/functions/fnc_throwGrenade.sqf index 4105e861f6..a440c8fd1b 100644 --- a/addons/grenades/functions/fnc_throwGrenade.sqf +++ b/addons/grenades/functions/fnc_throwGrenade.sqf @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); if (_weapon != "Throw") exitWith {}; @@ -27,40 +27,26 @@ if (isNull _projectile) then { private _config = configFile >> "CfgAmmo" >> _ammo; -// handle special grenades and sounds +// Handle special grenades and sounds if (local _unit) then { - // handle priming sound, if present - private _soundConfig = getArray (configFile >> "CfgAmmo" >> _ammo >> QGVAR(pullPinSound)); + // Handle priming sound, if present + private _soundConfig = getArray (_config >> QGVAR(pullPinSound)); + if (_soundConfig isNotEqualTo []) then { _soundConfig params ["_file", "_volume", "_pitch", "_distance"]; - playSound3D [_file, objNull, false, getPosASL _projectile, _volume, _pitch, _distance]; + playSound3D [_file, objNull, insideBuilding _unit >= 0.5, getPosASL _projectile, _volume, _pitch, _distance]; }; if (getNumber (_config >> QGVAR(flashbang)) == 1) then { - private _bangs = 1; - private _entry = _config >> QGVAR(flashbangBangs); - if (isNumber _entry || isText _entry) then { - _bangs = getNumber _entry; - }; - private _fuzeTimeBase = getNumber (_config >> "explosionTime"); - - private _interval = 0.5; - _entry = _config >> QGVAR(flashbangInterval); - if (isNumber _entry || isText _entry) then { - _interval = getNumber _entry; - }; - - private _maxDeviation = 0.1; - _entry = _config >> QGVAR(flashbangIntervalMaxDeviation); - if (isNumber _entry || isText _entry) then { - _maxDeviation = getNumber _entry; - }; + private _bangs = [_config >> QGVAR(flashbangBangs), "NUMBER", 1] call CBA_fnc_getConfigEntry; + private _interval = [_config >> QGVAR(flashbangInterval), "NUMBER", 0.5] call CBA_fnc_getConfigEntry; + private _maxDeviation = [_config >> QGVAR(flashbangIntervalMaxDeviation), "NUMBER", 0.1] call CBA_fnc_getConfigEntry; for "_i" from 0 to (_bangs - 1) do { - private _fuzeTime = _fuzeTimeBase + _i*_interval + random [- _maxDeviation, 0, _maxDeviation]; + private _fuzeTime = _fuzeTimeBase + _i * _interval + random [-_maxDeviation, 0, _maxDeviation]; - [FUNC(flashbangThrownFuze), [_projectile], _fuzeTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(flashbangThrownFuze), _projectile, _fuzeTime] call CBA_fnc_waitAndExecute; }; }; }; @@ -71,47 +57,56 @@ if (getNumber (_config >> QGVAR(flare)) == 1) then { private _color = getArray (_config >> QGVAR(color)); private _intensity = _color deleteAt 3; - [FUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(flare), [_projectile, _color, _intensity, _timeToLive], _fuzeTime] call CBA_fnc_waitAndExecute; }; if (getNumber (_config >> QGVAR(incendiary)) == 1) then { private _fuzeTime = getNumber (_config >> "explosionTime"); private _timeToLive = getNumber (_config >> "timeToLive"); - [FUNC(incendiary), [_projectile, _timeToLive, side _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // WE WANT THE OBJECTS SIDE HERE! + [LINKFUNC(incendiary), [_projectile, _timeToLive, side group _unit], _fuzeTime] call CBA_fnc_waitAndExecute; // Get the unit's real side (will return civilian if unconscious) }; -// handle throw modes +// Handle throw modes if (_unit != ACE_player) exitWith {}; if (_unit getVariable [QEGVAR(advanced_throwing,primed), false]) exitWith {LOG("advanced_throwing throw");}; -private _mode = missionNamespace getVariable [QGVAR(currentThrowMode), 0]; +if (GVAR(currentThrowMode) == 0) exitWith {}; -if (_mode != 0) then { - private _velocity = velocity _projectile; +private _velocity = velocity _projectile; - switch (_mode) do { - //high throw - case 1 : { - _velocity = [ - 0.5 * (_velocity select 0), - 0.5 * (_velocity select 1), - [0, 0, 0] distance (_velocity vectorMultiply 0.5) - ]; - }; - //precise throw - case 2 : { - _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); - }; - //roll grande - case 3 : { - //@todo - }; - //drop grenade - case 4 : { - _velocity = [0, 0, 0]; - }; +switch (GVAR(currentThrowMode)) do { + // High throw + case 1: { + _velocity = _velocity vectorMultiply 0.5; + + _velocity set [2, vectorMagnitude _velocity]; }; + // Precise throw + case 2: { + _velocity = (_unit weaponDirection _weapon) vectorMultiply (vectorMagnitude _velocity); + }; + // Roll grenade + case 3: { + private _posASL = getPosASL _projectile; - _projectile setVelocity _velocity; + // getPos is unreliable, as surfaces in some ruins are not recognised as surfaces + private _lisPos = (lineIntersectsSurfaces [_posASL, _posASL vectorAdd [0, 0, -1e11], ACE_player, objNull, true, 1, "ROADWAY", "FIRE"]) select 0; + _projectile setPosASL ((_lisPos select 0) vectorAdd [0, 0, 0.2]); + + // Rotate throwables by 90° to the side by default, so cylindrical throwables can be rolled + private _vectorDirAndUp = getArray (_config >> QGVAR(rollVectorDirAndUp)); + _vectorDirAndUp params [["_vectorDir", [0, 1, 0], [[]], 3], ["_vectorUp", [1, 0, 0], [[]], 3]]; + + // Do as if object were facing north + _projectile setVectorDirAndUp ([[_vectorDir, _vectorUp], -(direction _projectile), 0, 0] call BIS_fnc_transformVectorDirAndUp); + + _velocity = (vectorDir _unit) vectorMultiply 10; + }; + // Drop grenade + case 4: { + _velocity = [0, 0, 0]; + }; }; + +_projectile setVelocity _velocity; diff --git a/addons/grenades/initSettings.inc.sqf b/addons/grenades/initSettings.inc.sqf new file mode 100644 index 0000000000..6a6ceb8c37 --- /dev/null +++ b/addons/grenades/initSettings.inc.sqf @@ -0,0 +1,10 @@ +[ + QGVAR(convertExplosives), + "CHECKBOX", + [LSTRING(convertExplosives_DisplayName), LSTRING(convertExplosives_Description)], + LSTRING(Settings_DisplayName), + true, + 1, + {[QGVAR(convertExplosives), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/grenades/initSettings.sqf b/addons/grenades/initSettings.sqf deleted file mode 100644 index b6fa36f459..0000000000 --- a/addons/grenades/initSettings.sqf +++ /dev/null @@ -1,9 +0,0 @@ -[ - QGVAR(convertExplosives), "CHECKBOX", - [LSTRING(convertExplosives_DisplayName), LSTRING(convertExplosives_Description)], - LSTRING(Settings_DisplayName), - true, - true, - {}, - true -] call CBA_fnc_addSetting; diff --git a/addons/grenades/script_component.hpp b/addons/grenades/script_component.hpp index 49dbe92a3f..e49fa21ca9 100644 --- a/addons/grenades/script_component.hpp +++ b/addons/grenades/script_component.hpp @@ -16,7 +16,6 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define EFFECT_STAGE_RESETAI 0 -#define EFFECT_STAGE_DELETELIGHT 1 -#define EFFECT_STAGE_PARTIALRECOVERY 2 -#define EFFECT_STAGE_FULLRECOVERY 3 +#define EFFECT_SIZE 1 + +#define MIN_EXPLOSION_TIME_FOR_ROLL 1 diff --git a/addons/grenades/stringtable.xml b/addons/grenades/stringtable.xml index dd529085e9..b0630e3a43 100644 --- a/addons/grenades/stringtable.xml +++ b/addons/grenades/stringtable.xml @@ -12,7 +12,7 @@ Gránátkezelési mód váltása Cambia tipo di granata Alternar Modo de Granada - 投てき方法を切り替え + 投擲方法を切り替え 투척 방법 전환 切换投掷模式 切換投擲模式 @@ -103,6 +103,14 @@ 下丟投擲 Bombayı Yere Bırak + + Can't roll this grenade, switched to %1 + この手榴弾は転がせません、 %1 に切り替えます + Эта граната не может быть брошена, переключитесь на %1 + 이 수류탄은 굴릴 수 없습니다. %1(으)로 전환되었습니다. + Granate kann nicht rollen, zu %1 gewechselt + Granata non può rotolare, cambiato a %1 + M84 Stun Grenade M84 Blendgranate @@ -149,7 +157,7 @@ Anche conosciuta come flashbang. Causa accecamento immediato, sensazioni di sposatezza, mancanza d'equilibrio e disturbi al timpano. Também conhecida como flashbang. Causa uma clarão imediato, cegueira, surdez, zumbido e distúrbio no tímpano. フラッシュバンとも知られています。即時に失明と難聴、耳鳴り、内耳障害を引き起こします。 - 플래시뱅이라고도 알려져있습니다. 사용 즉시 섬광으로 인한 시력장애, 청각장애, 이명, 내이기관방해를 유발합니다. + 플래시뱅이라고도 알려져 있습니다. 사용 즉시 섬광으로 인한 시력장애, 청각장애, 이명, 내이기관방해를 유발합니다. 也被称为闪光弹,会造成暂时性失明,耳聋,耳鸣等效果。 也被稱為閃光彈,會造成暫時性失明,耳聾,耳鳴等效果 Flashbang olarak da bilinir. Ani flaş körlüğü, sağırlık, kulak çınlaması ve iç kulak rahatsızlığına neden olur. @@ -198,7 +206,7 @@ M127A1 Фальшфейер (белый) Bengala M127A1 (Blanca) M127A1 Feu à main (Blanc) - M127A1 信号弾 (白) + M127A1 手持ち式信号弾 (白) M127A1 수타식 신호탄 (하얀색) M127A1 手持式信号弹(白色) M127A1 手持式信號彈 (白色) @@ -215,7 +223,7 @@ M127A1 Фальшфейер (красный) Bengala M127A1 (Roja) M127A1 Feu à main (Rouge) - M127A1 信号弾 (赤) + M127A1 手持ち式信号弾 (赤) M127A1 수타식 신호탄 (빨간색) M127A1 手持式信号弹(红色) M127A1 手持式信號彈 (紅色) @@ -232,7 +240,7 @@ M127A1 Фальшфейер (зелёный) Bengala M127A1 (Verde) M127A1 Feu à main (Vert) - M127A1 信号弾 (緑) + M127A1 手持ち式信号弾 (緑) M127A1 수타식 신호탄 (초록색) M127A1 手持式信号弹(绿色) M127A1 手持式信號彈 (綠色) @@ -249,7 +257,7 @@ M127A1 Фальшфейер (жёлтый) Bengala M127A1 (Amarilla) M127A1 Feu à main (Jaune) - M127A1 信号弾 (黄) + M127A1 手持ち式信号弾 (黄) M127A1 수타식 신호탄 (노란색) M127A1 手持式信号弹(黄色) M127A1 手持式信號彈 (黃色) @@ -266,7 +274,7 @@ Фальшфейер (белый) Bengala (Blanca) Feu à main (Blanc) - 白の手持ち式信号弾 + 白色の手持ち式信号弾 하얀색 불꽃신호기 白色手持式信号弹 白色手持式信號彈 @@ -283,7 +291,7 @@ Фальшфейер (красный) Bengala (Roja) Feu à main (Rouge) - 赤の手持ち式信号弾 + 赤色の手持ち式信号弾 빨간색 불꽃신호기 红色手持式信号弹 紅色手持式信號彈 @@ -300,7 +308,7 @@ Фальшфейер (зелёный) Bengala (Verde) Feu à main (Vert) - 緑の手持ち式信号弾 + 緑色の手持ち式信号弾 초록색 불꽃신호기 绿色手持式信号弹 綠色手持式信號彈 @@ -317,7 +325,7 @@ Фальшфейер (жёлтый) Bengala (Amarilla) Feu à main (Jaune) - 黄の手持ち式信号弾 + 黄色の手持ち式信号弾 노란색 불꽃신호기 黄色手持式信号弹 黃色手持式信號彈 @@ -539,78 +547,92 @@ Explosive Satchel (Throwable) Ранец со взрывчаткой (метательный) Charge en sacoche (lançable) - 梱包爆薬 (投てき仕様) + 梱包爆薬 (投擲仕様) Carga de mochila explosiva (Lanzable) Pakiet ładunków wybuchowych (Rzucany) Rucksackladung (Werfbar) + Carica da Demolizioni (Lanciabile) 炸药包(可投掷) 폭파 장약 (투척) + Sacola Explosiva (Arremessável) Type: Charge<br />Rounds: 1<br />Used on: Things that need to die Тип: Взрывчатка<br />Боеприпасы 1<br />Применение: На предметах, которые должны быть уничтожены Type : Charge<br />Munitions : 1<br />Application : à balancer sur des trucs qui doivent mourir + Type: Carica<br />Colpi: 1<br />Usata su: cose che devono morire 種類: 爆薬<br />弾数: 1<br />次で使用: 破壊すべき物に Tipo: Carga<br />Unidades: 1<br />Usada: Cosas que necesitan morir Typ: Ładunek<br/>Naboje: 1<br/>Użycie: Na rzeczach które mają zginąć Typ: Ladung <br/>Patronen:1<br/>Benutzt für: Dinge die Sterben müssen 类型:炸药<br />数量:1<br />用于:需要死亡的事物 종류: 장약<br />갯수: 1<br />사용처: 죽여야 할 곳에 + Tipo: Carga<br />Munições: 1<br />Utilizada em: Coisas que devem morrer An explosive satchel that is throwable. 7 second fixed fuse Ранец со взрывчаткой. Детонация через 7 секунд Charge explosive lançable. Détonation après 7 secondes. - 投げられる梱包爆薬。起爆までの時間は 7 秒間 + Una carica da demolizioni lanciabile. Detona dopo 7 secondi fissi + 投げられる梱包爆薬。起爆まで7秒の固定時限信管付き。 Carga de mochila explosiva que se puede lanzar. Espoleta fija de 7 segundos Rzucany pakiet ładunków wybuchowych. 7 sekundowy zapalnik Werfbare Rucksackladung. 7 Sekunden Zeitzünder 一个可投掷的炸药包。7秒定时引信 던질 수 있는 폭파 장약입니다. 던지고 7초 후에 터집니다 + Uma sacola explosiva que pode ser arremessada. Pavio de 7 segundos Explosive Charge (Throwable) Заряд со взрывчаткой (метательный) Charge explosive (lançable) - 爆薬ブロック (投てき仕様) + Carica Esplosiva (Lanciabile) + 爆薬ブロック (投擲仕様) Carga explosiva (Lanzable) Ładunek wybuchowy (Rzucany) Sprengladung (Werfbar) 炸药块(可投掷) 폭파 블럭 (투척) + Carga Explosiva (Arremessável) An explosive charge that is throwable. 7 second fixed fuse Заряд со взрывчаткой. Детонация через 7 секунд Bloc explosif lançable. Détonation après 7 secondes. - 投げられる爆薬ブロック。起爆までの時間は 7 秒間 + Una carica esplosiva lanciabile. Detona dopo 7 secondi fissi + 投げられる爆薬ブロック。起爆まで7秒の固定時限信管付き。 Carga explosiva que se puede lanzar. Espoleta fija de 7 segundos Rzucany ładunkek wybuchowy. 7 sekundowy zapalnik Werfbare Sprengladung. 7 Sekunden Zeitzünder 一个可投掷的炸药块。7秒定时引信 던질 수 있는 폭파 블럭입니다. 던지고 7초 후에 터집니다 + Uma carga explosiva que pode ser arremessada. Pavio de 7 segundos Convert to short fuse Применить фитиль Appliquer une mèche + Converti a spoletta corta 短信管へ変更 Convertir a espoleta corta Konwertuj na krótki zapalnik Zündschnur verkürzen 切换为短引信 단축 신관으로 바꾸기 + Converter para pavio curto Remove short fuse Убрать фитиль Retirer la mèche + Rimuovi spoletta corta 短信管を削除 Quitar espoleta corta Usuń krótki zapalnik Kurze Zündschnur entfernen 去除短引信 단축 신관 제거하기 + Remover pavio curto ACE Grenades @@ -632,23 +654,27 @@ Allow Explosive Conversion Разрешить фитили Autoriser les mèches (charges lançables) - 爆薬変更を許可 + Abilita conversione a lanciabili + 爆発物の変換を許可 Permitir conversión de explosivos Pozwól na konwersję ładunków wybuchowych Erlaube die Umwandlung von Sprengstoffen 允许转换炸药 폭발물 변환 가능여부 + Permitir Conversão de Explosivos Allow converting explosives to throwables Разрешает преобразовывать взрывчатку в метательные снаряды Cette option permet de rendre les charges explosives lançables, à la manière des grenades.\nPour celà, ouvrir l'inventaire et double-cliquer sur les charges, afin de leur appliquer une mèche.\nLa mèche peut se retirer en suivant la même procédure. - 爆発物を投てき仕様へ交換できるようにします。 + Permette la conversione di certi esplosivi piazzabili a esplosivi lanciabili. + このオプションを使用すると、爆発物が手榴弾のように投擲可能になります。\nこれを行うには、インベントリを開いて爆発物をダブルクリックして、爆発物を短信管に変更します。\n信管は同じ手順で取り外すことができます。 Permitir convertir explosivos a lanzables Zezwala na konwersje ładunków wybuchowych na rzucane wersje Erlaube die Umwandlung von Sprengstoffen in werfbare Ladungen 允许将炸药转换为可投掷物 폭발물을 투척무기로 변환할 수 있도록 허용합니다. + Permitir conversão de explosivos em arremessáveis diff --git a/addons/gunbag/XEH_preInit.sqf b/addons/gunbag/XEH_preInit.sqf index ad244390fa..3149314f87 100644 --- a/addons/gunbag/XEH_preInit.sqf +++ b/addons/gunbag/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // restore gunbag info after respawn ["CAManBase", "respawn", { @@ -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/gunbag/functions/fnc_offGunbagCallback.sqf b/addons/gunbag/functions/fnc_offGunbagCallback.sqf index 8edd3e4582..68b22fb1ef 100644 --- a/addons/gunbag/functions/fnc_offGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_offGunbagCallback.sqf @@ -11,7 +11,7 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_offGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_offGunbagCallback * * Public: No */ @@ -23,39 +23,28 @@ private _gunbag = backpackContainer _target; private _state = _gunbag getVariable [QGVAR(gunbagWeapon), []]; if (_state isEqualTo []) exitWith { - [localize LSTRING(empty)] call EFUNC(common,displayTextStructured); + [LLSTRING(empty)] call EFUNC(common,displayTextStructured); }; _state params ["_weapon", "_items", "_magazines"]; -_unit addWeapon _weapon; +[_unit, _weapon, true, _magazines] call EFUNC(common,addWeapon); -// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten -([_unit, _weapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"]; +// Add attachments { - if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then { - TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex); - _unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex]; - }; -} forEach _magazines; - -removeAllPrimaryWeaponItems _unit; - -{ - _unit addWeaponItem [_weapon, _x]; -} forEach (_items + _magazines); + _unit addWeaponItem [_weapon, _x, true]; +} forEach (_items select {_x != ""}); _unit selectWeapon _weapon; -_magazines = _magazines apply {_x select 0}; +private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass); -private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass); - -// remove virtual load +// Remove virtual load [_target, _gunbag, -_mass] call EFUNC(movement,addLoadToUnitContainer); + _gunbag setVariable [QGVAR(gunbagWeapon), [], true]; -// play sound +// Play sound if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then { [_target, _gunbag] call EFUNC(backpacks,backpackOpened); }; diff --git a/addons/gunbag/functions/fnc_swapGunbagCallback.sqf b/addons/gunbag/functions/fnc_swapGunbagCallback.sqf index a7d319506b..cb4bca2ea4 100644 --- a/addons/gunbag/functions/fnc_swapGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_swapGunbagCallback.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Ir0n1E and mjc4wilton + * Author: Ir0n1E, mjc4wilton * Swap primary weapon and weapon in gunbag. * * Arguments: @@ -11,66 +11,49 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_swapGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_swapGunbagCallback * * Public: No */ params ["_unit", "_target"]; -private _currentWeapon = primaryWeapon _unit; //Get Current Weapon + +// Set up current weapon for storing private _gunbag = backpackContainer _target; +private _currentItems = (getUnitLoadout _unit) select 0; +private _currentMagazines = _currentItems select [4, 2]; +_currentItems deleteRange [4, 2]; -//---Set up current weapon for storing -private _currentWeaponState = [_unit, _currentWeapon] call EFUNC(common,getWeaponState); //Gets weapon attachments +private _currentWeapon = _currentItems deleteAt 0; -/* - * example return value _state - * [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]] - */ +private _currentMass = [_currentWeapon, _currentItems, _currentMagazines apply {_x select 0}] call FUNC(calculateMass); -_currentWeaponState params ["_currentWeaponItems", "", "_currentWeaponMagazines", "_currentWeaponAmmo"]; //Extract Weapon Attachments to separate arrays +// Set up weapon in gunbag +private _newState = _gunbag getVariable [QGVAR(gunbagWeapon), []]; -private _currentWeaponMass = [_currentWeapon, _currentWeaponItems, _currentWeaponMagazines] call FUNC(calculateMass); - -{ - _currentWeaponMagazines set [_forEachIndex, [_x, _currentWeaponAmmo select _forEachIndex]]; -} forEach _currentWeaponMagazines; - -//---Set up weapon in gunbag -private _newWeaponState = _gunbag getVariable [QGVAR(gunbagWeapon), []]; - -if (_newWeaponState isEqualTo []) exitWith { +if (_newState isEqualTo []) exitWith { [LLSTRING(empty)] call EFUNC(common,displayTextStructured); }; -_newWeaponState params ["_newWeapon", "_newWeaponItems", "_newWeaponMagazines"]; +_newState params ["_newWeapon", "_newItems", "_newMagazines"]; -//---Swap Weapons +// Swap Weapons _unit removeWeapon _currentWeapon; -_unit addWeapon _newWeapon; -// Game will auto add magazines from player's inventory, put these back in player inventory as they will be overwritten -([_unit, _newWeapon] call EFUNC(common,getWeaponState)) params ["", "", "_addedMags", "_addedAmmo"]; +[_unit, _newWeapon, true, _newMagazines] call EFUNC(common,addWeapon); + +// Add attachments { - if (((_x select 0) != "") && {(_addedMags select _forEachIndex) != ""}) then { - TRACE_2("Re-adding mag",_x,_addedMags select _forEachIndex); - _unit addMagazine [_addedMags select _forEachIndex, _addedAmmo select _forEachIndex]; - }; -} forEach _newWeaponMagazines; - -removeAllPrimaryWeaponItems _unit; - -{ - _unit addWeaponItem [_newWeapon, _x]; -} forEach (_newWeaponItems + _newWeaponMagazines); + _unit addWeaponItem [_newWeapon, _x, true]; +} forEach (_newItems select {_x != ""}); _unit selectWeapon _newWeapon; -_newWeaponMagazines = _newWeaponMagazines apply {_x select 0}; +private _newMass = [_newWeapon, _newItems, _newMagazines apply {_x select 0}] call FUNC(calculateMass); -private _newWeaponMass = [_newWeapon, _newWeaponItems, _newWeaponMagazines] call FUNC(calculateMass); +// Update virtual load +[_target, _gunbag, _currentMass - _newMass] call EFUNC(movement,addLoadToUnitContainer); -// update virtual load -[_target, _gunbag, _currentWeaponMass - _newWeaponMass] call EFUNC(movement,addLoadToUnitContainer); -_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentWeaponItems, _currentWeaponMagazines], true]; //Replace weapon in gunbag +// Replace weapon in gunbag +_gunbag setVariable [QGVAR(gunbagWeapon), [_currentWeapon, _currentItems, _currentMagazines], true]; diff --git a/addons/gunbag/functions/fnc_toGunbagCallback.sqf b/addons/gunbag/functions/fnc_toGunbagCallback.sqf index 4930d1d95a..9958eed32b 100644 --- a/addons/gunbag/functions/fnc_toGunbagCallback.sqf +++ b/addons/gunbag/functions/fnc_toGunbagCallback.sqf @@ -11,38 +11,32 @@ * None * * Example: - * [player, target] call ace_gunbag_fnc_toGunbagCallback + * [player, cursorObject] call ace_gunbag_fnc_toGunbagCallback * * Public: No */ params ["_unit", "_target"]; -private _weapon = primaryWeapon _unit; +// Set up current weapon for storing private _gunbag = backpackContainer _target; +private _items = (getUnitLoadout _unit) select 0; -private _state = [_unit, _weapon] call EFUNC(common,getWeaponState); +private _magazines = _items select [4, 2]; +_items deleteRange [4, 2]; -/* - * example return value _state - * [["","","optic_Aco",""],["arifle_MX_GL_ACO_F","GL_3GL_F"],["30Rnd_65x39_caseless_mag","1Rnd_HE_Grenade_shell"],[30,1]] - */ +private _weapon = _items deleteAt 0; -_state params ["_items", "", "_magazines", "_ammo"]; - -private _mass = [_weapon, _items, _magazines] call FUNC(calculateMass); - -{ - _magazines set [_forEachIndex, [_x, _ammo select _forEachIndex]]; -} forEach _magazines; +private _mass = [_weapon, _items, _magazines apply {_x select 0}] call FUNC(calculateMass); _unit removeWeapon _weapon; -// add virtual load +// Add virtual load [_target, _gunbag, _mass] call EFUNC(movement,addLoadToUnitContainer); + _gunbag setVariable [QGVAR(gunbagWeapon), [_weapon, _items, _magazines], true]; -// play sound +// Play sound if (["ace_backpacks"] call EFUNC(common,isModLoaded)) then { [_target, _gunbag] call EFUNC(backpacks,backpackOpened); }; diff --git a/addons/gunbag/initSettings.sqf b/addons/gunbag/initSettings.inc.sqf similarity index 100% rename from addons/gunbag/initSettings.sqf rename to addons/gunbag/initSettings.inc.sqf diff --git a/addons/gunbag/stringtable.xml b/addons/gunbag/stringtable.xml index eed1b370ee..6389a667c8 100644 --- a/addons/gunbag/stringtable.xml +++ b/addons/gunbag/stringtable.xml @@ -19,14 +19,14 @@ Gunbag (Tan) - Waffentasche (hellbraun) - Housse d'arme (marron clair) + Waffentasche (Hellbraun) + Housse d'arme (Marron clair) Чехол (желтовато-коричневый) Pouzdro na zbraň (Žlutohnědá) ガンバッグ (タン) - Torba na broń (jasnobrązowa) + Torba na broń (Jasnobrązowa) 총가방 (황갈색) - Borsa per Armi (Tan) + Borsa per Armi (Marroncina) 枪袋(黄褐色) 槍袋 (黃褐色) Bolsa de Arma (Bege) @@ -58,7 +58,7 @@ ガンバッグへ武器を入れる Włóż broń do torby 무기를 총가방에 넣기 - Metti l'arma nella borsa per armi + Metti l'arma nella borsa 将武器放置枪袋 將武器放置槍袋 Colocar arma na Bolsa de Arma @@ -74,8 +74,10 @@ Silah çantasında silah değişimi Intercambiar arma en funda de arma Waffe in Waffentasche tauschen + Scambia arma nella borsa 交换枪袋中的武器 총가방 안에 있는 무기랑 교환하기 + Trocar arma na Bolsa de Arma Enable Weapon Swap @@ -86,8 +88,10 @@ Silah Değiştirmeyi Etkinleştir Habilitar cambio de arma Aktiviere Tauschen von Waffen + Abilita Scambio Arma 启用武器互换 무기 교환 활성화 + Habilitar Troca de Arma Allows interaction to directly swap the primary weapon and stored weapon. @@ -98,8 +102,10 @@ Etkileşimin doğrudan birincil silahı ve depolanan silahı değiştirmesine izin verir. Permitir interacción para intercambiar el arma principal y el arma guardada. Erlaube den direkten Wechsel von Primärer und verstauter Waffe über das Interaktionsmenü. + Permetti un'interazione per scambiare l'arma primaria con quella nella borsa. 允许互动直接切换主武器和存储武器。 보관 중인 무기를 주무기와 바로 바꾸는 것을 허용합니다. + Permite interação para trocar a arma primária e a arma armazenada. Get weapon out of gunbag @@ -110,7 +116,7 @@ ガンバッグから武器を出す Wyciągnij broń z torby 무기를 총가방에서 꺼내기 - Prendi l'arma dalla borsa per armi + Prendi l'arma dalla borsa 将武器拿出枪袋 將武器拿出槍袋 Retirar arma da Bolsa de Arma diff --git a/addons/headless/XEH_PREP.hpp b/addons/headless/XEH_PREP.hpp index 11e09adf10..e1c65cc083 100644 --- a/addons/headless/XEH_PREP.hpp +++ b/addons/headless/XEH_PREP.hpp @@ -1,3 +1,4 @@ +ACEX_PREP(blacklist); ACEX_PREP(endMissionNoPlayers); ACEX_PREP(handleConnectHC); ACEX_PREP(handleDisconnect); diff --git a/addons/headless/XEH_postInit.sqf b/addons/headless/XEH_postInit.sqf index 103d5c1834..90677042f4 100644 --- a/addons/headless/XEH_postInit.sqf +++ b/addons/headless/XEH_postInit.sqf @@ -1,15 +1,49 @@ #include "script_component.hpp" -["ace_settingsInitialized", { +if (!isMultiplayer) exitWith {}; + +["CBA_settingsInitialized", { // Register and remove HCs if not client that is not server and distribution or end mission enabled if ((!hasInterface || isServer) && {XGVAR(enabled) || XGVAR(endMission) != 0}) then { if (isServer) then { // Request rebalance on any unit spawn (only if distribution enabled) if (XGVAR(enabled)) then { - ["AllVehicles", "initPost", FUNC(handleSpawn), nil, nil, true] call CBA_fnc_addClassEventHandler; + ["CAManBase", "initPost", LINKFUNC(handleSpawn), nil, nil, true] call CBA_fnc_addClassEventHandler; }; // Add disconnect EH addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + + [QGVAR(transferGroupsRebalance), { + params ["_groups", "_owner", "_rebalance"]; + + if (_groups isNotEqualTo [] && {_owner > 1}) then { + { + _x setGroupOwner _owner; + } forEach _groups; + }; + + // Rebalance units + if (_rebalance in [REBALANCE, FORCED_REBALANCE]) then { + (_rebalance == FORCED_REBALANCE) call FUNC(rebalance); + }; + }] call CBA_fnc_addEventHandler; + + // If CBA's loadout validation is enabled, warn users + if (XGVAR(transferLoadout) > 0 && {(missionNamespace getVariable ["CBA_network_loadoutValidation", 0]) isEqualTo 2}) then { + WARNING("CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled"); + [QEGVAR(common,displayTextStructured), ["CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled", 3]] call CBA_fnc_globalEvent; + }; + + ["CBA_SettingChanged", { + params ["_setting", "_value"]; + + if (_setting != "CBA_network_loadoutValidation") exitWith {}; + + if (XGVAR(transferLoadout) > 0 && {_value isEqualTo 2}) then { + WARNING("CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled"); + [QEGVAR(common,displayTextStructured), ["CBA_network_loadoutValidation is enabled - acex_headless_transferLoadout should therefore be disabled", 3]] call CBA_fnc_globalEvent; + }; + }] call CBA_fnc_addEventHandler; } else { // Register HC (this part happens on HC only) [QXGVAR(headlessClientJoined), [player]] call CBA_fnc_globalEvent; // Global event for API purposes diff --git a/addons/headless/XEH_preInit.sqf b/addons/headless/XEH_preInit.sqf index 3c18740cc8..c51b62cf57 100644 --- a/addons/headless/XEH_preInit.sqf +++ b/addons/headless/XEH_preInit.sqf @@ -6,14 +6,13 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" if (isServer) then { GVAR(headlessClients) = []; GVAR(inRebalance) = false; GVAR(endMissionCheckDelayed) = false; - GVAR(blacklistType) = [BLACKLIST_UAV]; - [QXGVAR(headlessClientJoined), FUNC(handleConnectHC)] call CBA_fnc_addEventHandler; + [QXGVAR(headlessClientJoined), LINKFUNC(handleConnectHC)] call CBA_fnc_addEventHandler; }; ADDON = true; diff --git a/addons/headless/functions/fnc_blacklist.sqf b/addons/headless/functions/fnc_blacklist.sqf new file mode 100644 index 0000000000..1c15406ba6 --- /dev/null +++ b/addons/headless/functions/fnc_blacklist.sqf @@ -0,0 +1,51 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Modifies which units are blacklisted from being transferred to HCs. + * + * Arguments: + * 0: Units + * 1: Add (true) or remove (false) from blacklist (default: true) + * 2: Owner to transfer units to (default: -1) + * 3: Rebalance (default: 0) + * + * Return Value: + * None + * + * Example: + * [cursorObject, true] call ace_headless_fnc_blacklist + * + * Public: Yes + */ + +params [["_units", objNull, [objNull, grpNull, []]], ["_blacklist", true, [false]], ["_owner", -1, [false]], ["_rebalance", NO_REBALANCE, [0]]]; + +if !(_units isEqualType []) then { + _units = [_units]; +}; + +// Make sure passed arguments are objects or groups +_units = _units select {_x isEqualType objNull || {_x isEqualType grpNull}}; +_units = _units select {!isNull _x}; + +if (_units isEqualTo []) exitWith {}; + +private _transfer = _blacklist && {_owner > 1}; +private _groups = []; + +{ + _x setVariable [QXGVAR(blacklist), _blacklist, true]; + + if (_transfer) then { + if (_x isEqualType objNull) then { + _groups pushBack group _x; + } else { + _groups pushBack _x; + }; + }; +} forEach _units; + +// Try to move AI to new owner; Also takes care of rebalancing groups +if (_transfer || {_rebalance in [REBALANCE, FORCED_REBALANCE]}) then { + [QGVAR(transferGroupsRebalance), [_groups arrayIntersect _groups, _owner, _rebalance]] call CBA_fnc_serverEvent; +}; diff --git a/addons/headless/functions/fnc_handleConnectHC.sqf b/addons/headless/functions/fnc_handleConnectHC.sqf index b19ef25012..e5acaf48fc 100644 --- a/addons/headless/functions/fnc_handleConnectHC.sqf +++ b/addons/headless/functions/fnc_handleConnectHC.sqf @@ -19,17 +19,14 @@ params ["_headlessClient"]; // Exit if HC already registered // No need to check if distribution or end mission enabled, as if disabled this will never run -if (_headlessClient in GVAR(headlessClients)) exitWith {}; - -// Register for use -GVAR(headlessClients) pushBack _headlessClient; +if (GVAR(headlessClients) pushBackUnique _headlessClient == -1) exitWith {}; if (XGVAR(log)) then { INFO_1("Registered HC: %1",_headlessClient); }; // Exit if AI distribution is disabled -if (!XGVAR(enabled)) exitWith {true}; +if (!XGVAR(enabled)) exitWith {}; // Rebalance [true] call FUNC(rebalance); diff --git a/addons/headless/functions/fnc_handleDisconnect.sqf b/addons/headless/functions/fnc_handleDisconnect.sqf index c94cec2599..a18f22a3bd 100644 --- a/addons/headless/functions/fnc_handleDisconnect.sqf +++ b/addons/headless/functions/fnc_handleDisconnect.sqf @@ -17,7 +17,7 @@ */ params ["_object"]; -TRACE_1("HandleDisconnect",_this); +TRACE_1("HandleDisconnect",_object); // Exit if not HC if !(_object in GVAR(headlessClients)) exitWith { @@ -28,9 +28,7 @@ if !(_object in GVAR(headlessClients)) exitWith { if (CBA_missionTime < 150) then { TRACE_1("Mission start delay",CBA_missionTime); GVAR(endMissionCheckDelayed) = true; - [{ - call FUNC(endMissionNoPlayers); - }, [], 150 - CBA_missionTime] call CBA_fnc_waitAndExecute; + [LINKFUNC(endMissionNoPlayers), [], 150 - CBA_missionTime] call CBA_fnc_waitAndExecute; } else { // End instantly or after delay if (XGVAR(endMission) == 1) then { @@ -39,7 +37,7 @@ if !(_object in GVAR(headlessClients)) exitWith { } else { TRACE_2("Delayed 60s end",GVAR(endMission),CBA_missionTime); GVAR(endMissionCheckDelayed) = true; - [FUNC(endMissionNoPlayers), [], 60] call CBA_fnc_waitAndExecute; + [LINKFUNC(endMissionNoPlayers), [], 60] call CBA_fnc_waitAndExecute; }; }; }; diff --git a/addons/headless/functions/fnc_handleSpawn.sqf b/addons/headless/functions/fnc_handleSpawn.sqf index 50277e3845..56b74f407d 100644 --- a/addons/headless/functions/fnc_handleSpawn.sqf +++ b/addons/headless/functions/fnc_handleSpawn.sqf @@ -4,27 +4,22 @@ * Handles AI spawn and requests a rebalance if applicable. * * Arguments: - * 0: Object + * 0: Unit * * Return Value: * None * * Example: - * [object] call ace_headless_fnc_handleSpawn + * [cursorObject] call ace_headless_fnc_handleSpawn * * Public: No */ -params ["_object"]; -TRACE_1("Spawn",_object); +params ["_unit"]; +TRACE_1("Spawn",_unit); -// Exit if HC transferring disabled or object not a unit (including unit inside vehicle) or is player -if (!(_object in allUnits) || {isPlayer _object}) exitWith {}; - -// Exit and blacklist if of blacklist type -if ({_object isKindOf _x} count GVAR(blacklistType) > 0) exitWith { - _object setVariable [QXGVAR(blacklist), true]; -}; +// Exit if unit is player or UAV crew +if (isPlayer _unit || {unitIsUAV _unit}) exitWith {}; // Rebalance [false] call FUNC(rebalance); diff --git a/addons/headless/functions/fnc_rebalance.sqf b/addons/headless/functions/fnc_rebalance.sqf index 84be441ebe..5ec32f39bd 100644 --- a/addons/headless/functions/fnc_rebalance.sqf +++ b/addons/headless/functions/fnc_rebalance.sqf @@ -23,7 +23,7 @@ TRACE_3("Rebalance",GVAR(inRebalance),GVAR(headlessClients),_force); if (GVAR(inRebalance) || {GVAR(headlessClients) isEqualTo []}) exitWith {}; // Transfer after rebalance delay -[FUNC(transferGroups), [_force], XGVAR(Delay)] call CBA_fnc_waitAndExecute; +[LINKFUNC(transferGroups), _force, XGVAR(delay)] call CBA_fnc_waitAndExecute; // Currently in rebalance flag GVAR(inRebalance) = true; diff --git a/addons/headless/functions/fnc_transferGroups.sqf b/addons/headless/functions/fnc_transferGroups.sqf index cee85a5109..0efbe26365 100644 --- a/addons/headless/functions/fnc_transferGroups.sqf +++ b/addons/headless/functions/fnc_transferGroups.sqf @@ -17,6 +17,9 @@ params ["_force"]; +// Filter out any invalid entries +GVAR(headlessClients) = GVAR(headlessClients) select {!isNull _x}; + GVAR(headlessClients) params [ ["_HC1", objNull, [objNull]], ["_HC2", objNull, [objNull]], @@ -36,12 +39,13 @@ private _idHC2 = -1; private _idHC3 = -1; private _currentHC = 0; -if (!local _HC1) then { +// objNull is never local +if (!local _HC1 && !isNull _HC1) then { _idHC1 = owner _HC1; _currentHC = 1; }; -if (!local _HC2) then { +if (!local _HC2 && !isNull _HC2) then { _idHC2 = owner _HC2; if (_currentHC == 0) then { @@ -49,7 +53,7 @@ if (!local _HC2) then { }; }; -if (!local _HC3) then { +if (!local _HC3 && !isNull _HC3) then { _idHC3 = owner _HC3; if (_currentHC == 0) then { @@ -57,82 +61,150 @@ if (!local _HC3) then { }; }; +if (_currentHC == 0) exitWith { + TRACE_1("No Valid HC to transfer to",_currentHC); + + if (XGVAR(log)) then { + INFO("No Valid HC to transfer to"); + }; +}; + // Prepare statistics private _numTransferredHC1 = 0; private _numTransferredHC2 = 0; private _numTransferredHC3 = 0; +private _units = []; +private _transfer = false; +private _previousOwner = -1; + // Transfer AI groups { - // No transfer if empty group - private _transfer = ((units _x) isNotEqualTo []) && {!(_x getVariable [QXGVAR(blacklist), false])}; - if (_transfer) then { - // No transfer if waypoints with synchronized triggers exist for the group - private _allWaypointsWithTriggers = (waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}; - if (_allWaypointsWithTriggers isNotEqualTo []) exitWith { + _units = units _x; + + // No transfer if empty group or if group is blacklisted + if (_units isEqualTo [] || {_x getVariable [QXGVAR(blacklist), false]}) then { + continue; + }; + + // No transfer if waypoints with synchronized triggers exist for the group + if (((waypoints _x) select {(synchronizedTriggers _x) isNotEqualTo []}) isNotEqualTo []) then { + continue; + }; + + { + // No transfer if already transferred + if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { _transfer = false; }; - { - // No transfer if already transferred - if (!_force && {(owner _x) in [_idHC1, _idHC2, _idHC3]}) exitWith { - _transfer = false; - }; + // No transfer if any unit in group is blacklisted + if (_x getVariable [QXGVAR(blacklist), false]) exitWith { + _transfer = false; + }; - // No transfer if player in this group - if (isPlayer _x) exitWith { - _transfer = false; - }; + // No transfer if player or UAV in this group + if (isPlayer _x || {unitIsUAV _x}) exitWith { + _transfer = false; + }; - // No transfer if any unit in group is blacklisted - if (_x getVariable [QXGVAR(blacklist), false]) exitWith { - _transfer = false; - }; + private _vehicle = objectParent _x; - // No transfer if vehicle unit is in or crew in that vehicle is blacklisted - if (vehicle _x != _x && {(vehicle _x) getVariable [QXGVAR(blacklist), false]}) exitWith { - _transfer = false; - }; + // No transfer if the vehicle the unit is in or if the crew in that vehicle is blacklisted + if ((_vehicle getVariable [QXGVAR(blacklist), false]) || {unitIsUAV _vehicle}) exitWith { + _transfer = false; + }; - // Save gear if unit about to be transferred with current loadout (naked unit work-around) - if (XGVAR(transferLoadout) == 1) then { - _x setVariable [QGVAR(loadout), [_x] call CBA_fnc_getLoadout, true]; - }; - } forEach (units _x); + // Save gear if unit about to be transferred with current loadout (naked unit work-around) + if (XGVAR(transferLoadout) == 1) then { + _x setVariable [QGVAR(loadout), _x call CBA_fnc_getLoadout, true]; + }; + } forEach _units; + + if (!_transfer) then { + continue; }; // Round robin between HCs if load balance enabled, else pass all to one HC - if (_transfer) then { - switch (_currentHC) do { - case 1: { - private _transferred = _x setGroupOwner _idHC1; - if (_loadBalance) then { - _currentHC = [3, 2] select (!local _HC2); - }; - if (_transferred) then { - _numTransferredHC1 = _numTransferredHC1 + 1; + _previousOwner = groupOwner _x; + + switch (_currentHC) do { + case 1: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC2 != -1) then { + _currentHC = 2; + } else { + if (_idHC3 != -1) then { + _currentHC = 3; + }; }; }; - case 2: { - private _transferred = _x setGroupOwner _idHC2; - if (_loadBalance) then { - _currentHC = [1, 3] select (!local _HC3); - }; - if (_transferred) then { - _numTransferredHC2 = _numTransferredHC2 + 1; + + // Don't transfer if it's already local to HC1 + if (_previousOwner == _idHC1) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC1, _previousOwner, _idHC1], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC1; + + [QGVAR(groupTransferPost), [_x, _HC1, _previousOwner, _idHC1, _transferred], [_previousOwner, _idHC1]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC1 = _numTransferredHC1 + 1; + }; + }; + case 2: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC3 != -1) then { + _currentHC = 3; + } else { + if (_idHC1 != -1) then { + _currentHC = 1; + }; }; }; - case 3: { - private _transferred = _x setGroupOwner _idHC3; - if (_loadBalance) then { - _currentHC = [2, 1] select (!local _HC1); - }; - if (_transferred) then { - _numTransferredHC3 = _numTransferredHC3 + 1; + + // Don't transfer if it's already local to HC2 + if (_previousOwner == _idHC2) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC2, _previousOwner, _idHC2], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC2, _previousOwner, _idHC2, _transferred], [_previousOwner, _idHC2]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC2 = _numTransferredHC2 + 1; + }; + }; + case 3: { + if (_loadBalance) then { + // Find the next valid HC + // If none are valid, _currentHC will remain the same + if (_idHC1 != -1) then { + _currentHC = 1; + } else { + if (_idHC2 != -1) then { + _currentHC = 2; + }; }; }; - default { - TRACE_1("No Valid HC to transfer to", _currentHC); + + // Don't transfer if it's already local to HC3 + if (_previousOwner == _idHC3) exitWith {}; + + [QGVAR(groupTransferPre), [_x, _HC3, _previousOwner, _idHC3], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API + + private _transferred = _x setGroupOwner _idHC2; + + [QGVAR(groupTransferPost), [_x, _HC3, _previousOwner, _idHC3, _transferred], [_previousOwner, _idHC3]] call CBA_fnc_targetEvent; // API + + if (_transferred) then { + _numTransferredHC3 = _numTransferredHC3 + 1; }; }; }; @@ -140,7 +212,7 @@ private _numTransferredHC3 = 0; if (XGVAR(log)) then { private _numTransferredTotal = _numTransferredHC1 + _numTransferredHC2 + _numTransferredHC3; - INFO_4("Groups Transferred: Total: %1 - HC1: %2 - HC2: %3 - HC3: %4", _numTransferredTotal, _numTransferredHC1, _numTransferredHC2, _numTransferredHC3); + INFO_4("Groups Transferred: Total: %1 - HC1: %2 - HC2: %3 - HC3: %4",_numTransferredTotal,_numTransferredHC1,_numTransferredHC2,_numTransferredHC3); }; // Allow rebalance flag diff --git a/addons/headless/initSettings.sqf b/addons/headless/initSettings.inc.sqf similarity index 70% rename from addons/headless/initSettings.sqf rename to addons/headless/initSettings.inc.sqf index cb5fe6e53d..ec720fce7c 100644 --- a/addons/headless/initSettings.sqf +++ b/addons/headless/initSettings.inc.sqf @@ -4,9 +4,9 @@ [ELSTRING(common,Enabled), LSTRING(EnabledDesc)], format ["ACE %1", LLSTRING(Module)], false, - true, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + 1, + {[QXGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -15,9 +15,7 @@ [LSTRING(Delay), LSTRING(DelayDesc)], format ["ACE %1", LLSTRING(Module)], [0, 60, 15, -1], - true, - {[QGVAR(delay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + 1 ] call CBA_fnc_addSetting; [ @@ -26,9 +24,9 @@ [LSTRING(EndMission), LSTRING(EndMissionDesc)], format ["ACE %1", LLSTRING(Module)], [[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(Instant), LSTRING(Delayed)], 0], - true, - {[QGVAR(delay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + 1, + {[QXGVAR(endMission), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -37,9 +35,7 @@ [LSTRING(Log), LSTRING(LogDesc)], format ["ACE %1", LLSTRING(Module)], false, - true, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + 1 ] call CBA_fnc_addSetting; [ @@ -48,7 +44,7 @@ [LSTRING(TransferLoadout), LSTRING(TransferLoadoutDesc)], format ["ACE %1", LLSTRING(Module)], [[0, 1, 2], [ELSTRING(Common,Disabled), LSTRING(TransferLoadoutCurrent), LSTRING(TransferLoadoutConfig)], 0], - true, - {}, - true // needs mission restart + 1, + {[QXGVAR(transferLoadout), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/headless/script_component.hpp b/addons/headless/script_component.hpp index c73e2260de..272b288d5f 100644 --- a/addons/headless/script_component.hpp +++ b/addons/headless/script_component.hpp @@ -17,4 +17,7 @@ #include "\z\ace\addons\main\script_macros.hpp" #define DELAY_DEFAULT 15 -#define BLACKLIST_UAV "UAV", "UAV_AI_base_F", "B_UAV_AI", "O_UAV_AI", "I_UAV_AI" + +#define NO_REBALANCE 0 +#define REBALANCE 1 +#define FORCED_REBALANCE 2 diff --git a/addons/headless/stringtable.xml b/addons/headless/stringtable.xml index b58fe139ff..35dcb11862 100644 --- a/addons/headless/stringtable.xml +++ b/addons/headless/stringtable.xml @@ -13,32 +13,35 @@ Headless Headless клиент Headless + Headless This module allows you to setup automatic transferring of AI to Headless Clients. (Default: No) Dieses Modul erlaubt es dir, die KI automatisch auf einen Headless Client zu transferieren. (Standard: Nein) Ten moduł zezwala na automatyczny transfer AI do Headless Cient. (Domyślnie: Nie) 이 모듈을 사용하면 헤드리스 클라이언트에 AI 자동 전송을 설정할 수 있습니다. (기본값 : No) - モジュールはAIを自動的にヘッドレスクライアントへ移行します。(標準: 無効) + モジュールはAIを自動的にヘッドレスクライアントへ移行します。 (デフォルト: 無効) Ce module permet de mettre en place un transfert aotmatique de l'IA vers le Headless Clients. (Défaut: Non) 此模块能让你自动转换 AI 的控制权给其他 Headless 客户端。(预设:关闭) 此模塊能讓你自動轉換AI的控制權給其他無頭客戶端。(預設:關閉) - Questo modulo ti consente di impostare il trasferimento automatico delle AI su dei Client Headless. (Default: No) + Questo modulo ti consente di impostare il trasferimento automatico delle IA su dei Client Headless. (Predefinito: No) Этот модуль позволяет настроить автоматическую передачу управления ИИ Headless клиентам. (По умолчанию: Откл) Este modulo permite habilitar la transferencia de IA a los Headless Clients. (Defecto: No) + Este módulo permite configurar a transferência automática de IA para Headless Clients. (Padrão: Não) Enables transferring of AI to Headless Clients. Aktiviert den Transfer der KI auf die Headless Clients. Włącza transfer AI do Headless Client. AI를 헤드리스 클라이언트로 전송할 수 있습니다. - AIをヘッドレスクライアントへ移行を有効化 + AI のヘッドレス クライアントへの転送を有効化します。 Permet le transfert des IA au Headless Clients. 开启转换 AI 控制权给 Headless 客户端。 開啟轉換AI控制權給無頭客戶端。 - Abilita il trasferimento delle AI sugli Headless Client. + Abilita il trasferimento delle IA sugli Headless Client. Передает управление ИИ Headless клиентам. Habilita la transferencia de IA a los Headless Clients + Ativa a transferência de IA para Headless Clients. Delay @@ -52,19 +55,21 @@ Latenza Задержка Retardo + Atraso Minimal delay between transfers, in seconds. (Default: 15) Minimale Verzögerung zwischen Transfers in Sekunden. (Standard: 15) Minimalny odstęp pomiędzy transferami w sekundach. (Domyślnie: 15) 전송 간 최소 지연 시간, 초당. (기본값: 15) - 移行する際の最低遅延を秒数で設定します。(標準: 15) + 移行する際の最低遅延を秒単位で設定します。 (デフォルト: 15) Délai minimum entres les transferts, en secondes. (Défaut: 15) 设定每次转换间隔多少秒。(预设:15秒) 設定每次轉換間隔多少秒。(預設:15秒) - Latenza minima tra i trasferimenti, in secondi. (Default: 15) + Latenza minima tra i trasferimenti, in secondi. (Predefinito: 15) Минимальная задержка в секундах между передачами. (По умолчанию: 15) Retardo mínimo entre transferencias en segundos. (Default: 15) + Atraso mínimo entre transferências, em segundos. (Padrão: 15) End Mission @@ -78,12 +83,13 @@ Koniec misji Завершать миссию Finalizar misión + Finalizar Missão End mission when there are no players connected (same as 'persistent = 0' in server configuration but with Headless Client support). Beende die Mission, wenn keine Spieler mehr verbunden sind (das gleiche wie 'persitent = 0' in den Serverkonfigurationen aber mit Headless Client Unterstützung). 연결된 플레이어가 없을 때 임무 종료. (서버 구성에서는 'persistent = 0'과 같지만 Headless Client는 지원함) - プレイヤーが接続していない場合はミッション終了します。(サーバ設定の'presistent =0'と同じですが、ヘッドレスクライアントは適用されます) + プレイヤーが接続していない場合はミッション終了します。(サーバ設定の'presistent =0'と同じですが、ヘッドレスクライアントをサポートします) Termine la mission lorsqu'il n'y a plus de joueur connecté (idem que 'persistent = 0' dans la config serveur mais avec la gestion du Headless Client). 当服务器里没有任何玩家还连线时自动结束任务(效果同于伺服器设定的'persistent = 0',但支援 Headless 客户端)。 當伺服器裡沒有任何玩家還連線時自動結束任務(效果同於伺服器設定的'persistent = 0',但支援無頭客戶端)。 @@ -91,6 +97,7 @@ Kończy misje kiedy nie ma połączonych graczy(tak samo jak 'persistent = 0' w konfiguracji serwer ale z wsparciem Headless Client Завершает миссию, если нет присоединенных игроков (аналогично 'persistent = 0' в настройках сервера, но с включенной поддержкой Headless клиентов). Finalizar la misión cuando no hay jugadores conectados (igual que la opción de servidor 'persistent = 0', pero con soporte para Headless Client). + Finaliza a missão quando não há jogadores conectados (o mesmo que 'persistent = 0' na configuração do servidor, mas com suporte para Headless Client). Instant @@ -104,6 +111,7 @@ Natychmiastowy Мгновенно Instantáneo + Instantâneo Delayed (60s) @@ -117,6 +125,7 @@ Opóźniony (60s) С задержкой (60 с) Retardado (60s) + Atrasado (60s) Log @@ -130,23 +139,26 @@ Registra Журнал Registrar + Registo Log transfer statistics and Headless Client (dis)connections to RPT. (Default: No) Zeichnet Transferstatistiken, Verbindungen und Verbindungsabbrüche in einer RPT-Datei auf. (Standard: Nein) Zapisz statystyki transferu i status połączenia Headless Clienta do RPT. (Domyślnie: Tak) 전송 통계 및 헤드리스 클라이언트 연결(해제)를 RPT파일에 로그함. (기본값: No) - 統計とヘッドレスクライアントの接続有無を PRT へ記録します。(標準: 無効) + 統計とヘッドレスクライアントの接続有無を PRT へ記録します。 (デフォルト: 無効) Archive les statistiques de transfert et de (dé)connections du Headless Client dans le RPT. (Défaut: Non) 记录 Headless 客户端间的转换数量与连线/断线等记录到 RPT 报告档中。(预设:关闭) 記錄無頭客戶端間的轉換數量與連線/斷線等記錄到RPT報告檔中。(預設:關閉) - Registra le statistiche del trasferimento e delle (dis)connessioni dell'Headless Clienti su RPT. (Default: No) + Registra le statistiche del trasferimento e delle (dis)connessioni dell'Headless Clienti su RPT. (Predefinito: No) Вести журнал передач и подключений Headless клиентов в файл RPT. (По умолчанию: Откл) Registrar las estadísticas de transferencia y las (des)conexiones de Headless Client hacia el RPT. (Default: No) + Regista as estatísticas de transferência e as (des)conexões do Headless Client para o RPT. (Padrão: Não) Transfer Loadout Transferiere Ausrüstung + Trasferisci Equipaggiamento 装備の移送 裝備傳輸 装备转移 @@ -155,10 +167,12 @@ 로드아웃 전송 Transferir equipamiento Transfert équipement + Transferir Equipamento Transfer loadout of units attempts to work around an issue where units appear naked after transferring to a Headless Client. Transferiere die Ausrüstung einer Einheit, um einen Fehler zu umgehen, bei welchem Einheiten nach dem Transfer auf einen Headless Client nackt erscheinen. + Il trasferimento di equipaggiamenti tenta di mitigare un problema dove unità appaiono nude dopo essere state trasferite al Headless Client. 装備の移送はヘッドレスクライアントへの移行後にユニットが裸で出現する問題の回避を試みます。 Передача снаряжения юнитов позволяет обходить проблему, при которой юниты оказываются без снаряжения после передачи управления Headless клиенту. 裝備傳輸用於試著暫時應付單位透過無頭客戶端傳輸時所導致裸裝之問題。 @@ -167,10 +181,12 @@ 헤드리스 클라이언트로 넘어갈 때 유닛이 벌거벗고 있는 상황을 해결하기 위해 로드아웃을 유닛에 전송합니다. Transferir el equipamiento de unidades intenta solventar el problema por el cual las unidades aparecen desnudas despues de ser transferidas a un Headless Client. Transférer l'équipement des unités pour contourner une erreur où les unités apparaissent nues après un transfer vers le Headless Client. + Transferir equipamento de unidades para contornar um problema onde as unidades aparecem nuas após a transferência para um Headless Client. Current Loadout Derzeitige Ausrüstung + Equipaggiamento Corrente 現在の装備 目前裝備 当前装备 @@ -179,10 +195,12 @@ 현재 로드아웃 Equipamiento actual Equipement actuel + Equipamento Atual Config Loadout Konfiguriere Ausrüstung + Equipaggiamento Configurato コンフィグの装備 設置裝備 设置装备 @@ -191,6 +209,7 @@ 로드아웃 설정 Configuración de equipamiento Configuration de l'équipement + Configuração do Equipamento Headless Blacklist @@ -204,6 +223,7 @@ Czarna lista Headless Черный список Headless Lista negra de Headless + Lista Negra Headless Disables transferring of this AI unit/group to Headless Clients. No effect on player units. @@ -212,11 +232,12 @@ Désactive le transfert de ce(tte) unité/groupe au Headless Clients. Sans effet sur les unités des joueurs. 禁止转换黑名单中的 AI 单位/群组到 Headless 客户端上。此功能对玩家单位无用。 禁止轉換黑名單中的AI單位/群組到無頭客戶端上。此功能對玩家單位無用。 - Disabilita il trasferimento di questa unità/gruppo di AI negli Headless Client. Non ha effetto sui giocatori. + Disabilita il trasferimento di questa unità/gruppo di IA negli Headless Client. Non ha effetto sui giocatori. 이 AI 유닛/그룹을 헤드리스 클라이언트로 전송하지 못하도록 합니다. 플레이어 유닛에는 영향을 주지 않습니다. Wyłącza transfer tych jednostek/grup AI do Headless Clients. Bez efektu na jednostkach gracza. Отключает передачу управления этого юнита/группы Headless клиентам. Не влияет на юниты игроков. Deshabilita la transferencia de esta unidad/grupo de IA hacia los Headless Clients.Sin efecto sobre unidades de jugadores. + Desativa a transferência desta unidade/grupo de IA para Headless Clients. Sem efeito nas unidades de jogadores. diff --git a/addons/hearing/CfgEventHandlers.hpp b/addons/hearing/CfgEventHandlers.hpp index 310be3675b..59cd1b3629 100644 --- a/addons/hearing/CfgEventHandlers.hpp +++ b/addons/hearing/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); @@ -13,15 +12,7 @@ class Extended_PreInit_EventHandlers { class Extended_PostInit_EventHandlers { class ADDON { - clientinit = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); - }; -}; - -class Extended_Init_EventHandlers { - class CAManBase { - class GVAR(AddEarPlugs) { - serverInit = QUOTE(_this call FUNC(addEarPlugs)); - }; + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/hearing/CfgVehicles.hpp b/addons/hearing/CfgVehicles.hpp index a762534460..636184ecd2 100644 --- a/addons/hearing/CfgVehicles.hpp +++ b/addons/hearing/CfgVehicles.hpp @@ -5,7 +5,7 @@ class CfgVehicles { class ACE_Equipment { class ACE_PutInEarplugs { displayName = CSTRING(EarPlugs_On); - condition = QUOTE(GVAR(EnableCombatDeafness) && {!([_player] call FUNC(hasEarPlugsIn)) && {'ACE_EarPlugs' in items _player}}); + condition = QUOTE(GVAR(enableCombatDeafness) && {!(_player call FUNC(hasEarPlugsIn)) && {[ARR_2(_player,'ACE_EarPlugs')] call EFUNC(common,hasItem)}}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE([ARR_2(_player,true)] call FUNC(putInEarPlugs)); showDisabled = 0; @@ -13,7 +13,7 @@ class CfgVehicles { }; class ACE_RemoveEarplugs { displayName = CSTRING(EarPlugs_Off); - condition = QUOTE(GVAR(EnableCombatDeafness) && {[_player] call FUNC(hasEarPlugsIn)}); + condition = QUOTE(GVAR(enableCombatDeafness) && {_player call FUNC(hasEarPlugsIn)}); exceptions[] = {"isNotSwimming", "isNotInside", "isNotSitting"}; statement = QUOTE([ARR_2(_player,true)] call FUNC(removeEarPlugs)); showDisabled = 0; diff --git a/addons/hearing/CfgWeapons.hpp b/addons/hearing/CfgWeapons.hpp index 9e0053a284..8cef02edfd 100644 --- a/addons/hearing/CfgWeapons.hpp +++ b/addons/hearing/CfgWeapons.hpp @@ -10,7 +10,7 @@ class CfgWeapons { picture = QPATHTOF(UI\ACE_earplugs_x_ca.paa); scope = 2; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.1; }; }; @@ -80,7 +80,7 @@ class CfgWeapons { class H_HelmetO_ocamo: H_HelmetB { HEARING_PROTECTION_PELTOR; - }; // Defender and Assasin Helmet inherit. + }; // Defender and Assassin Helmet inherit. class H_HelmetO_ViperSP_hex_f: H_HelmetB { HEARING_PROTECTION_PELTOR; diff --git a/addons/hearing/XEH_PREP.hpp b/addons/hearing/XEH_PREP.hpp index e06fa5d56c..a2bcbb708a 100644 --- a/addons/hearing/XEH_PREP.hpp +++ b/addons/hearing/XEH_PREP.hpp @@ -1,8 +1,8 @@ - PREP(addEarPlugs); PREP(earRinging); PREP(explosionNear); PREP(firedNear); +PREP(getAmmoLoudness); PREP(handleRespawn); PREP(hasEarPlugsIn); PREP(moduleHearing); diff --git a/addons/hearing/XEH_postInit.sqf b/addons/hearing/XEH_postInit.sqf index d8b21f214a..4261933bd9 100644 --- a/addons/hearing/XEH_postInit.sqf +++ b/addons/hearing/XEH_postInit.sqf @@ -1,8 +1,21 @@ #include "script_component.hpp" +if (isServer) then { + ["CBA_settingsInitialized", { + TRACE_1("settingInit - server",GVAR(enableCombatDeafness)); + + // Only install event handler if combat deafness is enabled + if (!GVAR(enableCombatDeafness)) exitWith {}; + + ["CAManBase", "Init", LINKFUNC(addEarPlugs), true, [], true] call CBA_fnc_addClassEventHandler; + }] call CBA_fnc_addEventHandler; +}; + if (!hasInterface) exitWith {}; -GVAR(cacheAmmoLoudness) = call CBA_fnc_createNamespace; +#include "initKeybinds.inc.sqf" + +GVAR(cacheAmmoLoudness) = createHashMap; GVAR(deafnessDV) = 0; GVAR(deafnessPrior) = 0; @@ -14,16 +27,20 @@ GVAR(volumeAttenuation) = 1; GVAR(lastPlayerVehicle) = objNull; ["CBA_settingsInitialized", { - TRACE_1("settingInit",GVAR(EnableCombatDeafness)); + TRACE_1("settingInit",GVAR(enableCombatDeafness)); + // Only run PFEH and install event handlers if combat deafness is enabled - if (!GVAR(EnableCombatDeafness)) exitWith {}; + if (!GVAR(enableCombatDeafness)) exitWith {}; // Spawn volume updating process - [LINKFUNC(updateVolume), 1, [false]] call CBA_fnc_addPerFrameHandler; + [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"]; + TRACE_2("vehicle change",_player,_vehicle); _this call FUNC(updatePlayerVehAttenuation); @@ -34,6 +51,7 @@ GVAR(lastPlayerVehicle) = objNull; GVAR(lastPlayerVehicle) = objNull; TRACE_2("removed veh eh",_firedEH,GVAR(lastPlayerVehicle)); }; + if ((!isNull _vehicle) && {_player != _vehicle}) then { private _firedEH = _vehicle addEventHandler ["FiredNear", {call FUNC(firedNear)}]; _vehicle setVariable [QGVAR(firedEH), _firedEH]; @@ -41,8 +59,8 @@ GVAR(lastPlayerVehicle) = objNull; TRACE_2("added veh eh",_firedEH,GVAR(lastPlayerVehicle)); }; }, true] call CBA_fnc_addPlayerEventHandler; - ["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler; + ["turret", LINKFUNC(updatePlayerVehAttenuation), false] call CBA_fnc_addPlayerEventHandler; // Reset deafness on respawn (or remote control player switch) ["unit", { @@ -53,9 +71,11 @@ GVAR(lastPlayerVehicle) = objNull; private _firedEH = _oldPlayer getVariable [QGVAR(firedEH), -1]; _oldPlayer removeEventHandler ["FiredNear", _firedEH]; _oldPlayer setVariable [QGVAR(firedEH), nil]; + private _explosionEH = _oldPlayer getVariable [QGVAR(explosionEH), -1]; _oldPlayer removeEventHandler ["Explosion", _explosionEH]; _oldPlayer setVariable [QGVAR(explosionEH), nil]; + TRACE_3("removed unit eh",_oldPlayer,_firedEH,_explosionEH); }; // Don't add a new EH if the unit respawned @@ -63,17 +83,21 @@ GVAR(lastPlayerVehicle) = objNull; if ((getNumber (configOf _player >> "isPlayableLogic")) == 1) exitWith { TRACE_1("skipping playable logic",typeOf _player); // VirtualMan_F (placeable logic zeus / spectator) }; + private _firedEH = _player addEventHandler ["FiredNear", {call FUNC(firedNear)}]; _player setVariable [QGVAR(firedEH), _firedEH]; + private _explosionEH = _player addEventHandler ["Explosion", {call FUNC(explosionNear)}]; _player setVariable [QGVAR(explosionEH), _explosionEH]; + TRACE_3("added unit eh",_player,_firedEH,_explosionEH); }; GVAR(deafnessDV) = 0; GVAR(deafnessPrior) = 0; GVAR(time3) = 0; - [] call FUNC(updateHearingProtection); + + call FUNC(updateHearingProtection); }, true] call CBA_fnc_addPlayerEventHandler; // Update protection on possible helmet change diff --git a/addons/hearing/XEH_preInit.sqf b/addons/hearing/XEH_preInit.sqf index 5d6b275adc..e47eafa56e 100644 --- a/addons/hearing/XEH_preInit.sqf +++ b/addons/hearing/XEH_preInit.sqf @@ -6,18 +6,24 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ["CBA_loadoutSet", { params ["_unit", "_loadout", "_extendedInfo"]; + if (_extendedInfo getOrDefault ["ace_earplugs", false]) then { _unit setVariable ["ACE_hasEarPlugsIn", true, true]; - [[true]] remoteExec [QFUNC(updateVolume), _unit]; + + // Only force update volume if unit is a player (including remote controlled) + if (_unit call EFUNC(common,isPlayer)) then { + [QGVAR(updateVolume), true, _unit] call CBA_fnc_targetEvent; + }; }; }] call CBA_fnc_addEventHandler; ["CBA_loadoutGet", { params ["_unit", "_loadout", "_extendedInfo"]; + if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { _extendedInfo set ["ace_earplugs", true] }; diff --git a/addons/hearing/functions/fnc_addEarPlugs.sqf b/addons/hearing/functions/fnc_addEarPlugs.sqf index b73c94bf01..11999f7737 100644 --- a/addons/hearing/functions/fnc_addEarPlugs.sqf +++ b/addons/hearing/functions/fnc_addEarPlugs.sqf @@ -4,7 +4,7 @@ * Called on unit initialization. Adds earplugs if the unit is equipped with either a really loud primary weapon or a rocket launcher. * * Arguments: - * 0: A Soldier + * 0: Unit * * Return Value: * None @@ -15,49 +15,62 @@ * Public: No */ +// Only run this after the settings are initialized +if (!EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [LINKFUNC(addEarPlugs), _this]; +}; + +// Exit if hearing is disabled or if autoAdd is disabled +if (!GVAR(enableCombatDeafness) || {GVAR(autoAddEarplugsToUnits) == 0}) exitWith {}; + 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]; -}; +// Exit if the unit already has earplugs (in ears (persistence scenarios) or inventory) +if (_unit call FUNC(hasEarPlugsIn) || {[_unit, "ACE_EarPlugs"] call EFUNC(common,hasItem)}) exitWith {}; -// 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 {}; - -// add earplugs if the soldier has a rocket launcher -if ((secondaryWeapon _unit) != "") exitWith { +// Add earplugs if enabled for everyone or if the unit has a rocket launcher +if (GVAR(autoAddEarplugsToUnits) == 2 || {(secondaryWeapon _unit) != ""}) exitWith { TRACE_1("has launcher - adding",_unit); _unit addItem "ACE_EarPlugs"; }; -// otherwise add earplugs if the soldier has a big rifle -if ((primaryWeapon _unit) == "") exitWith {}; +// Otherwise add earplugs if the unit has a big rifle +private _weapon = primaryWeapon _unit; -(primaryWeaponMagazine _unit) params [["_magazine", ""]]; -if (_magazine == "") exitWith {}; +if (_weapon == "") exitWith {}; -private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); -private _ammo = getText (configFile >> "CfgMagazines" >> _magazine >> "ammo"); -private _count = getNumber (configFile >> "CfgMagazines" >> _magazine >> "count"); - -private _caliber = getNumber (configFile >> "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 (_caliber <= 0) then { 6.5 } else { _caliber }; +if (isNil QGVAR(cacheMaxAmmoLoudness)) then { + GVAR(cacheMaxAmmoLoudness) = createHashMap; }; -private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; -//If unit has a machine gun boost effective loudness 50% -if (_count >= 50) then {_loudness = _loudness * 1.5}; +// Cache maximum loudness for future calls +private _maxLoudness = GVAR(cacheMaxAmmoLoudness) getOrDefaultCall [_weapon, { + // Get the weapon's compatible magazines, so that all magazines are cached + // From all the loudness factors, take the max + private _maxLoudness = selectMax ((compatibleMagazines _weapon) apply {_x call FUNC(getAmmoLoudness)}); -TRACE_2("primaryWeapon",_unit,_loudness); + // ace_gunbag_fnc_isMachineGun + private _config = _weapon call CBA_fnc_getItemConfig; -if (_loudness > 0.2) then { + // Definition of a machine gun by BIS_fnc_itemType + private _cursor = getText (_config >> "cursor"); + + if (toLowerANSI _cursor in ["", "emptycursor"]) then { + _cursor = getText (_config >> "cursorAim"); + }; + + // If unit has a machine gun boost effective loudness 50% + if (_cursor == "MG") then { + _maxLoudness = _maxLoudness * 1.5; + }; + + _maxLoudness +}, true]; + +TRACE_3("primaryWeapon",_unit,_weapon,_maxLoudness); + +if (_maxLoudness > 0.2) then { TRACE_1("loud gun - adding",_unit); _unit addItem "ACE_EarPlugs"; }; diff --git a/addons/hearing/functions/fnc_earRinging.sqf b/addons/hearing/functions/fnc_earRinging.sqf index f5a2a714db..57888e90a2 100644 --- a/addons/hearing/functions/fnc_earRinging.sqf +++ b/addons/hearing/functions/fnc_earRinging.sqf @@ -1,24 +1,25 @@ #include "..\script_component.hpp" /* * Author: KoffeinFlummi, commy2, Rocko, Rommel, Ruthberg - * Handle new sound souce near ace_player and apply hearing damage + * Handle new sound souce near ace_player and apply hearing damage. * * Arguments: - * 0: strength of ear ringing + * 0: Strength of ear ringing * * Return Value: * None * * Example: - * [_strength] call ace_hearing_fnc_earRinging + * 10 call ace_hearing_fnc_earRinging * * Public: No */ + params ["_strength"]; if (_strength < 0.05) exitWith {}; if (!isNull curatorCamera) exitWith {}; -if ((!GVAR(enabledForZeusUnits)) && {player != ACE_player}) exitWith {}; +if (!GVAR(enabledForZeusUnits) && {player != ACE_player}) exitWith {}; TRACE_2("adding",_strength * GVAR(damageCoefficent),GVAR(deafnessDV)); diff --git a/addons/hearing/functions/fnc_explosionNear.sqf b/addons/hearing/functions/fnc_explosionNear.sqf index c65cf31c76..583c55749e 100644 --- a/addons/hearing/functions/fnc_explosionNear.sqf +++ b/addons/hearing/functions/fnc_explosionNear.sqf @@ -4,8 +4,8 @@ * Handles deafness due to explosions going off near the player. * * Arguments: - * 0: vehicle - Object the event handler is assigned to (player) - * 1: damage - Damage inflicted to the object + * 0: Unit + * 1: Damage inflicted to the unit * * Return Value: * None @@ -21,7 +21,6 @@ params ["_unit", "_damage"]; TRACE_2("explosion near player",_unit,_damage); private _strength = (0 max _damage) * 30; -if (_strength < 0.01) exitWith {}; -// Call inmediately, as it will get pick up later anyway by the update thread -[_strength] call FUNC(earRinging); +// Call immediately, as it will get picked up later by the update thread anyway +_strength call FUNC(earRinging); diff --git a/addons/hearing/functions/fnc_firedNear.sqf b/addons/hearing/functions/fnc_firedNear.sqf index 98ee093381..1c9a1c5496 100644 --- a/addons/hearing/functions/fnc_firedNear.sqf +++ b/addons/hearing/functions/fnc_firedNear.sqf @@ -4,95 +4,60 @@ * Handles deafness due to large-caliber weapons going off near the player. * * Arguments: - * 0: Unit - Object the event handler is assigned to - * 1: Firer: Object - Object which fires a weapon near the unit - * 2: Distance - Distance in meters between the unit and firer - * 3: weapon - Fired weapon - * 4: muzzle - Muzzle that was used (not used) - * 5: mode - Current mode of the fired weapon (not used) - * 6: ammo - Ammo used + * 0: Object the event handler is assigned to (unused) + * 1: Object which fires a weapon near the unit + * 2: Distance in meters between the unit and firer + * 3: Weapon + * 4: Muzzle + * 5: Current mode of the fired weapon + * 6: Ammo + * 7: Unit that fired the weapon * * Return Value: * None * * Example: - * [clientFiredNearEvent] call ace_hearing_fnc_firedNear - * [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless"] call ace_hearing_fnc_firedNear + * [player, player, 10, "arifle_MX_ACO_pointer_F", "arifle_MX_ACO_pointer_F", "single", "B_65x39_Caseless", player] call ace_hearing_fnc_firedNear * * Public: No */ -params ["_object", "_firer", "_distance", "_weapon", "", "", "_ammo"]; +params ["", "_firer", "_distance", "_weapon", "_muzzle", "_mode", "_ammo", "_gunner"]; if (_weapon in ["Throw", "Put"]) exitWith {}; if (_distance > 50) exitWith {}; -private _vehAttenuation = if ((ACE_player == (vehicle ACE_player)) || {isTurnedOut ACE_player}) then {1} else {GVAR(playerVehAttenuation)}; -private _distance = 1 max _distance; - -private _silencer = switch (_weapon) do { - case (primaryWeapon _firer) : {(primaryWeaponItems _firer) select 0}; - case (secondaryWeapon _firer) : {(secondaryWeaponItems _firer) select 0}; - case (handgunWeapon _firer) : {(handgunItems _firer) select 0}; - default {""}; -}; - +_distance = 1 max _distance; private _audibleFireCoef = 1; -if (_silencer != "") then { - _audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "audibleFire"); -}; -private _loudness = GVAR(cacheAmmoLoudness) getVariable (format ["%1%2",_weapon,_ammo]); -if (isNil "_loudness") then { - private _muzzles = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles"); - private _weaponMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines"); - { - if (_x != "this") then { - private _muzzleMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> _x >> "magazines"); - _weaponMagazines append _muzzleMagazines; - }; - } count _muzzles; - { - private _ammoType = getText(configFile >> "CfgMagazines" >> _x >> "ammo"); - _weaponMagazines set [_forEachIndex, [_x, _ammoType]]; - } forEach _weaponMagazines; +// Unit that fired is on foot +private _magazine = if (_gunner == _firer) then { + // Check if the unit has a suppressor + private _suppressor = (_firer weaponAccessories _weapon) select 0; - private _magazine = ""; - { - _x params ["_magazineType", "_ammoType"]; - if (_ammoType == _ammo) exitWith { - _magazine = _magazineType; - }; - } count _weaponMagazines; - - if (_magazine == "") then { - _loudness = 0; - TRACE_2("No mag for Weapon/Ammo??",_weapon,_ammo); - } else { - private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); - private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_caliber"); - _caliber = call { - // If explicilty defined, use ACE_caliber - if ((count configProperties [(configFile >> "CfgAmmo" >> _ammo), "configName _x == 'ACE_caliber'", false]) == 1) exitWith {_caliber}; - 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 (_caliber <= 0) then { 6.5 } else { _caliber }; - }; - - _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; - TRACE_6("building cache",_weapon,_ammo,_magazine,_initSpeed,_caliber,_loudness); + if (_suppressor != "") then { + _audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _suppressor >> "ItemInfo" >> "AmmoCoef" >> "audibleFire"); }; - GVAR(cacheAmmoLoudness) setVariable [(format ["%1%2",_weapon,_ammo]), _loudness]; + + (_firer weaponState _muzzle) select 3 +} else { + // Unit that fired is in a vehicle + (weaponState [_firer, _firer unitTurret _gunner, _weapon, _muzzle, _mode]) select 3 }; +if (_magazine == "") exitWith { + TRACE_5("No mag for weapon/ammo??",_weapon,_muzzle,_ammo,_firer,_gunner); +}; + +TRACE_6("mag",_magazine,_weapon,_muzzle,_ammo,_firer,_gunner); + +private _vehAttenuation = [GVAR(playerVehAttenuation), 1] select (isNull objectParent ACE_player || {isTurnedOut ACE_player}); +private _loudness = _magazine call FUNC(getAmmoLoudness); + _loudness = _loudness * _audibleFireCoef; private _strength = _vehAttenuation * (_loudness - (_loudness / 50 * _distance)); // linear drop off TRACE_1("result",_strength); -if (_strength < 0.01) exitWith {}; - -// Call inmediately, as it will get pick up later anyway by the update thread -[_strength] call FUNC(earRinging); +// Call immediately, as it will get picked up later by the update thread anyway +_strength call FUNC(earRinging); diff --git a/addons/hearing/functions/fnc_getAmmoLoudness.sqf b/addons/hearing/functions/fnc_getAmmoLoudness.sqf new file mode 100644 index 0000000000..062b96fa71 --- /dev/null +++ b/addons/hearing/functions/fnc_getAmmoLoudness.sqf @@ -0,0 +1,44 @@ +#include "..\script_component.hpp" +/* + * Author: KoffeinFlummi, commy2, johnb43 + * Get the loudness of ammo. + * However, because `initSpeed` is a magazine attribute, the magazine name needs to be used instead of the ammo. + * + * Arguments: + * 0: Magazine + * + * Return Value: + * None + * + * Example: + * "30Rnd_65x39_caseless_mag" call ace_hearing_fnc_getAmmoLoudness + * + * Public: No + */ + +params ["_magazine"]; + +GVAR(cacheAmmoLoudness) getOrDefaultCall [_magazine, { + private _magazineConfig = configFile >> "CfgMagazines" >> _magazine; + private _ammo = getText (_magazineConfig >> "ammo"); + private _initSpeed = getNumber (_magazineConfig >> "initSpeed"); + + private _cfgAmmo = configFile >> "CfgAmmo"; + private _ammoConfig = _cfgAmmo >> _ammo; + private _caliber = getNumber (_ammoConfig >> "ACE_caliber"); + + _caliber = switch (true) do { + // If explicilty defined, use ACE_caliber + case (inheritsFrom (_ammoConfig >> "ACE_caliber") isEqualTo _ammoConfig): {_caliber}; + case (_ammo isKindOf ["ShellBase", _cfgAmmo]): {80}; + case (_ammo isKindOf ["RocketBase", _cfgAmmo]): {200}; + case (_ammo isKindOf ["MissileBase", _cfgAmmo]): {600}; + case (_ammo isKindOf ["SubmunitionBase", _cfgAmmo]): {80}; + default {[_caliber, 6.5] select (_caliber <= 0)}; + }; + + private _loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5; + TRACE_5("building cache",_ammo,_magazine,_initSpeed,_caliber,_loudness); + + _loudness +}, true] diff --git a/addons/hearing/functions/fnc_handleRespawn.sqf b/addons/hearing/functions/fnc_handleRespawn.sqf index b436aa7c41..a075d7901e 100644 --- a/addons/hearing/functions/fnc_handleRespawn.sqf +++ b/addons/hearing/functions/fnc_handleRespawn.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Reset earplugs on respawn, and then re-add if appropriate + * Reset earplugs on respawn, and then re-add if appropriate. * * Arguments: * 0: Unit @@ -10,29 +10,29 @@ * None * * Example: - * [player] call ACE_hearing_fnc_handleRespawn; + * player call ace_hearing_fnc_handleRespawn; * * Public: No */ +// Do not add or remove earplugs if gear should be preserved +if (missionNamespace getVariable [QEGVAR(respawn,savePreDeathGear), false]) exitWith {}; + params ["_unit"]; TRACE_2("params",_unit,typeOf _unit); -if (!local _unit) exitWith {}; //XEH should only be called on local units - -//Do not add or remove earplugs if gear should be preserved -if (missionNamespace getVariable [QEGVAR(respawn,SavePreDeathGear), false]) exitWith {}; +if (!local _unit) exitWith {}; // XEH should only be called on local units private _respawn = [0] call BIS_fnc_missionRespawnType; -//if respawn is not Group or side: +// If respawn is not group or side: if (_respawn <= 3) then { - //Remove earplugs if they have them: + // Remove earplugs if they have them: if (_unit getVariable ["ACE_hasEarPlugsin", false]) then { TRACE_1("had EarPlugs in - removing",_unit); _unit setVariable ["ACE_hasEarPlugsin", false, true]; }; }; -//Re-add if they need them: -[_unit] call FUNC(addEarPlugs); +// Re-add if they need them +_unit call FUNC(addEarPlugs); diff --git a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf index f4b84281fb..fd6682e4de 100644 --- a/addons/hearing/functions/fnc_hasEarPlugsIn.sqf +++ b/addons/hearing/functions/fnc_hasEarPlugsIn.sqf @@ -4,16 +4,17 @@ * Check if the unit has earplugs put in. * * Arguments: - * 0: Unit (player) + * 0: Unit * * Return Value: - * Have Earplugs in + * Has Earplugs in * * Example: - * [ace_player] call ace_hearing_fnc_hasEarPlugsIn + * player call ace_hearing_fnc_hasEarPlugsIn * * Public: No */ + params ["_unit"]; _unit getVariable ["ACE_hasEarPlugsin", false] diff --git a/addons/hearing/functions/fnc_moduleHearing.sqf b/addons/hearing/functions/fnc_moduleHearing.sqf index 924f2baa21..f7943a712e 100644 --- a/addons/hearing/functions/fnc_moduleHearing.sqf +++ b/addons/hearing/functions/fnc_moduleHearing.sqf @@ -10,7 +10,7 @@ * None * * Example: - * [player] call ACE_hearing_fnc_moduleHearing + * player call ace_hearing_fnc_moduleHearing * * Public: No */ @@ -23,6 +23,8 @@ params ["_logic"]; if ((_logic getVariable "DisableEarRinging") != -1) then { [_logic, QGVAR(DisableEarRinging), "DisableEarRinging"] call EFUNC(common,readSettingFromModule); }; + [_logic, QGVAR(enabledForZeusUnits), "enabledForZeusUnits"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(autoAddEarplugsToUnits), "autoAddEarplugsToUnits"] call EFUNC(common,readSettingFromModule); + INFO("Hearing Module Initialized."); diff --git a/addons/hearing/functions/fnc_putInEarplugs.sqf b/addons/hearing/functions/fnc_putInEarplugs.sqf index 2af4df8e86..aa2166a112 100644 --- a/addons/hearing/functions/fnc_putInEarplugs.sqf +++ b/addons/hearing/functions/fnc_putInEarplugs.sqf @@ -1,38 +1,35 @@ #include "..\script_component.hpp" /* - * Author: Hope Johnson and commy2 + * Author: Hope Johnson, commy2 * Puts in earplugs. * * Arguments: - * 0: Unit (player) + * 0: Unit * 1: Display hint (default: false) * * Return Value: * None * * Example: - * [ace_player, false] call ace_hearing_fnc_putInEarplugs + * [player, false] call ace_hearing_fnc_putInEarplugs * * Public: No */ -params ["_player", ["_displayHint", false, [false]]]; +if (!GVAR(enableCombatDeafness)) exitWith {}; -if (!GVAR(EnableCombatDeafness)) exitWith {}; +params ["_unit", ["_displayHint", false]]; // Plugs in inventory, putting them in -_player removeItem "ACE_EarPlugs"; +_unit removeItem "ACE_EarPlugs"; -_player setVariable ["ACE_hasEarPlugsIn", true, true]; +_unit setVariable ["ACE_hasEarPlugsIn", true, true]; if (_displayHint) then { - [localize LSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured); + [LLSTRING(EarPlugs_Are_On)] call EFUNC(common,displayTextStructured); }; -//Force an immediate fast volume update: -[[true]] call FUNC(updateVolume); +// Force an immediate volume update +true call FUNC(updateVolume); -// No Earplugs in inventory, telling user -//[localize LSTRING(NoPlugs)] call EFUNC(common,displayTextStructured); - -[] call FUNC(updateHearingProtection); +call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_removeEarplugs.sqf b/addons/hearing/functions/fnc_removeEarplugs.sqf index 20a49bb530..743e89ef53 100644 --- a/addons/hearing/functions/fnc_removeEarplugs.sqf +++ b/addons/hearing/functions/fnc_removeEarplugs.sqf @@ -1,39 +1,40 @@ #include "..\script_component.hpp" /* - * Author: Hope Johnson and commy2 + * Author: Hope Johnson, commy2 * Takes out earplugs. * * Arguments: - * 0: Unit (player) - * 1: Display hint (default false) + * 0: Unit + * 1: Display hint (default: false) * * Return Value: * None * * Example: - * [ace_player, false] call ace_hearing_fnc_removeEarplugs + * [player, false] call ace_hearing_fnc_removeEarplugs * * Public: No */ -params ["_player", ["_displayHint", false, [false]]]; +if (!GVAR(enableCombatDeafness)) exitWith {}; -if (!GVAR(EnableCombatDeafness)) exitWith {}; +params ["_unit", ["_displayHint", false]]; -if !([_player, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith { // inventory full +// Inventory full +if !([_unit, "ACE_EarPlugs"] call CBA_fnc_canAddItem) exitWith { [LELSTRING(common,Inventory_Full)] call EFUNC(common,displayTextStructured); }; // Plugs already in and removing them. -_player addItem "ACE_EarPlugs"; +_unit addItem "ACE_EarPlugs"; -_player setVariable ["ACE_hasEarPlugsIn", false, true]; +_unit setVariable ["ACE_hasEarPlugsIn", false, true]; if (_displayHint) then { - [localize LSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured); + [LLSTRING(EarPlugs_Are_Off)] call EFUNC(common,displayTextStructured); }; -//Force an immediate fast volume update: -[[true]] call FUNC(updateVolume); +// Force an immediate volume update +true call FUNC(updateVolume); -[] call FUNC(updateHearingProtection); +call FUNC(updateHearingProtection); diff --git a/addons/hearing/functions/fnc_updateHearingProtection.sqf b/addons/hearing/functions/fnc_updateHearingProtection.sqf index 15973b73a9..b9d7f1f9a0 100644 --- a/addons/hearing/functions/fnc_updateHearingProtection.sqf +++ b/addons/hearing/functions/fnc_updateHearingProtection.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Updates the hearing protection and volume attenuation for player on earbuds/helmet change + * Updates the hearing protection and volume attenuation for player on earbuds/helmet change. * * Arguments: * None @@ -10,12 +10,12 @@ * None * * Example: - * [] call ace_hearing_fnc_updateHearingProtection + * call ace_hearing_fnc_updateHearingProtection * * Public: No */ -TRACE_1("params",_this); +LOG("updateHearingProtection"); if (isNull ACE_player) exitWith { GVAR(damageCoefficent) = 0; @@ -23,22 +23,32 @@ if (isNull ACE_player) exitWith { }; // Handle Earplugs -private _hasEarPlugsIn = [ACE_player] call FUNC(hasEarPlugsIn); +private _hasEarPlugsIn = ACE_player call FUNC(hasEarPlugsIn); GVAR(damageCoefficent) = [1, 0.25] select _hasEarPlugsIn; -GVAR(volumeAttenuation) = [1, GVAR(EarplugsVolume)] select _hasEarPlugsIn; +GVAR(volumeAttenuation) = [1, GVAR(earplugsVolume)] select _hasEarPlugsIn; // Handle Headgear -if (headgear ACE_player != "") then { - private _protection = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(protection)) min 1; +private _headgear = headgear ACE_player; + +if (_headgear != "") then { + private _heargearConfig = configFile >> "CfgWeapons" >> _headgear; + + private _protection = getNumber (_heargearConfig >> QGVAR(protection)) min 1; GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection); - private _attenuation = getNumber (configFile >> "CfgWeapons" >> headgear ACE_player >> QGVAR(lowerVolume)) min 1; + + private _attenuation = getNumber (_heargearConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); }; // Handle Goggles -if (goggles ACE_player != "") then { - private _protection = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(protection)) min 1; +private _goggles = goggles ACE_player; + +if (_goggles != "") then { + private _gogglesConfig = configFile >> "CfgGlasses" >> _goggles; + + private _protection = getNumber (_gogglesConfig >> QGVAR(protection)) min 1; GVAR(damageCoefficent) = GVAR(damageCoefficent) * (1 - _protection); - private _attenuation = getNumber (configFile >> "CfgGlasses" >> goggles ACE_player >> QGVAR(lowerVolume)) min 1; + + private _attenuation = getNumber (_gogglesConfig >> QGVAR(lowerVolume)) min 1; GVAR(volumeAttenuation) = GVAR(volumeAttenuation) * (1 - _attenuation); }; diff --git a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf index 207c0f07a3..856b694a3f 100644 --- a/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf +++ b/addons/hearing/functions/fnc_updatePlayerVehAttenuation.sqf @@ -7,10 +7,10 @@ * None * * Return Value: - * Ammount that unit can hear outside + * Amount that unit can hear outside * * Example: - * [] call ace_hearing_fnc_updatePlayerVehAttenuation + * call ace_hearing_fnc_updatePlayerVehAttenuation * * Public: No */ @@ -20,12 +20,14 @@ private _vehicle = vehicle ACE_player; if (isNull _vehicle) exitWith {}; private _newAttenuation = 1; + if (ACE_player != _vehicle) then { - private _turretPath = [ACE_player] call EFUNC(common,getTurretIndex); - private _effectType = getText (configOf _vehicle >> "attenuationEffectType"); + private _vehicleConfig = configOf _vehicle; + private _turretPath = _vehicle unitTurret ACE_player; + private _effectType = getText (_vehicleConfig >> "attenuationEffectType"); if (_turretPath isNotEqualTo []) then { - private _turretConfig = [(configOf _vehicle), _turretPath] call EFUNC(common,getTurretConfigPath); + private _turretConfig = [_vehicleConfig, _turretPath] call EFUNC(common,getTurretConfigPath); if ((getNumber (_turretConfig >> "disableSoundAttenuation")) == 1) then { _effectType = ""; @@ -40,7 +42,7 @@ if (ACE_player != _vehicle) then { case (_effectType == ""): {1}; case (_effectType == "CarAttenuation"); case (_effectType == "RHS_CarAttenuation"): { // Increase protection for armored cars - private _armor = getNumber (configOf _vehicle >> "HitPoints" >> "HitBody" >> "armor"); + private _armor = getNumber (_vehicleConfig >> "HitPoints" >> "HitBody" >> "armor"); linearConversion [2, 8, _armor, 0.5, 0.3, true];}; case (_effectType == "OpenCarAttenuation"): {1}; case (_effectType == "TankAttenuation"): {0.1}; diff --git a/addons/hearing/functions/fnc_updateVolume.sqf b/addons/hearing/functions/fnc_updateVolume.sqf index 0029cdc4de..bb1d57e3c1 100644 --- a/addons/hearing/functions/fnc_updateVolume.sqf +++ b/addons/hearing/functions/fnc_updateVolume.sqf @@ -1,55 +1,61 @@ #include "..\script_component.hpp" /* - * Author: commy2 and esteldunedain and Ruthberg + * Author: commy2, esteldunedain, Ruthberg * Updates and applies the current deafness. Called every 1 sec from a PFEH. * * Arguments: - * 0: Args - * - 0: Just update volume (skip ringing/recovery) (default: false) + * 0: Update volume only (skip ringing/recovery) (default: false) * * Return Value: * None * * Example: - * [] call ace_hearing_fnc_updateVolume + * call ace_hearing_fnc_updateVolume * * Public: No */ +if (isGamePaused) exitWith {}; + if (!alive ACE_player) exitWith { - if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; + if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; + TRACE_1("dead - removing hearing effects",ACE_player); + [QUOTE(ADDON), 1, true] call EFUNC(common,setHearingCapability); }; -(_this select 0) params [["_justUpdateVolume", false]]; +params [["_updateVolumeOnly", false]]; GVAR(deafnessDV) = (GVAR(deafnessDV) min 20) max 0; GVAR(volume) = (1 - (GVAR(deafnessDV) / 20)) max 0.05; + TRACE_3("",GVAR(volume),GVAR(deafnessDV),GVAR(deafnessDV) - GVAR(deafnessPrior)); -if (!_justUpdateVolume) then { +if (!_updateVolumeOnly) then { // Ring if we got a big increase in the last second or enough accumulated damage if (GVAR(deafnessDV) - GVAR(deafnessPrior) > 1 || GVAR(deafnessDV) > 10) then { if (CBA_missionTime - GVAR(time3) < 3) exitWith {}; + if (!isGameFocused) exitWith {}; // prevent audio from stacking when tabbed out + GVAR(time3) = CBA_missionTime; - if (!isGameFocused) exitWith {}; if (GVAR(deafnessDV) > 19.75) then { - playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(DisableEarRinging)); + playSound (["ACE_Combat_Deafness_Heavy", "ACE_Combat_Deafness_Heavy_NoRing"] select GVAR(disableEarRinging)); } else { - playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(DisableEarRinging)); + playSound (["ACE_Combat_Deafness_Medium", "ACE_Combat_Deafness_Medium_NoRing"] select GVAR(disableEarRinging)); }; }; + GVAR(deafnessPrior) = GVAR(deafnessDV); // Hearing takes longer to return to normal after it hits rock bottom - GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0; + GVAR(deafnessDV) = (GVAR(deafnessDV) - (0.5 * (GVAR(volume) max 0.1))) max 0; }; -if (missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; +if (missionNamespace getVariable [QGVAR(disableVolumeUpdate), false]) exitWith {}; private _volume = GVAR(volume); @@ -57,8 +63,8 @@ private _volume = GVAR(volume); _volume = _volume min GVAR(volumeAttenuation); // Reduce volume if player is unconscious -if (ACE_player getVariable ["ACE_isUnconscious", false]) then { - _volume = _volume min GVAR(UnconsciousnessVolume); +if (lifeState ACE_player == "INCAPACITATED") then { + _volume = _volume min GVAR(unconsciousnessVolume); }; [QUOTE(ADDON), _volume, true] call EFUNC(common,setHearingCapability); diff --git a/addons/hearing/initKeybinds.inc.sqf b/addons/hearing/initKeybinds.inc.sqf new file mode 100644 index 0000000000..d129966198 --- /dev/null +++ b/addons/hearing/initKeybinds.inc.sqf @@ -0,0 +1,18 @@ +["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 // return + }; + + if (GVAR(enableCombatDeafness) && {ACE_player call FUNC(hasEarPlugsIn)}) exitWith { + [ACE_player, true] call FUNC(removeEarPlugs); + + true // return + }; + + false // return +}] call CBA_fnc_addKeybind; // UNBOUND diff --git a/addons/hearing/initSettings.sqf b/addons/hearing/initSettings.inc.sqf similarity index 60% rename from addons/hearing/initSettings.sqf rename to addons/hearing/initSettings.inc.sqf index f22a7b4eda..adc6c6def7 100644 --- a/addons/hearing/initSettings.sqf +++ b/addons/hearing/initSettings.inc.sqf @@ -1,15 +1,19 @@ -private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; +private _category = format ["ACE %1", LLSTRING(Module_DisplayName)]; [ - QGVAR(enableCombatDeafness), "CHECKBOX", + QGVAR(enableCombatDeafness), + "CHECKBOX", [LSTRING(EnableCombatDeafness_DisplayName), LSTRING(EnableCombatDeafness_Description)], _category, true, - 1 + 1, + {[QGVAR(enableCombatDeafness), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ - QGVAR(earplugsVolume), "SLIDER", + QGVAR(earplugsVolume), + "SLIDER", [LSTRING(earplugsVolume_DisplayName), LSTRING(earplugsVolume_Description)], _category, [0, 1, 0.5, 1], @@ -17,7 +21,8 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(unconsciousnessVolume), "SLIDER", + QGVAR(unconsciousnessVolume), + "SLIDER", [LSTRING(unconsciousnessVolume_DisplayName), LSTRING(unconsciousnessVolume_Description)], _category, [0, 1, 0.4, 1], @@ -25,15 +30,16 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(disableEarRinging), "CHECKBOX", + QGVAR(disableEarRinging), + "CHECKBOX", [LSTRING(DisableEarRinging_DisplayName), LSTRING(DisableEarRinging_Description)], _category, - false, - 0 + false ] call CBA_fnc_addSetting; [ - QGVAR(enabledForZeusUnits), "CHECKBOX", + QGVAR(enabledForZeusUnits), + "CHECKBOX", [LSTRING(enabledForZeusUnits_DisplayName), LSTRING(enabledForZeusUnits_Description)], _category, true, @@ -41,9 +47,10 @@ private _category = format ["ACE %1", localize LSTRING(Module_DisplayName)]; ] call CBA_fnc_addSetting; [ - QGVAR(autoAddEarplugsToUnits), "CHECKBOX", + QGVAR(autoAddEarplugsToUnits), + "LIST", [LSTRING(autoAddEarplugsToUnits_DisplayName), LSTRING(autoAddEarplugsToUnits_Description)], _category, - true, + [[0, 1, 2], [ELSTRING(common,Disabled), LSTRING(heavyWeaponUnits), ELSTRING(common,Enabled)], 1], 1 ] call CBA_fnc_addSetting; diff --git a/addons/hearing/stringtable.xml b/addons/hearing/stringtable.xml index 1aeac049ba..9aba1ab56b 100644 --- a/addons/hearing/stringtable.xml +++ b/addons/hearing/stringtable.xml @@ -29,7 +29,7 @@ Erősebb hanghatásoktól védő füldugó, megakadályozza a nagy hanggal járó fegyverzettől való halláskárosodást. Protetor para ouvidos permitem que o usuário esteja próximo a ruídos sem danificar sua audição. Proteggono l'apparato uditivo, permettendo a chi li indossa di resistere ai suoni particolarmente forti senza alcun danno. - 着けることにより、近くの大きな銃声から聴覚を保護します。 + 耳栓を着けることにより、近くの大きな銃声から聴覚を保護します。 보호용 귀마개는 화기로부터의 큰소리로부터 사용자의 청력을 보호합니다. 配戴防护耳塞,遇到大声的武器发射时也不会损害听力。 配戴防護耳塞,遇到大聲的武器發射時也不會損害聽力 @@ -45,7 +45,7 @@ Füldugó berakva Protetores colocados Indossa i tappi auricolari - 耳栓を着ける + 耳栓を装着 귀마개 착용 塞入耳塞 塞入耳塞 @@ -78,8 +78,8 @@ Bouchons mis Füldugó berakva Protetores colocados - Indossa i tappi auricolari - 耳栓を着けました + Tappi auricolari indossati + 耳栓を装着しました 귀마개 착용 耳塞已塞入 耳塞已塞入 @@ -95,7 +95,7 @@ Bouchons enlevés Füldugó kivéve Protetores retirados - Levati i tappi auricolari + Tappi auricolari rimossi 耳栓を外しました 귀마개 뺌 耳塞已取出 @@ -128,7 +128,7 @@ Vypnout pískání v uších Wyłącz dzwonienie w uszach Fülcsengés letiltása - Disabilita i fischi nelle orecchie + Disabilita il fischio nelle orecchie Desabilitar zumbido de ouvidos 耳鳴りを無効化 이명현상 끄기 @@ -141,10 +141,10 @@ Desactiva el efecto de zumbido cuando el jugador recibe daño auditivo. Usuń szum w uszach przy chwilowej utracie słuchu. Enlève l'effet d'acouphène lorsqu'un joueur subit des dommages auditifs. - Quando il giocatore riceve danni all'udito, non fa sentire i fischi nelle orecchie + Quando il giocatore riceve danni all'udito, non far sentire il fischio nelle orecchie Remove o efeito de zunido quando o jogador recebe dano na audição Убирает эффект звона в ушах, когда игрок получает повреждение слуха - プレイヤーの聴覚が損傷したら耳鳴りの効果を削除します + プレイヤーが聴覚にダメージを受けた際の耳鳴り効果音を無効化します 플레이어가 청력손실을 입을 때 생기는 이명현상을 제거합니다. 关闭耳鸣效果时,就算玩家受到相当程度的听力伤害,也不会造成耳鸣效果 關閉耳鳴效果時,就算玩家受到相當程度的聽力傷害, 也不會造成耳鳴效果 @@ -177,7 +177,7 @@ Harci süketség engedélyezése? Оглушение Sordità da combattimento - 戦闘による難聴を有効化 + 戦闘難聴を有効化 전투 난청 켜기 启用战斗性耳聋? 啟用戰鬥性耳聾? @@ -190,9 +190,9 @@ Snižuje schopnost sluchu pokud dojde k jeho poškození hlasitou a blízkou střelbou Ativar surdez em combate? Уменьшает возможность игрока слышать звуки при повреждении органов слуха - Riduci l'abilità uditiva quando il giocatore riceve danno uditivo + Assorda il giocatore quando riceve danni all'udito Réduit la capacité auditive du joueur lorsqu'il subit des dommages auditifs. - 音による損傷をうけ、聴覚が減る可能性があります + プレイヤーが聴覚にダメージを受けると聴力が低下します 청력에 손상을 입으면 듣는 소리가 감소합니다. 当玩家听力受损时降低听力能力? 當玩家聽力受損時降低聽力能力? @@ -208,7 +208,7 @@ Pemet le réglage de la surdité au combat et des bourdonnements. Si actif, les joueurs sans protection auditive peuvent être assourdis quand une arme est utilisée à proximité, ou lorsqu'une explosion se produit. Controles de sordera de combate y zumbido en los oídos. Al activarlo, los jugadores pueden ser ensordecidos cuando un arma se dispara cerca o una explosión tiene lugar sin protección auditiva Controlla la sordità da combattimento e fischio alle orecchie. Quando attivato, i giocatori possono essere assordati quando un'arma spara vicino o avviene un'esplosione senza protezione uditiva - 戦闘による難聴や、耳鳴りを設定します。有効では聴覚を保護していないと近傍の銃声や爆発音により、難聴になります。 + 戦闘による難聴や、耳鳴りを設定します。有効にすると聴覚を保護していないと近くの銃声や爆発音により、プレイヤーが難聴になる可能性が発生します。 전투 난청과 이명현상을 조작합니다. 작동시 플레이어가 화기나 폭발의 주변에 있을경우 청력보호장치가 없을때 청력손실을 입습니다. 设定战斗性耳聋和耳鸣。当启用后,玩家会在有武器在旁边射击或爆炸产生时造成耳鸣效果 設定戰鬥性耳聾和耳鳴。當啟用後,玩家會在有武器在旁邊射擊或爆炸產生時造成耳鳴效果 @@ -221,9 +221,9 @@ Afeta Zeus CR Efecto Zeus RC Vliv na Zeus RC - Effetto Zeus RC + Affligge unità Zeus RC Affecte le CàD Zeus - Zeus RC への効果 + Zeus遠隔操作ユニットへの効果 Zeus RC 효과 启用效果在宙斯远程遥控 啟用效果在宙斯遠程遙控 @@ -236,9 +236,9 @@ Permite que unidades remotamente controladas pelo Zeus sejam atingidas por danos auditivos. Permitir a las unidades por control remoto de zeus que puedan tener daños auditivos. Aktivovat efekt ztráty sluchu pro vzdáleně ovládané jednotky. - Consenti alle unità controllate in remoto da Zeus di ricevere danni all'udito. + Abilita danni all'udito per unità controllate in remoto da Zeus. Permet aux unités contrôlées à distance par Zeus de subir des dommages auditifs. - Zeus により遠隔操作されたユニットにも、聴覚へ損傷を受けるようにします。 + Zeusにより遠隔操作されたユニットも、聴覚ダメージの効果を受けるようにします。 Zeus가 원격으로 청력손실을 입힐 수 있게 합니다. 设定宙斯远程遥控的单位也会受到耳鸣的效果。 設定宙斯遠程遙控的單位也會受到耳鳴的效果。 @@ -265,10 +265,10 @@ Добавляет предмет `ACE_EarPlugs` всем юнитам, которые имеют громкое оружие. Можно отключить при ручной настройке снаряжения. Adicionar o item `ACE_EarPlugs` a todas as unidades que tenham armas barulhentas. Pode ser desabilitado com carregamentos customizados. Přidat `ACE_EarPlugs` všem jednotkám které mají zbraň. Můžete vypnout, pokud používáte vlastní výbavu. - Aggiungi l'oggetto 'ACE_EarPlugs' a tutte le unità che hanno armi rumorose. Può essere disabilitato se vengono usati loadout personalizzati. + Aggiungi l'oggetto 'ACE_EarPlugs' a tutte le unità che hanno armi/lanciatori rumorosi. Può essere disabilitato se vengono usati loadout personalizzati. Agregar el item `ACE_EarPlugs` a todas las unidades equipadas con armas muy ruidosas. Desactivar si quieren utilizarse equipamientos personalizados. Ajoute l'objet `Ace_EarPlugs` à toutes les unités ayant des armes bruyantes. Peut être désactivé si de l'équipement personnalisé est utilisé. - 全ユニットへ`ACE_EarPlugs`アイテムを持たせます。これは変更された武装で無効化できます。 + 全てのユニットに`ACE_EarPlugs`アイテムを所持させます。これはロードアウトの編集で無効化できます。 무기를 가지고 있는 모든 인원에게 'ACE_EarPlugs'를 지급합니다. 임의의 장비를 사용시 비활성화할 수 있습니다. 增加`ACE_EarPlugs`物品给拥有巨大噪音武器的单位。当你想自定装备时,此功能可被关闭。 增加`ACE_EarPlugs`物品給擁有巨大噪音武器的單位。當你想自定裝備時,此功能可被關閉。 @@ -292,10 +292,10 @@ Volume muffling Lautstärkedämpfung Atténuation du volume - 音量低下 + 音量の抑制 降低音量 進低音量 - Volume attenuazione + Attenuazione del volume Tłumienie głośności Глушение звука Abafamento de Volume @@ -306,10 +306,10 @@ Earplugs Volume Lautstärke Ohrenstöpsel - 耳栓時の音量 + 耳栓装着時音量 耳塞时音量 耳塞時音量 - Volume tappi per le orecchie + Volume con i Tappi Głośność Stoperów Громкость в берушах Volume do Protetor Auricular @@ -321,7 +321,7 @@ Volume when using earplugs. Lautstärke wenn man Ohrenstöpsel benutzt - 耳栓使用時の音量を決定します。 + 耳栓を使用した時の音量。 决定带上耳塞时的音量 使用耳塞時音量 Volume audio quandi si indossano i tappi per le orecchie. @@ -336,7 +336,7 @@ Unconscious Volume Lautstärke Bewusstlosigkeit - 気絶時の音量 + 無意識状態時音量 无意识时音量 昏迷時音量 Volume quando incoscente @@ -351,7 +351,7 @@ Volume when unconscious. Lautstärke während man Bewusstlos ist - 気絶時の音量を決定します。 + 無意識状態になった時の音量。 决定处于无意识时的音量 昏迷時使用耳塞的音量 Volume quando incoscente. @@ -363,5 +363,25 @@ Volumen durante la inconsciencia. 기절 시 볼륨입니다. + + Put/take out earplugs + 耳栓の着脱 + Вставить/вынуть беруши + Metti/Togli tappi + 귀마개 토글 + Mettre/enlever les bouchons + Ohrstöpsel einsetzen/herausnehmen + Poner/quitar tapones + + + Only units with heavy weapons + Uniquement les unités dotées d'armes lourdes + Только юниты с тяжелым вооружением + Nur Einheiten mit schweren Waffen + 重火器を装備したユニットのみ + Sólo unidades con armas pesadas + Solo a unità con armi pesanti + 중화기를 가진 유닛만 해당 + diff --git a/addons/hellfire/CfgMagazines.hpp b/addons/hellfire/CfgMagazines.hpp index 8abf2529b5..d025afadde 100644 --- a/addons/hellfire/CfgMagazines.hpp +++ b/addons/hellfire/CfgMagazines.hpp @@ -32,7 +32,7 @@ class CfgMagazines { count = 3; mass = 250; pylonWeapon = QGVAR(launcher); - hardpoints[] = {"B_MISSILE_PYLON", "UNI_SCALPEL", "CUP_NATO_HELO_LARGE", "RHS_HP_LONGBOW_RACK"}; + hardpoints[] = {"B_MISSILE_PYLON", "UNI_SCALPEL", "CUP_NATO_HELO_LARGE"}; model = "\A3\Weapons_F\DynamicLoadout\PylonPod_3x_Missile_LG_scalpel_F.p3d"; mirrorMissilesIndexes[] = {2, 1, 3}; }; @@ -41,7 +41,7 @@ class CfgMagazines { count = 4; mass = 340; pylonWeapon = QGVAR(launcher); - hardpoints[] = {"UNI_SCALPEL", "CUP_NATO_HELO_LARGE", "RHS_HP_HELLFIRE_RACK", "RHS_HP_LONGBOW_RACK"}; + hardpoints[] = {"UNI_SCALPEL", "CUP_NATO_HELO_LARGE"}; model = "\A3\Weapons_F\DynamicLoadout\PylonPod_4x_Missile_LG_scalpel_F.p3d"; mirrorMissilesIndexes[] = {2, 1, 4, 3}; }; diff --git a/addons/hellfire/functions/fnc_attackProfile.sqf b/addons/hellfire/functions/fnc_attackProfile.sqf index 28dda99086..26bc3f1ff0 100644 --- a/addons/hellfire/functions/fnc_attackProfile.sqf +++ b/addons/hellfire/functions/fnc_attackProfile.sqf @@ -93,5 +93,5 @@ if (_attackStage >= 3 && { _seekerType isEqualTo "ARH" }) then { }; }; -// TRACE_1("Adjusted target position", _returnTargetPos); +// TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf b/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf index fb12cad00f..14d89f82e3 100644 --- a/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf +++ b/addons/hellfire/functions/fnc_getAttackProfileSettings.sqf @@ -31,11 +31,10 @@ private _configLaunchHeightClear = getNumber (_attackConfig >> QGVAR(launchHeigh private _startingStage = if (_configLaunchHeightClear > 0) then { STAGE_LAUNCH; // LOAL-HI / LO } else { - if (_seekerTargetPos isEqualTo [0,0,0]) then { - STAGE_SEEK_CRUISE; // LOAL-DIR - } else { - STAGE_ATTACK_CRUISE // LOBL - }; + [ + STAGE_ATTACK_CRUISE, + STAGE_SEEK_CRUISE + ] select (_seekerTargetPos isEqualTo [0,0,0]); }; // Set data in param array diff --git a/addons/hellfire/functions/fnc_setupVehicle.sqf b/addons/hellfire/functions/fnc_setupVehicle.sqf index 49eefd8274..ce3961d77a 100644 --- a/addons/hellfire/functions/fnc_setupVehicle.sqf +++ b/addons/hellfire/functions/fnc_setupVehicle.sqf @@ -46,7 +46,7 @@ if ((getNumber (configOf _vehicle >> QGVAR(addLaserDesignator))) == 1) then { params ["_vehicle", "_turretPath"]; TRACE_3("checking for laser",_vehicle,_turretPath,_vehicle turretLocal _turretPath); if (!alive _vehicle) exitWith {}; - if (!(_vehicle turretLocal _turretPath)) then {WARNING("Turret not local");}; + if !(_vehicle turretLocal _turretPath) then {WARNING("Turret not local");}; private _hasLaser = false; { // Most addons just use "Laserdesignator_mounted", but this should cover custom ones diff --git a/addons/hellfire/stringtable.xml b/addons/hellfire/stringtable.xml index df16c00c9f..647f349273 100644 --- a/addons/hellfire/stringtable.xml +++ b/addons/hellfire/stringtable.xml @@ -22,33 +22,39 @@ Самонаводящаяся Ракета с фугасной противотанковой боевой частью и полуактивной лазерной системой наведения Misil de guiado láser semi-activo con cabeza de alto explosivo anti-tanque Missile antichar à guidage laser semi-actif (charge HEAT) + Missile a guida laser semi-attiva con una testata HEAT セミ アクティブ レーダー誘導の対戦車弾頭 Rakieta naprowadzana laserowo z głowicą przeciwpancerną Halbaktive Laser-Zielsuchrakete mit HEAT-Gefechtskopf 高爆反坦克弹头半主动激光制导导弹 반능동 레이저 유도미사일로 대전차 고폭 탄두를 탑재하고 있습니다. + Míssil teleguiado a laser semi-ativo com ogiva antitanque altamente explosiva Millimeter-wave radar guided missile with high explosive anti-tank warhead Радиолокационная управляемая ракета миллиметрового диапазона с фугасной противотанковой боевой частью Misil guiado por radar de onda milimétrica con cabeza de alto explosivo anti-tanque Missile antichar à guidage radar à ondes courtes (charge HEAT) + Missile a guida radar con una testata HEAT ミリ波レーダー誘導の対戦車弾頭 Rakieta namierzana radarowo z głowicą przeciwpancerną Millimeterwellenradar-Lenkflugkörper mit HEAT-Gefechtskopf 高爆反坦克弹头毫米波雷达制导导弹 밀리미터파 레이더 유도 미사일로 대전차 고폭 탄두를 탑재하고 있습니다. + Míssil guiado por radar de ondas milimétricas com ogiva antitanque altamente explosiva Semi-active laser homing missile with metal augmented charge anti-personnel warhead Самонаводящаяся ракета с металлической увеличенной зарядной противопехотной боевой частью и полуактивной лазерной системой наведения Misil guiado por láser semi-activo con cabeza de carga de metal aumentada anti-persona + Missile a guida laser semi-attiva con una testata a frammentazione antiuomo Missile antipersonnel thermobarique à guidage laser semi-actif セミ アクティブ レーダー誘導の対人弾 Rakieta naprowadzana laserowo z głowicą odłamkową Halbaktive Laser-Zielsuchrakete mit metallverstärktem Antipersonen-Gefechtskopf 金属增强人员杀伤弹头半主动激光制导导弹 반능동 레이저 유도 미사일로 대인 금속 강화 탄두가 탑재하고 있습니다. + Míssil teleguiado a laser semi-ativo com ogiva antipessoal de carga aumentada de metal diff --git a/addons/hitreactions/ACE_Settings.hpp b/addons/hitreactions/ACE_Settings.hpp index 90c1445eba..78a510a141 100644 --- a/addons/hitreactions/ACE_Settings.hpp +++ b/addons/hitreactions/ACE_Settings.hpp @@ -1,4 +1,3 @@ - class ACE_Settings { class GVAR(minDamageToTrigger) { movedToSQF = 1; diff --git a/addons/hitreactions/CfgEventHandlers.hpp b/addons/hitreactions/CfgEventHandlers.hpp index eecf08c69d..b737b7bcbf 100644 --- a/addons/hitreactions/CfgEventHandlers.hpp +++ b/addons/hitreactions/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); @@ -11,6 +10,12 @@ class Extended_PreInit_EventHandlers { }; }; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + class Extended_Hit_EventHandlers { class CAManBase { class ADDON { diff --git a/addons/hitreactions/XEH_PREP.hpp b/addons/hitreactions/XEH_PREP.hpp index 7701b8ef19..eea48dcaa8 100644 --- a/addons/hitreactions/XEH_PREP.hpp +++ b/addons/hitreactions/XEH_PREP.hpp @@ -1,3 +1,3 @@ - +PREP(checkWeaponDrop); PREP(fallDown); PREP(getRandomAnimation); diff --git a/addons/hitreactions/XEH_postInit.sqf b/addons/hitreactions/XEH_postInit.sqf new file mode 100644 index 0000000000..2750ae1159 --- /dev/null +++ b/addons/hitreactions/XEH_postInit.sqf @@ -0,0 +1,94 @@ +#include "script_component.hpp" + + +[QGVAR(updateFiredEHs), { + TRACE_2("updateFiredEH",GVAR(weaponDropChanceArmHitPlayer),GVAR(weaponDropChanceArmHitAI)); + if (GVAR(weaponDropChanceArmHitPlayer) + GVAR(weaponDropChanceArmHitAI) == 0) then { + if (isNil QGVAR(firedEHs)) exitWith {}; + { + _x call CBA_fnc_removeEventHandler; + } forEach GVAR(firedEHs); + GVAR(firedEHs) = nil; + TRACE_1("removed EHs",GVAR(firedEHs)); + } else { + if (!isNil QGVAR(firedEHs)) exitWith {}; + private _firedEH = { + if (!local (_this select 0)) exitWith {}; + (_this select 6) addEventHandler ["HitPart", { + params ["", "_entity", "", "", "", "", "_selections"]; + [_entity, _selections] call FUNC(checkWeaponDrop); + }]; + }; + GVAR(firedEHs) = []; + { + GVAR(firedEHs) pushBack [_x, [_x, _firedEH] call CBA_fnc_addEventHandler]; + } forEach ["ace_firedNonPlayer", "ace_firedPlayer"]; + TRACE_1("added EHs",GVAR(firedEHs)); + }; +}] call CBA_fnc_addEventHandler; + +[QGVAR(dropWeapon), { + params ["_unit"]; + TRACE_1("dropWeaponEH",_unit); + + if !(_unit getVariable [QGVAR(canDropWeapon), true]) exitWith {}; + + // Prevents AI from losing both primary and pistol when being shot with their pistol out + _unit setVariable [QGVAR(canDropWeapon), false]; + + private _weapon = currentWeapon _unit; + private _thrownWeapon = _unit call EFUNC(common,throwWeapon); + + [{ + params ["_unit"]; + + _unit setVariable [QGVAR(canDropWeapon), nil]; + }, _unit, 0.5] call CBA_fnc_waitAndExecute; + + if (_unit call EFUNC(common,isPlayer)) exitWith {}; // Don't make players pick their own weapons up + + // Wait before executing, as otherwise the unit would pick up the weapon immediately + [{ + [{ + (_this select 0) params ["_unit", "_weapon", "_thrownWeapon", "_timeout"]; + + // If the unit has been deleted or dead, if the weapon doesn't exist anymore or if it's been too long, stop + if (!alive _unit || {!local _unit} || {isNull _thrownWeapon} || {CBA_missionTime >= _timeout}) exitWith { + (_this select 1) call CBA_fnc_removePerFrameHandler; + }; + + // Don't pick up weapon when unit is unconscious + if (lifeState _unit == "INCAPACITATED") exitWith {}; + + // If the unit has no essential weapons, force them to get their weapon, otherwise wait until no enemies are present + if !( + (primaryWeapon _unit == "" && {handgunWeapon _unit == ""}) || + {(_unit distance (_unit findNearestEnemy _unit)) > missionNamespace getVariable [QGVAR(safePickupDistance), DEFAULT_PICKUP_DISTANCE]} + ) exitWith {}; + + // If the unit is too far away, make them move closer + if (_unit distance _thrownWeapon >= 4) exitWith { + private _pos = getPosATL _thrownWeapon; + + _unit setDestination [_pos, "LEADER PLANNED", true]; + _unit doMove _pos; + }; + + (_this select 1) call CBA_fnc_removePerFrameHandler; + + _unit action ["TakeWeapon", _thrownWeapon, _weapon]; + + // Make the unit switch weapons + [{ + (_this select 0) hasWeapon (_this select 1) + }, { + params ["_unit", "_weapon"]; + + if (!alive _unit || {!local _unit} || {primaryWeapon _unit != _weapon}) exitWith {}; + + // Switch to the primary weapon, if it was picked up + _unit selectWeapon _weapon; + }, [_unit, _weapon], 5] call CBA_fnc_waitUntilAndExecute; + }, 5, _this] call CBA_fnc_addPerFrameHandler; + }, [_unit, _weapon, _thrownWeapon, CBA_missionTime + 300], random [2, 3, 4]] call CBA_fnc_waitAndExecute; +}] call CBA_fnc_addEventHandler; diff --git a/addons/hitreactions/XEH_preInit.sqf b/addons/hitreactions/XEH_preInit.sqf index 9361d05015..296279c7eb 100644 --- a/addons/hitreactions/XEH_preInit.sqf +++ b/addons/hitreactions/XEH_preInit.sqf @@ -6,6 +6,18 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" + +GVAR(armSelections) = [ + "leftshoulder", + "rightshoulder", + "lefthand", + "leftforearm", + "leftarmroll", + "rightforearm", + "rightarmroll", + "righthand", + "rightarm" +]; ADDON = true; diff --git a/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf b/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf new file mode 100644 index 0000000000..ad4e7c4a41 --- /dev/null +++ b/addons/hitreactions/functions/fnc_checkWeaponDrop.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: KJW + * Checks if an entity should drop their weapon based on projectile hit info. + * + * Arguments: + * 0: Entity that was hit + * 1: Selection names that were hit + * + * Return Value: + * None + * + * Example: + * [player, []] call ace_hitreactions_fnc_checkWeaponDrop + * + * Public: No + */ + +params ["_entity", "_selections"]; + +// Make sure entity is a unit +if !(_entity isKindOf "CAManBase") exitWith {}; + +// Don't throw weapon if unit is unconscious or dead +if !(lifeState _entity in ["HEALTHY", "INJURED"]) exitWith {}; + +if (random 1 >= ([GVAR(weaponDropChanceArmHitAI), GVAR(weaponDropChanceArmHitPlayer)] select (_entity call EFUNC(common,isPlayer)))) exitWith {}; + +if (_selections findAny GVAR(armSelections) == -1) exitWith {}; + +if (getNumber ((currentWeapon _entity) call CBA_fnc_getItemConfig >> QGVAR(undroppable)) == 1) exitWith {}; + +[QGVAR(dropWeapon), _entity, _entity] call CBA_fnc_targetEvent; diff --git a/addons/hitreactions/initSettings.inc.sqf b/addons/hitreactions/initSettings.inc.sqf new file mode 100644 index 0000000000..820f664767 --- /dev/null +++ b/addons/hitreactions/initSettings.inc.sqf @@ -0,0 +1,30 @@ +private _category = [LELSTRING(common,categoryUncategorized), QUOTE(COMPONENT_BEAUTIFIED)]; + +[ + QGVAR(minDamageToTrigger), + "SLIDER", + LSTRING(minDamageToTrigger_displayName), + _category, + [-1, 1, 0.1, 1], + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(weaponDropChanceArmHitPlayer), + "SLIDER", + LSTRING(weaponDropChanceArmHitPlayer_displayName), + _category, + [0, 1, 0, 2, true], + 1, + {[QGVAR(updateFiredEHs)] call CBA_fnc_localEvent} +] call CBA_fnc_addSetting; + +[ + QGVAR(weaponDropChanceArmHitAI), + "SLIDER", + LSTRING(weaponDropChanceArmHitAI_displayName), + _category, + [0, 1, 0, 2, true], + 1, + {[QGVAR(updateFiredEHs)] call CBA_fnc_localEvent} +] call CBA_fnc_addSetting; diff --git a/addons/hitreactions/initSettings.sqf b/addons/hitreactions/initSettings.sqf deleted file mode 100644 index 2ca4ceaeac..0000000000 --- a/addons/hitreactions/initSettings.sqf +++ /dev/null @@ -1,9 +0,0 @@ -private _category = [LELSTRING(common,categoryUncategorized), QUOTE(COMPONENT_BEAUTIFIED)]; - -[ - QGVAR(minDamageToTrigger), "SLIDER", - LSTRING(minDamageToTrigger_displayName), - _category, - [-1, 1, 0.1, 1], - 1 -] call CBA_fnc_addSetting; diff --git a/addons/hitreactions/script_component.hpp b/addons/hitreactions/script_component.hpp index dccbef24f7..dd407a914b 100644 --- a/addons/hitreactions/script_component.hpp +++ b/addons/hitreactions/script_component.hpp @@ -15,3 +15,5 @@ #endif #include "\z\ace\addons\main\script_macros.hpp" + +#define DEFAULT_PICKUP_DISTANCE 8 diff --git a/addons/hitreactions/stringtable.xml b/addons/hitreactions/stringtable.xml index 3b8018a936..ff541ad6a3 100644 --- a/addons/hitreactions/stringtable.xml +++ b/addons/hitreactions/stringtable.xml @@ -3,10 +3,10 @@ Min Damage to trigger falling - Danno Minimo da caduta + Danno Minimo per far cadere 觸發倒下前最低需受到多少傷害 触发倒下前最低需受到多少伤害 - 崩れ落ちるまでの最低損傷値 + 転倒が発生するダメージの最低値 넘어질 때 발생하는 최소 피해량 Mindestschaden, um Sturz auszulösen Minimalne obrażenie, żeby aktywować spadanie @@ -17,5 +17,21 @@ Düşmeyi tetikleyen min hasar Daño mínimo para provocar la caída + + Player Weapon Drop Chance (Arm Hit) + プレイヤーが武器を落とす確率 (腕部への被弾) + Шанс выпадения оружия у игрока (попадание в руку) + 플레이어가 무기를 떨굴 확률 (팔 피격) + Spieler Wahrscheinlichkeit, die Waffe fallen zu lassen (Arm Treffer) + Probabilità dei giocatori di far cadere l'arma (colpo al braccio) + + + AI Weapon Drop Chance (Arm Hit) + AIが武器を落とす確率 (腕部への被弾) + Шанс выпадения оружия у ИИ (попадание в руку) + 인공지능이 무기를 떨굴 확률 (팔 피격) + KI-Wahrscheinlichkeit, die Waffe fallen zu lassen (Arm Treffer) + Probabilità dell'IA di far cadere l'arma (colpo al braccio) + diff --git a/addons/hot/stringtable.xml b/addons/hot/stringtable.xml index 85c8690fef..3c872e1994 100644 --- a/addons/hot/stringtable.xml +++ b/addons/hot/stringtable.xml @@ -21,7 +21,7 @@ Semi-automatic command to line of sight (SACLOS) Halbautomatische Steuerung über Sichtverbindung (SACLOS) Semi-automatyczna komenda do pola widzenia - Comando Semi-Automatico via Contatto Visivo(SACLOS) + Comando Semi-Automatico su Contatto Visivo (SACLOS) 半自動指令照準線一致誘導方式 (SACLOS) Полуавтоматическое командное наведение по линии визирования (SACLOS) Comando semi-automático para a linha de visão (SACLOS) @@ -37,7 +37,7 @@ Wire-Guided Missile Drahtgelenkte Rakete Pocisk kierowany przewodowo - Missile filoguidato + Missile Filoguidato 有線誘導ミサイル Ракета с проводным управлением Míssil Guiado por Fio @@ -133,7 +133,7 @@ Wire-Guided Missile (Anti-Personnel) Anti Personen Lenkflugkörper Pocisk kierowany przewodowo (przeciwpiechotny) - Missile filoguidato antiuomo + Missile Filoguidato Antiuomo 有線誘導ミサイル (対人) Ракета с проводным управлением (Противопехотная) Míssil Guiado por Fio (Anti-Pessoal) diff --git a/addons/hunterkiller/CfgVehicles.hpp b/addons/hunterkiller/CfgVehicles.hpp index 4ba64d8a95..b0fc79fc2b 100644 --- a/addons/hunterkiller/CfgVehicles.hpp +++ b/addons/hunterkiller/CfgVehicles.hpp @@ -21,4 +21,8 @@ class CfgVehicles { class MBT_04_base_F: Tank_F { ADDON = 1; }; + class Wheeled_APC_F; + class AFV_Wheeled_01_base_F: Wheeled_APC_F { + ADDON = 1; + }; }; diff --git a/addons/hunterkiller/stringtable.xml b/addons/hunterkiller/stringtable.xml index 9c686365d9..5d42659329 100644 --- a/addons/hunterkiller/stringtable.xml +++ b/addons/hunterkiller/stringtable.xml @@ -9,7 +9,9 @@ ハンターキラー Hunter Killer Hunter Killer + Hunter Killer Hunter Killer + Hunter Killer Override @@ -19,7 +21,9 @@ オーバーライド Nadpisanie Überschreibe + Sovrascrivi Surcharge + Sobrescrever Force other turret to slew onto your viewpoint @@ -29,7 +33,9 @@ 他のタレットを強制的に自分の視点に旋回させる Obróć drugą wieżyczkę w kierunku, w którym zwrócona jest twoja wieżyczka. Zwingt andere Türme, sich auf deine Blickrichtung zu drehen + Costringe altre torrette a puntare dove è puntata la tua. Force une autre tourelle à s'aligner sur votre point de vue. + Força outra torreta a alinhar-se com o seu ponto de vista. Observe @@ -39,7 +45,9 @@ オブザーブ Obserwowanie Observiere + Osserva Observation + Observar Slew your turret onto other turret's viewpoint @@ -49,7 +57,9 @@ 自分のタレットを相手のタレットの視点に旋回させる。 Obróć swoją wieżyczkę tam, gdzie patrzy druga. Richtet deinen Turm auf die Blickrichtung eines anderen Turms + Punta la tua torretta nella direzione di un'altra torretta. Aligne votre tourelle sur le point de vue d'une autre tourelle. + Alinhe a sua torreta com o ponto de vista de outra torreta. diff --git a/addons/huntir/functions/fnc_cam.sqf b/addons/huntir/functions/fnc_cam.sqf index 54b6516fff..411dbfe30e 100644 --- a/addons/huntir/functions/fnc_cam.sqf +++ b/addons/huntir/functions/fnc_cam.sqf @@ -77,8 +77,7 @@ GVAR(no_cams) sort true; if (((getPosVisual _x) select 2) > 20 && {!(_x in GVAR(no_cams))} && {_x getHitPointDamage "HitCamera" < 0.25}) then { GVAR(no_cams) pushBack _x; }; - true - } count GVAR(nearHuntIRs); + } forEach GVAR(nearHuntIRs); { if (((getPosVisual _x) select 2) <= 20 || {!(_x in GVAR(nearHuntIRs))} || {_x getHitPointDamage "HitCamera" >= 0.25}) then { GVAR(no_cams) deleteAt _forEachIndex; @@ -145,7 +144,7 @@ GVAR(no_cams) sort true; GVAR(cam) camCommit 0; ctrlSetText [1, format["%1 m", round(GVAR(pos) select 2)]]; - ctrlSetText [2, format["%1", GVAR(cur_cam) + 1]]; + ctrlSetText [2, str (GVAR(cur_cam) + 1)]; private _cam_time = CBA_missionTime - (GVAR(huntIR) getVariable [QGVAR(startTime), CBA_missionTime]); ctrlSetText [3, format["%1 s", round(_cam_time)]]; private _cam_pos = getPosVisual GVAR(huntIR); diff --git a/addons/huntir/stringtable.xml b/addons/huntir/stringtable.xml index 0ea8abc37b..74e68b6432 100644 --- a/addons/huntir/stringtable.xml +++ b/addons/huntir/stringtable.xml @@ -29,7 +29,7 @@ Projectile HuntIR HuntIR lövedék Cartucho HuntIR - HuntIR 弾頭 + HuntIR弾 헌트IR 유탄 高空战术摄像头弹药 高空戰術成像器彈藥 @@ -46,7 +46,7 @@ Ecran HuntIR HuntIR Monitor Monitor HuntIR - HuntIR モニタ + HuntIR モニター 헌트IR 모니터 高空战术摄像头显示面板 高空戰術成像器顯示面板 @@ -114,7 +114,7 @@ Temps d'enregistrement : Felvételi idő: Tempo de gravação: - 録画時間: + 記録時間: 녹화시간: 记录时间: 記錄時間: @@ -194,12 +194,12 @@ Left/Right - Rotar camara Levá/Pravá - Rotace kamery Влево/Вправо - Вращать камеру - Left/Right - Ruota telecamera + Sinistra/Destra - Ruota telecamera Lewo/Prawo - obrót kamery w poziomie Gauche/Droite - Rotation de la caméra Jobb/Bal - Kamera forgatás Esquerda/Direita - Rotaciona câmera - Left/Right - カメラ回転 + Left/Right - カメラの回転 좌/우 - 카메라 돌리기 左/右—旋转摄像头 左/右 - 旋轉攝影機 @@ -211,12 +211,12 @@ Up/Down - Subir/bajar camara Nahoru/Dolu - Zvýšít/snížit úhel pohledu kamery Вверх/Вниз - Поднять/опустить камеру - Up/Down - Alza/abbassa telecamera + Su/Giù - Alza/abbassa telecamera Góra/Dół - obrót kamery w pionie Haut/Bas - Monter/descendre la caméra Fel/Le - Kamera döntése/süllyesztése Acima/Abaixo - Eleva/Abaixa a câmera - Up/Down - カメラ角度を変更 + Up/Down - カメラの角度 상/하 카메라 올리기/내리기 上/下—上升/下降摄像头 上/下 - 上升/下降攝影機 @@ -262,12 +262,12 @@ Esc - Salir del menú de ayuda Esc - Ukončit pomoc Esc - Выйти из помощи - Esc - Chiudi aiuto + Esc - Aiuto dal Menù Esc - wyjście z ekranu Pomocy Esc - Sortir de l'aide Exit - Kilépés a súgóból Esc - Sai do Ajuda - Esc - ヘルプ終了 + Esc - ヘルプを閉じる Esc - 도움말 나가기 Esc—离开帮助 Esc - 離開幫助 diff --git a/addons/intelitems/CfgMagazines.hpp b/addons/intelitems/CfgMagazines.hpp index cb5bbf495d..75d1ca29ee 100644 --- a/addons/intelitems/CfgMagazines.hpp +++ b/addons/intelitems/CfgMagazines.hpp @@ -2,7 +2,7 @@ class CfgMagazines { class CA_Magazine; class GVAR(base): CA_Magazine { count = 1; - mass = 1; + mass = 0.1; ACE_isUnique = 1; GVAR(intel) = 1; GVAR(control) = ""; diff --git a/addons/intelitems/XEH_preInit.sqf b/addons/intelitems/XEH_preInit.sqf index 76f13135d9..ff09f6ea0e 100644 --- a/addons/intelitems/XEH_preInit.sqf +++ b/addons/intelitems/XEH_preInit.sqf @@ -18,8 +18,8 @@ if (isServer) then { GVAR(intelData) = [true] call CBA_fnc_createNamespace; publicVariable QGVAR(intelData); - [QGVAR(handleMagIndex), FUNC(handleMagIndex)] call CBA_fnc_addEventHandler; - [QGVAR(setObjectData), FUNC(setObjectData)] call CBA_fnc_addEventHandler; + [QGVAR(handleMagIndex), LINKFUNC(handleMagIndex)] call CBA_fnc_addEventHandler; + [QGVAR(setObjectData), LINKFUNC(setObjectData)] call CBA_fnc_addEventHandler; }; if (hasInterface) then { diff --git a/addons/intelitems/stringtable.xml b/addons/intelitems/stringtable.xml index 280dde30a6..8f13939090 100644 --- a/addons/intelitems/stringtable.xml +++ b/addons/intelitems/stringtable.xml @@ -4,6 +4,7 @@ ACE Intel Items ACE Aufklärungsgegenstände + ACE Oggetti Intel ACE 情報物品 ACE 情报物品 ACE 機密アイテム @@ -13,10 +14,12 @@ ACE 정보 아이템 ACE Objetos de Inteligencia ACE Objets de Renseignements + ACE Itens de Inteligência Intel Items Aufklärungsgegenstände + Oggetti Intel 情報物品 情报物品 機密アイテム @@ -26,36 +29,42 @@ 정보 아이템 Objetos de Inteligencia Objets de Renseignements + Itens de Inteligência Notepad Notizblock + Blocco Note 筆記本 笔记本 - メモ + メモ帳 Блокнот Notes Not Defteri 노트패드 Bloc de notas Bloc-notes + Bloco de Notas Notepad - Can access from the map screen Notizblock - Über die Karte abrufbar + Blocco Note - Accessibile dalla mappa 筆記本 - 可以透過地圖界面來存取 笔记本—可以透过地图界面访问 - メモ - マップ画面から確認可能 + メモ帳 - マップ画面から確認可能 Блокнот - Можно получить доступ с экрана карты Notes - Dostępne z mapy Not Defteri - Haritadan erişim sağlanabilinir 노트패드 - 지도에서 확인 가능합니다 Block de notas - Puede accederse desde la pantalla de mapa Bloc-note - Consultable depuis la carte + Bloco de Notas - Pode ser acessado a partir da tela de mapa Document Dokument + Documento 文件 文件 資料 @@ -65,23 +74,27 @@ 문서 Documento Document + Documento Printed Document - Can access from the map screen Bedrucktes Dokument - Über die Karte abrufbar + Documento stampato - Accessibile dalla mappa 影印文件 - 可以透過地圖界面來存取 影印文件—可以透过地图界面访问 - メモ - マップ画面から確認可能 + 印刷された資料 - マップ画面から確認可能 Распечатанный документ - Можно получить доступ с экрана карты Wydrukowane Dokumenty - Dostępne z mapy Yazılı Döküman - Haritadan erişim sağlanabilinir 문서들 - 지도에서 확인 가능합니다 Documento Impreso - Puede accederse desde la pantalla de mapa Document imprimé - Consultable depuis la carte + Documento Impresso - Pode ser acessado a partir da tela de mapa Photo Foto + Foto 相片 照片 写真 @@ -91,10 +104,12 @@ 사진 Fotografía Photo + Fotografia Photo - Can access from the map screen Foto - Über die Karte abrufbar + Foto - Accessibile dalla mappa 相片 - 可以透過地圖界面來存取 照片—可以透过地图界面访问 写真 - マップ画面から確認可能 @@ -104,6 +119,7 @@ 사진 - 지도에서 확인 가능합니다 Fotografía - Puede accederse desde la pantalla de mapa Photo - Consultable depuis la carte + Fotografia - Pode ser acessada a partir da tela de mapa Text @@ -124,6 +140,7 @@ Photo Filename Foto-Dateiname + Nome File della Foto 相片名稱 照片文件名 写真名 @@ -133,13 +150,14 @@ 사진명 Nombre de fichero de la Fotografía Nom du fichier photo + Nome do Arquivo da Fotografia Pick Up Vyzvednout Ramasser Aufnehmen - Prelevare + Raccogli Podnieś Pegar Подобрать diff --git a/addons/interact_menu/XEH_clientInit.sqf b/addons/interact_menu/XEH_clientInit.sqf index a76bf90e1c..d0c6d93940 100644 --- a/addons/interact_menu/XEH_clientInit.sqf +++ b/addons/interact_menu/XEH_clientInit.sqf @@ -3,16 +3,16 @@ if (!hasInterface) exitWith {}; // Wait until player controls (man,vehicle or uav) a thing before compiling the menu -GVAR(controllableSelfActionsAdded) = [] call CBA_fnc_createNamespace; +GVAR(controllableSelfActionsAdded) = createHashMap; DFUNC(newControllableObject) = { params ["_object"]; private _type = typeOf _object; TRACE_2("newControllableObject",_object,_type); if (_type == "") exitWith {}; - if (!(GVAR(controllableSelfActionsAdded) getVariable [_type, false])) then { + if !(_type in GVAR(controllableSelfActionsAdded)) then { [_type] call FUNC(compileMenuSelfAction); - GVAR(controllableSelfActionsAdded) setVariable [_type, true]; + GVAR(controllableSelfActionsAdded) set [_type, nil]; [{ TRACE_1("sending newControllableObject event",_this); // event for other systems to add self actions, running addActionToClass before this will cause compiling @@ -27,8 +27,7 @@ DFUNC(newControllableObject) = { GVAR(blockDefaultActions) = []; -GVAR(cachedBuildingTypes) = []; -GVAR(cachedBuildingActionPairs) = []; +GVAR(cachedBuildingTypes) = createHashMap; GVAR(ParsedTextCached) = []; @@ -47,7 +46,7 @@ GVAR(ParsedTextCached) = []; }] call CBA_fnc_addEventHandler; //Add Actions to Houses: -["ace_interactMenuOpened", {_this call FUNC(userActions_addHouseActions)}] call CBA_fnc_addEventHandler; +["ace_interactMenuOpened", LINKFUNC(userActions_addHouseActions)] call CBA_fnc_addEventHandler; ["ACE3 Common", QGVAR(InteractKey), (localize LSTRING(InteractKey)), { diff --git a/addons/interact_menu/XEH_preInit.sqf b/addons/interact_menu/XEH_preInit.sqf index 0d321112f9..88269bcc04 100644 --- a/addons/interact_menu/XEH_preInit.sqf +++ b/addons/interact_menu/XEH_preInit.sqf @@ -6,18 +6,18 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" if (!hasInterface) exitWith { ADDON = true; }; -["All", "init", {_this call FUNC(compileMenu)}] call CBA_fnc_addClassEventHandler; +["All", "init", LINKFUNC(compileMenu)] call CBA_fnc_addClassEventHandler; -GVAR(ActNamespace) = [] call CBA_fnc_createNamespace; -GVAR(ActSelfNamespace) = [] call CBA_fnc_createNamespace; +GVAR(ActNamespace) = createHashMap; +GVAR(ActSelfNamespace) = createHashMap; // Compile actions for CAManBase now and use for all mans types ["CAManBase"] call FUNC(compileMenu); -GVAR(cacheManActions) = +(GVAR(ActNamespace) getVariable ["CAManBase", []]); // copy +GVAR(cacheManActions) = +(GVAR(ActNamespace) getOrDefault ["CAManBase" call EFUNC(common,getConfigName), []]); // copy // Event handlers for all interact menu controls DFUNC(handleMouseMovement) = { diff --git a/addons/interact_menu/functions/fnc_addActionToClass.sqf b/addons/interact_menu/functions/fnc_addActionToClass.sqf index 93d54c991c..ccea8c4654 100644 --- a/addons/interact_menu/functions/fnc_addActionToClass.sqf +++ b/addons/interact_menu/functions/fnc_addActionToClass.sqf @@ -48,6 +48,8 @@ if (param [4, false, [false]]) exitwith { (_parentPath + [_action select 0]) }; +_objectType = _objectType call EFUNC(common,getConfigName); + // Ensure the config menu was compiled first if (_typeNum == 0) then { [_objectType] call FUNC(compileMenu); @@ -56,18 +58,14 @@ if (_typeNum == 0) then { }; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; - _namespace setVariable [_objectType, _actionTrees]; -}; +private _actionTrees = _namespace getOrDefault [_objectType, [], true]; if (_parentPath isEqualTo ["ACE_MainActions"]) then { [_objectType, _typeNum] call FUNC(addMainAction); }; private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); -if (isNil {_parentNode}) exitWith { +if (isNil "_parentNode") exitWith { ERROR_4("Failed to add action - action (%1) to parent %2 on object %3 [%4]",(_action select 0),_parentPath,_objectType,_typeNum); [] }; diff --git a/addons/interact_menu/functions/fnc_addActionToZeus.sqf b/addons/interact_menu/functions/fnc_addActionToZeus.sqf index b4dbb69f4a..3175bf14ad 100644 --- a/addons/interact_menu/functions/fnc_addActionToZeus.sqf +++ b/addons/interact_menu/functions/fnc_addActionToZeus.sqf @@ -19,7 +19,7 @@ if (!hasInterface) exitWith { [] }; if (!params [["_parentPath", [], [[]]], ["_action", [], [[]], 11]]) exitWith {ERROR("Bad Params"); []}; -if ((_parentPath param [0, ""]) != "ACE_ZeusActions") exitWith {ERROR_1("Bad path %1 - should have ACE_ZeusActions as base", _parentPath); []}; +if ((_parentPath param [0, ""]) != "ACE_ZeusActions") exitWith {ERROR_1("Bad path %1 - should have ACE_ZeusActions as base",_parentPath); []}; TRACE_2("addActionToZeus",_parentPath,_action); private _currentPath = GVAR(ZeusActions); @@ -37,7 +37,7 @@ private _pathValid = false; } forEach _currentPath; } forEach _parentPath; -if (!_pathValid) exitWith {ERROR_1("Bad path %1", _parentPath); []}; +if (!_pathValid) exitWith {ERROR_1("Bad path %1",_parentPath); []}; TRACE_1("Adding Action",_currentPath); _currentPath pushBack [_action, []]; diff --git a/addons/interact_menu/functions/fnc_addMainAction.sqf b/addons/interact_menu/functions/fnc_addMainAction.sqf index 86b37bf416..beb02997b9 100644 --- a/addons/interact_menu/functions/fnc_addMainAction.sqf +++ b/addons/interact_menu/functions/fnc_addMainAction.sqf @@ -19,15 +19,11 @@ params ["_objectType", "_typeNum"]; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; - +private _actionTrees = _namespace getOrDefault [_objectType, []]; private _parentNode = [_actionTrees, ["ACE_MainActions"]] call FUNC(findActionNode); -if (isNil {_parentNode}) then { - TRACE_2("No Main Action on object", _objectType, _typeNum); +if (isNil "_parentNode") then { + TRACE_2("No Main Action on object",_objectType,_typeNum); private _mainAction = ["ACE_MainActions", localize ELSTRING(interaction,MainAction), "", {}, {true}] call FUNC(createAction); [_objectType, _typeNum, [], _mainAction] call EFUNC(interact_menu,addActionToClass); }; diff --git a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf index 82235493e6..9a3eb31598 100644 --- a/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf +++ b/addons/interact_menu/functions/fnc_collectActiveActionTree.sqf @@ -43,12 +43,21 @@ _origActionData params [ "_distance" ]; +private _result = [_target, ACE_player, _customParams] call _conditionCode; + +// Handle nil as false +if (isNil "_result") then { + ERROR_1("Action [%1] bad condition return",_actionName); + + _result = false; +}; + // Return nothing if the action itself is not active -if !([_target, ACE_player, _customParams] call _conditionCode) exitWith { +if (!_result) exitWith { [] }; -// Return nothing if the action is to far (including checking sub actions) [DISABLED FOR NOW ref #2196] +// Return nothing if the action is too far (including checking sub actions) [DISABLED FOR NOW ref #2196] // if (_distanceToBasePoint > _distance) exitWith { // [] // }; @@ -64,21 +73,19 @@ if (_insertChildrenCode isNotEqualTo {}) then { // Collect dynamic children class actions { private _action = [_x select 2, _x, _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree); - if ((count _action) > 0) then { + if (_action isNotEqualTo []) then { _activeChildren pushBack _action; }; - nil - } count _dynamicChildren; + } forEach _dynamicChildren; }; // Collect children class actions { private _action = [_object, _x, _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree); - if ((count _action) > 0) then { + if (_action isNotEqualTo []) then { _activeChildren pushBack _action; }; - nil -} count _origActionChildren; +} forEach _origActionChildren; // Collect children object actions { @@ -87,12 +94,11 @@ if (_insertChildrenCode isNotEqualTo {}) then { // Check if the action is children of the original action if (_pPath isEqualTo _fullPath) then { private _action = [_object, [_actionData,[]], _fullPath, _distanceToBasePoint] call FUNC(collectActiveActionTree); - if ((count _action) > 0) then { + if (_action isNotEqualTo []) then { _activeChildren pushBack _action; }; }; - nil -} count GVAR(objectActionList); +} forEach GVAR(objectActionList); // If the original action has no statement, and no children, don't display it @@ -103,14 +109,14 @@ if ((_activeChildren isEqualTo []) && {_statementCode isEqualTo {}}) exitWith { if (GVAR(consolidateSingleChild) && {count _activeChildren == 1} && {_statementCode isEqualTo {}}) then { _activeChildren select 0 params ["_childActionData", "_childChildren", "_childObject"]; - _childActionData params ["", "_displayNameChild", "_iconChild", "_statementChild", "", "", "_customParamsChild", "", "", "_paramsChild"]; + _childActionData params ["", "_displayNameChild", "_iconChild", "_statementChild", "_conditionChild", "_insertChildrenChild", "_customParamsChild", "", "", "_paramsChild"]; _origActionData = [ _actionName, format ["%1 > %2", _displayName, _displayNameChild], _iconChild, _statementChild, - _conditionCode, - _insertChildrenCode, + _conditionChild, + _insertChildrenChild, _customParamsChild, _position, _distance, diff --git a/addons/interact_menu/functions/fnc_compileMenu.sqf b/addons/interact_menu/functions/fnc_compileMenu.sqf index 35b0ea7177..8c5d3c5fa1 100644 --- a/addons/interact_menu/functions/fnc_compileMenu.sqf +++ b/addons/interact_menu/functions/fnc_compileMenu.sqf @@ -17,22 +17,22 @@ params ["_target"]; -private _objectType = _target; -if (_target isEqualType objNull) then { - _objectType = typeOf _target; +private _objectType = if (_target isEqualType objNull) then { + typeOf _target +} else { + _target call EFUNC(common,getConfigName) }; -private _namespace = GVAR(ActNamespace); // Exit if the action menu is already compiled for this class -if (!isNil {_namespace getVariable _objectType}) exitWith {}; +if (_objectType in GVAR(ActNamespace)) exitWith {}; if (_objectType isKindOf "VirtualMan_F") exitWith { // these have config: isPlayableLogic = 1 TRACE_1("skipping playable logic",_objectType); - _namespace setVariable [_objectType, []]; + GVAR(ActNamespace) set [_objectType, []]; }; if ((_objectType isKindOf "CAManBase") && {!isNil QGVAR(cacheManActions)}) exitWith { - _namespace setVariable [_objectType, +GVAR(cacheManActions)]; // copy + GVAR(ActNamespace) set [_objectType, +GVAR(cacheManActions)]; // copy }; private _recurseFnc = { @@ -45,7 +45,7 @@ private _recurseFnc = { private _displayName = getText (_entryCfg >> "displayName"); private _distance = _parentDistance; if (isNumber (_entryCfg >> "distance")) then {_distance = getNumber (_entryCfg >> "distance");}; - // if (_distance < _parentDistance) then {WARNING_3("[%1] distance %2 less than parent %3", configName _entryCfg, _distance, _parentDistance);}; + // if (_distance < _parentDistance) then {WARNING_3("[%1] distance %2 less than parent %3",configName _entryCfg,_distance,_parentDistance);}; private _icon = if (isArray (_entryCfg >> "icon")) then { getArray (_entryCfg >> "icon"); } else { @@ -74,7 +74,7 @@ private _recurseFnc = { if (_condition isEqualTo "") then {_condition = "true"}; } else { // Add canInteract (including exceptions) and canInteractWith to condition - private _canInteractCondition = format [QUOTE([ARR_3(ACE_player,_target,%1)] call EFUNC(common,canInteractWith)), getArray (_entryCfg >> "exceptions")]; + private _canInteractCondition = format [QUOTE([ARR_3(ACE_player,_target,%1)] call EFUNC(common,canInteractWith)),getArray (_entryCfg >> "exceptions")]; private _conditionFormatPattern = ["%1 && {%2}", "%2"] select (_condition isEqualTo "" || {_condition == "true"}); _condition = format [_conditionFormatPattern, _condition, _canInteractCondition]; }; @@ -114,8 +114,7 @@ private _recurseFnc = { ]; _actions pushBack _entry; }; - nil - } count (configProperties [_actionsCfg, "isClass _x", true]); + } forEach (configProperties [_actionsCfg, "isClass _x", true]); _actions }; @@ -140,7 +139,7 @@ if (_objectType isKindOf "CAManBase") then { }; }; -_namespace setVariable [_objectType, _actions]; +GVAR(ActNamespace) set [_objectType, _actions]; /* [ diff --git a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf index 75fdb93819..8f19dfabbe 100644 --- a/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf +++ b/addons/interact_menu/functions/fnc_compileMenuSelfAction.sqf @@ -17,15 +17,14 @@ params ["_target"]; -private _objectType = _target; -if (_target isEqualType objNull) then { - _objectType = typeOf _target; +private _objectType = if (_target isEqualType objNull) then { + typeOf _target +} else { + _target call EFUNC(common,getConfigName) }; -private _namespace = GVAR(ActSelfNamespace); // Exit if the action menu is already compiled for this class -if (!isNil {_namespace getVariable _objectType}) exitWith {}; - +if (_objectType in GVAR(actSelfNamespace)) exitWith {}; private _recurseFnc = { params ["_actionsCfg"]; @@ -84,8 +83,7 @@ private _recurseFnc = { ]; _actions pushBack _entry; }; - nil - } count (configProperties [_actionsCfg, "isClass _x", true]); + } forEach (configProperties [_actionsCfg, "isClass _x", true]); _actions }; @@ -132,4 +130,4 @@ private _actions = [ ] ]; -_namespace setVariable [_objectType, _actions]; +GVAR(ActSelfNamespace) set [_objectType, _actions]; diff --git a/addons/interact_menu/functions/fnc_createAction.sqf b/addons/interact_menu/functions/fnc_createAction.sqf index d920922ddb..ae00f4fb82 100644 --- a/addons/interact_menu/functions/fnc_createAction.sqf +++ b/addons/interact_menu/functions/fnc_createAction.sqf @@ -49,7 +49,7 @@ _position = if (_position isEqualType "") then { } else { if (_position isEqualType []) then { // If the action is set to a array position, create the suitable code - compile format ["%1", _position]; + compile str _position; } else { _position; }; diff --git a/addons/interact_menu/functions/fnc_createVehiclesActions.sqf b/addons/interact_menu/functions/fnc_createVehiclesActions.sqf index b2e9407c8d..3aef7b4552 100644 --- a/addons/interact_menu/functions/fnc_createVehiclesActions.sqf +++ b/addons/interact_menu/functions/fnc_createVehiclesActions.sqf @@ -23,10 +23,13 @@ params ["_vehicles", "_statement", "_target"]; _vehicles apply { private _name = getText ((configOf _x) >> "displayName"); private _ownerName = [_x, true] call EFUNC(common,getName); + private _distanceStr = (ACE_player distance _x) toFixed 1; if ("" != _ownerName) then { - _name = format ["%1 (%2)", _name, _ownerName]; + _name = format ["%1 (%2, %3m)", _name, _ownerName, _distanceStr]; + } else { + _name = format ["%1 (%2m)", _name, _distanceStr]; }; private _icon = [_x] call EFUNC(common,getVehicleIcon); - private _action = [format ["%1", _x], _name, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction); + private _action = [str _x, _name, _icon, _statement, {true}, {}, _x] call EFUNC(interact_menu,createAction); [_action, [], _target] } diff --git a/addons/interact_menu/functions/fnc_initMenuReorder.sqf b/addons/interact_menu/functions/fnc_initMenuReorder.sqf index 48445b3fa0..d55f2f06ea 100644 --- a/addons/interact_menu/functions/fnc_initMenuReorder.sqf +++ b/addons/interact_menu/functions/fnc_initMenuReorder.sqf @@ -17,7 +17,7 @@ params ["_class"]; -private _actionTrees = GVAR(ActSelfNamespace) getVariable _class; +private _actionTrees = GVAR(ActSelfNamespace) get _class; private _rootNode = [_actionTrees, ["ACE_SelfActions"]] call FUNC(findActionNode); private _rootActions = _rootNode select 1; private _settingCategoryPrefix = format ["ACE %1 - ", LELSTRING(Interaction,InteractionMenuSelf)]; diff --git a/addons/interact_menu/functions/fnc_keyDown.sqf b/addons/interact_menu/functions/fnc_keyDown.sqf index 5bce40d0a8..9cb638bcea 100644 --- a/addons/interact_menu/functions/fnc_keyDown.sqf +++ b/addons/interact_menu/functions/fnc_keyDown.sqf @@ -116,7 +116,7 @@ GVAR(selfMenuOffset) = (AGLtoASL (positionCameraToWorld [0, 0, 2])) vectorDiff ( //Auto expand the first level when self, mounted vehicle or zeus (skips the first animation as there is only one choice) if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (!(isNull (ACE_controlledUAV select 0))) then { + if !(isNull (ACE_controlledUAV select 0)) then { GVAR(menuDepthPath) = [["ACE_SelfActions", (ACE_controlledUAV select 0)]]; GVAR(expanded) = true; GVAR(expandedTime) = diag_tickTime; diff --git a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf index 55aa0f4f82..7585616ef6 100644 --- a/addons/interact_menu/functions/fnc_removeActionFromClass.sqf +++ b/addons/interact_menu/functions/fnc_removeActionFromClass.sqf @@ -19,23 +19,22 @@ params ["_objectType", "_typeNum", "_fullPath"]; +_objectType = _objectType call EFUNC(common,getConfigName); + private _res = _fullPath call FUNC(splitPath); _res params ["_parentPath", "_actionName"]; private _namespace = [GVAR(ActNamespace), GVAR(ActSelfNamespace)] select _typeNum; -private _actionTrees = _namespace getVariable _objectType; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; +private _actionTrees = _namespace getOrDefault [_objectType, []]; private _parentNode = [_actionTrees, _parentPath] call FUNC(findActionNode); -if (isNil {_parentNode}) exitWith {}; +if (isNil "_parentNode") exitWith {}; // Iterate through children of the father private _found = false; { if (((_x select 0) select 0) == _actionName) exitWith { - TRACE_2("Deleting Action", _forEachIndex, _x); + TRACE_2("Deleting Action",_forEachIndex,_x); _found = true; (_parentNode select 1) deleteAt _forEachIndex; }; diff --git a/addons/interact_menu/functions/fnc_renderActionPoints.sqf b/addons/interact_menu/functions/fnc_renderActionPoints.sqf index 058b5ed846..62d29be91f 100644 --- a/addons/interact_menu/functions/fnc_renderActionPoints.sqf +++ b/addons/interact_menu/functions/fnc_renderActionPoints.sqf @@ -61,7 +61,7 @@ private _fnc_renderNearbyActions = { } forEach GVAR(objectActionList); // Iterate through base level class actions and render them if appropiate - private _classActions = GVAR(ActNamespace) getVariable [typeOf _target, []]; + private _classActions = GVAR(ActNamespace) getOrDefault [typeOf _target, []]; { private _action = _x; // Try to render the menu @@ -95,8 +95,7 @@ private _fnc_renderSelfActions = { GVAR(objectActionList) = _target getVariable [QGVAR(selfActions), []]; // Iterate through base level class actions and render them if appropiate - private _namespace = GVAR(ActSelfNamespace); - private _classActions = _namespace getVariable typeOf _target; + private _classActions = GVAR(ActSelfNamespace) get typeOf _target; private _pos = if !(GVAR(useCursorMenu)) then { //Convert to ASL, add offset and then convert back to AGL (handles waves when over water) @@ -124,7 +123,7 @@ GVAR(collectedActionPoints) resize 0; // Render nearby actions, unit self actions or vehicle self actions as appropiate if (GVAR(openedMenuType) == 0) then { if (isNull curatorCamera) then { - if (!(isNull (ACE_controlledUAV select 0))) then { + if !(isNull (ACE_controlledUAV select 0)) then { // Render UAV self actions when in control of UAV AI (ACE_controlledUAV select 0) call _fnc_renderSelfActions; } else { diff --git a/addons/interact_menu/functions/fnc_renderMenu.sqf b/addons/interact_menu/functions/fnc_renderMenu.sqf index e7bb42b4cf..3aa8a05ab3 100644 --- a/addons/interact_menu/functions/fnc_renderMenu.sqf +++ b/addons/interact_menu/functions/fnc_renderMenu.sqf @@ -95,7 +95,7 @@ if (_useListMenu) then { _scaleX = _textSize * 0.17 * 1.1; _scaleY = 0.17 * 0.30 * 4/3; } else { - private _textSize = if (GVAR(textSize) > 2) then {1.3} else {1}; + private _textSIze = [1, 1.3] select (GVAR(textSize) > 2); _scaleX = _textSize * 0.17 * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.1) max 0.5); _scaleY = _textSize * 0.17 * 4/3 * (((0.8 * (0.46 / sin (0.5 * _angleInterval))) min 1.1) max 0.5); }; diff --git a/addons/interact_menu/functions/fnc_splitPath.sqf b/addons/interact_menu/functions/fnc_splitPath.sqf index 8c0856d118..8fabaca5a5 100644 --- a/addons/interact_menu/functions/fnc_splitPath.sqf +++ b/addons/interact_menu/functions/fnc_splitPath.sqf @@ -17,11 +17,13 @@ */ private _parentPath = []; -for [{private _i = 0},{_i < (count _this) - 1},{_i = _i + 1}] do { - _parentPath pushBack (_this select _i); -}; -private _actionName = if (count _this > 0) then { - _this select ((count _this) - 1); + +_parentPath append _this; + +private _count = count _this; + +private _actionName = if (_count > 0) then { + _parentPath deleteAt (_count - 1) // TODO: replace with _parentPath deleteAt [-1] and drop _count in 2.18 } else { "" }; diff --git a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf index c11da0c271..8f28950840 100644 --- a/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf +++ b/addons/interact_menu/functions/fnc_userActions_getHouseActions.sqf @@ -17,8 +17,9 @@ params ["_typeOfBuilding"]; -private _searchIndex = GVAR(cachedBuildingTypes) find _typeOfBuilding; -if (_searchIndex != -1) exitWith {GVAR(cachedBuildingActionPairs) select _searchIndex}; +private _cachedMemPoints = GVAR(cachedBuildingTypes) get _typeOfBuilding; + +if (!isNil "_cachedMemPoints") exitWith {_cachedMemPoints}; private _memPoints = []; private _memPointsActions = []; @@ -148,8 +149,6 @@ private _ladders = getArray (configFile >> "CfgVehicles" >> _typeOfBuilding >> " } forEach _ladders; -GVAR(cachedBuildingTypes) pushBack _typeOfBuilding; -GVAR(cachedBuildingActionPairs) pushBack [_memPoints, _memPointsActions]; - +GVAR(cachedBuildingTypes) set [_typeOfBuilding, [_memPoints, _memPointsActions]]; [_memPoints, _memPointsActions] diff --git a/addons/interact_menu/initSettings.sqf b/addons/interact_menu/initSettings.inc.sqf similarity index 96% rename from addons/interact_menu/initSettings.sqf rename to addons/interact_menu/initSettings.inc.sqf index 22287189c3..c175bd17c2 100644 --- a/addons/interact_menu/initSettings.sqf +++ b/addons/interact_menu/initSettings.inc.sqf @@ -46,9 +46,7 @@ private _categoryColors = [_category, format ["| %1 |", LELSTRING(common,subcate QGVAR(textSize), "LIST", LSTRING(textSize), _category, - [[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2], - 0, - {[QGVAR(textSize), _this] call EFUNC(common,cbaSettings_settingChanged)} + [[0, 1, 2, 3, 4], ["str_very_small", "str_small", "str_medium", "str_large", "str_very_large"], 2] ] call CBA_fnc_addSetting; [ diff --git a/addons/interact_menu/stringtable.xml b/addons/interact_menu/stringtable.xml index 1b8435c61e..cb05331633 100644 --- a/addons/interact_menu/stringtable.xml +++ b/addons/interact_menu/stringtable.xml @@ -10,9 +10,9 @@ Zawsze wyświetlaj kursor dla własnej interakcji Toujours afficher le curseur pour les interactions sur soi-même Mindig legyen a saját cselekvés kurzorja látható - Mostra sempre il cursore delle autointerazioni + Mostra sempre il cursore per le autointerazioni Sempre mostrar cursor para interação pessoal - セルフ インタラクションへ常にカーソルを表示 + カーソルを常に表示 자기상호작용 시 항상 커서를 보이기 自我互动时永远显示光标 自我互動時永遠顯示游標 @@ -29,7 +29,7 @@ Immer den Mauszeiger für Fremd-Interaktionen anzeigen Mindig legyen a cselekvés kurzorja látható Sempre mostrar cursor para interação - インタラクションへ常にカーソルを表示 + カーソルを常に表示 상호작용 시 항상 커서를 보이기 互动时永远显示光标 互動時永遠顯示游標 @@ -46,7 +46,7 @@ Interaktionsmenü in Listen anzeigen Cselekvő menük listaként való megjelenítése Mostrar menu de interação como listas - インタラクション メニューを一覧表示 + メニューをリストで表示 상호작용메뉴를 리스트화 해서 보이기 以列表方式显示互动表单 以列表方式顯示互動表單 @@ -78,9 +78,9 @@ Klawisz własnej interakcji Touche d'interaction personnelle Saját cselekvő gomb - Tasto interazione su se stessi + Tasto autointerazioni Tecla de Interação Pessoal - セルフ インタラクション キー + セルフ・インタラクション キー 자기상호작용 키 自我互动键 自我互動鍵 @@ -95,9 +95,9 @@ Własne akcje Interaction personnelle Saját cselekvések - Interazioni su se stessi + Autointerazioni Ações Pessoais - 自分への動作 + 自分へのアクション 자기 동작 自我动作 自我動作 @@ -112,9 +112,9 @@ Akcje pojazdu Interaction véhicule Járműves cselekvések - Interazioni con veicoli + Interazioni su veicoli Ações de Veículos - 車両への動作 + 車両へのアクション 차량 동작 载具动作 載具動作 @@ -130,8 +130,8 @@ Zeus cselekvések Ações do Zeus Действия Зевса - Azioni Zeus - Zeus への動作 + Interazioni Zeus + Zeusのアクション 제우스 동작 宙斯操作 宙斯操作 @@ -148,7 +148,7 @@ Interacción - Texto al max. Cselekvés - Szöveg max. Interação - Max. de Texto - インタラクション - 文字の色 + インタラクション - 文字の表示色の最大値 상호작용 - 문자색깔 互动—文字颜色最大值 互動 - 文字最大化 @@ -165,7 +165,7 @@ Interacción - Texto al min. Cselekvés - Szöveg min. Interação - Min. de Texto - インタラクション - 文字の背景色 + インタラクション - 文字の表示色の最低値 상호작용 - 문자배경색 互动—文字颜色最小值 互動 - 文字最小化 @@ -182,7 +182,7 @@ Interacción - Sombras al max. Cselekvés - Árnyék max. Interação - Max. de Sombra - インタラクション - 文字への影の色 + インタラクション - 文字の影色の最大値 상호작용 - 문자그림자색 互动—阴影最大值 互動 - 陰影最大化 @@ -199,7 +199,7 @@ Interacción - Sombras al min. Cselekvés - Árnyék min. Interação - Min. de Sombra - インタラクション - 文字への影の最低色 + インタラクション - 文字の影色の最低値 상호작용 - 문자그림자배경색 互动—阴影最小值 互動 - 陰影最小化 @@ -216,7 +216,7 @@ Udržuj kurzor na středu Manter o cursor centralizado Mantieni il cursore centrato - 常にカーソルを中央にする + カーソルを常に中心にする 커서를 항상 가운데에 둡니다 保持光标在中心点 保持游標在中心點 @@ -233,7 +233,7 @@ Mantiene el cursor centrado y despliega los menús alrededor. Útil si el tamaño de la pantalla es limitado. Manter o cursor centralizado e mover o menu de opções. Útil caso o tamanho da tela seja limitado. Mantieni il cursore centrato e sposta il menù intorno. Utile se lo schermo è piccolo. - 常にカーソルを中央へ表示させ、オプション メニューが移動します。画面の大きさが制限されている時に使いやすくなります。 + カーソルを常に中心に表示し、オプション メニューを移動させます。画面の大きさが制限されている時に便利です。 커서를 항상 가운데에 두고 메뉴를 움직입니다. 화면의 크기가 제한되있을 때 유용합니다. 保持光标在中心点并平移周遭的选项菜单。这对在屏幕尺寸有限的玩家很有用! 保持游標在中心點並平移周遭的選項選單。這對在螢幕尺寸有限的玩家很有用! @@ -250,7 +250,7 @@ Execute a ação quando soltar a tecla de menu Cselekvés végrehajtása a menügomb elengedésekor Esegui l'azione quando rilasci il tasto menu - メニュー キーを離した時に動作を実行 + キーを離した時にアクションを実行 메뉴 키를 놓을 때 행동하기 当放开菜单键后就执行动作 當放開選單鍵後就執行動作 @@ -267,7 +267,7 @@ Tamanho do texto de interação Cselekvő szöveg mérete Dimensione del testo d'interazione - インタラクション文字の大きさ + 文字の大きさ 상호작용 - 문자크기 互动菜单文字大小 互動選單文字大小 @@ -284,7 +284,7 @@ Sombra do texto de interação Cselekvő szöveg árnyéka Ombra del testo d'interazione - インタラクション文字へ影 + 文字の影表示 상호작용 - 문자그림자 互动菜单文字阴影 互動選單文字陰影 @@ -301,7 +301,7 @@ Permite controlar a sombra do texto. Contorno ignora sombras com cores customizadas. Hozzáférést biztosít a szöveg árnyékának kezeléséhez. A körvonal nem veszi figyelembe az egyedi árnyékszíneket. Permette di controllare l'ombra del testo. L'impostazione "Contorno" ignora il colore dell'ombra. - 文字への影を設定します。縁取りは設定された影の色を無視します。 + 文字に影を表示します。縁取りは設定された影の色を無視します。 문자의 그림자를 조절하는 것을 가능케 합니다. 외곽선은 임의의 그림자색을 무시합니다. 允许控制文字阴影。轮廓部分则会忽略自定义的阴影颜色。 允許控制文字陰影。輪廓部分則會忽略自定義的陰影顏色 @@ -335,7 +335,7 @@ Cselekvő menü háttere Фон меню взаимодействия Sfondo Menù Interazioni - インタラクション メニューの背景 + メニューの背景 상호작용 메뉴 배경 互动菜单背景 互動選單背景 @@ -352,7 +352,7 @@ A háttér elmosása a cselekvő menü használata alatt. Размыть фон, пока открыто меню взаимодействия. Sfoca lo sfondo mentre il Menù Interazioni è aperto. - インタラクション メニューを開いたとき、背景にボケを与えます。 + インタラクション メニューを開いたときに背景をぼかします。 상호작용 메뉴가 열릴 시 배경을 흐릿하게 처리합니다. 当互动菜单开启时,模糊背景画面。 當互動選單開啟時,模糊背景畫面 @@ -369,7 +369,7 @@ Kép elmosása Размытый Sfoca schermo - ボケ画面 + 背景をぼかす 화면 흐리게 模糊画面 模糊畫面 @@ -386,7 +386,7 @@ Fekete Черный Nero - ブラック + 背景を暗くする 까맣게 黑色 黑色 @@ -403,7 +403,7 @@ Mostrar ações para edifícios Показывать действия для зданий Mostra azioni per edifici - 建物へ動作を表示 + 建物へアクションを表示 건물에 행동을 취함 显示建筑物可用的动作 顯示建築物可用的動作 @@ -419,8 +419,8 @@ Cselekvéseket engedélyez ajtók kinyitására és létrák mászására. (Figyelem: ez teljesítményvesztéssel járhat a menü megnyitásakor, főleg városokban) Adiciona ações de interações para abrir portas e montar escadas em edifícios. (Nota: Existe um custo de performance quando aberto o menu de interação, especialmente em cidades) Добавляет действия открывания дверей и залезания на лестницы для зданий. (Примечание: возможно падение производительности при открытии меню взаимодействия, особенно в городах) - Aggiunge azioni interattive per l'apertura delle porte e piazzamento scale su edifici. (Nota: C'è un costo in performance quando si apre il Menù Interazioni, soprattutto in città) - 建物にある扉の開閉やはしごの昇降といった動作をインタラクションへ追加します。(街などでインタラクション メニューを開くと動作が低下します) + Aggiunge interazioni per l'apertura delle porte e piazzamento di scale su edifici. (Nota: C'è un costo in performance quando si apre il Menù Interazioni, soprattutto in città) + 建物にドアを開閉したり梯子を昇降するためのインタラクション アクションを追加します。\n(注: 街中でインタラクション メニューを開く際には特に描画パフォーマンスに影響を及ぼします) 건물의 문을 열거나 사다리에 오르는 상호작용 행동을 추가합니다. (주의: 상호작용 메뉴를 열 경우 성능하락이 있을 수 있음, 특히 마을 내부에서) 增加互动菜单的功能在可开启的门与建筑物的梯子上。(注意:此功能有可能会降低系统效能,特别是在城镇区更明显) 增加互動選單的功能在可開啟的門與建築物的梯子上。(注意: 此功能有可能會降低系統效能,特別是在城鎮區更明顯) @@ -449,10 +449,10 @@ Скорость анимации меню взаимодействия Velocidade da animação de interação Rychlost animace interakce - Velocità Animazioni Interazioni + Velocità di Animazione delle Interazioni Velocidad de animación del menú de interacción Vitesse de l'animation d'interaction - インタラクションのアニメーション速度 + アニメーション速度 상호작용 움직임 속도 互动菜单动画速度 互動選單動畫速度 @@ -465,10 +465,10 @@ Ускоряет анимацию меню и уменьшает задержку при наведении мыши для раскрытия подменю Faz com que as animações do menu de interação sejam mais rápidas, diminuindo a necessidade de esperar para mostrar as ações Zrychlí animaci menu a sníží tak čas potřebný pro plné zobrazení podmenu - Rende le animazioni Menù più veloci e diminuisce il tempo richiesto per mostrare sotto-azioni + Rende le animazioni del Menù più veloci e diminuisce il tempo richiesto per mostrare sotto-azioni Hace la animación del menú más rápida, reduciendo el tiempo necesario para abrir sub-acciones. Rend les animations du menu plus rapide, et réduit le temps nécessaire à l'affichage des sous menus d'action. - ホバーで子アクションを表示した時に出るメニューのアニメーション速度を早くしたり遅くしたりできます + メニューのアニメーションを高速化し、サブアクションを表示するために必要なホバーにかかる時間を短縮します。 使菜单的动画速度更快,并减少子选项显现出来的时间 使選單的動畫速度更快,並減少子選項顯現出來的時間 상호작용을 표시하기 위해 메뉴 애니메이션을 빠르게 만들고 마우스를 가져오는 데 필요한 시간을 줄입니다. @@ -480,7 +480,7 @@ セレクターの色 菜单颜色 選單的顏色 - Controllo Settore + Colore Selettore Kolor wybierającego Цвет селектора Cor do Seletor @@ -493,24 +493,28 @@ Consolidate single child actions Объединять ед. дочерные действия - サブ動作を統合 + 1個のみの子アクションを統合 Consolidar acciones hijo únicas Combiner les sous-actions uniques Untergeordnete Aktionen zusammenfassen + Combina sotto-azioni singole Połącz akcje podrzędne 整合子操作 하위 동작 통합 + Consolidar sub-ações únicas Combines parent action with only one child action together. Объединять родительское действие с единственным дочерним действием в одно. - メインの動作とサブ動作一つを統合して表示します。 + アクションが1個のみの子アクションを親アクションと結合し表示を整理します。 Combina acciones padre con una única accion hijo de forma conjunta Lorsqu'un menu ne contient qu'une seule sous-action, elle est combinée avec son menu parent. + Combina interazioni con una sola sotto-azione in una singola interazione. Übergeordnete Aktionen mit nur einer Unteraktion zusammenfassen. Gdy menu zawiera tylko jedną akcję podrzędną, łączy ją z akcją nadrzędną. 主操作与子操作集成显示。 대분류로 나뉜 행동을 한눈에 보여줍니다 + Quando um menu contém apenas uma subação, ele é combinado com seu menu pai. diff --git a/addons/interaction/XEH_postInit.sqf b/addons/interaction/XEH_postInit.sqf index 75e92c02c9..f461e2a770 100644 --- a/addons/interaction/XEH_postInit.sqf +++ b/addons/interaction/XEH_postInit.sqf @@ -78,7 +78,7 @@ ACE_Modifier = 0; }] call CBA_fnc_addEventHandler; if (isServer) then { - [QGVAR(replaceTerrainObject), FUNC(replaceTerrainObject)] call CBA_fnc_addEventHandler; + [QGVAR(replaceTerrainObject), LINKFUNC(replaceTerrainObject)] call CBA_fnc_addEventHandler; }; if (!hasInterface) exitWith {}; @@ -136,7 +136,7 @@ GVAR(isOpeningDoor) = false; if !([ACE_player, cursorTarget] call FUNC(canTapShoulder)) exitWith {false}; //Tap whichever shoulder is closest - private _shoulderNum = [0, 1] select (([cursorTarget, ACE_player] call BIS_fnc_relativeDirTo) > 180); + private _shoulderNum = parseNumber (([cursorTarget, ACE_player] call BIS_fnc_relativeDirTo) > 180); // Statement [ACE_player, cursorTarget, _shoulderNum] call FUNC(tapShoulder); @@ -168,7 +168,7 @@ private _action = [ // action display name will be overwritten in modifier function QGVAR(takeWeapon), "take", "\A3\ui_f\data\igui\cfg\actions\take_ca.paa", {_player action ["TakeWeapon", _target, weaponCargo _target select 0]}, - {count weaponCargo _target == 1}, + {(count weaponCargo _target == 1) && {[_player, objNull, []] call EFUNC(common,canInteractWith)}}, // Not checking if container is claimed nil, nil, nil, nil, nil, { params ["_target", "", "", "_actionData"]; diff --git a/addons/interaction/XEH_preInit.sqf b/addons/interaction/XEH_preInit.sqf index 4dd0bb13e6..c5873bcfc9 100644 --- a/addons/interaction/XEH_preInit.sqf +++ b/addons/interaction/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" DFUNC(repair_Statement) = { // moved from config because of build problems TRACE_1("repair_Statement",_this); 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_addPassengerActions.sqf b/addons/interaction/functions/fnc_addPassengerActions.sqf index 112919ee80..9b8981bfd0 100644 --- a/addons/interaction/functions/fnc_addPassengerActions.sqf +++ b/addons/interaction/functions/fnc_addPassengerActions.sqf @@ -20,11 +20,7 @@ params ["", "", "_parameters"]; _parameters params ["_unit"]; -private _namespace = EGVAR(interact_menu,ActNamespace); -private _actionTrees = _namespace getVariable typeOf _unit; -if (isNil "_actionTrees") then { - _actionTrees = []; -}; +private _actionTrees = EGVAR(interact_menu,ActNamespace) getOrDefault [typeOf _unit, []]; private _actions = []; @@ -33,7 +29,6 @@ private _actions = []; _x params ["_actionData", "_children"]; _actions pushBack [_actionData, _children, _unit]; - false -} count (_actionTrees select 0 select 1); +} forEach (_actionTrees select 0 select 1); _actions diff --git a/addons/interaction/functions/fnc_addPassengersActions.sqf b/addons/interaction/functions/fnc_addPassengersActions.sqf index 40ba9672ef..50b0d98a21 100644 --- a/addons/interaction/functions/fnc_addPassengersActions.sqf +++ b/addons/interaction/functions/fnc_addPassengersActions.sqf @@ -43,7 +43,7 @@ private _icon = ""; _actions pushBack [ [ - format ["%1", _unit], + str _unit, [_unit, true] call EFUNC(common,getName), [_icon, "#FFFFFF"], { diff --git a/addons/interaction/functions/fnc_canJoinGroup.sqf b/addons/interaction/functions/fnc_canJoinGroup.sqf index facc3376ee..ec2feb8240 100644 --- a/addons/interaction/functions/fnc_canJoinGroup.sqf +++ b/addons/interaction/functions/fnc_canJoinGroup.sqf @@ -18,7 +18,6 @@ params ["_unit", "_target"]; -alive _target -&& {!(_target getVariable ["ACE_isUnconscious", false])} +_target call EFUNC(common,isAwake) && {side group _unit == side group _target} && {group _unit != group _target} // return diff --git a/addons/interaction/functions/fnc_canJoinTeam.sqf b/addons/interaction/functions/fnc_canJoinTeam.sqf index 09d0281dca..e0e3684ce9 100644 --- a/addons/interaction/functions/fnc_canJoinTeam.sqf +++ b/addons/interaction/functions/fnc_canJoinTeam.sqf @@ -18,7 +18,6 @@ params ["_unit", "_target"]; -alive _target -&& {!(_target getVariable ["ACE_isUnconscious", false])} +_target call EFUNC(common,isAwake) && {!([_target] call EFUNC(common,isPlayer))} && {_target in units group _unit} diff --git a/addons/interaction/functions/fnc_canPassMagazine.sqf b/addons/interaction/functions/fnc_canPassMagazine.sqf index 9d0bed083d..97478bffa7 100644 --- a/addons/interaction/functions/fnc_canPassMagazine.sqf +++ b/addons/interaction/functions/fnc_canPassMagazine.sqf @@ -19,7 +19,7 @@ params ["_player", "_target", "_weapon"]; if (!GVAR(enableMagazinePassing)) exitWith {false}; -if (_weapon isEqualTo "") exitWith {false}; +if (_weapon isEqualTo "" || {!(_target call EFUNC(common,isAwake))}) exitWith {false}; if (((vehicle _target) != _target) && {(vehicle _target) != (vehicle _player)}) exitWith {false}; private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines; diff --git a/addons/interaction/functions/fnc_canPullOutBody.sqf b/addons/interaction/functions/fnc_canPullOutBody.sqf index 167d09ecdb..2676bfc203 100644 --- a/addons/interaction/functions/fnc_canPullOutBody.sqf +++ b/addons/interaction/functions/fnc_canPullOutBody.sqf @@ -19,7 +19,7 @@ params ["_body", "_unit"]; // Defer to ACE Medical's unload patient if present -if (["ace_medical"] call EFUNC(common,isModLoaded)) exitWith {false}; +if (GETEGVAR(medical,enabled,false)) exitWith {false}; private _vehicle = objectParent _body; diff --git a/addons/interaction/functions/fnc_canPush.sqf b/addons/interaction/functions/fnc_canPush.sqf index 28197d12cd..ff339d5952 100644 --- a/addons/interaction/functions/fnc_canPush.sqf +++ b/addons/interaction/functions/fnc_canPush.sqf @@ -10,7 +10,7 @@ * Can Push * * Example: - * [target] call ace_interaction_fnc_canPush + * cursorObject call ace_interaction_fnc_canPush * * Public: No */ @@ -19,4 +19,5 @@ params ["_target"]; alive _target && {getMass _target <= 2600 || getNumber (configOf _target >> QGVAR(canPush)) == 1} && -{vectorMagnitude velocity _target < 3} +{vectorMagnitude velocity _target < 3} && +{isNull isVehicleCargo _target} // Check if vehicle is loaded as ViV cargo diff --git a/addons/interaction/functions/fnc_canTapShoulder.sqf b/addons/interaction/functions/fnc_canTapShoulder.sqf index 049c178152..51f271fb4c 100644 --- a/addons/interaction/functions/fnc_canTapShoulder.sqf +++ b/addons/interaction/functions/fnc_canTapShoulder.sqf @@ -19,6 +19,5 @@ params ["_unit", "_target"]; _target isKindOf "CAManBase" && -{alive _target} && -{_unit distance _target < 4} && -{!(_target getVariable ["ACE_isUnconscious", false])} // return +{_target call EFUNC(common,isAwake)} && +{_unit distance _target < 4} // return 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_getDown.sqf b/addons/interaction/functions/fnc_getDown.sqf index b8f6d7c50d..531cd23c54 100644 --- a/addons/interaction/functions/fnc_getDown.sqf +++ b/addons/interaction/functions/fnc_getDown.sqf @@ -22,11 +22,10 @@ params ["_unit", "_target"]; [_unit, "GestureGo"] call EFUNC(common,doGesture); -private _chance = [0.5, 0.8] select (count weapons _unit > 0); +private _chance = [0.5, 0.8] select (weapons _unit isNotEqualTo []); { - if (count weapons _x == 0 && {random 1 < _chance}) then { + if (weapons _x isEqualTo [] && {random 1 < _chance}) then { [QGVAR(getDown), [_x], [_x]] call CBA_fnc_targetEvent; }; - false -} count (_target nearEntities ["Civilian", SEND_RADIUS]); +} forEach (_target nearEntities ["Civilian", SEND_RADIUS]); 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_openDoor.sqf b/addons/interaction/functions/fnc_openDoor.sqf index a03ca26c04..11b9c67c91 100644 --- a/addons/interaction/functions/fnc_openDoor.sqf +++ b/addons/interaction/functions/fnc_openDoor.sqf @@ -35,12 +35,12 @@ if (_animations isEqualTo []) exitWith {}; private _lockedVariable = format ["bis_disabled_%1", _door]; private _lockedVariableAlt = _lockedVariable; // GM Buildings may have door names like door_01 but locking expects door_1 -if ((count _door == 7) && {(_door select [0, 6]) == "door_0"}) then { +if ((count _door == 7) && {(_door select [0, 6]) == "door_0"}) then { _lockedVariableAlt = format ["bis_disabled_door_%1", _door select [6, 1]]; // stip off the leading zero then check both vars }; // Check if the door can be locked aka have locked variable, otherwhise cant lock it -if ((_house animationPhase (_animations select 0) <= 0) && +if ((_house animationPhase (_animations select 0) <= 0) && {(_house getVariable [_lockedVariable, 0] == 1) || {_house getVariable [_lockedVariableAlt, 0] == 1}}) exitWith { private _lockedAnimation = format ["%1_locked_source", _door]; TRACE_3("locked",_house,_lockedAnimation,isClass (configOf _house >> "AnimationSources" >> _lockedAnimation)); @@ -63,18 +63,24 @@ GVAR(doorTargetPhase) = _house animationPhase (_animations select 0); GVAR(isOpeningDoor) = true; GVAR(usedScrollWheel) = false; +// Raise local started opening event +[QGVAR(doorOpeningStarted), [_house, _door, _animations]] call CBA_fnc_localEvent; + [{ - (_this select 0) params ["_house", "_animations", "_position", "_time", "_frame"]; + (_this select 0) params ["_house", "_animations", "_position", "_time", "_frame", "_door"]; if !(GVAR(isOpeningDoor)) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; // didn't use incremental opening. Just do animation normally. if !(GVAR(usedScrollWheel)) then { - private _phase = [0, 1] select (_house animationPhase (_animations select 0) < 0.5); + private _phase = parseNumber (_house animationPhase (_animations select 0) < 0.5); - {_house animate [_x, _phase]; false} count _animations; + {_house animate [_x, _phase]} forEach _animations; }; + + // Raise local stopped opening event + [QGVAR(doorOpeningStopped), [_house, _door, _animations]] call CBA_fnc_localEvent; }; // check if player moved too far away @@ -87,5 +93,5 @@ GVAR(usedScrollWheel) = false; GVAR(usedScrollWheel) = true; }; // do incremental door opening - {_house animate [_x, GVAR(doorTargetPhase)]; false} count _animations; -}, 0.1, [_house, _animations, getPosASL ACE_player, CBA_missionTime + 0.2, diag_frameno + 2]] call CBA_fnc_addPerFrameHandler; + {_house animate [_x, GVAR(doorTargetPhase)]} forEach _animations; +}, 0.1, [_house, _animations, getPosASL ACE_player, CBA_missionTime + 0.2, diag_frameno + 2, _door]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/interaction/functions/fnc_passMagazine.sqf b/addons/interaction/functions/fnc_passMagazine.sqf index 09513b4762..8750078502 100644 --- a/addons/interaction/functions/fnc_passMagazine.sqf +++ b/addons/interaction/functions/fnc_passMagazine.sqf @@ -7,6 +7,7 @@ * 0: Unit that passes the magazine * 1: Unit to pass the magazine to * 2: Weapon classname + * 3: Play passing animation (default: true) * * Return Value: * None @@ -16,7 +17,7 @@ * * Public: No */ -params ["_player", "_target", "_weapon"]; +params ["_player", "_target", "_weapon", ["_animate", true, [true]]]; private _compatibleMags = [_weapon] call CBA_fnc_compatibleMagazines; private _filteredMags = magazinesAmmoFull _player select { @@ -35,18 +36,12 @@ private _magToPassIndex = 0; }; } foreach _filteredMags; -//remove all magazines and add them again, except the one to be passed -//needed because of missing commands, see http://feedback.arma3.com/view.php?id=12782 +//remove the magazine from _player and add it to _target _magToPass params ["_magToPassClassName", "_magToPassAmmoCount"]; -_player removeMagazines _magToPassClassName; -{ - _x params ["_className", "_ammoCount"]; - if ((_className == _magToPassClassName) && (_forEachIndex != _magToPassIndex)) then { - _player addMagazine [_className, _ammoCount]; - }; -} foreach _filteredMags; +// Exit if failed to remove specific magazine +if !([_player, _magToPassClassName, _magToPassAmmoCount] call EFUNC(common,removeSpecificMagazine)) exitWith {}; -[_player, "PutDown"] call EFUNC(common,doGesture); +if (_animate) then {[_player, "PutDown"] call EFUNC(common,doGesture)}; _target addMagazine [_magToPassClassName, _magToPassAmmoCount]; diff --git a/addons/interaction/functions/fnc_sendAway.sqf b/addons/interaction/functions/fnc_sendAway.sqf index cef314756f..b986ea2661 100644 --- a/addons/interaction/functions/fnc_sendAway.sqf +++ b/addons/interaction/functions/fnc_sendAway.sqf @@ -22,14 +22,13 @@ params ["_unit"]; [_unit, "GestureGo"] call EFUNC(common,doGesture); -private _chance = [0.5, 0.8] select (count weapons _unit > 0); +private _chance = [0.5, 0.8] select (weapons _unit isNotEqualTo []); { - if (count weapons _x == 0 && {random 1 < _chance}) then { + if (weapons _x isEqualTo [] && {random 1 < _chance}) then { private _position = getPosASL _unit vectorAdd (eyeDirection _unit vectorMultiply SEND_DISTANCE); _position set [2, 0]; [QGVAR(sendAway), [_x, _position], [_x]] call CBA_fnc_targetEvent; }; - false -} count (_unit nearEntities ["Civilian", SEND_RADIUS]); +} forEach (_unit nearEntities ["Civilian", SEND_RADIUS]); 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/interaction/initSettings.sqf b/addons/interaction/initSettings.inc.sqf similarity index 97% rename from addons/interaction/initSettings.sqf rename to addons/interaction/initSettings.inc.sqf index b502ed36b0..2cefb162a7 100644 --- a/addons/interaction/initSettings.sqf +++ b/addons/interaction/initSettings.inc.sqf @@ -20,7 +20,7 @@ false, true, {[QGVAR(disableNegativeRating), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ diff --git a/addons/interaction/stringtable.xml b/addons/interaction/stringtable.xml index 07b29373a9..38c86f5f99 100644 --- a/addons/interaction/stringtable.xml +++ b/addons/interaction/stringtable.xml @@ -163,7 +163,7 @@ Меню взаимодействия Cselekvő menü Menu de Interação - Menù interazione + Menù Interazioni インタラクション メニュー 상호작용 메뉴 互动菜单 @@ -180,7 +180,7 @@ Меню взаимодействия (с собой) Cselekvő menü (saját) Menu de Interação (Individual) - Menù interazione (individuale) + Menù Interazioni (su se stesso) インタラクション メニュー (セルフ) 상호작용 메뉴(자신) 互动菜单(自我) @@ -215,7 +215,7 @@ Ajtó bezárása Zablokuj drzwi Zamknout dveře - ドアの鍵をしめる + ドアを施錠 문 잠그기 锁门 鎖門 @@ -232,7 +232,7 @@ Zár kinyitása Odblokuj drzwi Odemknout dveře - ドアの鍵をあける + ドアを解錠 잠긴 문 열기 解锁门 解鎖門 @@ -249,7 +249,7 @@ Zárt ajtó Zablokowano drzwi Zamčené dveře - ドアの鍵をしめました + ドアを施錠しました 잠긴 문 门已上锁 門已上鎖 @@ -266,7 +266,7 @@ Nyitott ajtó Odblokowano drzwi Odemčené dveře - ドアの鍵をあけました + ドアを解錠しました 열린 문 门未上锁 門未上鎖 @@ -327,34 +327,40 @@ Rename Group グループ名変更 Renommer le groupe + Rinomina il gruppo Переименовать группу Gruppe umbenennen Zmień nazwę grupy 小队重命名 그룹 명칭 다시 짓기 Renombrar grupo + Renomear Grupo This group name is already in use. このグループ名は既に使われています。 Ce nom de groupe est déjà attribué. + C'è già un gruppo con questo nome. Данное имя группы уже используется. Dieser Gruppenname ist bereits in Verwendung. Ta nazwa grupy jest już w użyciu. 该小队名称已被使用 그 명칭은 이미 사용 중 입니다. Este nombre de grupo ya está siendo usado. + Este nome de grupo já está em uso. NEW GROUP NAME: 新しいグループ名: NOUVEAU NOM DE GROUPE : + NUOVO NOME GRUPPO: НОВОЕ ИМЯ ГРУППЫ NEUER GRUPPENNAME: NOWA NAZWA GRUPY: 新的小队名: 새 그룹 명칭: NUEVO NOMBRE DE GRUPO: + NOVO NOME DE GRUPO: DANCE! @@ -452,7 +458,7 @@ Вас похлопали по ПРАВОМУ плечу Você foi tocado no ombro Ti è stato dato un colpetto sulla spalla destra - 右肩を叩かれました + 右肩を叩かれた 누군가 오른쪽 어깨를 쳤다 你的右肩膀被轻拍了一下 你的右肩膀被輕拍了一下 @@ -469,7 +475,7 @@ Вас похлопали по ЛЕВОМУ плечу Você foi tocado no ombro. Ti è stato dato un colpetto sulla spalla sinistra - 左肩を叩かれました + 左肩を叩かれた 누군가 왼쪽 어깨를 쳤다 你的左肩膀被轻拍了一下 你的左肩膀被輕拍了一下 @@ -655,7 +661,7 @@ Назначить в Красную группу Assigner à rouge Assegna al team rosso - レッドにする + レッドに割り当て 빨강에 등록 指派为红组 指派為紅組 @@ -672,7 +678,7 @@ Назначить в Зеленую группу Assigner à vert Assegna al team verde - グリーンにする + グリーンに割り当て 초록에 등록 指派为绿组 指派為綠組 @@ -689,7 +695,7 @@ Назначить в Синюю группу Assigner à bleu Assegna al team blu - ブルーにする + ブルーに割り当て 파랑에 등록 指派为蓝组 指派為藍組 @@ -706,7 +712,7 @@ Назначить в Желтую группу Assigner à jaune Assegna al team giallo - イエローにする + イエローに割り当て 노랑에 등록 指派为黄组 指派為黃組 @@ -842,7 +848,7 @@ Perdão Perdona Megbocsátás - 許す + 赦免する 허용 原谅 原諒 @@ -873,7 +879,7 @@ Tecla modificadora Клавиша-модификатор Tecla Modificadora - Tasto modifica + Tasto modificatore Módosító billentyű Modifikátor キーを割り当て @@ -892,7 +898,7 @@ Hatótávolságon kívül Poza zasięgiem Mimo dosah - Fuori limite + Fuori portata 範囲内にありません 범위 내에 없습니다 不在范围内 @@ -940,7 +946,7 @@ ひっくり返す 翻动 - Gira + Capovolgi Przewróć Virar Tourner @@ -958,7 +964,7 @@ Interakcja Interactuar Cselekvés - Interagire + Interagisci Interagir インタラクト 상호작용 @@ -1027,7 +1033,7 @@ Activer la gestion d'équipe Csapatkezelés engedélyezése Habilitar gestão de equipes - Abilità Management Squadra + Abilita Gestione Squadra チーム管理の有効化 팀 설정 활성화 启用小队管理 @@ -1044,8 +1050,8 @@ Permet aux joueurs d'utiliser la gestion d'équipe. Valeur par défaut : activé. A játékosoknak engedélyezve legyen a csapatkezelő menü? Alapértelmezett: Igen Devem os jogadores ter permissão de usar o menu de gestão de equipes? Padrão: Sim - Possono i giocatori usare il Menù Managment Squadra? Default: Si - プレイヤーがチーム管理メニューを使えるかどうかを設定します。標準: 有効化 + I giocatori possono usare il Menù di Gestione Squadra? Predefinito: Si + プレイヤーがチーム管理メニューを使えるかどうかを設定します。 デフォルト: 有効化 플레이어들이 팀 설정하는 것을 허락합니까? 기본설정: 예 允许玩家使用小队管理菜单? 预设:是 允許玩家使用小隊管理選單? 預設: 是 @@ -1055,7 +1061,7 @@ Disable negative rating Negative Bewertung deaktivieren 否定評価を無効化 - Disabilita valutazione negativa + Impedisci Valutazione Negativa 關閉負面評價 关闭负面评价 부정행위 가중치 사용 안함 @@ -1070,7 +1076,7 @@ Should players receive negative rating? When enabled players are only receiving positive ratings which prevents friendly AI fire when destroying friendly equipment or killing team members. Sollen Spieler negative Bewertungen erhalten dürfen? Wenn diese Option aktiviert ist, erhalten Spieler nur positive Bewertungen, was Freundbeschuss durch KI verhindert, wenn befreundete Ausrüstung zerstört oder befreundete Einheiten von Spielern des selben Teams getötet werden. 否定評価を受けますか?有効化した場合プレイヤーは肯定評価のみを受け、友軍の装備を壊したり殺害をしてもAIからの攻撃を防ぎます。 - I giocatori dovrebbero ricevere delle valutazioni negative ? Quando è abilitato i giocatori ricevono esclusivamente valutazioni positive che prevengono il fuoco delle AI alleate quando distruggono equipaggiamenti o uccidono membri della squadra. + I giocatori possono ricevere valutazioni negative? Se abilitato i giocatori riceveranno esclusivamente valutazioni positive, impedendo l'ingaggio da parte di IA alleate quando distruggono equipaggiamenti o uccidono alleati/civili. 玩家是否會收到負面評價? 當本功能開啟時玩家只會接收到正面評價,所以當玩家做出擊殺友軍AI、毀壞友軍裝備或殺害小隊夥伴都不會收到負面評價 玩家是否会收到负面评价? 当本功能开启时玩家只会接收到正面评价,所以当玩家做出击杀友军 AI、毁坏友军装备或杀害小队伙伴都不会收到负面评价。 플레이어의 부정행위 가중치를 계산합니까? 활성화된 플레이어는 낮은 부정행위 가중치를 가질 때, 아군의 장비나 병력을 사격해도 아군 AI의 사격을 받지 않습니다. @@ -1091,7 +1097,7 @@ A csapatkezelés engedélyezi a tagok színének meghatározását, a vezetés átvételét, és csapatoknál be-és kilépést. O módulo de gestão de equipe é composto por: a atribuição de cores para os membros da equipe, comando das equipes, juntando-se / deixando equipes. Управление группами позволяет назначать цвета членам групп, брать командование, вступать в группы или покидать их. - Management Squadra permette l'assegnazione di colori per membri della squadra, prendere il comando ed entrare/uscire dalle squadre. + Gestione Squadra permette l'assegnazione di colori per membri della squadra, prendere il comando ed entrare/uscire dalle squadre. チーム管理はチーム メンバーへ色の割り当てや指揮権を取ったり、チームの出入りを許可します。 팀 설정은 팀 멤버에게 색을 부여하거나 팀에 참여 혹은 나가게 할 수 있게 합니다. 队伍管理系统允许将指定颜色分配到队伍成员上,接管队长职位或加入/离开队伍 @@ -1184,10 +1190,10 @@ %1 передал вам магазин %2. %1 passou a você um carregador %2. %1 ti podal zásobník %2. - %1 ti ha passato un caricatore %2 . + %1 ti ha passato un caricatore %2. %1 te pasó un cargador %2. %1 vous a passé un chargeur de %2. - %1 はあなたに %2 弾倉を渡した + %1 は あなたに弾倉 %2 を渡した。 %1에게서 %2탄창을 받았다 %1给你%2弹匣 %1給你%2彈匣 @@ -1199,7 +1205,7 @@ Показывать действие "передать магазин" Mostrar a interação "Passar carregador" Zobrazit "interakci "podat zásobník" - Mostra interazione "passa caricatore" + Mostra l'interazione "passa caricatore" Mostrar "Pasar cargador" en el menú de interacción Montrer l'interaction "Passer un chargeur" "弾倉を渡す"をインタラクションに表示 @@ -1248,8 +1254,10 @@ Fixer %1 Przyczep %1 Befestige %1 + Attacca %1 附加 %1 %1 붙이기 + Fixar %1 Detach %1 @@ -1259,8 +1267,10 @@ Retirer %1 Odczep %1 Löse %1 + Stacca %1 拆卸 %1 %1 떼내기 + Desfixar %1 Enables attach/detach weapon attachment actions for current weapon. @@ -1268,10 +1278,12 @@ インタラクションから使用中の武器に対してのアタッチメント取り外しを可能にします。 Activar acciones de acoplar/desacoplar accesorios para el arma actual. Cette option permet de fixer/retirer des accessoires d'arme à partir du menu d'interaction personnel. + Abilita le interazioni di attacco/stacco degli accessori sull'arma usata. Włącza akcje przyczepienia/odczepienia dodatków dla obecnej broni Aktiviert das Befestigen/Lösen von Waffenausätzen an der aktuellen Waffe. 启用当前武器的附加/拆卸武器配件的动作。 현재 사용하고 있는 무기에서 부착물을 붙이거나 떼냅니다. + Ativa as ações de fixar/desfixar acessórios para a arma atual. Allow group rename @@ -1279,10 +1291,12 @@ Permettre le renommage de groupe Разрешить переименование группы Erlaube das Umbenennen der Gruppe + Permetti la rinomina del gruppo Zezwól na zmianę nazwy grupy 允许小队重命名 그룹 이름 재설정 허가 Permitir renombrar grupo + Permitir renomear grupo Allows a group leader to rename their group if the name is not already taken. @@ -1290,10 +1304,12 @@ Cette option permet aux chefs de groupe de modifier le nom de leur groupe. Разрешить лидеру группы её переименование, если имя не занято. Erlaube Gruppenführer das Umbenennen Ihrer Gruppe, wenn der Name nicht bereits vergeben ist. + Permetti ad un capogruppo di rinominare il proprio gruppo se quel nome non è già assegnato. Pozwala liderowi grupy na zmianę jej nazwy, jeżeli ta nazwa nie jest już w użyciu. 允许队长在队名未被占用的情况下重命名。 그룹 리더가 그룹 이름을 재설정하는 것을 허가합니다. Permite al lider de un grupo renombrar a su grupo si el nombre no está siendo actualmente usado. + Permite que o líder renomeie seu grupo se o nome não estiver sendo usado. Warning: can cause some objects to collide with others. @@ -1301,10 +1317,12 @@ Attention : certains objets peuvent entrer en collision avec d'autres. 警告: 一部のオブジェクトが干渉する可能性があります。 Achtung: einige Objekte könnten mit anderen Kollidieren. + Attenzione: può causare collisioni tra oggetti. Uwaga: niektóre obiekty mogą kolidować z innymi. 警告:会导致一些物体与其他物体发生碰撞。 주의: 물체끼리 충돌하는 현상이 있을 수 있음. Advertencia: puede provocar que algunos objetos choquen con otros. + Aviso: pode causar que alguns objetos colidam com outros. diff --git a/addons/inventory/CfgEventHandlers.hpp b/addons/inventory/CfgEventHandlers.hpp index 5b92811746..f95adcb029 100644 --- a/addons/inventory/CfgEventHandlers.hpp +++ b/addons/inventory/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); @@ -20,5 +19,12 @@ class Extended_PostInit_EventHandlers { class Extended_DisplayLoad_EventHandlers { class RscDisplayInventory { ADDON = QUOTE(_this call FUNC(inventoryDisplayLoad)); + GVAR(displayNameWeight) = QUOTE(_this call FUNC(displayNameWeight)); // separate to allow other mods to disable them individually + }; +}; + +class Extended_DisplayUnload_EventHandlers { + class RscDisplayInventory { + ADDON = QUOTE(GVAR(unit) = ACE_player); }; }; diff --git a/addons/inventory/RscDisplayInventory.hpp b/addons/inventory/RscDisplayInventory.hpp index 3149000777..91e68f5fb1 100644 --- a/addons/inventory/RscDisplayInventory.hpp +++ b/addons/inventory/RscDisplayInventory.hpp @@ -27,26 +27,26 @@ class RscCombo; #define W_MAKEITBIGGA(num) (num * (safeZoneH / 40)) #define H_MAKEITBIGGA(num) (num * (safeZoneH / 30)) -#define X_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QUOTE(QGVAR(inventoryDisplaySize)),0)]),X_BIS(num),X_MAKEITBIGGA(num))]) -#define Y_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QUOTE(QGVAR(inventoryDisplaySize)),0)]),Y_BIS(num),Y_MAKEITBIGGA(num))]) -#define W_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QUOTE(QGVAR(inventoryDisplaySize)),0)]),W_BIS(num),W_MAKEITBIGGA(num))]) -#define H_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QUOTE(QGVAR(inventoryDisplaySize)),0)]),H_BIS(num),H_MAKEITBIGGA(num))]) +#define X_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QQGVAR(inventoryDisplaySize),0)]),X_BIS(num),X_MAKEITBIGGA(num))]) +#define Y_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QQGVAR(inventoryDisplaySize),0)]),Y_BIS(num),Y_MAKEITBIGGA(num))]) +#define W_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QQGVAR(inventoryDisplaySize),0)]),W_BIS(num),W_MAKEITBIGGA(num))]) +#define H_PART(num) QUOTE(linearConversion [ARR_5(0,2,(missionNamespace getVariable [ARR_2(QQGVAR(inventoryDisplaySize),0)]),H_BIS(num),H_MAKEITBIGGA(num))]) class RscDisplayInventory { class controls { class CA_ContainerBackground: RscText { - //crate: GroundLoad adjust size + // Crate: GroundLoad adjust size x = X_PART(1); y = Y_PART(1); w = W_PART(12); - h = H_PART(22.5); //default 23 + h = H_PART(22.5); // default 23 }; class CA_PlayerBackground: RscText { - //center player's container: decrease height because of progressbar height decrease + // Center player's container: Decrease height because of progressbar height decrease x = X_PART(14.6); y = Y_PART(2); w = W_PART(24.4); - h = H_PART(21.5); //default 22 + h = H_PART(21.5); // default 22 }; class TitleBackground: RscText { x = X_PART(14.6); @@ -98,7 +98,7 @@ class RscDisplayInventory { }; class BackgroundSlotPrimaryFlashlight: BackgroundSlotPrimary { x = X_PART(30.6); - y = Y_PART(9.2); //not sure why different (double check release) + y = Y_PART(9.2); // not sure why different (double check release) w = W_PART(1.9); h = H_PART(2); }; @@ -283,11 +283,11 @@ class RscDisplayInventory { h = H_PART(1); }; class GroundLoad: RscProgress { - //crate: GroundLoad adjust size + // Crate: GroundLoad adjust size x = X_PART(1.5); y = Y_PART(22.5); w = W_PART(11); - h = H_PART(0.5); //Default 1 + h = H_PART(0.5); // Default 1 }; class SlotPrimary: GroundTab { x = X_PART(26.6); @@ -345,7 +345,7 @@ class RscDisplayInventory { }; class SlotSecondaryUnderBarrel: SlotPrimary { x = X_PART(29); - y = Y_PART(14.59); //Why is this different? (check release) + y = Y_PART(14.59); // Why is this different? (check release) w = W_PART(2.3); h = H_PART(2); }; @@ -518,11 +518,11 @@ class RscDisplayInventory { h = H_PART(0.5); }; class TotalLoad: GroundLoad { - //center: progressbar height decrease + // Center: progressbar height decrease x = X_PART(15.1); y = Y_PART(22.5); w = W_PART(23.4); - h = H_PART(0.5); //Default 1 + h = H_PART(0.5); // default 1 }; class ContainerMarker: GroundTab { x = X_PART(0); diff --git a/addons/inventory/XEH_PREP.hpp b/addons/inventory/XEH_PREP.hpp index 7c58268e23..824ebf63d7 100644 --- a/addons/inventory/XEH_PREP.hpp +++ b/addons/inventory/XEH_PREP.hpp @@ -1,10 +1,6 @@ - PREP(addCustomFilter); PREP(currentItemListBox); -PREP(forceItemListUpdate); -PREP(inventoryDisplayLoad); -PREP(onLBSelChanged); - +PREP(displayNameWeight); PREP(filterWeapons); PREP(filterMagazines); PREP(filterItems); @@ -14,3 +10,6 @@ PREP(filterVests); PREP(filterBackpacks); PREP(filterGrenades); PREP(filterMedical); +PREP(forceItemListUpdate); +PREP(inventoryDisplayLoad); +PREP(onLBSelChanged); diff --git a/addons/inventory/XEH_postInit.sqf b/addons/inventory/XEH_postInit.sqf index c5dc6c48f6..a670a7bfd5 100644 --- a/addons/inventory/XEH_postInit.sqf +++ b/addons/inventory/XEH_postInit.sqf @@ -2,40 +2,39 @@ if (!hasInterface) exitWith {}; -// cache config -// items in the inventory display can only be distinguished by their lb names and pictures -// this can cause collisions (mainly weapons with attachments), -// but if the item has the same name and picture it at least shouldn't change the filter anyway -// luckily we don't need private items, so dummy and parent classes are out of the picture +// If medical_treatment is loaded, get its items +if (["ace_medical_treatment"] call EFUNC(common,isModLoaded)) then { + private _medicalList = +(uiNamespace getVariable [QGVAR(medicalItemList), createHashMap]); -GVAR(ItemKeyNamespace) = [] call CBA_fnc_createNamespace; -private _allItems = uiNamespace getVariable [QGVAR(ItemKeyCache), []]; //See XEH_preStart.sqf + _medicalList merge [uiNamespace getVariable [QEGVAR(medical_treatment,treatmentItems), createHashMap], true]; -// isEqualType is hacking protection as we cannot trust that the cache hasn't been manipulated -{ - if (_x isEqualType [] && {_x isEqualTypeArray ["", configNull]}) then { - GVAR(ItemKeyNamespace) setVariable _x; - }; -} forEach ([[], _allItems] select (_allItems isEqualType [])); + GVAR(medicalItemList) = compileFinal _medicalList; +} else { + GVAR(medicalItemList) = uiNamespace getVariable [QGVAR(medicalItemList), compileFinal createHashMap]; +}; GVAR(customFilters) = []; GVAR(selectedFilterIndex) = -1; -// add custom filters +// Add custom filters +[LLSTRING(Grenades), QFUNC(filterGrenades)] call FUNC(addCustomFilter); +[LLSTRING(Backpacks), QFUNC(filterBackpacks)] call FUNC(addCustomFilter); +[LLSTRING(Uniforms), QFUNC(filterUniforms)] call FUNC(addCustomFilter); +[LLSTRING(Vests), QFUNC(filterVests)] call FUNC(addCustomFilter); +[LLSTRING(Headgear), QFUNC(filterHeadgear)] call FUNC(addCustomFilter); +[LLSTRING(Medical), QFUNC(filterMedical)] call FUNC(addCustomFilter); -// get list of grenades -GVAR(Grenades_ItemList) = uiNamespace getVariable [QGVAR(Grenades_ItemList), []]; -if (!(GVAR(Grenades_ItemList) isEqualType [])) then {GVAR(Grenades_ItemList) = []}; +// Used for displaying the correct name when opening a subordinate's inventory +GVAR(unit) = ACE_player; -[localize LSTRING(Grenades), QFUNC(filterGrenades)] call FUNC(addCustomFilter); +["CAManBase", "InventoryOpened", { + params ["_unit", "_container"]; -[localize LSTRING(Backpacks), QFUNC(filterBackpacks)] call FUNC(addCustomFilter); -[localize LSTRING(Uniforms), QFUNC(filterUniforms)] call FUNC(addCustomFilter); -[localize LSTRING(Vests), QFUNC(filterVests)] call FUNC(addCustomFilter); -[localize LSTRING(Headgear), QFUNC(filterHeadgear)] call FUNC(addCustomFilter); + // GVAR(unit) is ACE_player by default + if (_unit isEqualTo ACE_player) exitWith {}; -// get list of medical items -GVAR(Medical_ItemList) = uiNamespace getVariable [QGVAR(Medical_ItemList), []]; -if (!(GVAR(Medical_ItemList) isEqualType [])) then {GVAR(Medical_ItemList) = []}; - -[localize LSTRING(Medical), QFUNC(filterMedical)] call FUNC(addCustomFilter); + // If the player is a group leader and opens a subordinate's inventory or has a subordinate open the player's backpack, update name to correct unit + if (leader ACE_player == ACE_player && {(_unit in units ACE_player) || {(objectParent _container) isEqualTo ACE_player}}) then { + GVAR(unit) = _unit; + }; +}] call CBA_fnc_addClassEventHandler; diff --git a/addons/inventory/XEH_preInit.sqf b/addons/inventory/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/inventory/XEH_preInit.sqf +++ b/addons/inventory/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/inventory/XEH_preStart.sqf b/addons/inventory/XEH_preStart.sqf index 18999d638e..a9a634ab5a 100644 --- a/addons/inventory/XEH_preStart.sqf +++ b/addons/inventory/XEH_preStart.sqf @@ -2,52 +2,49 @@ #include "XEH_PREP.hpp" -//item cache, see XEH_postInit.sqf +// Cache config +// Items in the inventory display can all use lb data to get their classname (exception: backpacks, handled separately) private _allItems = ("getNumber (_x >> 'scope') > 0" configClasses (configFile >> "CfgWeapons")); _allItems append ("getNumber (_x >> 'scope') > 0" configClasses (configFile >> "CfgGlasses")); -_allItems append ("getNumber (_x >> 'scope') == 2" configClasses (configFile >> "CfgMagazines")); -_allItems append ("getNumber (_x >> 'scope') > 0 && {getNumber (_x >> 'isBackpack') == 1}" configClasses (configFile >> "CfgVehicles")); +_allItems append ("getNumber (_x >> 'scope') > 0" configClasses (configFile >> "CfgMagazines")); -uiNamespace setVariable [QGVAR(ItemKeyCache), _allItems apply { +uiNamespace setVariable [QGVAR(itemKeyCache), compileFinal ((_allItems apply {configName _x}) createHashMapFromArray _allItems)]; + +// Backpacks in the inventory display can only be distinguished by their lb names and pictures, lb data returns "" +_allItems = "getNumber (_x >> 'scope') > 0 && {getNumber (_x >> 'isBackpack') == 1}" configClasses (configFile >> "CfgVehicles"); + +uiNamespace setVariable [QGVAR(backpackKeyCache), compileFinal createHashMapFromArray (_allItems apply { private _displayName = getText (_x >> "displayName"); private _picture = getText (_x >> "picture"); - // list box seems to delete the leading backslash - if (_picture select [0,1] == "\") then { + // List box seems to delete the leading backslash + if (_picture select [0, 1] == "\") then { _picture = _picture select [1]; }; - [format ["%1:%2", _displayName, _picture], _x]; -}]; + // Handle missing file extension, as inventory returns path with extension + if (count _picture > 0 && !(_picture regexMatch ".*?\.paa")) then { + if (!fileExists (_picture + ".paa")) exitWith {}; + _picture = _picture + ".paa"; + }; -// generate list of grenades -private _grenades_ItemList = []; + // Listboxes store pictures as lowercase + [format ["%1:%2", _displayName, toLowerANSI _picture], _x] +})]; + +// Generate list of grenades +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; +private _grenadeList = createHashMap; { - _grenades_ItemList append getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"); -} forEach getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); + _grenadeList insert [true, (getArray (_cfgThrow >> _x >> "magazines")) apply {_x call EFUNC(common,getConfigName)}, []]; +} forEach getArray (_cfgThrow >> "muzzles"); -// make list case insensitive -_grenades_ItemList = _grenades_ItemList apply {toLower _x}; +uiNamespace setVariable [QGVAR(grenadesItemList), compileFinal _grenadeList]; -// filter duplicates -_grenades_ItemList = _grenades_ItemList arrayIntersect _grenades_ItemList; +// Generate list of medical items +private _medicalList = QUOTE(getNumber (_x >> 'scope') > 0 && {getNumber (_x >> 'ItemInfo' >> 'type') in [ARR_2(TYPE_FIRST_AID_KIT,TYPE_MEDIKIT)]}) configClasses (configFile >> "CfgWeapons"); -uiNamespace setVariable [QGVAR(Grenades_ItemList), _grenades_ItemList]; +_medicalList = _medicalList apply {configName _x}; -// generate list of medical items -private _medical_ItemList = ["FirstAidKit", "Medikit"]; -{ - _medical_ItemList append getArray (_x >> "items"); -} forEach ("true" configClasses (configFile >> QEGVAR(medical_treatment,Actions))); - -// remove all numbers from list -_medical_ItemList = _medical_ItemList select {_x isEqualType ""}; - -// make list case insensitive -_medical_ItemList = _medical_ItemList apply {toLower _x}; - -// filter duplicates -_medical_ItemList = _medical_ItemList arrayIntersect _medical_ItemList; - -uiNamespace setVariable [QGVAR(Medical_ItemList), _medical_ItemList]; +uiNamespace setVariable [QGVAR(medicalItemList), compileFinal (_medicalList createHashMapFromArray [])]; diff --git a/addons/inventory/functions/fnc_addCustomFilter.sqf b/addons/inventory/functions/fnc_addCustomFilter.sqf index 6dd6e1f559..50820fa448 100644 --- a/addons/inventory/functions/fnc_addCustomFilter.sqf +++ b/addons/inventory/functions/fnc_addCustomFilter.sqf @@ -12,11 +12,13 @@ * None * * Example: - * ["displayname", "filter"] call ACE_inventory_fnc_addCustomFilter + * ["displayname", "filter"] call ace_inventory_fnc_addCustomFilter * * Public: No */ -params [["_filterName", "ERROR: No Name", [""]], ["_fncName", "", [""]]]; +params [["_filterName", "", [""]], ["_fncName", "", [""]]]; + +if (_filterName == "") exitWith {}; GVAR(customFilters) pushBack [_filterName, _fncName]; diff --git a/addons/inventory/functions/fnc_currentItemListBox.sqf b/addons/inventory/functions/fnc_currentItemListBox.sqf index b3e5ce40b8..1546e8a509 100644 --- a/addons/inventory/functions/fnc_currentItemListBox.sqf +++ b/addons/inventory/functions/fnc_currentItemListBox.sqf @@ -12,7 +12,7 @@ * Currently selected item list box * * Example: - * [DISPLAY] call ACE_inventory_fnc_currentItemListBox + * [DISPLAY] call ace_inventory_fnc_currentItemListBox * * Public: No */ @@ -27,7 +27,6 @@ scopeName "main"; if (ctrlShown _control) then { _control breakOut "main"; }; - false -} count [IDC_ITEMLIST_GROUND, IDC_ITEMLIST_SOLDIER, IDC_ITEMLIST_UNIFORM, IDC_ITEMLIST_VEST, IDC_ITEMLIST_BACKPACK]; +} forEach [IDC_ITEMLIST_GROUND, IDC_ITEMLIST_SOLDIER, IDC_ITEMLIST_UNIFORM, IDC_ITEMLIST_VEST, IDC_ITEMLIST_BACKPACK]; controlNull diff --git a/addons/movement/functions/fnc_inventoryDisplayLoad.sqf b/addons/inventory/functions/fnc_displayNameWeight.sqf similarity index 68% rename from addons/movement/functions/fnc_inventoryDisplayLoad.sqf rename to addons/inventory/functions/fnc_displayNameWeight.sqf index 95299a3b34..c480593d85 100644 --- a/addons/movement/functions/fnc_inventoryDisplayLoad.sqf +++ b/addons/inventory/functions/fnc_displayNameWeight.sqf @@ -10,26 +10,27 @@ * None * * Example: - * [DISPLAY] call ACE_movement_fnc_inventoryDisplayLoad + * [DISPLAY] call ace_inventory_fnc_displayNameWeight * * Public: No */ params ["_display"]; -// forces player name control to display irrespective of isStreamFriendlyUIEnabled +// Forces player name control to display irrespective of isStreamFriendlyUIEnabled (_display displayCtrl 111) ctrlShow true; private _fnc_update = { params ["_display"]; + private _control = _display displayCtrl 111; private _format = ["%1 - %2 %3 (%4)", "%2 %3 (%4)"] select isStreamFriendlyUIEnabled; _control ctrlSetText format [_format, - [ACE_player, false, true] call EFUNC(common,getName), - localize ELSTRING(common,Weight), - [ACE_player] call EFUNC(common,getWeight), - [ACE_player, true] call EFUNC(common,getWeight) + [GVAR(unit), false, true] call EFUNC(common,getName), + LELSTRING(common,Weight), + GVAR(unit) call EFUNC(common,getWeight), + [GVAR(unit), true] call EFUNC(common,getWeight) ]; }; diff --git a/addons/inventory/functions/fnc_filterBackpacks.sqf b/addons/inventory/functions/fnc_filterBackpacks.sqf index 6cb94f3d1c..db1edd9756 100644 --- a/addons/inventory/functions/fnc_filterBackpacks.sqf +++ b/addons/inventory/functions/fnc_filterBackpacks.sqf @@ -10,7 +10,7 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterBackpacks + * [CONFIG] call ace_inventory_fnc_filterBackpacks * * Public: No */ diff --git a/addons/inventory/functions/fnc_filterGrenades.sqf b/addons/inventory/functions/fnc_filterGrenades.sqf index 6d2b813ae4..7e871699b8 100644 --- a/addons/inventory/functions/fnc_filterGrenades.sqf +++ b/addons/inventory/functions/fnc_filterGrenades.sqf @@ -10,11 +10,11 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterGrenades + * [CONFIG] call ace_inventory_fnc_filterGrenades * * Public: No */ params ["_config"]; -toLower configName _config in GVAR(Grenades_ItemList) +(configName _config) in (uiNamespace getVariable QGVAR(grenadesItemList)) diff --git a/addons/inventory/functions/fnc_filterHeadgear.sqf b/addons/inventory/functions/fnc_filterHeadgear.sqf index 134a4fc45f..010c33040f 100644 --- a/addons/inventory/functions/fnc_filterHeadgear.sqf +++ b/addons/inventory/functions/fnc_filterHeadgear.sqf @@ -10,7 +10,7 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterHeadgear + * [CONFIG] call ace_inventory_fnc_filterHeadgear * * Public: No */ diff --git a/addons/inventory/functions/fnc_filterItems.sqf b/addons/inventory/functions/fnc_filterItems.sqf index 0bdb18310f..a3c2567233 100644 --- a/addons/inventory/functions/fnc_filterItems.sqf +++ b/addons/inventory/functions/fnc_filterItems.sqf @@ -10,11 +10,14 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterItems + * [CONFIG] call ace_inventory_fnc_filterItems * * Public: No */ params ["_config"]; -!(getNumber (_config >> "ItemInfo" >> "type") in [TYPE_UNIFORM, TYPE_VESTS, TYPE_HEADGEAR]) && {!(_this call FUNC(filterBackpacks))} +!(_this call FUNC(filterMedical)) && +{!(_this call FUNC(filterBackpacks))} && +{!(_this call FUNC(filterHeadgear))} && +{!(getNumber (_config >> "ItemInfo" >> "type") in [TYPE_UNIFORM, TYPE_VEST])} diff --git a/addons/inventory/functions/fnc_filterMagazines.sqf b/addons/inventory/functions/fnc_filterMagazines.sqf index 4b7747c5a8..e6d9237c21 100644 --- a/addons/inventory/functions/fnc_filterMagazines.sqf +++ b/addons/inventory/functions/fnc_filterMagazines.sqf @@ -10,9 +10,9 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterMagazines + * [CONFIG] call ace_inventory_fnc_filterMagazines * * Public: No */ -!(_this call FUNC(filterBackpacks)) && {!(_this call FUNC(filterGrenades))} +!(_this call FUNC(filterGrenades)) && {!(_this call FUNC(filterBackpacks))} diff --git a/addons/inventory/functions/fnc_filterMedical.sqf b/addons/inventory/functions/fnc_filterMedical.sqf index ec44ba2a76..73cfdbdffb 100644 --- a/addons/inventory/functions/fnc_filterMedical.sqf +++ b/addons/inventory/functions/fnc_filterMedical.sqf @@ -10,11 +10,11 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterMedical + * [CONFIG] call ace_inventory_fnc_filterMedical * * Public: No */ params ["_config"]; -toLower configName _config in GVAR(Medical_ItemList) +(configName _config) in GVAR(medicalItemList) diff --git a/addons/inventory/functions/fnc_filterUniforms.sqf b/addons/inventory/functions/fnc_filterUniforms.sqf index dc7d4e9287..b627475038 100644 --- a/addons/inventory/functions/fnc_filterUniforms.sqf +++ b/addons/inventory/functions/fnc_filterUniforms.sqf @@ -10,7 +10,7 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterUniforms + * [CONFIG] call ace_inventory_fnc_filterUniforms * * Public: No */ diff --git a/addons/inventory/functions/fnc_filterVests.sqf b/addons/inventory/functions/fnc_filterVests.sqf index 439d826390..2bb2af9ef4 100644 --- a/addons/inventory/functions/fnc_filterVests.sqf +++ b/addons/inventory/functions/fnc_filterVests.sqf @@ -10,7 +10,7 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterVests + * [CONFIG] call ace_inventory_fnc_filterVests * * Public: No */ diff --git a/addons/inventory/functions/fnc_filterWeapons.sqf b/addons/inventory/functions/fnc_filterWeapons.sqf index 2addf83665..db4d402099 100644 --- a/addons/inventory/functions/fnc_filterWeapons.sqf +++ b/addons/inventory/functions/fnc_filterWeapons.sqf @@ -10,7 +10,7 @@ * Item should appear in this list? * * Example: - * [CONFIG] call ACE_inventory_fnc_filterWeapons + * [CONFIG] call ace_inventory_fnc_filterWeapons * * Public: No */ diff --git a/addons/inventory/functions/fnc_forceItemListUpdate.sqf b/addons/inventory/functions/fnc_forceItemListUpdate.sqf index 165bff1e57..fb8f09b5c8 100644 --- a/addons/inventory/functions/fnc_forceItemListUpdate.sqf +++ b/addons/inventory/functions/fnc_forceItemListUpdate.sqf @@ -10,31 +10,38 @@ * None * * Example: - * [DISPLAY] call ACE_inventory_fnc_forceitemListUpdate + * [DISPLAY] call ace_inventory_fnc_forceItemListUpdate * * Public: No */ disableSerialization; + params ["_display"]; -private _index = GVAR(selectedFilterIndex); +// Get the appropriate filter +private _filterFunction = missionNamespace getVariable [(_display displayCtrl IDC_FILTERLISTS) lbData GVAR(selectedFilterIndex), ""]; + +if !(_filterFunction isEqualType {}) exitWith {}; + private _itemList = _display call FUNC(currentItemListBox); -private _filterFunction = missionNamespace getVariable ((_display displayCtrl IDC_FILTERLISTS) lbData _index); +private _itemKeyCache = uiNamespace getVariable QGVAR(itemKeyCache); +private _backpackKeyCache = uiNamespace getVariable QGVAR(backpackKeyCache); +private _config = configNull; -if (_filterFunction isEqualType {}) then { - private _i = 0; +for "_i" from (lbSize _itemList) to 0 step -1 do { + // All items have their classnames in lbData, except backpacks + _className = _itemList lbData _i; - while {_i < lbSize _itemList} do { - private _config = GVAR(ItemKeyNamespace) getVariable format ["%1:%2", _itemList lbText _i, _itemList lbPicture _i]; + _config = if (_className != "") then { + _itemKeyCache get _className + } else { + // Backpack are gotten with their display name and inventory icon + _backpackKeyCache get format ["%1:%2", _itemList lbText _i, _itemList lbPicture _i] + }; - if (!isNil "_config" && {!(_config call _filterFunction)}) then { - _itemList lbDelete _i; - - // in case the filter function returns nil. Otherwise could lock up the game. - _i = _i - 1; - }; - - _i = _i + 1; + // If item is valid and doesn't match the current filter, remove it + if (!isNil "_config" && {!(_config call _filterFunction)}) then { + _itemList lbDelete _i; }; }; diff --git a/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf b/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf index 1411ec6cc8..3e70bbd8d9 100644 --- a/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf +++ b/addons/inventory/functions/fnc_inventoryDisplayLoad.sqf @@ -10,71 +10,60 @@ * None * * Example: - * [DISPLAY] call ACE_inventory_fnc_inventoryDisplayLoad + * [DISPLAY] call ace_inventory_fnc_inventoryDisplayLoad * * Public: No */ disableSerialization; + params ["_display"]; private _filter = _display displayCtrl IDC_FILTERLISTS; -// engine defined behaviour is the following: +// Engine defined behaviour is the following: // lb value, data and text don't matter, only the index. -// the first three indecies are hard coded: 0 - weapons , 1 - magazines, 2 - items -// all of them show backpacks, because BI -// all other indecies show everything, so all we have to do is delete stuff we dont like -_filter ctrlAddEventHandler ["LBSelChanged", {_this call FUNC(onLBSelChanged)}]; +// The first three indecies are hard coded: 0 - weapons , 1 - magazines, 2 - items +// All of them show backpacks, because BI +// All other indecies show everything, so all we have to do is delete stuff we don't like +_filter ctrlAddEventHandler ["LBSelChanged", LINKFUNC(onLBSelChanged)]; -// have to add these a frame later, because this event happens before the engine adds the default filters +// Have to add these a frame later, because this event happens before the engine adds the default filters [{ disableSerialization; + params ["_filter"]; - // remove "All", so we can push it to the back later. - // to keep localization we can keep the lbText (displayed name). + // Remove "All", so we can push it to the back later + // To keep localization we keep the lbText (displayed name) private _index = lbSize _filter - 1; private _nameAll = _filter lbText _index; _filter lbDelete _index; - // add additional filter functions to the default filters. These remove backpacks etc. + // Add additional filter functions to the default filters. These remove backpacks etc. _filter lbSetData [0, QFUNC(filterWeapons)]; _filter lbSetData [1, QFUNC(filterMagazines)]; _filter lbSetData [2, QFUNC(filterItems)]; - // add our custom filters + // Add our custom filters { _x params ["_name", "_fncName"]; _index = _filter lbAdd _name; _filter lbSetData [_index, _fncName]; + } forEach GVAR(customFilters); - false - } count GVAR(customFilters); - - // readd "All" filter to last position and select it + // Readd "All" filter to last position and select it _index = _filter lbAdd _nameAll; _filter lbSetCurSel _index; -}, [_filter]] call CBA_fnc_execNextFrame; +}, _filter] call CBA_fnc_execNextFrame; -// monitor changes that can happen and force our update +// Monitor changes that can happen and force our update private _dummyControl = _display ctrlCreate ["RscMapControl", -1]; -_dummyControl ctrlSetPosition [0,0,0,0]; +_dummyControl ctrlSetPosition [0, 0, 0, 0]; _dummyControl ctrlCommit 0; _dummyControl ctrlAddEventHandler ["Draw", { - disableSerialization; - params ["_dummyControl"]; - - private _display = ctrlParent _dummyControl; - - private _itemList = _display call FUNC(currentItemListBox); - - // monitoring is done by setting a lb value. These are unused here and are reset every time the list box updates. - if (_itemList lbValue 0 != DUMMY_VALUE) then { - _display call FUNC(forceItemListUpdate); - _itemList lbSetValue [0, DUMMY_VALUE]; - }; + (ctrlParent (_this select 0)) call FUNC(forceItemListUpdate); }]; diff --git a/addons/inventory/functions/fnc_onLBSelChanged.sqf b/addons/inventory/functions/fnc_onLBSelChanged.sqf index 6fbc7020c0..a2316dc4b6 100644 --- a/addons/inventory/functions/fnc_onLBSelChanged.sqf +++ b/addons/inventory/functions/fnc_onLBSelChanged.sqf @@ -12,19 +12,16 @@ * None * * Example: - * [CONTROL, 5] call ACE_inventory_fnc_onLBSelChanged + * [CONTROL, 5] call ace_inventory_fnc_onLBSelChanged * * Public: No */ disableSerialization; + params ["_filter", "_index"]; GVAR(selectedFilterIndex) = _index; -[{ - disableSerialization; - params ["_display"]; - - [_display] call FUNC(forceItemListUpdate); -}, [ctrlParent _filter]] call CBA_fnc_execNextFrame; +// Force update +[LINKFUNC(forceItemListUpdate), ctrlParent _filter] call CBA_fnc_execNextFrame; diff --git a/addons/inventory/initSettings.sqf b/addons/inventory/initSettings.inc.sqf similarity index 100% rename from addons/inventory/initSettings.sqf rename to addons/inventory/initSettings.inc.sqf diff --git a/addons/inventory/stringtable.xml b/addons/inventory/stringtable.xml index 026e23476c..a020e96048 100644 --- a/addons/inventory/stringtable.xml +++ b/addons/inventory/stringtable.xml @@ -141,7 +141,7 @@ Médical Médico Медицина - 医療 + 医療品 의료 医疗 醫療 diff --git a/addons/irlight/XEH_postInit.sqf b/addons/irlight/XEH_postInit.sqf index 47763b8414..d95186f07b 100644 --- a/addons/irlight/XEH_postInit.sqf +++ b/addons/irlight/XEH_postInit.sqf @@ -2,7 +2,7 @@ [] call FUNC(initItemContextMenu); -addUserActionEventHandler ["headlights", "Deactivate", FUNC(onLightToggled)]; +addUserActionEventHandler ["headlights", "Deactivate", LINKFUNC(onLightToggled)]; ["ACE3 Equipment", QGVAR(hold), LLSTRING(MomentarySwitch), { ACE_player action ["GunLightOn", ACE_player]; diff --git a/addons/irlight/stringtable.xml b/addons/irlight/stringtable.xml index b30889b771..506e9deb9d 100644 --- a/addons/irlight/stringtable.xml +++ b/addons/irlight/stringtable.xml @@ -4,100 +4,170 @@ DBAL-A3 (red) DBAL-A3 (rot) + DBAL-A3 (Rosso) DBAL-A3 (czerwony) DBAL-A3 (빨강) DBAL-A3 (rouge) + DBAL-A3 (vermelho) + DBAL-A3 (赤) + DBAL-A3 (красный) + DBAL-A3 (rojo) DBAL-A3 (green) - DBAL-A3 (grün) - DBAL-A3 (zielony) + DBAL-A3 (Grün) + DBAL-A3 (Verde) + DBAL-A3 (Zielony) DBAL-A3 (녹색) - DBAL-A3 (vert) + DBAL-A3 (Vert) + DBAL-A3 (Verde) + DBAL-A3 (緑) + DBAL-A3 (зеленый) + DBAL-A3 (verde) <t color='#9cf953'>Use: </t>Turn Laser ON/OFF<br>Double click to switch mode <t color='#9cf953'>Benutzen: </t>Laser EIN/AUS<br>Doppelklick um Modus zu wechseln + <t color='#9cf953'>Usa: </t>Laser ACCESO/SPENTO<br>Doppio Click per cambiare modalità <t color='#9cf953'>Użycie: </t>Laser WŁ/WYŁ<br>Kliknij dwukrotnie, aby zmienić tryb <t color='#9cf953'>사용: </t>레이저 켜기/끄기<br>터블 클릭으로 모드 전환 <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>Двойной щелчок для переключения режима + <t color='#9cf953'>Uso: </t>Alternar Láser ON/OFF<br>Doble click para cambiar estado Dual Beam Aiming Laser Doppelstrahllaservisier + Puntatore Laser Multiuso Laser Celowniczy z Podwójną Wiązką 이중 빔 조준 레이저 Viseur laser à double faisceau + Laser de Pontaria de Duplo Feixe + 複合ビーム照準レーザー + Двухлучевой прицельный лазер + Láser de Apuntado de Doble Haz Visible Laser Sichtbarer Laser + Laser Visibile Laser Widzialny 가시 레이저 Laser visible + Laser Visível + 可視光レーザー + Видимый лазер + Láser Visible IR Laser IR-Laser + Laser IR Laser IR 적외선 레이저 Laser IR + Laser IR + IRレーザー + ИК-лазер + Láser IR IR Illuminator IR-Taschenlampe + Illuminatore IR Iluminator IR 적외선 조명 Illuminateur IR + Iluminador IR + IRイルミネーター + ИК-осветитель + Iluminador IR IR Laser and Illuminator IR-Laser und -Licht + Laser e Illuminatore IR Laser IR i Iluminator 적외선 레이저와 조명 Illuminateur et laser IR + Laser e Iluminador IR + IRレーザーとイルミネーター + ИК-лазер и осветитель + Láser e Iluminador IR Wide Beam Breiter Lichtstrahl + Fascio Ampio Szeroka Wiązka 넓은 빔 Faisceau large + Feixe Largo + 広角ビーム + Широкий луч + Haz Ancho Medium Beam Mittlerer Lichtstrahl + Fascio Intermedio Średnia Wiązka 중간 빔 Faisceau moyen + Feixe Médio + 標準ビーム + Средний луч + Haz Medio Narrow Beam Schmaler Lichtstrahl + Fascio Stretto Wąska Wiązka 좁은 빔 Faisceau étroit + Feixe Estreito + 狭角ビーム + Узкий луч + Haz Estrecho <t color='#9cf953'>Use: </t>Turn Light ON/OFF<br>Double click to switch mode <t color='#9cf953'>Benutzen: </t>Licht EIN/AUS<br>Doppelklick um Modus zu wechseln + <t color='#9cf953'>Usa: </t>Luce ACCESA/SPENTA<br>Doppio Click per cambiare modalità <t color='#9cf953'>Użycie: </t>Iluminator WŁ/WYŁ<br>Kliknij dwukrotnie, aby zmienić tryb <t color='#9cf953'>사용: </t>조명 켜기/끄기<br>더블 클릭으로 모드 전환 <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>Двойной щелчок для переключения режима + <t color='#9cf953'>Uso: </t>Alternar Luz ON/OFF<br>Doble click para cambiar estado Special Purpose IR LED Illuminator Infrarot LED Taschenlampe + Torcia LED IR Iluminator IR LED Specjalnego Przeznaczenia 특수목적 적외선 LED 조명 Illuminateur LED IR à usage spécial + Iluminador LED IR de Uso Especial + 特殊用途のIR LEDイルミネーター + ИК-светодиодный осветитель специального назначения + Iluminador LED IR de Propósito Especial Illuminator / Laser Momentary Switch Licht / Laser Tastschalter + Accensione momentanea Laser/Illuminatore Przełącznik Chwilowy Iluminator / Laser 조명/레이저 빠르게 스위치 Commutateur temporaire illuminateur/laser + Interruptor Momentâneo Iluminador/Laser + イルミネーター/レーザーモーメンタリースイッチ + Мгновенный переключатель осветителя/лазера + Conmutador Momentáneo Iluminador / Láser diff --git a/addons/javelin/XEH_clientInit.sqf b/addons/javelin/XEH_clientInit.sqf index 66d645968f..ecd80fb0ce 100644 --- a/addons/javelin/XEH_clientInit.sqf +++ b/addons/javelin/XEH_clientInit.sqf @@ -3,4 +3,4 @@ if (!hasInterface) exitWith {}; -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" diff --git a/addons/javelin/functions/fnc_mapHelperDraw.sqf b/addons/javelin/functions/fnc_mapHelperDraw.sqf index 2794d46f58..4f7ac84b4a 100644 --- a/addons/javelin/functions/fnc_mapHelperDraw.sqf +++ b/addons/javelin/functions/fnc_mapHelperDraw.sqf @@ -18,7 +18,7 @@ */ if (isNil QGVAR(arguments)) then { - TRACE_1("Starting optic draw", _this); + TRACE_1("Starting optic draw",_this); // reset shooter var: private _currentShooter = if (ACE_player call CBA_fnc_canUseWeapon) then {ACE_player} else {vehicle ACE_player}; diff --git a/addons/javelin/functions/fnc_onOpticDraw.sqf b/addons/javelin/functions/fnc_onOpticDraw.sqf index e6809a8e04..aacc4f5fa1 100644 --- a/addons/javelin/functions/fnc_onOpticDraw.sqf +++ b/addons/javelin/functions/fnc_onOpticDraw.sqf @@ -146,13 +146,13 @@ if (isNull _newTarget) then { _fireDisabledEH = [_fireDisabledEH] call FUNC(disableFire); } else { if ((!isNull _newTarget) && {_currentTarget != _newTarget}) then { - TRACE_1("New Target, reseting locking", _newTarget); + TRACE_1("New Target, reseting locking",_newTarget); _lockStartTime = CBA_missionTime; _currentTarget = _newTarget; }; if ((CBA_missionTime - _lockStartTime) > __LOCKONTIME) then { // Lock on after 3 seconds - TRACE_2("LOCKED!", _currentTarget, _lockStartTime); + TRACE_2("LOCKED!",_currentTarget,_lockStartTime); __JavelinIGUISeek ctrlSetTextColor __ColorGreen; __JavelinIGUITargetingLines ctrlShow true; diff --git a/addons/javelin/initKeybinds.sqf b/addons/javelin/initKeybinds.inc.sqf similarity index 100% rename from addons/javelin/initKeybinds.sqf rename to addons/javelin/initKeybinds.inc.sqf diff --git a/addons/javelin/stringtable.xml b/addons/javelin/stringtable.xml index 0054cf4f03..ab1ff30a10 100644 --- a/addons/javelin/stringtable.xml +++ b/addons/javelin/stringtable.xml @@ -11,7 +11,7 @@ Célpontra állás (Lenyomva tartott) Aggangia il bersaglio Fijar objetivo (Mantener) - Travar Alvo(Segurar) + Travar Alvo (Segurar) 目標を捕捉 (長押し) 표적 획득 (누르기) 锁定目标(按住) diff --git a/addons/kestrel4500/XEH_postInit.sqf b/addons/kestrel4500/XEH_postInit.sqf index 033dbafbe8..12688a6adf 100644 --- a/addons/kestrel4500/XEH_postInit.sqf +++ b/addons/kestrel4500/XEH_postInit.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" GVAR(Menus) = ["Date", "Direction", "Wind SPD m/s", "CROSSWIND m/s", "HEADWIND m/s", "TEMP °C", "CHILL °C", "HUMIDITY %", "HEAT INDEX °C", "DEW POINT °C", "WET BULB °C", "BARO hPA", "ALTITUDE m", "DENS ALT m", "User Screen 1", "User Screen 2"]; diff --git a/addons/kestrel4500/functions/fnc_collectData.sqf b/addons/kestrel4500/functions/fnc_collectData.sqf index 14fd6047f2..318a5a7123 100644 --- a/addons/kestrel4500/functions/fnc_collectData.sqf +++ b/addons/kestrel4500/functions/fnc_collectData.sqf @@ -15,6 +15,8 @@ * Public: No */ +#define TEMPERATURE_SLOT_INDEX 5 + private _playerDir = getDir ACE_player; private _playerAltitude = (getPosASL ACE_player) select 2; private _temperature = _playerAltitude call EFUNC(weather,calculateTemperatureAtHeight); @@ -41,9 +43,10 @@ if (isNil QGVAR(MIN) || isNil QGVAR(MAX)) then { [0, _playerDir] call FUNC(updateMemory); if (GVAR(MinAvgMaxMode) == 1) then { + private _useAB = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]; { GVAR(ENTRIES) set [_x, (GVAR(ENTRIES) select _x) + 1]; - } count [2, 3, 4]; + } forEach [2, 3, 4]; // Wind SPD private _windSpeed = call FUNC(measureWindSpeed); @@ -51,7 +54,7 @@ if (GVAR(MinAvgMaxMode) == 1) then { // CROSSWIND private _crosswind = 0; - if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + if (_useAB) then { _crosswind = abs(sin(GVAR(RefHeading) - _playerDir) * _windSpeed); } else { _crosswind = abs(sin(GVAR(RefHeading)) * _windSpeed); @@ -60,7 +63,7 @@ if (GVAR(MinAvgMaxMode) == 1) then { // HEADWIND private _headwind = 0; - if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + if (_useAB) then { _headwind = cos(GVAR(RefHeading) - _playerDir) * _windSpeed; } else { _headwind = cos(GVAR(RefHeading)) * _windSpeed; @@ -74,4 +77,18 @@ if (GVAR(MinAvgMaxMode) == 1) then { GVAR(TOTAL) set [4, (GVAR(TOTAL) select 4) + _headwind]; }; -{ _x call FUNC(updateMemory); true } count [[5, _temperature],[6, _chill],[7, _humidity],[8, _heatIndex],[9, _dewPoint],[10, _wetBulb],[11, _barometricPressure],[12, _altitude],[13, _densityAltitude]]; +private _data = [ + _temperature, + _chill, + _humidity, + _heatIndex, + _dewPoint, + _wetBulb, + _barometricPressure, + _altitude, + _densityAltitude +]; + +{ + [TEMPERATURE_SLOT_INDEX + _forEachIndex, _x] call FUNC(updateMemory); +} forEach _data; diff --git a/addons/kestrel4500/functions/fnc_generateOutputData.sqf b/addons/kestrel4500/functions/fnc_generateOutputData.sqf index 2143904f80..59bb3056dd 100644 --- a/addons/kestrel4500/functions/fnc_generateOutputData.sqf +++ b/addons/kestrel4500/functions/fnc_generateOutputData.sqf @@ -93,7 +93,7 @@ if (GVAR(referenceHeadingMenu) == 0) then { }; case 1: { // Direction if (!GVAR(MinAvgMax)) then { - _textCenterBig = format["%1", format["%1 %2", GVAR(Directions) select GVAR(Direction), round(_playerDir)]]; + _textCenterBig = format["%1 %2", GVAR(Directions) select GVAR(Direction), round(_playerDir)]; } else { _textCenterLine1Left = "Min"; _textCenterLine2Left = "Avg"; diff --git a/addons/kestrel4500/initKeybinds.sqf b/addons/kestrel4500/initKeybinds.inc.sqf similarity index 100% rename from addons/kestrel4500/initKeybinds.sqf rename to addons/kestrel4500/initKeybinds.inc.sqf diff --git a/addons/kestrel4500/stringtable.xml b/addons/kestrel4500/stringtable.xml index f6580aa507..50bf366fc0 100644 --- a/addons/kestrel4500/stringtable.xml +++ b/addons/kestrel4500/stringtable.xml @@ -29,7 +29,7 @@ Kestrel 4500 Medidor Balístico Ativo Kestrel 4500 kézi szél-és időjárásmérő Příruční meteostanice Kestrel 4500 - ケストレル 4500 携帯型風速計 + ケストレル 4500 携帯気象計 케스트렐 4500 휴대형 기상 관측기 猎隼4500 掌上型天气追踪仪 獵隼4500掌上型天氣追蹤儀 @@ -91,7 +91,7 @@ Otwórz Kestrel 4500 Открыть Kestrel 4500NV Ouvrir le Kestrel 4500 - Accendi Kestrel 4500 + Apri Kestrel 4500 Abrir Kestrel 4500 Kestrel 4500 öffnen Kestrel 4500 elővétele 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 2f75baa929..35050d1dc3 100644 --- a/addons/killtracker/XEH_postInit.sqf +++ b/addons/killtracker/XEH_postInit.sqf @@ -19,7 +19,8 @@ if ((getText (missionconfigfile >> "CfgDebriefingSections" >> QUOTE(XADDON) >> "variable")) != QXGVAR(outputText)) exitWith { TRACE_1("no mission debriefing config",_this); }; -if (!(["ACE_Medical"] call EFUNC(common,isModLoaded))) exitWith { + +if !(GETEGVAR(medical,enabled,false)) exitWith { WARNING("No ACE-Medical"); XGVAR(outputText) = "No ACE-Medical"; }; @@ -64,7 +65,7 @@ GVAR(killCount) = 0; private _killInfo = []; if (!isNull _killer) then { - if (!(_killer isKindof "CAManBase")) then { // If killer is a vehicle log the vehicle type + if !(_killer isKindof "CAManBase") then { // If killer is a vehicle log the vehicle type _killInfo pushBack format [LLSTRING(Vehicle), getText ((configOf _killer) >> "displayName")]; }; if (isNull _instigator) then { @@ -73,11 +74,11 @@ GVAR(killCount) = 0; }; }; private _unitIsPlayer = hasInterface && {_unit in [player, ace_player]}; // isPlayer check will fail at this point - private _killerIsPlayer = (!isNull _instigator) && {_unit != _instigator} && {[_instigator] call EFUNC(common,isPlayer)}; - TRACE_2("",_unitIsPlayer,_killerIsPlayer); + private _instigatorIsPlayer = (!isNull _instigator) && {_unit != _instigator} && {[_instigator] call EFUNC(common,isPlayer)}; + TRACE_2("",_unitIsPlayer,_instigatorIsPlayer); // Don't do anything if neither are players - if (!(_unitIsPlayer || _killerIsPlayer)) exitWith {}; + if !(_unitIsPlayer || _instigatorIsPlayer) exitWith {}; // Log firendly fire private _fnc_getSideFromConfig = { @@ -89,7 +90,7 @@ GVAR(killCount) = 0; default {civilian}; }; }; - if ((!isNull _instigator) && {_unit != _instigator} && {_instigator isKindOf "CAManBase"}) then { + if (!isNull _instigator && {_unit != _instigator} && {_instigator isKindOf "CAManBase"}) then { // Because of unconscious group switching/captives it's probably best to just use unit's config side private _unitSide = [_unit] call _fnc_getSideFromConfig; private _killerSide = [_instigator] call _fnc_getSideFromConfig; @@ -110,23 +111,23 @@ GVAR(killCount) = 0; // If unit was player then send event to self if (_unitIsPlayer) then { - private _killerName = "Self?"; - if ((!isNull _killer) && {_unit != _killer}) then { - if (_killerIsPlayer) then { - _killerName = [_killer, true, false] call EFUNC(common,getName); + private _instigatorName = "Self?"; + if ((!isNull _instigator) && {_unit != _instigator}) then { + if (_instigatorIsPlayer) then { + _instigatorName = [_instigator, true, false] call EFUNC(common,getName); } else { - _killerName = _killer getVariable [QGVAR(aiName), ""]; // allow setting a custom AI name (e.g. VIP Target) - if (_killerName == "") then { - _killerName = format ["*AI* - %1", getText ((configOf _killer) >> "displayName")]; + _instigatorName = _instigator getVariable [QGVAR(aiName), ""]; // allow setting a custom AI name (e.g. VIP Target) + if (_instigatorName == "") then { + _instigatorName = format ["*AI* - %1", getText ((configOf _instigator) >> "displayName")]; }; }; }; - TRACE_3("send death event",_unit,_killerName,_killInfo); - [QGVAR(death), [_killerName, _killInfo]] call CBA_fnc_localEvent; + TRACE_3("send death event",_unit,_instigatorName,_killInfo); + [QGVAR(death), [_instigatorName, _killInfo]] call CBA_fnc_localEvent; }; - // If killer was player then send event to killer - if (_killerIsPlayer) then { + // If shooter was player then send event to them (and optionally the whole crew) + if (_instigatorIsPlayer && {_unitIsPlayer || GVAR(trackAI)}) then { private _unitName = ""; if (_unitIsPlayer) then { _unitName = [_unit, true, false] call EFUNC(common,getName); // should be same as profileName @@ -136,7 +137,18 @@ 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; + TRACE_3("send kill event",_instigator,_unitName,_killInfo); + [QGVAR(kill), [_unitName, _killInfo], _instigator] call CBA_fnc_targetEvent; + + if (GVAR(showCrewKills) && {!(_killer isKindOf "CAManBase")}) then { + private _crew = [driver _killer, gunner _killer, commander _killer] - [_instigator]; + _crew = _crew select {[_x] call EFUNC(common,isPlayer)}; + _crew = _crew arrayIntersect _crew; + TRACE_1("showCrewKills",_crew); + _killInfo = format [" - [%1, %2", localize "str_a3_rscdisplaygarage_tab_crew", _killInfo select [4]]; + { + [QGVAR(kill), [_unitName, _killInfo], _x] call CBA_fnc_targetEvent; + } forEach _crew; + }; }; }] 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..9e4775bd7f --- /dev/null +++ b/addons/killtracker/initSettings.inc.sqf @@ -0,0 +1,17 @@ +[ + QGVAR(trackAI), + "CHECKBOX", + [LSTRING(TrackAI_DisplayName), LSTRING(TrackAI_Description)], + LSTRING(Category), + true, + 1 +] call CBA_fnc_addSetting; + +[ + QGVAR(showCrewKills), + "CHECKBOX", + [LSTRING(showCrewKills_DisplayName), LSTRING(showCrewKills_Description)], + LSTRING(Category), + false, + 1 +] call CBA_fnc_addSetting; diff --git a/addons/killtracker/stringtable.xml b/addons/killtracker/stringtable.xml index 35d292cd15..64b9ee764d 100644 --- a/addons/killtracker/stringtable.xml +++ b/addons/killtracker/stringtable.xml @@ -1,52 +1,71 @@ + + ACE Kill Tracker + ACE Tracciatore di Uccisioni + ACE Kill Tracker + ACE Отслеживание убийств + ACE キル追跡 + ACE 킬트래커 + ACE Suivi des morts + ACE Abschüsse + ACE Contador de Muertes + ACE Killed Events - ACE キルトラッカー - ACE Abgeschossene Ereignisse + ACE キルイベント + ACE Abschusszähler + ACE Eventi di Morte ACE Licznik Zabójstw ACE 击杀事件 ACE 사살 이벤트 ACE Счётчик убийств ACE Eventos de Muertes ACE Evénements Morts + ACE Contagem de Abates Total Kills: Всего убийств: Liczba zabójstw: Toplam Öldürme: - 総キル: + 合計キル数: Gesammte Abschüsse: + Uccisioni Totali: 总击杀数: 총 사살수: Muertes totales: Total de morts : + Abates totais: Kill: %1 %2 Убил: %1 %2 Zabójstwo: %1 %2 Öldürülen: %1 %2 - キル: %1 %2 + 殺害: %1 %2 Abschuss: %1 %2 + Uccisione: %1 %2 击杀:%1 %2 사살: %1 %2 Muertes: %1 %2 Meurtre : %1 %2 + Abate: %1 %2 Killer: %1 %2 Убийца: %1 %2 Zabójca: %1 %2 Öldüren: %1 %2 - キラー: %1 %2 + 殺害者: %1 %2 Täter: %1 %2 + Uccisore: %1 %2 击杀者:%1 %2 사살자: %1 %2 Asesino: %1 %2 Tueur : %1 %2 + Assassino: %1 %2 Vehicle: %1 @@ -54,11 +73,13 @@ Pojazd: %1 Araç :%1 車両: %1 - Fahrzeuge %! + Fahrzeuge: %1 + Veicoli: %1 载具:%1 차량: %1 Vehículo: %1 Véhicule : %1 + Veículo: %1 Friendly Fire @@ -76,5 +97,43 @@ 同士討ち Dost Atışı + + Track AI units killed by player + Traccia IA uccise da giocatori + Sledovat AI zabité hráči + Отслеживание юнитов ИИ, убитых игроком + プレイヤーがキルしたAIユニットを追跡 + 플레이어가 죽인 AI 트래킹 + Suivi de l'IA tuée par les joueurs + Zähle vom Spieler getöteten KI-Einheiten + Cuenta las unidades de IA matadas por el jugador + + + 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をミッション終了デブリーフィング画面に表示させるかどうかを定義します。 + 사후강평 중 살해된 AI가 킬트래킹에 표시되는지 여부를 정의합니다. + Définit si les IA tuées seront affichées dans le tracker pendant le débriefing de la mission. + Legt fest, ob getötete KIs während des Endbildschirms der Mission in den Abschüssen angezeigt werden. + Define si las IAs matadas se mostrarán en el contador de muertes en el debiefring de la misión. + + + Show vehicle kills to other crew members + Показать уничтоженные машины другим членам экипажа + Zeige der Fahrzeugbesatzung die Abschüsse des Fahrzeugs + Mostra uccisioni del veicolo a membri dell'equipaggio + 車両でのキルを乗員全員に表示する + 다른 승무원에게 차량 처치 표시 + + + Show kills from a vehicle to driver, gunner and commander + Показать уничтоженную технику водителю, стрелку и командиру + Zeige Abschüsse des Fahrzeugs dem Fahrer, Richtschützen und Kommandanten an + Mostra uccisioni del veicolo al pilota, artigliere e comandante + 車両でのキルを操縦手、砲手、車長で共有して表示する + 차량 처치를 운전수, 사수, 지휘관에게 보여줍니다 + 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/XEH_postInit.sqf b/addons/laser/XEH_postInit.sqf index ec6b6aca2d..768752bee2 100644 --- a/addons/laser/XEH_postInit.sqf +++ b/addons/laser/XEH_postInit.sqf @@ -2,7 +2,7 @@ #include "\a3\ui_f\hpp\defineDIKCodes.inc" if (hasInterface) then { -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" GVAR(pfID) = -1; diff --git a/addons/laser/XEH_preInit.sqf b/addons/laser/XEH_preInit.sqf index 4fe49c5db4..00049594c6 100644 --- a/addons/laser/XEH_preInit.sqf +++ b/addons/laser/XEH_preInit.sqf @@ -15,6 +15,6 @@ GVAR(laserEmitters) = createHashMap; GVAR(trackedLaserTargets) = []; GVAR(pfehID) = -1; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/laser/functions/fnc_addLaserTarget.sqf b/addons/laser/functions/fnc_addLaserTarget.sqf index 08ea6f65b0..f0414fd3ad 100644 --- a/addons/laser/functions/fnc_addLaserTarget.sqf +++ b/addons/laser/functions/fnc_addLaserTarget.sqf @@ -20,9 +20,9 @@ params ["_targetObject", "_vehicle"]; TRACE_2("params",_targetObject,_vehicle); // Get the designator variables, or use defaults -private _waveLength = _vehicle getVariable [QEGVAR(laser,waveLength), ACE_DEFAULT_LASER_WAVELENGTH]; -private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; -private _beamSpread = _vehicle getVariable [QEGVAR(laser,beamSpread), ACE_DEFAULT_LASER_BEAMSPREAD]; +private _waveLength = _vehicle getVariable [QGVAR(waveLength), ACE_DEFAULT_LASER_WAVELENGTH]; +private _laserCode = _vehicle getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; +private _beamSpread = _vehicle getVariable [QGVAR(beamSpread), ACE_DEFAULT_LASER_BEAMSPREAD]; TRACE_3("codes",_waveLength,_laserCode,_beamSpread); // Laser method is the method ACE_Laser will use to determine from where to where it should project the designator cone @@ -55,5 +55,5 @@ TRACE_1("",GVAR(trackedLaserTargets)); if (GVAR(pfehID) == -1) then { TRACE_1("starting pfeh",count GVAR(trackedLaserTargets)); - GVAR(pfehID) = [DFUNC(laserTargetPFH), 0, []] call CBA_fnc_addPerFrameHandler; + GVAR(pfehID) = [LINKFUNC(laserTargetPFH), 0, []] call CBA_fnc_addPerFrameHandler; }; 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_handleLaserTargetCreation.sqf b/addons/laser/functions/fnc_handleLaserTargetCreation.sqf index b8cedf22c3..bd42a3e5a5 100644 --- a/addons/laser/functions/fnc_handleLaserTargetCreation.sqf +++ b/addons/laser/functions/fnc_handleLaserTargetCreation.sqf @@ -24,13 +24,13 @@ TRACE_1("params",_this); private _owners = allUnits select {(lasertarget _x) == _targetObject}; if (count _owners == 1) exitWith { - TRACE_2("Laser target owner [allUnits]", _targetObject, _owners select 0); + TRACE_2("Laser target owner [allUnits]",_targetObject,_owners select 0); [_targetObject, _owners select 0] call FUNC(addLaserTarget); }; _owners = vehicles select {(lasertarget _x) == _targetObject}; if (count _owners == 1) exitWith { - TRACE_2("Laser target owner [vehicles]", _targetObject, _owners select 0); + TRACE_2("Laser target owner [vehicles]",_targetObject,_owners select 0); [_targetObject, _owners select 0] call FUNC(addLaserTarget); }; @@ -58,7 +58,7 @@ TRACE_1("params",_this); }; }; if (!_foundSource) then { - WARNING_1("Laser target doesn't have owner", _targetObject); + WARNING_1("Laser target doesn't have owner",_targetObject); }; }, _this] call CBA_fnc_execNextFrame; diff --git a/addons/laser/functions/fnc_laserTargetPFH.sqf b/addons/laser/functions/fnc_laserTargetPFH.sqf index 5c5f51931b..af2098a6f8 100644 --- a/addons/laser/functions/fnc_laserTargetPFH.sqf +++ b/addons/laser/functions/fnc_laserTargetPFH.sqf @@ -26,10 +26,10 @@ GVAR(trackedLaserTargets) = GVAR(trackedLaserTargets) select { // Turn off the laser in ace_laser [_laserUuid] call FUNC(laserOff); - TRACE_1("Laser off:", _laserUuid); + TRACE_1("Laser off:",_laserUuid); false } else { - private _newCode = _owner getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; + private _newCode = _owner getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; if (_laserCode != _newCode) then { TRACE_2("code change",_newCode,_laserCode); [QGVAR(updateCode), [_laserUuid, _newCode]] call CBA_fnc_globalEvent; diff --git a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf index 9d3e2d6fa1..4ceb15d814 100644 --- a/addons/laser/functions/fnc_seekerFindLaserSpot.sqf +++ b/addons/laser/functions/fnc_seekerFindLaserSpot.sqf @@ -101,9 +101,9 @@ private _finalOwner = objNull; }; } forEach (values GVAR(laserEmitters)); // Go through all values in hash -TRACE_2("",count _spots, _spots); +TRACE_2("",count _spots,_spots); -if ((count _spots) > 0) then { +if (_spots isNotEqualTo []) then { private _bucketList = nil; private _bucketPos = nil; private _c = 0; @@ -115,7 +115,7 @@ if ((count _spots) > 0) then { while { count(_spots) != count(_excludes) && _c < (count _spots) } do { scopeName "mainSearch"; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _index = _buckets pushBack [_x, [_x]]; _excludes pushBack _forEachIndex; _bucketPos = _x select 0; @@ -124,7 +124,7 @@ if ((count _spots) > 0) then { }; } forEach _spots; { - if (!(_forEachIndex in _excludes)) then { + if !(_forEachIndex in _excludes) then { private _testPos = (_x select 0); if ((_testPos vectorDistanceSqr _bucketPos) <= 100) then { _bucketList pushBack _x; 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/functions/fnc_shootRay.sqf b/addons/laser/functions/fnc_shootRay.sqf index 434560eea7..862e972dd1 100644 --- a/addons/laser/functions/fnc_shootRay.sqf +++ b/addons/laser/functions/fnc_shootRay.sqf @@ -21,7 +21,7 @@ BEGIN_COUNTER(shootRay); params ["_posASL", "_dir", ["_ignoreVehicle1", objNull], ["_ignoreVehicle2", objNull]]; -// TRACE_2("ray origin:", _posASL, _dir); +// TRACE_2("ray origin:",_posASL,_dir); private _distance = 0; private _resultPos = nil; @@ -43,7 +43,7 @@ if (_intersects isNotEqualTo []) then { _resultPos = _posASL vectorAdd (_dir vectorMultiply _distance); }; -TRACE_3("", _resultPos, _distance, _intersects); +TRACE_3("",_resultPos,_distance,_intersects); #ifdef DRAW_LASER_INFO if (!isNil "_resultPos") then { diff --git a/addons/laser/functions/fnc_showVehicleHud.sqf b/addons/laser/functions/fnc_showVehicleHud.sqf index 778df61a6c..35120a294d 100644 --- a/addons/laser/functions/fnc_showVehicleHud.sqf +++ b/addons/laser/functions/fnc_showVehicleHud.sqf @@ -91,7 +91,7 @@ GVAR(pfID) = [{ // Do Laser Scan: private _ammo = getText (configFile >> "CfgMagazines" >> _vehicle currentMagazineTurret _turretPath >> "ammo"); private _laserSource = _vehicle modelToWorldWorld (_vehicle selectionPosition _seekerSource); - private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; + private _laserCode = _vehicle getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; private _seekerAngle = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_missileguidance" >> "seekerAngle"); private _seekerMaxRange = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ace_missileguidance" >> "seekerMaxRange"); private _laserResult = [_laserSource, vectorDir _vehicle, _seekerAngle, _seekerMaxRange, [ACE_DEFAULT_LASER_WAVELENGTH,ACE_DEFAULT_LASER_WAVELENGTH], _laserCode, _vehicle] call EFUNC(laser,seekerFindLaserSpot); diff --git a/addons/laser/functions/fnc_toggleLST.sqf b/addons/laser/functions/fnc_toggleLST.sqf index 59969d014e..eae4ad68ef 100644 --- a/addons/laser/functions/fnc_toggleLST.sqf +++ b/addons/laser/functions/fnc_toggleLST.sqf @@ -39,7 +39,7 @@ if (_enabled) exitWith {}; [_pfhID] call CBA_fnc_removePerFrameHandler; }; - private _laserCode = _vehicle getVariable [QEGVAR(laser,code), ACE_DEFAULT_LASER_CODE]; + private _laserCode = _vehicle getVariable [QGVAR(code), ACE_DEFAULT_LASER_CODE]; private _angle = 25; private _pos = _vehicle modelToWorldVisualWorld [0,0,0]; diff --git a/addons/laser/initKeybinds.sqf b/addons/laser/initKeybinds.inc.sqf similarity index 100% rename from addons/laser/initKeybinds.sqf rename to addons/laser/initKeybinds.inc.sqf diff --git a/addons/laser/initSettings.sqf b/addons/laser/initSettings.inc.sqf similarity index 100% rename from addons/laser/initSettings.sqf rename to addons/laser/initSettings.inc.sqf diff --git a/addons/laser/stringtable.xml b/addons/laser/stringtable.xml index 6f9bbfa653..c6bf7cfc25 100644 --- a/addons/laser/stringtable.xml +++ b/addons/laser/stringtable.xml @@ -44,8 +44,8 @@ Lézerkód Código del láser Laser kód - Codice laser - レーザ コード + Codice Laser + レーザー コード 레이저 코드 激光码 雷射碼 @@ -61,8 +61,8 @@ Lézer - kódciklus növelése - XXX# Láser - Aumentar código - XXX# Laser - Kód +XXX# - Laser - Cambia codice - XXX# - レーザ - コードの数値を増やす - XXX# + Laser - Cicla Codice - XXX# + レーザー - コードの数値を増やす - XXX# 레이저 - 코드 순환 위 - XXX# 激光—循环切换激光码 上 - XXX# 雷射 - 循環切換雷射碼 上 - XXX# @@ -78,8 +78,8 @@ Lézer - kódciklus növelése - XX#X Láser - Aumentar código - 1##X Laser - Kód +XX#X - Laser - Cambia codice - XX#X - レーザ - コードの数値を増やす - XX#X + Laser - Cicla Codice - XX#X + レーザー - コードの数値を増やす - XX#X 레이저 - 코드 순환 위 - 1##X 激光—循环切换激光码 上 - XX#X 雷射 - 循環切換雷射碼 上 - XX#X @@ -95,8 +95,8 @@ Lézer - kódciklus növelése - X#XX Láser - Aumentar código - X#XX Laser - Kód +X#XX - Laser - Cambia codice - X#XX - レーザ - コードの数値を増やす - X#XX + Laser - Cicla Codice - X#XX + レーザー - コードの数値を増やす - X#XX 레이저 - 코드 순환 위 - X#XX 激光—循环切换激光码 上 - X#XX 雷射 - 循環切換雷射碼 上 - X#XX @@ -112,8 +112,8 @@ Lézer - kódciklus csökkentése Láser - Reducir código Laser - Kód - - Laser - Cambia codice - - レーザ - コードの数値を減らす + Laser - Cicla Codice giù + レーザー - コードの数値を減らす 레이저 - 코드 순환 아래 激光—循环切换激光码 下 雷射 - 循環切換雷射碼 下 @@ -124,16 +124,24 @@ レーザースポットトラッカー: オン Laserowe Śledzenie Punktu: Wł. Laserziel Verfolgung: An + Tracciamento Designazioni Laser: Attivato 레이저 스팟 추적기: 켬 Traqueur laser : activé + Rastreador a Laser: Ligado + Лазерный точечный трекер: Включен + Rastreador del Puntero Láser: On Laser Spot Tracker: Off レーザースポットトラッカー: オフ Laserowe Śledzenie Punktu: Wył. Laserziel Verfolgung: Aus + Tracciamento Designazioni Laser: Disattivato 레이저 스팟 추적기: 끔 Traqueur laser : désactivé + Rastreador a Laser: Desligado + Лазерный точечный трекер: выключен + Rastreador del Puntero Láser: Off Draw Laser on Map @@ -144,7 +152,9 @@ Отображать лазер на карте Dibujar láser en mapa Laser auf Karte zeichnen + Mostra Laser su Mappa Dessiner le laser sur la carte + Desenhar Laser no Mapa Active laser designator's position will be drawn on the map @@ -155,7 +165,9 @@ Точка, куда светит активный лазер, будет указана на карте La posición del designador láser activo será dibujada en el mapa Die Position des aktiven Lasermarkierers wird auf der Karte eingezeichnet + Mostra la posizione del proprio designatore laser sulla mappa Active la position du désignateur laser sur la carte. + A posição do designador laser ativo será desenhada no mapa diff --git a/addons/laserpointer/stringtable.xml b/addons/laserpointer/stringtable.xml index fb93914b44..b8d0a657d8 100644 --- a/addons/laserpointer/stringtable.xml +++ b/addons/laserpointer/stringtable.xml @@ -12,7 +12,7 @@ Puntero láser Puntatore laser Laser - レーザ ポインタ + レーザー ポインター 레이저 지시기 激光指示器 雷射指示器 @@ -29,7 +29,7 @@ Puntero láser (rojo) Puntatore laser (rosso) Laser (vermelho) - レーザ ポインタ (赤) + レーザー ポインター (赤) 레이저 지시기 (빨강) 激光指示器(红色) 雷射指示器 (紅色) @@ -37,16 +37,16 @@ Laser Pointer (green) - Pointeur laser (vert) - Laserpointer (grün) + Pointeur laser (Vert) + Laserpointer (Grün) Лазерный прицел (зелёный) Laserové ukazovátko (Zelené) - Wskaźnik laserowy (zielony) + Wskaźnik laserowy (Zielony) Lézer-pointer (zöld) - Puntero láser (verde) - Puntatore laser (verde) - Laser (verde) - レーザ ポインタ (緑) + Puntero láser (Verde) + Puntatore laser (Verde) + Laser (Verde) + レーザー ポインター (緑) 레이저 지시기 (초록) 激光指示器(绿色) 雷射指示器 (綠色) @@ -74,13 +74,13 @@ <t color='#9cf953'>Použití: </t>Zapnout/vypnout laser <t color='#9cf953'>Utilisation : </t>Allumer/Éteindre le laser <t color='#9cf953'>Benutzen: </t>Laser EIN/AUS - <t color='#9cf953'>Uso: </t>Laser ON/OFF + <t color='#9cf953'>Utilizzo: </t>Laser ACCESO/SPENTO <t color='#9cf953'>Użyj: </t>wł./wył. laser <t color='#9cf953'>Uso: </t>Ativar/Desativar laser <t color='#9cf953'>Использовать: </t>ВКЛ/ВЫКЛ лазер <t color='#9cf953'>Usar: </t>Encender/Apagar láser <t color='#9cf953'>Használat: </t>Lézer BE/KI kapcsolása - <t color='#9cf953'>つかう: </t>レーザの起動/停止 + <t color='#9cf953'>つかう: </t>レーザーの起動/停止 <t color='#9cf953'>사용키: </t>레이저 켜기/끄기 <t color='#9cf953'>使用:</t>激光开启/关闭 <t color='#9cf953'>使用: </t>雷射開啟/關閉 @@ -114,7 +114,7 @@ Infravörös Lézer IR Laser Laser IV - 赤外線レーザ + 赤外線レーザー 적외선 레이저 红外线激光 紅外線雷射 @@ -126,12 +126,12 @@ Przełącz Laser / Laser IR Изменить режим Лазер / ИК-лазер Alterner laser/laser IR - Alterna Laser / IR Laser + Alterna Laser / Laser IR Cambiar láser / Láser IR Lézer / Infravörös Lézer váltása Přepnout Laser / Infračervený Laser Alternar entre Laser / Laser IV - レーザ/赤外線レーザを切り替える + レーザー/赤外線レーザーを切り替える 가시광/적외선 레이저 전환 切换激光/红外线激光 切換雷射/紅外線雷射 diff --git a/addons/logistics_rope/CfgWeapons.hpp b/addons/logistics_rope/CfgWeapons.hpp index c5f1b384a2..d8789c6407 100644 --- a/addons/logistics_rope/CfgWeapons.hpp +++ b/addons/logistics_rope/CfgWeapons.hpp @@ -3,7 +3,7 @@ class CfgWeapons { class ACE_ItemCore; class ACE_ropeBase: ACE_ItemCore { scope = 1; - picture = QPATHTOF(data\m_rope_ca); + picture = QPATHTOF(data\m_rope_ca.paa); // model = "\A3\Structures_F_Heli\Items\Tools\Rope_01_F.p3d"; // model is Locked to Helicopter DLC descriptionShort = CSTRING(descriptionShort); }; diff --git a/addons/logistics_rope/stringtable.xml b/addons/logistics_rope/stringtable.xml index ff4624d027..b292ed9499 100644 --- a/addons/logistics_rope/stringtable.xml +++ b/addons/logistics_rope/stringtable.xml @@ -7,10 +7,12 @@ Une corde en fibres torsadées. Généralement utilisée pour la descente en rappel ou le remorquage. Витой канат. Обычно используется для спуска или буксирования. Ein verdrehtes Geflecht aus Fasern. Wird normalerweise zum Abseilen oder Abschleppen verwendet. + Una Corda composta da fibre intrecciate. Usata per Fastroping o trainare veicoli. Lina skręcona z włókien. Zwykle używana do zjazdów lub holowania. 编织绳。通常用于索降和牵引拖曳。 꼬아진 섬유입니다. 주로 레펠이나 견인에 사용됩니다. Malla trenzada de fibras. Normalmente utilizada para descolgarse desde ella o remolcar. + Uma trança torcida de fibras. Normalmente usada para rapel ou reboque. Rope 3.2 meters diff --git a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf index 3e7ce4f15c..925178d642 100644 --- a/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_canRefuelUAV.sqf @@ -18,4 +18,4 @@ params ["_caller", "_target"]; -("ACE_UAVBattery" in (_caller call EFUNC(common,uniqueItems))) && {(fuel _target) < 1} && {(speed _target) < 1} && {!(isEngineOn _target)} && {(_target distance _caller) <= 4} +(alive _target) && {"ACE_UAVBattery" in (_caller call EFUNC(common,uniqueItems))} && {(fuel _target) < 1} && {(speed _target) < 1} && {!(isEngineOn _target)} && {(_target distance _caller) <= 4} diff --git a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf index 8c73052c45..a471e82cbf 100644 --- a/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf +++ b/addons/logistics_uavbattery/functions/fnc_refuelUAV.sqf @@ -17,7 +17,7 @@ */ params ["_caller", "_target"]; -if (!(_this call FUNC(canRefuelUAV))) exitWith {}; +if !(_this call FUNC(canRefuelUAV)) exitWith {}; private _onFinish = { (_this select 0) params ["_caller", "_target"]; diff --git a/addons/logistics_uavbattery/stringtable.xml b/addons/logistics_uavbattery/stringtable.xml index 5ca12e7d4e..9671f451b7 100644 --- a/addons/logistics_uavbattery/stringtable.xml +++ b/addons/logistics_uavbattery/stringtable.xml @@ -10,7 +10,7 @@ A drón fel van töltve Dron je nabitý O VANT está cheio - Il drone è pieno + Il drone è carico БПЛА полностью заряжен ドローンは充電完了 무인기 충전 완료 @@ -27,9 +27,9 @@ Szükséged van egy UAV akkumulátorra Potřebuješ UAV baterii Você precisa de uma bateria para VANTs - Hai bisogno di una Batteria UAV + Ti serve una Batteria UAV Требуется аккумулятор для БПЛА - UAV バッテリが必要です + UAV バッテリーが必要です 무인기 배터리가 필요합니다 你需要一个无人机电池 你需要一個無人載具電池 @@ -63,7 +63,7 @@ Bateria para VANT Batteria UAV Аккумулятор БПЛА - UAV バッテリ + UAV バッテリー 무인기 배터리 无人机电池 無人載具電池 @@ -78,7 +78,7 @@ Hordozható UAV-k feltöltéséhez való akkumulátor Používané k dobíjení UAV Usada para reabastecer o VANT - Usata per ricaricare la Batteria dell'UAV + Usata per ricaricare le batterie di UAV portabili Используется для зарядки переносных БПЛА 運んでいる UAV を充電に使う 무인기를 재충전 할 때 씁니다. @@ -95,7 +95,7 @@ Akku feltöltése... Dobíjení... Recarregando... - In ricarica... + Ricaricando... Заряжается... 充電しています・・・ 正在充电... diff --git a/addons/logistics_wirecutter/XEH_postInit.sqf b/addons/logistics_wirecutter/XEH_postInit.sqf index 29dc506396..fc0a38bf26 100644 --- a/addons/logistics_wirecutter/XEH_postInit.sqf +++ b/addons/logistics_wirecutter/XEH_postInit.sqf @@ -1,11 +1,11 @@ #include "script_component.hpp" if (hasInterface) then { - ["ace_interactMenuOpened", {_this call FUNC(interactEH)}] call CBA_fnc_addEventHandler; + ["ace_interactMenuOpened", LINKFUNC(interactEH)] call CBA_fnc_addEventHandler; }; if (isServer) then { - [QGVAR(destroyFence), {_this call FUNC(destroyFence)}] call CBA_fnc_addEventHandler; + [QGVAR(destroyFence), LINKFUNC(destroyFence)] call CBA_fnc_addEventHandler; }; GVAR(possibleWirecutters) = call (uiNamespace getVariable [QGVAR(possibleWirecutters), {[]}]); diff --git a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf index 46e38acb90..2176793aed 100644 --- a/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf +++ b/addons/logistics_wirecutter/functions/fnc_cutDownFence.sqf @@ -22,7 +22,10 @@ TRACE_2("Fence cutting started",_unit,_fence); if (_unit != ACE_player) exitWith {}; // Get cut time based on if unit is a engineer -private _cutTime = if (_unit call EFUNC(common,isEngineer)) then {CUT_TIME_ENGINEER} else {CUT_TIME_DEFAULT}; +private _cutTime = [ + CUT_TIME_DEFAULT, + CUT_TIME_ENGINEER +] select (_unit call EFUNC(common,isEngineer)); if !(_unit call EFUNC(common,isSwimming)) then { [_unit, "AinvPknlMstpSnonWnonDr_medic5", 0] call EFUNC(common,doAnimation); 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/logistics_wirecutter/stringtable.xml b/addons/logistics_wirecutter/stringtable.xml index 5e71db11b3..224d4239be 100644 --- a/addons/logistics_wirecutter/stringtable.xml +++ b/addons/logistics_wirecutter/stringtable.xml @@ -27,7 +27,7 @@ Służą do cięcia drutu i płotów Pince coupante Drótok, huzalok, és kábelek vágására alkalmas olló. - Tronchese + Tronchese per tagliare filo di metallo. Cortador de Arame ワイヤーカッター 절단기 diff --git a/addons/magazinerepack/XEH_preInit.sqf b/addons/magazinerepack/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/magazinerepack/XEH_preInit.sqf +++ b/addons/magazinerepack/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf index 9383089d28..c2785c5fad 100644 --- a/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf +++ b/addons/magazinerepack/functions/fnc_magazineRepackFinish.sqf @@ -25,7 +25,7 @@ _args params ["_magazineClassname", "_lastAmmoCount"]; private _fullMagazineCount = getNumber (configFile >> "CfgMagazines" >> _magazineClassname >> "count"); // Don't show anything if player can't interact -if (!([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith))) exitWith {}; +if !([ACE_player, objNull, ["isNotInside", "isNotSitting", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {}; // Count mags private _fullMags = 0; diff --git a/addons/magazinerepack/initSettings.sqf b/addons/magazinerepack/initSettings.inc.sqf similarity index 100% rename from addons/magazinerepack/initSettings.sqf rename to addons/magazinerepack/initSettings.inc.sqf diff --git a/addons/magazinerepack/stringtable.xml b/addons/magazinerepack/stringtable.xml index 1edefd0504..9ec8a0fe5a 100644 --- a/addons/magazinerepack/stringtable.xml +++ b/addons/magazinerepack/stringtable.xml @@ -23,7 +23,7 @@ Durata per proiettile 每發所需時間 每发所需时间 - 弾頭毎の所有時間 + 弾薬毎の所要時間 탄알 당 시간 Czas na nabój Время на патрон @@ -39,7 +39,7 @@ Durata per caricatore 每匣所需時間 每匣所需时间 - 弾倉毎の所有時間 + 弾倉毎の所要時間 탄창 당 시간 Czas na magazynek Время на магазин @@ -55,7 +55,7 @@ Durata per caricatore a nastro 每彈鍊所需時間 每弹炼所需时间 - ベルトリンク毎の所有時間 + ベルトリンク毎の所要時間 탄띠 당 시간 Czas na taśmę Время на звено ленты @@ -72,7 +72,7 @@ Przepakuj magazynki Přepáskovat zásobníky Riempi Caricatori - Reorganizar Carregadores + Preencher Carregadores Újratárazás Перепаковать магазины 弾倉を詰め替え @@ -89,7 +89,7 @@ Przepakowywanie magazynków... Přepáskovávám zásobník... Riempendo i caricatori... - Reorganizando Carregadores... + Preenchendo Carregadores... Újratárazás... Перепаковка магазинов... 弾倉を詰め替えしています・・・ @@ -109,7 +109,7 @@ %1 carregador(es) cheio(s) e %2 disparo(s) a mais %1 teljes tár és %2 extra lőszer %1 полных магазина(ов) и %2 патрона(ов) - %1 個の満杯の弾倉とあふれた %2 発の弾薬 + 満装填した弾倉 %1 個と<br/>残 %2 発装填の弾倉 %1개의 꽉찬 탄창과 %2발의 총알이 남았다 %1个满的弹匣与%2发额外子弹 %1個滿的彈匣與%2發額外子彈 @@ -125,8 +125,8 @@ Przepakowywanie zakończone Újratárazás befejezve Caricatori Riempiti - Reorganização Terminada - 詰め替えが完了しました + Preenchimento Completo + 詰め替えが完了しました。 탄창 채우기 끝남 整理完成 重整完成 @@ -142,8 +142,8 @@ Przepakowywanie przerwane Újratárazás megszakítva Riempimento Interrotto - Reorganização Interrompida - 詰め替えを中断しました + Preenchimento Interrompido + 詰め替えが中断されました。 탄창을 채우는 중 방해받음 弹匣整理被打断 重整被中斷 @@ -160,37 +160,42 @@ %1 teljes és %2 részleges %1 Pieno(i) e %2 Parziale(i) %1 Total e %2 Parcial - %1 個の満杯と %2 個の弾薬入り弾倉 - %1 꽉 찼고 %2 부분적으로 참 + 満装填した弾倉 %1 個と<br/>部分装填の弾倉 %2 個 + 꽉 찬 탄창:%1<br/>부분적으로 찬 탄창: %2 %1个满的与%2个部分的 %1個滿的與%2個部分的 %1 Dolu ve %2 Partial Repack Loaded Magazines - 装填済み弾倉を詰め替え + 装填済みの弾倉も詰め替える Remplir le chargeur engagé Перепаковать загруженные магазины Geladene Magazine umpacken + Riempi caricatori pieni Przepakuj załadowane magazynki 重新整理已上膛的弹匣 장전된 탄창에 총알 채우는 중 Reorganizar cargadores llenos + Preencher Carregadores Engajados Repacking magazines, weapon unloaded - 弾倉を詰め替えし、<br />非装填状態です + 弾倉の詰め替えのため 武器から弾薬を抜きました Remplissage des chargeurs, arme déchargée. Перепаковка магазинов, оружие разряжено Magazin umgepackt, Waffe entladen + Riempendo i caricatori, arma scarica Przepakowywanie magazynków, broń rozładowana 重新整理弹匣,武器未上膛 탄창 다시 채우는 중, 무기에서 탄창 뺌 Reorganizando cargadores, arma descargada + Preenchendo carregadores, arma descarregada Repack Animation Animation für Umpacken + Animazione per il riempimento Animacja przepakowywania 탄약 합치기 애니메이션 詰め替え時のアニメーション @@ -198,6 +203,7 @@ Анимация перепаковки Animación de reorganizar Animation de remplissage des chargeurs + Animação de Preenchimento diff --git a/addons/main/script_macros.hpp b/addons/main/script_macros.hpp index ed3a826678..495d592e5f 100644 --- a/addons/main/script_macros.hpp +++ b/addons/main/script_macros.hpp @@ -99,7 +99,11 @@ #define TYPE_SCUBA 604 // not implemented #define TYPE_HEADGEAR 605 #define TYPE_FACTOR 607 +#define TYPE_MAP 608 +#define TYPE_COMPASS 609 +#define TYPE_WATCH 610 #define TYPE_RADIO 611 +#define TYPE_GPS 612 #define TYPE_HMD 616 #define TYPE_BINOCULAR 617 #define TYPE_MEDIKIT 619 diff --git a/addons/main/script_version.hpp b/addons/main/script_version.hpp index e233476016..75b323ede3 100644 --- a/addons/main/script_version.hpp +++ b/addons/main/script_version.hpp @@ -1,4 +1,4 @@ #define MAJOR 3 -#define MINOR 16 +#define MINOR 17 #define PATCHLVL 1 -#define BUILD 74 +#define BUILD 86 diff --git a/addons/main/stringtable.xml b/addons/main/stringtable.xml index e97670f84f..b676359f74 100644 --- a/addons/main/stringtable.xml +++ b/addons/main/stringtable.xml @@ -6,10 +6,10 @@ ACE Logistik ACE Logistyka Logísticas ACE - ACE: логистика + ACE: Логистика ACE Logistika ACE Logística - Logistica ACE + ACE Logistica ACE Logistique ACE ロジスティクス ACE 后勤 diff --git a/addons/map/XEH_postInitClient.sqf b/addons/map/XEH_postInitClient.sqf index 56b2b560f4..534b37da8b 100644 --- a/addons/map/XEH_postInitClient.sqf +++ b/addons/map/XEH_postInitClient.sqf @@ -8,7 +8,7 @@ LOG(MSG_INIT); // Calculate the maximum zoom allowed for this map call FUNC(determineZoom); -GVAR(flashlights) = [] call CBA_fnc_createNamespace; +GVAR(flashlights) = createHashMap; ["CBA_settingsInitialized", { if (isMultiplayer && {GVAR(DefaultChannel) != -1}) then { @@ -19,9 +19,9 @@ GVAR(flashlights) = [] call CBA_fnc_createNamespace; setCurrentChannel GVAR(DefaultChannel); if (currentChannel == GVAR(DefaultChannel)) then { - // INFO_1("Channel Set - %1", currentChannel); + // INFO_1("Channel Set - %1",currentChannel); } else { - ERROR_2("Failed To Set Channel %1 (is %2)", GVAR(DefaultChannel), currentChannel); + ERROR_2("Failed To Set Channel %1 (is %2)",GVAR(DefaultChannel),currentChannel); }; }, 0, []] call CBA_fnc_addPerFrameHandler; }; @@ -73,8 +73,7 @@ GVAR(hasWatch) = true; GVAR(hasWatch) = false; { if (_x isKindOf ["ItemWatch", configFile >> "CfgWeapons"]) exitWith {GVAR(hasWatch) = true;}; - false - } count (assignedItems _unit); + } forEach (assignedItems _unit); }, true] call CBA_fnc_addPlayerEventHandler; @@ -93,7 +92,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/map/XEH_preInit.sqf b/addons/map/XEH_preInit.sqf index 92a7e896f3..3d0df4213e 100644 --- a/addons/map/XEH_preInit.sqf +++ b/addons/map/XEH_preInit.sqf @@ -7,6 +7,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/map/functions/fnc_blueForceTrackingModule.sqf b/addons/map/functions/fnc_blueForceTrackingModule.sqf index f7436e7bf9..af95ce3d6d 100644 --- a/addons/map/functions/fnc_blueForceTrackingModule.sqf +++ b/addons/map/functions/fnc_blueForceTrackingModule.sqf @@ -22,4 +22,4 @@ params ["_logic"]; [_logic, QGVAR(BFT_HideAiGroups), "HideAiGroups"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(BFT_ShowPlayerNames), "ShowPlayerNames"] call EFUNC(common,readSettingFromModule); -INFO_3("Blue Force Tracking Module Initialized:", GVAR(BFT_Enabled), GVAR(BFT_Interval), GVAR(BFT_HideAiGroups)); +INFO_3("Blue Force Tracking Module Initialized:",GVAR(BFT_Enabled),GVAR(BFT_Interval),GVAR(BFT_HideAiGroups)); diff --git a/addons/map/functions/fnc_isFlashlight.sqf b/addons/map/functions/fnc_isFlashlight.sqf index e563d74114..ae26b41569 100644 --- a/addons/map/functions/fnc_isFlashlight.sqf +++ b/addons/map/functions/fnc_isFlashlight.sqf @@ -17,14 +17,12 @@ params [["_class", "", [""]]]; -private _isFlashlight = GVAR(flashlights) getVariable _class; - -if (isNil "_isFlashlight") then { +GVAR(flashlights) getOrDefaultCall [_class, { private _items = ([_class] + (_class call CBA_fnc_switchableAttachments)); private _cfgWeapons = configFile >> "CfgWeapons"; // if this item or any of the switchable items is a flashlight - _isFlashlight = _items findIf { + _items findIf { private _weaponConfig = _cfgWeapons >> _x; [ @@ -34,10 +32,5 @@ if (isNil "_isFlashlight") then { isText (_x >> "ACE_Flashlight_Colour") || {!(getArray (_x >> "ambient") in [[], [0,0,0]]) && {getNumber (_x >> "irLight") == 0}} } != -1 // return - } != -1; - - // cache value - GVAR(flashlights) setVariable [_class, _isFlashlight]; -}; - -_isFlashlight // return + } != -1 // return +}, true] // return diff --git a/addons/map/initSettings.sqf b/addons/map/initSettings.inc.sqf similarity index 89% rename from addons/map/initSettings.sqf rename to addons/map/initSettings.inc.sqf index fa248bf736..20665b5a71 100644 --- a/addons/map/initSettings.sqf +++ b/addons/map/initSettings.inc.sqf @@ -67,14 +67,11 @@ false, true, { - [QGVAR(BFT_Enabled), _this] call EFUNC(common,cbaSettings_settingChanged); - if (GVAR(BFT_Enabled) && {isNil QGVAR(BFT_markers)}) then { GVAR(BFT_markers) = []; - [FUNC(blueForceTrackingUpdate), GVAR(BFT_Interval), []] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(blueForceTrackingUpdate), GVAR(BFT_Interval), []] call CBA_fnc_addPerFrameHandler; }; - }, - false + } ] call CBA_fnc_addSetting; [ @@ -94,9 +91,7 @@ [localize LSTRING(BFT_ShowPlayerNames_DisplayName), localize LSTRING(BFT_ShowPlayerNames_Description)], [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], false, - true, - {[QGVAR(BFT_ShowPlayerNames), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; [ @@ -105,7 +100,5 @@ [localize LSTRING(BFT_HideAiGroups_DisplayName), localize LSTRING(BFT_HideAiGroups_Description)], [format ["ACE %1", localize LSTRING(Module_DisplayName)], localize LSTRING(BFT_Module_DisplayName)], false, - true, - {[QGVAR(BFT_HideAiGroups), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; diff --git a/addons/map/stringtable.xml b/addons/map/stringtable.xml index e9b54537f0..5d91167639 100644 --- a/addons/map/stringtable.xml +++ b/addons/map/stringtable.xml @@ -29,7 +29,7 @@ Térkép megvilágítása Освещение карты Illuminazione Mappa - 地図に照明 + 地図の照明 지도에 조명 地图照明 地圖照明 @@ -45,7 +45,7 @@ Simular iluminación de mapa basada en la iluminación ambiente y los elementos de los jugadores? Simulovat nasvícení mapy v závisloti na okolí a předmětů hráče? Simula illuminazione della mappa in base alla luce ambientale e agli oggetti del giocatore? - 地図へ環境光やプレイヤーのアイテムに基づいた光のシミュレーションを行うかどうかを設定できます。 + 環境光やプレイヤーのアイテムに基づいた地図の照明をシミュレートしますか? 주변 환경 및 플레이어 조명에 의한 빛 변화를 지도에 반영할까요? 透过环境光与玩家的手电筒来决定地图亮度。 透過環境光與玩家的物品來決定地圖亮度? @@ -58,9 +58,9 @@ Brilho de lanterna no mapa Resplandor de linterna en el mapa Nasvícení mapy pomocí baterky - Luce della torcia in mappa + Effetto luminoso sul giocatore Lueur lampe carte - 地図をライトで照らす + 地図用ライトの光放射 지도 조명 발광 增加地图亮度 增加地圖亮度 @@ -74,8 +74,8 @@ Adicionar brilho externo para jogadores que usam lanterna no mapa? Añadir resplandor externo a los jugadores que utilizan la linterna en el mapa? Přidat externí záři hráči který používá baterku v mapě? - Aggiungi luce esterna a giocatori che usano la torcia in mappa? - プレイヤーが地図をフラッシュライトで照らせられるように設定します。 + Aggiungi un effetto di luce sul giocatore che sta usando la torcia in mappa, questo è visibile ad altri giocatori. + マップ上で懐中電灯を使用しているプレイヤーから辺りへの光放射を追加しますか? 지도에 조명을 사용하는 플레이어에 외부 불빛을 추가합니까? 当玩家打开手电筒时,增加地图亮度。 當玩家擁有手電筒時,增加地圖亮度? @@ -90,8 +90,8 @@ Tremblement de la carte Térkép-rázkódás Тряска карты - Scuoti la mappa - 地図を揺らす + Scuotimento della mappa + 地図の揺れ 지도 흔들림 地图震动 地圖震動 @@ -108,7 +108,7 @@ Rázkódjon-e a térkép mozgáskor? Заставлять карту трястись при ходьбе? Far scuotere la mappa mentre cammini? - 歩いているときは地図を揺らすかかどうかを設定できます。 + 歩いているときに地図を揺らしますか? 걸을 때 지도를 보면 흔들리게 합니까? 走路时打开地图会产生晃动。 走路時讓地圖有震動的感覺? @@ -139,8 +139,8 @@ Limite le niveau de zoom sur la carte. Korlátozva legyen-e a nagyítás mennyisége a térképnél? Ограничить максимальное приближение, доступное на карте? - Limita l'ammontare di zoom disponibile per la mappa? - 地図上で利用できる拡大倍率を制限できます。 + Limita i livelli di zoom disponibili sulla mappa? + 地図上で利用できる拡大倍率を制限しますか? 지도 확대에 제한을 둡니까? 限制地图上可允许缩放的倍率? 限制地圖上可允許縮放的倍率? @@ -156,7 +156,7 @@ Kurzor-koordináták mutatása Показывать координаты курсора Mostra coordinate sul cursore - カーソル先で座標を表示 + カーソル先の座標を表示 커서에 좌표를 보이기 显示光标的座标 顯示游標的座標 @@ -171,8 +171,8 @@ Affiche les coordonnées de la grille sur le pointeur de souris. Mutatva legyen-e a kurzornál található rész rácskoordinátája? Показывать координаты около курсора мыши? - Mostra la griglia coordinate sul cursore mouse? - カーソルで合わせた先を地図座標で表示するかどうかを設定できます。 + Mostra il numero della coordinata-griglia sul cursore del mouse in mappa? + カーソルで合わせた先の地図グリッド座標を表示しますか? 지도에서 커서 옆에 좌표가 뜨게 합니까? 显示鼠标光标所在的网格座标? 顯示滑鼠游標所在的網格座標? @@ -187,7 +187,7 @@ Ez a modul lehetővé teszi a térképnézet testreszabását. Этот модуль позволяет настроить отображение карты. Este módulo permite personalizar la pantalla del mapa. - Questo modulo ti permette di customizzare lo schermo della mappa. + Questo modulo ti permette di personalizzare lo schermo della mappa. このモジュールは地図画面を変更できます。 이 모듈은 지도 화면을 임의로 설정할 수 있게 해줍니다. 此模块允许自定地图的相关效果。 @@ -204,7 +204,7 @@ Blue Force követés Система слежения Blue Force Tracking Blue Force Tracking - ブルー フォース トラッキング + ブルー フォース トラッキング (BFT) GPS 피아식별기 显示蓝方追踪 顯示藍方蹤跡 @@ -235,8 +235,8 @@ Active le SFA. Valeur par défaut : désactivé. Blue Force követés engedélyezése. Alapértelmezett: Nem Включает систему служения BFT. По умолчанию: Нет - Abilita Blue Force Tracking. Default: No - ブルー フォース トラッキングを有効化します。標準: 無効 + Abilita Blue Force Tracking. Predefinito: No + ブルー フォース トラッキングを有効化します。 デフォルト: 無効 GPS 피아식별기 켭니다. 기본설정: 아니요 启用显示蓝方追踪。预设:否 啟用顯示藍方蹤跡. 預設: 否 @@ -268,7 +268,7 @@ Milyen gyakran frissüljenek a jelölők (másodpercben) Как часто должны обновляться маркеры (в секундах) Quanto spesso vengono aggiornati i marker (in secondi) - マーカが再描画される間隔を設定できます (秒) + マーカが再描画される間隔 (秒単位) 몇 초마다 마커를 새로 갱신합니까? 设定每多少时间重新标示出单位位置(秒) 設定每多少時間重新標示出單位位置 (秒) @@ -283,7 +283,7 @@ Cacher les groupes IA AI csoportok elrejtése Скрыть группы ботов - Nascondere gruppi IA + Nascondi gruppi IA AIグループを非表示 인공지능 그룹 숨기기 隐藏 AI 小队 @@ -299,8 +299,8 @@ Cache les marqueurs pour les groupes composés exclusivement d'unités IA. Jelölők elrejtése "csak AI" csoportoknál? Скрыть маркеры групп, которые состоят полностью из ботов? - Nascondi markers per gruppi di sole IA? - 'AIのみ'グループのマーカー表示有無を設定できます。 + Nascondi marker per gruppi di sole IA? + 'AIのみ'のグループのマーカー表示有無を設定できます。 인공지능만 있는 그룹의 마커를 숨깁니까? 隐藏'AI 小队'的追踪? 隱藏'AI小隊'的蹤跡? @@ -331,7 +331,7 @@ Affiche les noms de tous les joueurs individuellement. Itt található az adott játékos neveket? Показать отдельные имена игроков? - Mostra i nomi dei giocatori singoli? + Mostra i nomi di singoli giocatori? プレイヤーの名前の表示有無を設定できます。 각 플레이어의 이름을 표시합니까? 显示玩家的个别名称? @@ -347,7 +347,7 @@ Ez a modul lehetővé teszi a szövetséges egységek követését BFT térképjelzőjkkel. Этот модуль позволяет отслеживать перемещение союзных войск по карте при помощи маркеров BFT. Este módulo permite el seguimiento de las unidades aliadas con marcadores de mapa BFT. - Questo modulo permette il tracciamento di unità alleate con i marker BFT in mappa + Questo modulo permette il tracciamento di unità alleate mediante marker BFT in mappa. モジュールは BFT マップ マーカとともに、同勢力ユニットの追跡を許可します。 이 모듈은 아군을 지도상에서 추적할 수 있게 해줍니다. 此模块将使你能在地图上看见友方单位的追踪 @@ -362,7 +362,7 @@ Фонари Svítilny Linternas - Torcia + Torce フラッシュライト 손전등 手电筒 @@ -379,7 +379,7 @@ NVG NVG NVG - 夜間暗視装置 + 暗視装置 야간투시경 夜视仪 夜視鏡 @@ -491,7 +491,7 @@ Imposta Canale all'Avvio Setear canal al comenzar Définir un canal par défaut - 開始時のチャンネルを決定 + 開始時のチャンネルを指定 시작시 채널 设定游戏开始时的聊天频道 設定遊戲開始時的聊天頻道 @@ -503,10 +503,10 @@ Muda o canal do marcador no início da missão Изменить начальный канал для установки маркеров при запуске миссии Nastavit kanál po startu mise - Cambia il canale marker iniziale all'avvio di missione + Cambia il canale marker iniziale all'avvio della missione Cambiar el canal de marcadores inicial al comenzar la misión Change le canal de communication par défaut au début de la mission. - ミッション開始時にあらかじめ設定されているマーカ チャンネルを変更します + ミッション開始時に使用されるマーカーチャンネルの指定を変更します 미션 시작시 마커채널을 변경합니다 更改任务启动时的聊天频道 更改任務啟動時的聊天頻道 diff --git a/addons/map_gestures/XEH_preInit.sqf b/addons/map_gestures/XEH_preInit.sqf index 9bf1ff814e..42090ac724 100644 --- a/addons/map_gestures/XEH_preInit.sqf +++ b/addons/map_gestures/XEH_preInit.sqf @@ -6,8 +6,8 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" -GVAR(GroupColorCfgMappingNew) = call CBA_fnc_createNamespace; +GVAR(GroupColorCfgMappingNew) = createHashMap; ADDON = true; diff --git a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf index 17a8ffbb04..f533f9df34 100644 --- a/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf +++ b/addons/map_gestures/functions/fnc_addGroupColorMapping.sqf @@ -25,7 +25,7 @@ TRACE_3("params",_group,_leadColor,_unitColor); if (_group isEqualType grpNull) then {_group = groupID _group}; if (_group == "") exitWith {ERROR("Group ID is blank, which is not valid.")}; -if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; -if (!([_unitColor] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; +if !([_leadColor] call FUNC(isValidColorArray)) exitWith {ERROR("leadColor is not a valid color array.")}; +if !([_unitColor] call FUNC(isValidColorArray)) exitWith {ERROR("color is not a valid color array.")}; -GVAR(GroupColorCfgMappingNew) setVariable [_group, [_leadColor, _unitColor]]; +GVAR(GroupColorCfgMappingNew) set [toLower _group, [_leadColor, _unitColor]]; diff --git a/addons/map_gestures/functions/fnc_drawMapGestures.sqf b/addons/map_gestures/functions/fnc_drawMapGestures.sqf index 2f0c80de3e..0a69c1924b 100644 --- a/addons/map_gestures/functions/fnc_drawMapGestures.sqf +++ b/addons/map_gestures/functions/fnc_drawMapGestures.sqf @@ -41,7 +41,7 @@ private _players = [_positions, FUNC(getProximityPlayers), missionNamespace, QGV }; // If color settings for the group exist, then use those, otherwise fall back to the default colors - private _colorMap = GVAR(GroupColorCfgMappingNew) getVariable [(groupID (group _x)), [GVAR(defaultLeadColor), GVAR(defaultColor)]]; + private _colorMap = GVAR(GroupColorCfgMappingNew) getOrDefault [toLower groupID (group _x), [GVAR(defaultLeadColor), GVAR(defaultColor)]]; private _color = _colorMap select (_x != leader _x); TRACE_2("",_colorMap,_color); diff --git a/addons/map_gestures/functions/fnc_isValidColorArray.sqf b/addons/map_gestures/functions/fnc_isValidColorArray.sqf index 7cc9335800..bcd5fea38c 100644 --- a/addons/map_gestures/functions/fnc_isValidColorArray.sqf +++ b/addons/map_gestures/functions/fnc_isValidColorArray.sqf @@ -20,7 +20,7 @@ scopeName "main"; params ["_colorArray"]; if (isNil "_colorArray") exitWith {false}; -if (!(_colorArray isEqualType [])) exitWith {false}; +if !(_colorArray isEqualType []) exitWith {false}; if (count _colorArray != 4) exitWith {false}; { diff --git a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf index 07be21fc90..36bef695d5 100644 --- a/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleGroupSettings.sqf @@ -24,9 +24,10 @@ if (!_activated) exitWith {}; // Transcode string setting into usable array. Example: "1,1,1,1" -> [1, 1, 1, 1] private _leadColor = call compile ("[" + (_logic getVariable ["leadColor", ""]) + "]"); -if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")}; +if !([_leadColor] call FUNC(isValidColorArray)) exitWith {ERROR("leadColor is not a valid color array.")}; + private _color = call compile ("[" + (_logic getVariable ["color", ""]) + "]"); -if (!([_color] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")}; +if !([_color] call FUNC(isValidColorArray)) exitWith {ERROR("color is not a valid color array.")}; // Add all synchronized groups and reference custom configuration for them { diff --git a/addons/map_gestures/functions/fnc_moduleSettings.sqf b/addons/map_gestures/functions/fnc_moduleSettings.sqf index b637997af7..22913dceef 100644 --- a/addons/map_gestures/functions/fnc_moduleSettings.sqf +++ b/addons/map_gestures/functions/fnc_moduleSettings.sqf @@ -29,14 +29,14 @@ if (!_activated) exitWith {}; private _defaultLeadColor = _logic getVariable ["defaultLeadColor", ""]; if (_defaultLeadColor != "") then { _defaultLeadColor = call compile ("[" + _defaultLeadColor + "]"); - if (!([_defaultLeadColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; + if !([_defaultLeadColor] call FUNC(isValidColorArray)) exitWith {ERROR("defaultLeadColor is not a valid color array.")}; ["CBA_settings_setSettingMission", [QGVAR(defaultLeadColor), _defaultLeadColor, true]] call CBA_fnc_localEvent; }; private _defaultColor = _logic getVariable ["defaultColor", ""]; if (_defaultColor != "") then { _defaultColor = call compile ("[" + _defaultColor + "]"); - if (!([_defaultColor] call FUNC(isValidColorArray))) exitWith {ERROR("defaultColor is not a valid color array.")}; + if !([_defaultColor] call FUNC(isValidColorArray)) exitWith {ERROR("defaultColor is not a valid color array.")}; ["CBA_settings_setSettingMission", [QGVAR(defaultColor), _defaultColor, true]] call CBA_fnc_localEvent; }; diff --git a/addons/map_gestures/initSettings.sqf b/addons/map_gestures/initSettings.inc.sqf similarity index 100% rename from addons/map_gestures/initSettings.sqf rename to addons/map_gestures/initSettings.inc.sqf diff --git a/addons/map_gestures/stringtable.xml b/addons/map_gestures/stringtable.xml index 64168b6b70..cff2d15f4f 100644 --- a/addons/map_gestures/stringtable.xml +++ b/addons/map_gestures/stringtable.xml @@ -11,7 +11,7 @@ Kartenzeichen Gestos en mapa Pointage sur carte - マップ ジェスチャー + マップ ジェスチャ 지도 신호 地图指示 地圖指示器 @@ -39,11 +39,11 @@ Aktywuje gesty na mapie. Включает указания на карте. Povolit ukazování v mapě - Abilita i Gesti Mappa + Abilita i Gesti in Mappa Aktiviert die Kartenzeichen. Activar Gestos en Mapa Active le pointage sur carte. - マップ ジェスチャーを有効化 + マップ ジェスチャを有効化 지도 신호 활성화 启用地图指示 啟用地圖指示器 @@ -59,7 +59,7 @@ Maximale Reichweite der Kartenzeichen Máx. dist. para gestos en mapa Portée du pointage sur carte - マップ ジェスチャーの最大範囲 + マップ ジェスチャの最大範囲 지도 신호 최대 거리 地图指示最大范围 地圖指示器最大範圍 @@ -75,7 +75,7 @@ Maximale Reichweite zwischen Spielern um Kartenzeichen anzuzeigen Máxima distancia a la cual pueden verse el indicador de gestos Définit le rayon au-delà duquel un joueur ne verra plus l'indicateur de pointage des autres joueurs. - プレイヤーによるマップ ジェスチャーの表示範囲を設定します + マップ ジェスチャのインジケータを表示可能なプレーヤー間の最大距離 플레이어간에 지도 신호 표시거리를 설정합니다. 设定地图指示显示的最大范围距离 設定地圖指示器顯示的最大範圍距離 @@ -86,7 +86,7 @@ Interwał aktualizacji Интервал обновления Interval aktualizace - Intervallo Aggiornamento + Intervallo Aggiornamenti Update-Intervall Período de actualización Intervalle de mise à jour @@ -122,7 +122,7 @@ Farbe der Namenstexte. Color de los nombres Couleur du texte du nom - 名前への色 + 名前の文字色 글 색상 명칭 名称文字颜色 名稱文字顏色 @@ -133,11 +133,11 @@ Cor do texto da etiqueta de nome que fica embaixo da marcação de gestos no mapa. Kolor nazwy gracza obok markera gestu mapy. Цвет инмени игрока рядом с маркером жестов. - Colore del testo dei nametag oltre a quello dei Gesti Mappa + Colore del testo dei nametag accanto agli indicatori di gesti in mappa. Farbe der Namenstexte neben der Kartenzeichen-Markierung. Color de los nombres dibujados al lado del marcados de gestos. Définit la couleur du texte pour le nom à côté du marqueur de pointage sur carte. - マップ ジェスチャーに表示される、名前の色を決定します。 + マップ ジェスチャに添えて表示される名前の文字色。 지도 색상에 표시되는 이름의 색상을 결정합니다. 定义名称文字颜色。使其与地图指示颜色有所区别。 定義名稱文字顏色。使其與地圖指示器顏色有所區別 @@ -149,11 +149,11 @@ Domyślny kolor lidera Лид. цвет по умолчанию Výchozí barva velitele - Colore Default Caposquadra + Colore Caposquadra Predefinito Gruppenführer-Standardfarbe Color por defecto para el lider Couleur de commandement par défaut - リーダー用標準の色 + 部隊長用の標準色 리더 기본 색상 队长预设颜色 隊長預設顏色 @@ -163,11 +163,11 @@ Valor de cor alternativa para líderes de grupo Domyślny kolor dla liderów grup. Значение цвета для лидеров групп. - Colore di riserva dei capisquadra quando non c'è nessuna impostazione gruppo. [Modulo: lascia vuoto per non forzare su clients] + Colore di riserva per gli indicatori dei capisquadra quando non c'è nessuna impostazione per il gruppo. [Modulo: lascia vuoto per non forzare su client] Ersatz-Farbwert für Gruppenführer wenn keine Gruppeneinstellung vorhanden ist. [Modul: leer lassen um Anwendung bei Clients nicht zu erzwingen] Color por defecto para líderes cuando no está configurado [Módulo: dejar en blanco para no forzar] Définit la couleur par défaut pour les chefs de groupe quand il n'y a pas de réglage de groupe. [Module : laisser vide pour ne pas forcer chez les clients.] - グループ設定が存在しない場合に、グループ リーダーへ設定される色の値を設定します。[モジュール:空の場合はクライアントへ強制しません] + グループ設定がない場合に部隊長へ設定される色の値を設定します。[モジュール:空の場合はクライアントへ強制しません] 그룹 설정이 없는 경우 리더의 예비 색상 값입니다. [모듈: 클라이언트에서 강체하지 않기 위해 공백으로 비워둘 것] 当没有设定小队颜色时,此功能会定义队长的指示颜色。[模块:此栏留空来保持预设颜色] 當沒有設定小隊顏色時,此功能會定義隊長的指示器顏色。[模塊: 此欄留空來保持預設顏色] @@ -179,7 +179,7 @@ Kolor domyślny Цвет по умолчанию Výchozí barva - Colore Default + Colore Predefinito Standardfarbe Color por defecto Couleur par défaut @@ -194,11 +194,11 @@ Valor alternativo de cor Kolor domyślny Значение цвета. - Colore di riserva quando non ci sono impostazioni gruppo. [Modulo: lascia vuto per non forzare sui clients] + Colore di riserva quando non c'è un'impostazione per il gruppo. [Modulo: lascia vuoto per non forzare sui client] Ersatz-Farbwert wenn keine Gruppeneinstellung vorhanden ist. [Modul: leer lassen um Anwendung bei Clients nicht zu erzwingen] Color por defecto cuando no está configurado [Módulo: dejar en blanco para no forzar] Définit la couleur par défaut quand il n'y a pas de réglage pour le groupe. [Module : laisser vide pour ne pas forcer chez les clients.] - グループ設定が存在しない場合に、グループ リーダーへ設定される色の値を設定します。[モジュール:空の場合はクライアントへ強制しません] + グループ設定がない場合に設定される色の値を設定します。[モジュール:空の場合はクライアントへ強制しません] 그룹 설정이 없을 경우의 예비 색상입니다. [모듈: 클라이언트에서 강체하지 않기 위해 공백으로 비워둘 것] 当没有设定小队颜色时,此功能会定义玩家的指示颜色。[模块:此栏留空来保持预设颜色] 當沒有設定小隊顏色時,此功能會定義玩家的指示器顏色。[模塊: 此欄留空來保持預設顏色] @@ -214,7 +214,7 @@ Gruppenführer-Farbe Color para el líder Couleur de commandement - リーダー用の色 + 部隊長用の色 리더 색상 队长颜色 隊長顏色 @@ -228,7 +228,7 @@ Farbwert für Gruppenführer, die mit diesem Modul synchronisiert werden. Color para los líderes de los grupos sincronizados al módulo. Couleur pour les chefs des groupes synchronisés avec ce module. - モジュールで同期されたグループのリーダー用に色の値を決定します。 + モジュールで同期されたグループの隊長に設定される色の値。 그룹이 이 모듈에 동기화 됐을 때의 리더 색상입니다. 改变与此同步小队队长的指示颜色。 改變與此同步小隊隊長的指示器顏色 @@ -259,7 +259,7 @@ Farbwert für Gruppenmitglieder, die mit diesem Modul synchronisiert werden. Color para los miembros de los grupos sincronizados al módulo. Couleur pour les membres des groupes synchronisés avec ce module. - モジュールで同期されたグループのメンバ用に色の値を決定します。 + モジュールで同期されたグループの隊員に設定される色の値。 그룹이 이 모듈에 동기화 됐을 때의 멤버 색상입니다. 改变与此同步小队队员的指示颜色 改變與此同步小隊隊員的指示器顏色 @@ -270,66 +270,78 @@ Показывать только союзные жесты Pokazuj jedynie sojusznicze gesty Afficher uniquement le pointage des alliés - 友軍ジェスチャーのみ表示 + 友軍のジェスチャのみ表示 Mostrar sólo gestos de aliados Nur Gesten befreundeter Einheiten zeigen + Mostra solo gesti di alleati 仅显示友军指示 아군 신호만 보기 + Mostrar somente gestos aliados Shows only Gestures from Units that are from the same side or a Friendly side. Показывать жесты только от игроков союзной стороны. Affiche uniquement les pointages effectués par des unités qui sont du même camp, ou d'un camp allié. - 友軍ユニットのみからジェスチャーを表示します。 + Mostra solo gesti effettuati da unità che sono della stessa fazione o una fazione alleata. + 同じ陣営または味方陣営のユニットからのジェスチャのみを表示します。 Muestra únicamente gestos de las unidades que son del mismo bando o de un bando aliado Pokazuj tylko Gesty od jednostek z tej samej lub sojuszniczej strony Nur Gesten von Einheiten der selben oder einer verbündeten Seite zeigen. 仅显示来自同一阵营或友军的单位的指示。 같은 진영 혹은 아군 진영 인원들만 보이게 합니다. + Mostra somente gestos de unidades que são do mesmo lado ou de um lado aliado. Max range Camera Макс. дальность действия камеры Portée de la caméra - カメラ最大範囲 + カメラの最大範囲 Máximo alcance de cámara Maksymalny zasięg kamery Maximale Kamerareichweite + Distanza massima per videocamere 摄像机最大范围 카메라와 지도 신호의 최대 거리 + Distância máxima da câmera Max range between a Camera and players to show the map gesture indicator Устанавливает макс. дальность между игроком и камерой для отображения жестов на карте Définit le rayon au-delà duquel une caméra ne verra plus l'indicateur de pointage des autres joueurs. - プレイヤーが行うマップ ジェスチャーをカメラから確認できる最大範囲を設定します。 + 観戦カメラから確認可能なマップ ジェスチャのインジケータを表示するカメラとプレーヤー間の最大距離 Máxima distancia entre una cámara y los jugadores para mostrar el indicador de gestos en mapa + Distanza massima da cui videocamere (spettatore/zeus) può vedere i gesti di giocatori. Maksymalny zasięg pomiędzy kamerą a graczami do pokazania gestów na mapie Maximale Reichweite, in der eine Kamera das Kartenzeichen der Spieler zeigt 摄像机和玩家之间的最大范围显示地图指示 카메라와 플레이어간 지도 신호를 볼 수 있는 최대 거리를 정합니다 + Distância máxima entre uma câmera e jogadores para mostrar o indicador de gestos no mapa Allow Spectator Разрешить видеть в спектаторе Autoriser les spectateurs - スペクテイターに許可 + Permetti spettatori + 観戦者に許可 Permitir espectador Zezwól na Obserwatora Erlaube Zuschauer 允许旁观者 관전자 허용 + Permitir espectador Allows Spectator to See Map Gestures Позволяет наблюдателю видеть жесты на карте Permet aux spectateurs de voir le pointage des autres joueurs. - スペクテイターからマップ ジェスチャーを表示できるようにします。 + 観戦者からマップ ジェスチャを表示できるようにします。 + Permetti agli spettatori di vedere gesti in mappa Permitir al espectador ver los gestos de mapa Zezwól Obserwatorowi widzieć Gesty na mapie Erlaube, dass Zuschauer das Kartenzeichen sehen können 允许旁观者查看地图指示 관전자가 지도 신호를 볼 수 있습니다 + Permite espectadores verem o indicador de gestos no mapa Allow Curator @@ -339,19 +351,23 @@ Permitir Curador Zezwól na Zeusa Erlaube Zeus + Permetti Zeus 允许宙斯 큐레이터 허용 + Permitir curador Allows Curator to See Map Gestures Позволяет куратору видеть жесты на карте Permet aux curateurs de voir le pointage des autres joueurs. - キュレーターからマップ ジェスチャーを表示できるようにします。 + キュレーターからマップ ジェスチャを表示できるようにします。 Permitir al Curador ver los gestos de mapa + Permetti agli Zeus di vedere gesti in mappa Zezwól Zeusowi widzieć gesty na mapie Erlaube, dass Zeus das Kartenzeichen sehen kann 允许宙斯查看地图指示 큐레이터가 지도 신호를 볼 수 있습니다 + Permite curadores verem o indicador de gestos no mapa Briefing Mode @@ -359,21 +375,25 @@ Visibilité lors du briefing ブリーフィング モード Modo de briefing + Modalità Briefing Tryb Odprawy Briefing-Modus 简报模式 브리핑 모드 + Modo de briefing What player can see what Определяет, какая группа игроков может видеть жесты на карте во время брифинга Définit quels pointages les joueurs peuvent voir lors du briefing. - プレイヤーが見ることができる対象を決定します。 + プレイヤーが見ることができる対象 Qué puede ver cada jugador + Quali giocatori possono vedere gesti sulla mappa in fase di briefing. Co mogą widzieć gracze Welcher Spieler kann was sehen 什么玩家能看到什么 어떤 플레이어가 볼 수 있는지 정합니다 + O que cada jogador pode ver Disabled @@ -381,10 +401,12 @@ Pointage désactivé 無効化 Deshabilitado + Disabilitata Zablokowany Deaktiviert 禁用 비활성화 + Desativado Group @@ -420,17 +442,19 @@ Proximité 付近のみ Proximidad + Prossimità Umgebung Tylko w pobliżu 附近 근처 + Proximidade All Vše Tous Alle - Tutte + Tutto Wszystko Tudo Все @@ -449,7 +473,7 @@ Kartenzeichen - Gruppeneinstellungen Gestos en mapas - Configuración de grupos Pointage sur carte - réglages de groupe - マップ ジェスチャー - グループ設定 + マップ ジェスチャ - グループ設定 지도 신호 - 그룹 설정 地图指示—队伍设定 地圖指示器 - 隊伍設定 @@ -464,7 +488,7 @@ ACE Kartenzeichen ACE Gestos en mapa ACE Pointage sur carte - ACE マップ ジェスチャー + ACE マップ ジェスチャ ACE 지도 신호 ACE 地图指示 ACE 地圖指示器 diff --git a/addons/maptools/CfgEventHandlers.hpp b/addons/maptools/CfgEventHandlers.hpp index db25394390..bff1c64e94 100644 --- a/addons/maptools/CfgEventHandlers.hpp +++ b/addons/maptools/CfgEventHandlers.hpp @@ -1,4 +1,3 @@ - class Extended_PreStart_EventHandlers { class ADDON { init = QUOTE(call COMPILE_SCRIPT(XEH_preStart)); diff --git a/addons/maptools/CfgVehicles.hpp b/addons/maptools/CfgVehicles.hpp index 8c320de321..0757aafc51 100644 --- a/addons/maptools/CfgVehicles.hpp +++ b/addons/maptools/CfgVehicles.hpp @@ -1,62 +1,204 @@ +#define EXCEPTIONS exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"} + class CfgVehicles { class Man; class CAManBase: Man { class ACE_SelfActions { class ACE_MapGpsShow { displayName = CSTRING(MapGpsShow); - condition = QUOTE((!GVAR(mapGpsShow)) && {call FUNC(canUseMapGPS)}); - statement = QUOTE(GVAR(mapGpsShow) = true;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + condition = QUOTE(!GVAR(mapGpsShow) && {call FUNC(canUseMapGPS)}); + statement = QUOTE(GVAR(mapGpsShow) = true); + EXCEPTIONS; showDisabled = 0; }; class ACE_MapGpsHide { displayName = CSTRING(MapGpsHide); - condition = QUOTE((GVAR(mapGpsShow)) && {call FUNC(canUseMapGPS)}); - statement = QUOTE(GVAR(mapGpsShow) = false;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + condition = QUOTE(GVAR(mapGpsShow) && {call FUNC(canUseMapGPS)}); + statement = QUOTE(GVAR(mapGpsShow) = false); + EXCEPTIONS; showDisabled = 0; }; class ACE_MapTools { displayName = CSTRING(MapTools_Menu); condition = QUOTE(call FUNC(canUseMapTools)); statement = ""; - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + EXCEPTIONS; showDisabled = 0; + class ACE_MapToolsHide { displayName = CSTRING(MapToolsHide); condition = QUOTE(GVAR(mapTool_Shown) != 0); - statement = QUOTE(GVAR(mapTool_Shown) = 0;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + statement = QUOTE(GVAR(mapTool_Shown) = 0); + EXCEPTIONS; showDisabled = 1; }; class ACE_MapToolsShowNormal { displayName = CSTRING(MapToolsShowNormal); condition = QUOTE(GVAR(mapTool_Shown) != 1); - statement = QUOTE(if (GVAR(mapTool_Shown) == 0) then {GVAR(mapTool_moveToMouse) = true}; GVAR(mapTool_Shown) = 1;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + statement = QUOTE(if (GVAR(mapTool_Shown) == 0) then {GVAR(mapTool_moveToMouse) = true}; GVAR(mapTool_Shown) = 1); + EXCEPTIONS; showDisabled = 1; }; class ACE_MapToolsShowSmall { displayName = CSTRING(MapToolsShowSmall); condition = QUOTE(GVAR(mapTool_Shown) != 2); - statement = QUOTE(if (GVAR(mapTool_Shown) == 0) then {GVAR(mapTool_moveToMouse) = true}; GVAR(mapTool_Shown) = 2;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + statement = QUOTE(if (GVAR(mapTool_Shown) == 0) then {GVAR(mapTool_moveToMouse) = true}; GVAR(mapTool_Shown) = 2); + EXCEPTIONS; showDisabled = 1; }; - class ACE_MapToolsAlignNorth { - displayName = CSTRING(MapToolsAlignNorth); + class ACE_MapToolsAlign { + displayName = CSTRING(AlignTo); condition = QUOTE(GVAR(mapTool_Shown) != 0); - statement = QUOTE(GVAR(mapTool_angle) = 0;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + statement = ""; + EXCEPTIONS; + showDisabled = 0; + + class ACE_MapToolsAlignToPlottingBoardRuler { + displayName = CSTRING(ToPlottingBoardRulerLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_Shown) == 2); + statement = QUOTE(GVAR(mapTool_angle) = GVAR(plottingBoard_rulerAngle)); + EXCEPTIONS; + showDisabled = 1; + }; + class ACE_MapToolsAlignToPlottingBoardAcrylic { + displayName = CSTRING(ToPlottingBoardAcrylicLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_Shown) != 0); + statement = QUOTE(GVAR(mapTool_angle) = GVAR(plottingBoard_acrylicAngle)); + EXCEPTIONS; + showDisabled = 1; + }; + class ACE_MapToolsAlignToPlottingBoard { + displayName = CSTRING(ToPlottingBoardLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_Shown) != 0); + statement = QUOTE(GVAR(mapTool_angle) = GVAR(plottingBoard_angle)); + EXCEPTIONS; + showDisabled = 1; + }; + class ACE_MapToolsAlignCompass { + displayName = CSTRING(ToCompassLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && {ACE_player getSlotItemName TYPE_COMPASS != ''}); + statement = QUOTE(GVAR(mapTool_angle) = getDir ACE_player); + EXCEPTIONS; + showDisabled = 1; + }; + class ACE_MapToolsAlignNorth { + displayName = CSTRING(ToNorthLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0); + statement = QUOTE(GVAR(mapTool_angle) = 0); + EXCEPTIONS; + showDisabled = 1; + }; + }; + }; + class ACE_PlottingBoard { + displayName = CSTRING(ShowPlottingBoard); + condition = QUOTE(GVAR(plottingBoard_Shown) == 0 && {call FUNC(canUsePlottingBoard)}); + statement = QUOTE(GVAR(plottingBoard_Shown) = 1); + EXCEPTIONS; + showDisabled = 0; + }; + class ACE_PlottingBoardHide { + displayName = CSTRING(HidePlottingBoard); + condition = QUOTE(GVAR(plottingBoard_Shown) != 0 && {call FUNC(canUsePlottingBoard)}); + statement = QUOTE(GVAR(plottingBoard_Shown) = 0); + EXCEPTIONS; + showDisabled = 0; + + class ACE_PlottingBoardRulerShow { + displayName = CSTRING(TogglePlottingBoardRuler); + condition = QUOTE(GVAR(plottingBoard_Shown) == 1); + statement = QUOTE(GVAR(plottingBoard_Shown) = 2); + EXCEPTIONS; showDisabled = 1; }; - class ACE_MapToolsAlignCompass { - displayName = CSTRING(MapToolsAlignCompass); - condition = QUOTE(GVAR(mapTool_Shown) != 0 && {getUnitLoadout ACE_player param [ARR_2(9,[])] param [ARR_2(3,'')] != ''}); - statement = QUOTE(GVAR(mapTool_angle) = getDir ACE_player;); - exceptions[] = {"isNotDragging", "notOnMap", "isNotInside", "isNotSitting"}; + class ACE_PlottingBoardRulerHide { + displayName = CSTRING(TogglePlottingBoardRuler); + condition = QUOTE(GVAR(plottingBoard_Shown) == 2); + statement = QUOTE(GVAR(plottingBoard_Shown) = 1); + EXCEPTIONS; showDisabled = 1; }; + class ACE_PlottingBoardWipe { + displayName = CSTRING(WipeBoard); + condition = QUOTE(GVAR(plottingBoard_markers) isNotEqualTo createHashMap); + statement = QUOTE(call FUNC(wipeMarkers)); + EXCEPTIONS; + showDisabled = 1; + }; + class ACE_PlottingBoardAlign { + displayName = CSTRING(AlignTo); + condition = QUOTE(GVAR(plottingBoard_Shown) != 0); + statement = ""; + EXCEPTIONS; + showDisabled = 0; + + class ACE_PlottingBoardAlignBoard { + displayName = CSTRING(PlottingBoardLabel); + condition = QUOTE(true); + statement = ""; + EXCEPTIONS; + showDisabled = 0; + + class ACE_PlottingBoardAlignBoardMaptool { + displayName = CSTRING(ToMapToolLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_angle) != GVAR(mapTool_angle)); + statement = QUOTE(GVAR(plottingBoard_angle) = GVAR(mapTool_angle)); + EXCEPTIONS; + showDisabled = 0; + }; + class ACE_PlottingBoardAlignBoardUp { + displayName = CSTRING(ToUpLabel); + condition = QUOTE(GVAR(plottingBoard_angle) != 0); + statement = QUOTE(GVAR(plottingBoard_angle) = 0); + EXCEPTIONS; + showDisabled = 0; + }; + }; + class ACE_PlottingBoardAlignAcrylic { + displayName = CSTRING(PlottingBoardAcrylicLabel); + condition = QUOTE(true); + statement = ""; + EXCEPTIONS; + showDisabled = 0; + + class ACE_PlottingBoardAlignAcrylicMaptool { + displayName = CSTRING(ToMapToolLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_acrylicAngle) != GVAR(mapTool_angle)); + statement = QUOTE(GVAR(plottingBoard_acrylicAngle) = GVAR(mapTool_angle)); + EXCEPTIONS; + showDisabled = 0; + }; + class ACE_PlottingBoardAlignAcrylicUp { + displayName = CSTRING(ToUpLabel); + condition = QUOTE(GVAR(plottingBoard_acrylicAngle) != 0); + statement = QUOTE(GVAR(plottingBoard_acrylicAngle) = 0); + EXCEPTIONS; + showDisabled = 0; + }; + }; + class ACE_PlottingBoardAlignRuler { + displayName = CSTRING(PlottingBoardRulerLabel); + condition = QUOTE(GVAR(plottingBoard_Shown) == 2); + statement = ""; + EXCEPTIONS; + showDisabled = 0; + + class ACE_PlottingBoardAlignRulerMaptool { + displayName = CSTRING(ToMapToolLabel); + condition = QUOTE(GVAR(mapTool_Shown) != 0 && GVAR(plottingBoard_rulerAngle) != GVAR(mapTool_angle)); + statement = QUOTE(GVAR(plottingBoard_rulerAngle) = GVAR(mapTool_angle)); + EXCEPTIONS; + showDisabled = 0; + }; + class ACE_PlottingBoardAlignRulerUp { + displayName = CSTRING(ToUpLabel); + condition = QUOTE(GVAR(plottingBoard_rulerAngle) != 0); + statement = QUOTE(GVAR(plottingBoard_rulerAngle) = 0); + EXCEPTIONS; + showDisabled = 0; + }; + }; + }; }; }; }; @@ -69,30 +211,35 @@ class CfgVehicles { class Box_NATO_Support_F: NATO_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_MapTools,12); + MACRO_ADDITEM(ACE_PlottingBoard,12); }; }; class Box_East_Support_F: EAST_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_MapTools,12); + MACRO_ADDITEM(ACE_PlottingBoard,12); }; }; class Box_IND_Support_F: IND_Box_Base { class TransportItems { MACRO_ADDITEM(ACE_MapTools,12); + MACRO_ADDITEM(ACE_PlottingBoard,12); }; }; class Box_FIA_Support_F: FIA_Box_Base_F { class TransportItems { MACRO_ADDITEM(ACE_MapTools,12); + MACRO_ADDITEM(ACE_PlottingBoard,12); }; }; class ACE_Box_Misc: Box_NATO_Support_F { class TransportItems { MACRO_ADDITEM(ACE_MapTools,12); + MACRO_ADDITEM(ACE_PlottingBoard,12); }; }; }; diff --git a/addons/maptools/CfgWeapons.hpp b/addons/maptools/CfgWeapons.hpp index f8a95acc73..ca4d4a473e 100644 --- a/addons/maptools/CfgWeapons.hpp +++ b/addons/maptools/CfgWeapons.hpp @@ -11,7 +11,20 @@ class CfgWeapons { scope = 2; ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.2; + }; + }; + + class ACE_PlottingBoard: ACE_ItemCore { + displayName = CSTRING(PlottingBoard_Name); + author = ECSTRING(common,ACETeam); + descriptionShort = CSTRING(PlottingBoard_Description); + model = QPATHTOF(data\ace_MapTools.p3d); + picture = QPATHTOF(UI\plottingboard_item.paa); + scope = 2; + ACE_isTool = 1; + class ItemInfo: CBA_MiscItem_ItemInfo { + mass = 0.5; }; }; }; diff --git a/addons/maptools/README.md b/addons/maptools/README.md index a11f57a1a5..fe9c836c13 100644 --- a/addons/maptools/README.md +++ b/addons/maptools/README.md @@ -5,3 +5,4 @@ Adds the following map tools: - Roamer - Map drawing - Showing GPS on map +- Plotting Board diff --git a/addons/maptools/UI/plottingboard_item.paa b/addons/maptools/UI/plottingboard_item.paa new file mode 100644 index 0000000000..2d89f35514 Binary files /dev/null and b/addons/maptools/UI/plottingboard_item.paa differ diff --git a/addons/maptools/XEH_PREP.hpp b/addons/maptools/XEH_PREP.hpp index cf193698e5..ac9ed8b91f 100644 --- a/addons/maptools/XEH_PREP.hpp +++ b/addons/maptools/XEH_PREP.hpp @@ -7,3 +7,8 @@ PREP(handleMouseMove); PREP(isInsideMapTool); PREP(openMapGpsUpdate); PREP(updateMapToolMarkers); + +PREP(canUsePlottingBoard); +PREP(isInsidePlottingBoard); +PREP(handlePlottingBoardMarkers); +PREP(wipeMarkers); diff --git a/addons/maptools/XEH_postInitClient.sqf b/addons/maptools/XEH_postInitClient.sqf index eede4db015..5ce1e68892 100644 --- a/addons/maptools/XEH_postInitClient.sqf +++ b/addons/maptools/XEH_postInitClient.sqf @@ -1,4 +1,4 @@ -// by esteldunedain +// by esteldunedain, LorenLuke #include "script_component.hpp" @@ -9,19 +9,32 @@ GVAR(mapGpsShow) = true; GVAR(mapGpsNextUpdate) = -1; GVAR(mapTool_Shown) = 0; -GVAR(mapTool_pos) = [0,0]; +GVAR(mapTool_pos) = [0, 0]; GVAR(mapTool_angle) = 0; GVAR(mapTool_isDragging) = false; GVAR(mapTool_isRotating) = false; GVAR(mapTool_moveToMouse) = true; // used to display it in center of screen when opened -//Install the event handers for the map tools on the main in-game map -[{!isNull findDisplay 12}, -{ - ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["MouseMoving", {_this call FUNC(handleMouseMove);}]; - ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["MouseButtonDown", {[1, _this] call FUNC(handleMouseButton);}]; - ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["MouseButtonUp", {[0, _this] call FUNC(handleMouseButton)}]; - ((findDisplay 12) displayCtrl 51) ctrlAddEventHandler ["Draw", {call FUNC(updateMapToolMarkers); call FUNC(openMapGpsUpdate);}]; +GVAR(plottingBoard_Shown) = 0; +GVAR(plottingBoard_pos) = [0, 0]; +GVAR(plottingBoard_angle) = 0; +GVAR(plottingBoard_acrylicAngle) = 0; +GVAR(plottingBoard_rulerAngle) = 0; +GVAR(plottingBoard_isDragging) = false; +GVAR(plottingBoard_isRotating) = -1; +GVAR(plottingBoard_moveToMouse) = true; // used to display it in center of screen when opened +GVAR(plottingBoard_markers) = createHashMap; + +// Install the event handers for the map tools on the main in-game map +[{ + !isNull findDisplay 12 +}, { + private _map = (findDisplay 12) displayCtrl 51; + + _map ctrlAddEventHandler ["MouseMoving", LINKFUNC(handleMouseMove)]; + _map ctrlAddEventHandler ["MouseButtonDown", {[1, _this] call FUNC(handleMouseButton);}]; + _map ctrlAddEventHandler ["MouseButtonUp", {[0, _this] call FUNC(handleMouseButton)}]; + _map ctrlAddEventHandler ["Draw", {call FUNC(updateMapToolMarkers); call FUNC(openMapGpsUpdate);}]; }, []] call CBA_fnc_waitUntilAndExecute; ["visibleMap", { @@ -32,7 +45,13 @@ GVAR(mapTool_moveToMouse) = true; // used to display it in center of screen whe }; }] call CBA_fnc_addPlayerEventHandler; +addMissionEventHandler ["MarkerCreated", { + [_this, false] call FUNC(handlePlottingBoardMarkers); +}]; + +addMissionEventHandler ["MarkerDeleted", { + [[_this select 0, -1, objNull, _this select 1], true] call FUNC(handlePlottingBoardMarkers); +}]; GVAR(freeDrawingData) = []; GVAR(freedrawing) = false; - diff --git a/addons/maptools/XEH_preInit.sqf b/addons/maptools/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/maptools/XEH_preInit.sqf +++ b/addons/maptools/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/maptools/data/plottingBoardAcrylic.paa b/addons/maptools/data/plottingBoardAcrylic.paa new file mode 100644 index 0000000000..eaa8bf2e13 Binary files /dev/null and b/addons/maptools/data/plottingBoardAcrylic.paa differ diff --git a/addons/maptools/data/plottingBoardBack.paa b/addons/maptools/data/plottingBoardBack.paa new file mode 100644 index 0000000000..79772e7cb0 Binary files /dev/null and b/addons/maptools/data/plottingBoardBack.paa differ diff --git a/addons/maptools/data/plottingBoardRuler.paa b/addons/maptools/data/plottingBoardRuler.paa new file mode 100644 index 0000000000..83160af799 Binary files /dev/null and b/addons/maptools/data/plottingBoardRuler.paa differ diff --git a/addons/maptools/functions/fnc_calculateMapScale.sqf b/addons/maptools/functions/fnc_calculateMapScale.sqf index 667ee5ff5d..7c868d200a 100644 --- a/addons/maptools/functions/fnc_calculateMapScale.sqf +++ b/addons/maptools/functions/fnc_calculateMapScale.sqf @@ -1,21 +1,22 @@ #include "..\script_component.hpp" /* * Author: esteldunedain - * Returns the equivalent of 100m in screen coordinates + * Returns the equivalent of 100m in screen coordinates. * * Arguments: * None * * Return Value: - * None + * Map scale * * Example: - * call ACE_maptools_fnc_calculateMapScale + * call ace_maptools_fnc_calculateMapScale * * Public: No */ -private _pos = ((findDisplay 12) displayCtrl 51) ctrlMapScreenToWorld [0.5, 0.5]; -private _screenOffset = ((findDisplay 12) displayCtrl 51) posWorldToScreen [(_pos select 0) + 100, (_pos select 1)]; +private _mapCtrl = (findDisplay 12) displayCtrl 51; +private _pos = _mapCtrl ctrlMapScreenToWorld [0.5, 0.5]; +private _screenOffset = _mapCtrl posWorldToScreen (_pos vectorAdd [100, 0]); (_screenOffset select 0) - 0.5 diff --git a/addons/maptools/functions/fnc_canUseMapGPS.sqf b/addons/maptools/functions/fnc_canUseMapGPS.sqf index 1d28af74f6..e9ca813288 100644 --- a/addons/maptools/functions/fnc_canUseMapGPS.sqf +++ b/addons/maptools/functions/fnc_canUseMapGPS.sqf @@ -1,20 +1,23 @@ #include "..\script_component.hpp" /* * Author: esteldunedain - * canUseMapGPS + * Returns if the GPS on the map can be used. * * Arguments: * None * * Return Value: - * Boolean + * GPS can be used * * Example: - * call ACE_maptools_fnc_canUseMapGPS + * call ace_maptools_fnc_canUseMapGPS * * Public: No */ -visibleMap && -{alive ACE_player} && -{"ItemGPS" in (assignedItems ACE_player)} +if (!visibleMap || {!alive ACE_player}) exitWith {false}; + +private _panels = flatten (ACE_player infoPanelComponents "left"); +private _index = _panels find "MinimapDisplayComponent"; + +_index != -1 && {_panels select (_index + 1)} diff --git a/addons/maptools/functions/fnc_canUseMapTools.sqf b/addons/maptools/functions/fnc_canUseMapTools.sqf index ef45c9a527..8eb918dfdc 100644 --- a/addons/maptools/functions/fnc_canUseMapTools.sqf +++ b/addons/maptools/functions/fnc_canUseMapTools.sqf @@ -1,23 +1,23 @@ #include "..\script_component.hpp" /* * Author: esteldunedain - * canUseMapTools + * Returns if the map tools can be used. * * Arguments: * None * * Return Value: - * Boolean + * Map tools can be used * * Example: - * call ACE_maptools_fnc_canUseMapTools + * call ace_maptools_fnc_canUseMapTools * * Public: No */ visibleMap && {alive ACE_player} && -{"ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems))} && {!GVAR(mapTool_isDragging)} && {!GVAR(mapTool_isRotating)} && -{getUnitLoadout ACE_player param [9, []] param [0, ""] != ""} +{ACE_player getSlotItemName TYPE_MAP != ""} && +{[ACE_player, "ACE_MapTools"] call EFUNC(common,hasItem)} diff --git a/addons/maptools/functions/fnc_canUsePlottingBoard.sqf b/addons/maptools/functions/fnc_canUsePlottingBoard.sqf new file mode 100644 index 0000000000..9dfd2bf6b5 --- /dev/null +++ b/addons/maptools/functions/fnc_canUsePlottingBoard.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Returns if the plotting board can be used. + * + * Arguments: + * None + * + * Return Value: + * Plotting board can be used + * + * Example: + * call ace_maptools_fnc_canUsePlottingBoard + * + * Public: No + */ + +visibleMap && +{alive ACE_player} && +{!GVAR(plottingBoard_isDragging)} && +{GVAR(plottingBoard_isRotating) == -1} && +{[ACE_player, "ACE_PlottingBoard"] call EFUNC(common,hasItem)} diff --git a/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf b/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf index 722f96468e..782d8762a0 100644 --- a/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf +++ b/addons/maptools/functions/fnc_drawLinesOnRoamer.sqf @@ -4,63 +4,71 @@ * Prevents the cursor from entering the roamer when drawing lines and records the positions * * Arguments: - * 0: The Map + * 0: Map control * 1: Roamer Width * * Return Value: * None * * Example: - * [map, 300] call ace_maptools_fnc_drawLinesOnRoamer + * [CONTROL, 300] call ace_maptools_fnc_drawLinesOnRoamer * * Public: No */ if (!GVAR(drawStraightLines)) exitWith {}; -params ["_theMap", "_roamerWidth"]; +params ["_mapCtrl", "_roamerWidth"]; GVAR(mapTool_pos) params ["_roamerPosX", "_roamerPosY"]; private _posCenter = [_roamerPosX, _roamerPosY, 0]; private _posTopRight = [ -_roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, -_roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, -0]; + _roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, + _roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, + 0 +]; private _posTopLeft = [ -_roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, -_roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, -0]; + _roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, + _roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_TOP_TO_CENTER_PERC * _roamerWidth, + 0 +]; private _posBottomLeft = [ -_roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, -_roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, -0]; + _roamerPosX + (-cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, + _roamerPosY + (sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, + 0 +]; private _posBottomRight = [ -_roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, -_roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, -0]; + _roamerPosX + (cos GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (sin GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, + _roamerPosY + (-sin GVAR(mapTool_angle)) * DIST_LEFT_TO_CENTER_PERC * _roamerWidth + (cos GVAR(mapTool_angle)) * DIST_BOTTOM_TO_CENTER_PERC * _roamerWidth, + 0 +]; -private _fnc_Distance = { // Get distance point _p is from a line made from _a to _b (uses 3d array commands, but z should be 0) +private _fnc_distance = { // Get distance point _p is from a line made from _a to _b (uses 3d array commands, but z should be 0) // Ref: https://en.wikipedia.org/wiki/Distance_from_a_point_to_a_line#Vector_formulation params ["_a", "_b", "_p"]; + private _n = _b vectorDiff _a; private _pa = _a vectorDiff _p; private _c = _n vectorMultiply ((_pa vectorDotProduct _n) / (_n vectorDotProduct _n)); private _d = _pa vectorDiff _c; - sqrt (_d vectorDotProduct _d); + + sqrt (_d vectorDotProduct _d) }; -private _currentMousePos = _theMap ctrlMapScreenToWorld getMousePosition; +private _currentMousePos = _mapCtrl ctrlMapScreenToWorld getMousePosition; _currentMousePos set [2, 0]; // Break the roamer rectangle into 4 triangle, one for each side switch (true) do { case (_currentMousePos inPolygon [_posCenter, _posTopLeft, _posBottomLeft]): { // Left - private _distanceToRoamerLine = ([_posTopLeft, _posBottomLeft, _currentMousePos] call _fnc_Distance); - _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) - 90) ,0] call CBA_fnc_polar2vect); + private _distanceToRoamerLine = [_posTopLeft, _posBottomLeft, _currentMousePos] call _fnc_distance; + + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, GVAR(mapTool_angle) - 90, 0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line GVAR(freeDrawingData) = ["left", _currentMousePos, _currentMousePos]; } else { @@ -68,17 +76,21 @@ switch (true) do { if ((_currentMousePos distance2d _posTopLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posTopLeft)) then { GVAR(freeDrawingData) set [1, _currentMousePos]; }; + if ((_currentMousePos distance2d _posBottomLeft) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomLeft)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; }; - private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + + private _screenPosOfCorrectedPos = _mapCtrl ctrlMapWorldToScreen _currentMousePos; setMousePosition _screenPosOfCorrectedPos; }; case (_currentMousePos inPolygon [_posCenter, _posTopLeft, _posTopRight]): { // Top - private _distanceToRoamerLine = ([_posTopLeft, _posTopRight, _currentMousePos] call _fnc_Distance); - _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 0) ,0] call CBA_fnc_polar2vect); + private _distanceToRoamerLine = [_posTopLeft, _posTopRight, _currentMousePos] call _fnc_distance; + + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, GVAR(mapTool_angle), 0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line GVAR(freeDrawingData) = ["top", _currentMousePos, _currentMousePos]; } else { @@ -86,17 +98,21 @@ switch (true) do { if ((_currentMousePos distance2d _posTopLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posTopLeft)) then { GVAR(freeDrawingData) set [1, _currentMousePos]; }; + if ((_currentMousePos distance2d _posTopRight) < ((GVAR(freeDrawingData) select 2) distance2d _posTopRight)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; }; - private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + + private _screenPosOfCorrectedPos = _mapCtrl ctrlMapWorldToScreen _currentMousePos; setMousePosition _screenPosOfCorrectedPos; }; case (_currentMousePos inPolygon [_posCenter, _posTopRight, _posBottomRight]): { // Right - private _distanceToRoamerLine = ([_posTopRight, _posBottomRight, _currentMousePos] call _fnc_Distance); - _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 90) ,0] call CBA_fnc_polar2vect); + private _distanceToRoamerLine = [_posTopRight, _posBottomRight, _currentMousePos] call _fnc_distance; + + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, GVAR(mapTool_angle) + 90, 0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line GVAR(freeDrawingData) = ["right", _currentMousePos, _currentMousePos]; } else { @@ -104,17 +120,21 @@ switch (true) do { if ((_currentMousePos distance2d _posTopRight) < ((GVAR(freeDrawingData) select 1) distance2d _posTopRight)) then { GVAR(freeDrawingData) set [1, _currentMousePos]; }; + if ((_currentMousePos distance2d _posBottomRight) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomRight)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; }; - private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + + private _screenPosOfCorrectedPos = _mapCtrl ctrlMapWorldToScreen _currentMousePos; setMousePosition _screenPosOfCorrectedPos; }; case (_currentMousePos inPolygon [_posCenter, _posBottomLeft, _posBottomRight]): { // Bottom - private _distanceToRoamerLine = ([_posBottomLeft, _posBottomRight, _currentMousePos] call _fnc_Distance); - _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, (GVAR(mapTool_angle) + 180) ,0] call CBA_fnc_polar2vect); + private _distanceToRoamerLine = [_posBottomLeft, _posBottomRight, _currentMousePos] call _fnc_distance; + + _currentMousePos = _currentMousePos vectorAdd ([_distanceToRoamerLine, GVAR(mapTool_angle) + 180, 0] call CBA_fnc_polar2vect); + if (GVAR(freeDrawingData) isEqualTo []) then { // We start drawing on the line GVAR(freeDrawingData) = ["bottom", _currentMousePos, _currentMousePos]; } else { @@ -122,23 +142,26 @@ switch (true) do { if ((_currentMousePos distance2d _posBottomLeft) < ((GVAR(freeDrawingData) select 1) distance2d _posBottomLeft)) then { GVAR(freeDrawingData) set [1, _currentMousePos]; }; + if ((_currentMousePos distance2d _posBottomRight) < ((GVAR(freeDrawingData) select 2) distance2d _posBottomRight)) then { GVAR(freeDrawingData) set [2, _currentMousePos]; }; }; }; - private _screenPosOfCorrectedPos = _theMap ctrlMapWorldToScreen _currentMousePos; + + private _screenPosOfCorrectedPos = _mapCtrl ctrlMapWorldToScreen _currentMousePos; setMousePosition _screenPosOfCorrectedPos; }; }; #ifdef DEBUG_MODE_FULL -_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posTopRight,24,24,getDir player,'1,1',1,0.03,'TahomaB','right']; -_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posTopLeft,24,24,getDir player,'-1,1',1,0.03,'TahomaB','right']; -_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posBottomLeft,24,24,getDir player,'-1,-1',1,0.03,'TahomaB','right']; -_theMap drawIcon ['iconStaticMG',[1,0,0,1],_posBottomRight,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; +_mapCtrl drawIcon ['iconStaticMG',[1,0,0,1],_posTopRight,24,24,getDir player,'1,1',1,0.03,'TahomaB','right']; +_mapCtrl drawIcon ['iconStaticMG',[1,0,0,1],_posTopLeft,24,24,getDir player,'-1,1',1,0.03,'TahomaB','right']; +_mapCtrl drawIcon ['iconStaticMG',[1,0,0,1],_posBottomLeft,24,24,getDir player,'-1,-1',1,0.03,'TahomaB','right']; +_mapCtrl drawIcon ['iconStaticMG',[1,0,0,1],_posBottomRight,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; + if (GVAR(freeDrawingData) isNotEqualTo []) then { - _theMap drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 1,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; - _theMap drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 2,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; + _mapCtrl drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 1,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; + _mapCtrl drawIcon ['iconStaticMG',[0,0,1,1],GVAR(freeDrawingData) select 2,24,24,getDir player,'1,-1',1,0.03,'TahomaB','right']; }; #endif diff --git a/addons/maptools/functions/fnc_handleMouseButton.sqf b/addons/maptools/functions/fnc_handleMouseButton.sqf index beee6157eb..5c35c699d7 100644 --- a/addons/maptools/functions/fnc_handleMouseButton.sqf +++ b/addons/maptools/functions/fnc_handleMouseButton.sqf @@ -1,17 +1,17 @@ #include "..\script_component.hpp" /* - * Author: esteldunedain + * Author: esteldunedain, LorenLuke * Handle mouse buttons. * * Arguments: - * 0: 1 if mouse down down, 0 if mouse button up + * 0: 1 if mouse down down, 0 if mouse button up * 1: Parameters of the mouse button event * * Return Value: - * true if event was handled + * None * * Example: - * [0, [array]] call ACE_maptools_fnc_handleMouseButton + * [0, []] call ace_maptools_fnc_handleMouseButton * * Public: No */ @@ -24,20 +24,27 @@ TRACE_2("params",_dir,_params); if ((_button == 0) && {GVAR(freedrawing) || _ctrlKey}) exitWith { if (GVAR(freedrawing) && {_dir == 0}) then { GVAR(freedrawing) = false; + if (_shiftKey) exitWith { TRACE_1("using vanilla straight line",_shiftKey); }; + TRACE_2("Ending Line",GVAR(freedrawing),GVAR(freeDrawingData)); + [{ - if (allMapMarkers isEqualTo []) exitWith {}; - private _markerName = allMapMarkers select (count allMapMarkers - 1); + if (GVAR(freeDrawingData) isEqualTo []) exitWith {TRACE_1("never touched roamer",GVAR(freeDrawingData))}; + + private _allMarkers = allMapMarkers; + + if (_allMarkers isEqualTo []) exitWith {}; + + private _markerName = _allMarkers select -1; private _markerPos = getMarkerPos _markerName; - private _distanceCheck = _markerPos distance2d GVAR(drawPosStart); + private _distanceCheck = _markerPos distance2D GVAR(drawPosStart); TRACE_3("Line Drawn",_markerName,_markerPos,_distanceCheck); - if (_distanceCheck > 1) exitWith {WARNING("Wrong Marker!");}; - if ((count GVAR(freeDrawingData)) != 3) exitWith {TRACE_1("never touched roamer",GVAR(freeDrawingData));}; + if (_distanceCheck > 1) exitWith {WARNING("Wrong Marker!")}; GVAR(freeDrawingData) params ["", "_startStraightPos", "_endStraightPos"]; @@ -54,63 +61,112 @@ if ((_button == 0) && {GVAR(freedrawing) || _ctrlKey}) exitWith { TRACE_2("Starting Line",GVAR(freedrawing),GVAR(drawPosStart)); } else { GVAR(freedrawing) = false; - TRACE_1("weird - reseting",GVAR(freedrawing)); + TRACE_1("weird - resetting",GVAR(freedrawing)); }; }; - false + + false // return +}; + +// If it's not a left button event, exit +if (_button != 0) exitWith { + false // return }; private _handled = false; -// If it's not a left button event, exit -if (_button != 0) exitWith {_handled}; - // If releasing if (_dir != 1) then { if (GVAR(mapTool_isDragging) || GVAR(mapTool_isRotating)) then { GVAR(mapTool_isDragging) = false; GVAR(mapTool_isRotating) = false; - _handled = true; + }; + + if (GVAR(plottingBoard_isDragging) || GVAR(plottingBoard_isRotating) > -1) then { + GVAR(plottingBoard_isDragging) = false; + GVAR(plottingBoard_isRotating) = -1; }; } else { // If clicking - if !(call FUNC(canUseMapTools)) exitWith {}; + if (call FUNC(canUseMapTools)) then { + GVAR(mapTool_isDragging) = false; + GVAR(mapTool_isRotating) = false; - // Transform mouse screen position to coordinates - private _pos = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY]; - _pos set [count _pos, 0]; + // If no map tool marker then exit + if (GVAR(mapTool_Shown) != 0) then { + // Transform mouse screen position to coordinates + private _pos = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY]; - GVAR(mapTool_isDragging) = false; - GVAR(mapTool_isRotating) = false; + // Check if clicking the maptool + if (_pos call FUNC(isInsideMapTool)) then { + // Store data for dragging + GVAR(mapTool_startPos) = +GVAR(mapTool_pos); + GVAR(mapTool_startDragPos) = _pos; - // If no map tool marker then exit - if (GVAR(mapTool_Shown) == 0) exitWith {}; + private _rotateKeyPressed = switch (GVAR(rotateModifierKey)) do { + case 1: {_altKey}; + case 2: {_ctrlKey}; + case 3: {_shiftKey}; + default {false}; + }; - // Check if clicking the maptool - if (_pos call FUNC(isInsideMapTool)) exitWith { - // Store data for dragging - GVAR(mapTool_startPos) = + GVAR(mapTool_pos); - GVAR(mapTool_startDragPos) = + _pos; + if (_rotateKeyPressed) then { + // Store data for rotating + GVAR(mapTool_startAngle) = GVAR(mapTool_angle); - private _rotateKeyPressed = switch (GVAR(rotateModifierKey)) do { - case (1): {_altKey}; - case (2): {_ctrlKey}; - case (3): {_shiftKey}; - default {false}; + private _pos = GVAR(mapTool_startDragPos) vectorDiff GVAR(mapTool_startPos); + GVAR(mapTool_startDragAngle) = ((_pos select 0) atan2 (_pos select 1) + 360) % 360; + + // Start rotating + GVAR(mapTool_isRotating) = true; + } else { + // Start dragging + GVAR(mapTool_isDragging) = true; + }; + }; }; + }; - if (_rotateKeyPressed) then { - // Store data for rotating - GVAR(mapTool_startAngle) = + GVAR(mapTool_angle); - GVAR(mapTool_startDragAngle) = (180 + ((GVAR(mapTool_startDragPos) select 0) - (GVAR(mapTool_startPos) select 0)) atan2 ((GVAR(mapTool_startDragPos) select 1) - (GVAR(mapTool_startPos) select 1)) mod 360); - // Start rotating - GVAR(mapTool_isRotating) = true; - } else { - // Start dragging - GVAR(mapTool_isDragging) = true; + if (call FUNC(canUsePlottingBoard)) then { + GVAR(plottingBoard_isDragging) = false; + GVAR(plottingBoard_isRotating) = -1; + + if (GVAR(plottingBoard_Shown) != 0) then { + // Transform mouse screen position to coordinates + private _pos = _control ctrlMapScreenToWorld [_screenPosX, _screenPosY]; + private _click = _pos call FUNC(isInsidePlottingBoard); + + if (_click > -1) then { + GVAR(plottingBoard_startPos) = +GVAR(plottingBoard_pos); + GVAR(plottingBoard_startDragPos) = _pos; + + private _rotateKeyPressed = switch (GVAR(rotateModifierKey)) do { + case 1: {_altKey}; + case 2: {_ctrlKey}; + case 3: {_shiftKey}; + default {false}; + }; + + if (_rotateKeyPressed) then { + // Store data for rotating + private _ang = switch (_click) do { + case 1: {GVAR(plottingBoard_acrylicAngle)}; + case 2: {GVAR(plottingBoard_rulerAngle)}; + default {GVAR(plottingBoard_angle)}; + }; + + GVAR(plottingBoard_startAngle) = _ang; + + private _pos = GVAR(plottingBoard_startDragPos) vectorDiff GVAR(plottingBoard_startPos); + GVAR(plottingBoard_startDragAngle) = ((_pos select 0) atan2 (_pos select 1) + 360) % 360; + + // Start rotating + GVAR(plottingBoard_isRotating) = _click; + } else { + // Start dragging + GVAR(plottingBoard_isDragging) = true; + }; + }; }; - _handled = true; }; }; - -_handled diff --git a/addons/maptools/functions/fnc_handleMouseMove.sqf b/addons/maptools/functions/fnc_handleMouseMove.sqf index 5af4f02e30..3092d2d532 100644 --- a/addons/maptools/functions/fnc_handleMouseMove.sqf +++ b/addons/maptools/functions/fnc_handleMouseMove.sqf @@ -1,49 +1,66 @@ #include "..\script_component.hpp" /* - * Author: esteldunedain - * Handle mouse movement over the map tool. + * Author: esteldunedain, LorenLuke + * Handle mouse movement over the map tool and plotting board. * * Arguments: - * 0: Map Control - * 1: Mouse position on screen coordinates + * 0: Map control + * 1: Mouse x position + * 2: Mouse y position * * Return Value: - * true if event was handled + * None * * Example: - * [CONTROL, [0, 5, 1]] call ACE_maptools_fnc_handleMouseMove + * [CONTROL, [0, 5]] call ace_maptools_fnc_handleMouseMove * * Public: No */ -params ["_control", "_mousePosX", "_mousePosY"]; -TRACE_3("params",_control,_mousePosX,_mousePosY); +params ["_mapCtrl", "_mousePosX", "_mousePosY"]; +TRACE_3("params",_mapCtrl,_mousePosX,_mousePosY); // If have no map tools, then exit -if (((isNull ACE_player) || {!("ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems)))})) exitWith { - false -}; +if (isNull ACE_player || { + private _uniqueItems = ACE_player call EFUNC(common,uniqueItems); + + !(("ACE_MapTools" in _uniqueItems) || {"ACE_PlottingBoard" in _uniqueItems}) +}) exitWith {}; // If map tools not shown, then exit -if (GVAR(mapTool_Shown) == 0) exitWith {false}; +if (GVAR(mapTool_Shown) == 0 && {GVAR(plottingBoard_Shown) == 0}) exitWith {false}; -private _mousePosition = _control ctrlMapScreenToWorld [_mousePosX, _mousePosY]; +private _mousePosition = _mapCtrl ctrlMapScreenToWorld [_mousePosX, _mousePosY]; -// Translation +// Map tools - translation if (GVAR(mapTool_isDragging)) exitWith { - GVAR(mapTool_pos) set [0, (GVAR(mapTool_startPos) select 0) + (_mousePosition select 0) - (GVAR(mapTool_startDragPos) select 0)]; - GVAR(mapTool_pos) set [1, (GVAR(mapTool_startPos) select 1) + (_mousePosition select 1) - (GVAR(mapTool_startDragPos) select 1)]; - - true + GVAR(mapTool_pos) = GVAR(mapTool_startPos) vectorAdd _mousePosition vectorDiff GVAR(mapTool_startDragPos); }; -// Rotation +// Map tools - rotation if (GVAR(mapTool_isRotating)) exitWith { // Get new angle - private _angle = (180 + ((_mousePosition select 0) - (GVAR(mapTool_startPos) select 0)) atan2 ((_mousePosition select 1) - (GVAR(mapTool_startPos) select 1)) mod 360); - GVAR(mapTool_angle) = GVAR(mapTool_startAngle) + _angle - GVAR(mapTool_startDragAngle); + private _pos = _mousePosition vectorDiff GVAR(mapTool_startPos); + private _angle = (_pos select 0) atan2 (_pos select 1); - true + GVAR(mapTool_angle) = ((GVAR(mapTool_startAngle) + _angle - GVAR(mapTool_startDragAngle)) % 360 + 360) % 360; }; -false +// Plotting board - translation +if (GVAR(plottingBoard_isDragging)) exitWith { + GVAR(plottingBoard_pos) = GVAR(plottingBoard_startPos) vectorAdd _mousePosition vectorDiff GVAR(plottingBoard_startDragPos); +}; + +// Plotting board - rotation +if (GVAR(plottingBoard_isRotating) > -1) exitWith { + // Get new angle + private _pos = _mousePosition vectorDiff GVAR(plottingBoard_startPos); + private _angle = (_pos select 0) atan2 (_pos select 1); + private _returnAngle = ((GVAR(plottingBoard_startAngle) + _angle - GVAR(plottingBoard_startDragAngle)) % 360 + 360) % 360; + + switch (GVAR(plottingBoard_isRotating)) do { + case 0: {GVAR(plottingBoard_angle) = _returnAngle}; + case 1: {GVAR(plottingBoard_acrylicAngle) = _returnAngle}; + case 2: {GVAR(plottingBoard_rulerAngle) = _returnAngle}; + }; +}; diff --git a/addons/maptools/functions/fnc_handlePlottingBoardMarkers.sqf b/addons/maptools/functions/fnc_handlePlottingBoardMarkers.sqf new file mode 100644 index 0000000000..b7a0c7657a --- /dev/null +++ b/addons/maptools/functions/fnc_handlePlottingBoardMarkers.sqf @@ -0,0 +1,219 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke, johnb43 + * Handle map marker creation. + * If a marker is (partially) on the plotting board, the parts on the plotting board are attached to the plotting board + * and move with the board accordingly. + * + * Arguments: + * 0: Arguments + * - 0: Marker name + * - 1: Chat channel number + * - 2: Marker owner + * - 3: Local origin + * 1: Deleted + * + * Return Value: + * None + * + * Example: + * [CONTROL, [0, 5]] call ace_maptools_fnc_handlePlottingBoardMarkers + * + * Public: No + */ + +params ["_args", "_deleted"]; +_args params ["_marker", "_channelNumber", "_owner", "_local"]; + +if (_deleted) exitWith { + GVAR(plottingBoard_markers) deleteAt _marker; +}; + +// Do not process non-local or already processed markers, don't check if the plotting board isn't shown +if (!_local || {GVAR(plottingBoard_Shown) == 0} || {QUOTE(ADDON) in _marker}) exitWith {}; + +// Check if the channel the marker was made in can be marked on the plotting board +private _continue = true; + +if (isMultiplayer) then { + switch (GVAR(plottingBoardAllowChannelDrawing)) do { + case 0: { + if (_channelNumber != 5) then {_continue = false}; + }; + case 1: { + if !(_channelNumber in [3, 5]) then {_continue = false}; + }; + }; +}; + +if (!_continue) exitWith {}; + +private _boardPos = GVAR(plottingBoard_pos); +private _boardAng = GVAR(plottingBoard_acrylicAngle); + +private _markerPolyline = markerPolyline _marker; +private _count = count _markerPolyline; + +// If the marker is not a polyline marker +if (_count == 0) exitWith { + private _diffPos = (getMarkerPos _marker) vectorDiff _boardPos; + + // If the marker is on the acrylic or ruler of the plotting board, save it + if (vectorMagnitude _diffPos < PLOTTINGBOARD_DRAWRANGE) then { + private _relPos = [[0, 0], _diffPos, _boardAng] call CBA_fnc_vectRotate2D; + + GVAR(plottingBoard_markers) set [_marker, [_relPos, [], _boardAng, +_boardPos, 1]]; + }; +}; + +// If the marker is a polyline marker, but doesn't have enough components (happens when you ctrl-left click on the map), ignore +if (_count <= 4) exitWith {}; + +// Polyine markers (lines) +private _startPos = []; +private _endPos = []; +private _dir = []; +private _diffPos = []; + +private _a = 0; +private _b = 0; +private _c = 0; +private _t1 = nil; +private _t2 = nil; +private _delta = 0; + +private _intersectionValid1 = false; +private _intersectionValid2 = false; +private _intersectPoint1 = []; +private _intersectPoint2 = []; +private _intersectClose = []; +private _intersectFar = []; + +private _polylineIndex = 0; +private _markerArray = [[]]; +private _insideArray = []; + +for "_i" from 0 to _count - 1 - 2 step 2 do { + _startPos = [_markerPolyline select _i, _markerPolyline select (_i + 1)]; + _endPos = [_markerPolyline select (_i + 2), _markerPolyline select (_i + 3)]; + _dir = _endPos vectorDiff _startPos; + _diffPos = _startPos vectorDiff _boardPos; + + // Circle-line intersection: Check for intersections between plotting board and current piece of polyline + // https://stackoverflow.com/a/1084899 + _a = _dir vectorDotProduct _dir; + _b = 2 * (_diffPos vectorDotProduct _dir); + _c = (_diffPos vectorDotProduct _diffPos) - PLOTTINGBOARD_DRAWRANGE^2; + + _delta = _b^2 - 4 * _a * _c; + + // Stretch factors + _t1 = nil; + _t2 = nil; + + if (_delta > 0) then { + _t1 = (-_b + sqrt _delta) / (2 * _a); + _t2 = (-_b - sqrt _delta) / (2 * _a); + + // Don't look for intersection points beyond the start or end points + if (_t1 < 0 || _t1 > 1) then { + _t1 = nil; + }; + + if (_t2 < 0 || _t2 > 1) then { + _t2 = nil; + }; + }; + + // The current point is always part of a polyline + (_markerArray param [_polylineIndex, []]) append _startPos; + _insideArray set [_polylineIndex, vectorMagnitude _diffPos < PLOTTINGBOARD_DRAWRANGE]; // keep track if point is within plotting board + + _intersectionValid1 = !isNil "_t1"; + _intersectionValid2 = !isNil "_t2"; + + // If no valid intersection points, continue + if (!_intersectionValid1 && {!_intersectionValid2}) then { + continue; + }; + + // Extremely rare case if the marker is tangential to the plotting board: Ignore + if (_intersectionValid1 && {_intersectionValid2} && {_t1 == _t2}) then { + continue; + }; + + if (_intersectionValid1) then { + _intersectPoint1 = _startPos vectorAdd (_dir vectorMultiply _t1); + }; + + if (_intersectionValid2) then { + _intersectPoint2 = _startPos vectorAdd (_dir vectorMultiply _t2); + }; + + // When a marker crosses the plotting board entirely (one straight line through the plotting board) + if (_intersectionValid1 && {_intersectionValid2}) then { + // Take the closer point first + _intersectClose = [_intersectPoint1, _intersectPoint2] select (_t1 > _t2); + + // Finish previous polyline with the last point being the intersection + (_markerArray select _polylineIndex) append _intersectClose; + + // Create a new polyline, with the first point being the closest intersection + _polylineIndex = _polylineIndex + 1; + _markerArray set [_polylineIndex, _intersectClose]; + + // Now take the point further away + _intersectFar = [_intersectPoint1, _intersectPoint2] select (_t1 < _t2); + + // Make a polyline between the intersection points + (_markerArray select _polylineIndex) append _intersectClose; + (_markerArray select _polylineIndex) append _intersectFar; + _insideArray set [_polylineIndex, true]; // with 2 intersections, this part of the polyline must be inside + + // Create a new polyline, with the first point being the furthest intersection + _polylineIndex = _polylineIndex + 1; + _markerArray set [_polylineIndex, _intersectFar]; + } else { + // Only 1 intersection (either point 1 or 2, exclusive or) + if (_intersectionValid2) then { + _intersectPoint1 = _intersectPoint2; + }; + + // Finish previous polyline with the last point being the intersection + (_markerArray select _polylineIndex) append _intersectPoint1; + + // Create a new polyline, with the first point being the intersection + _polylineIndex = _polylineIndex + 1; + _markerArray set [_polylineIndex, _intersectPoint1]; + }; +}; + +// If there were no polyline intersections and the marker was not on the plotting board, don't create new markers +if (_insideArray isEqualTo [false]) exitWith {}; + +private _color = getMarkerColor _marker; +private _name = ""; +private _polylineRelative = []; +private _relPos = []; + +{ + _name = format ["%1-%2-%3", _marker, _forEachIndex, QUOTE(ADDON)]; // adding an identifier allow to check if marker was already processed + createMarkerLocal [_name, [0, 0], _channelNumber, _owner]; + _name setMarkerColorLocal _color; + _name setMarkerPolyline _x; // global marker broadcast + + // If the marker was on the plotting board, take it's unrotated position and store it + if (_insideArray select _forEachIndex) then { + _polylineRelative = []; + + for "_i" from 0 to count _x - 1 step 2 do { + _relPos = [[0, 0], [_x select _i, _x select (_i + 1)] vectorDiff _boardPos, _boardAng] call CBA_fnc_vectRotate2D; + _polylineRelative append _relPos; + }; + + GVAR(plottingBoard_markers) set [_name, [[0, 0], +_polylineRelative, _boardAng, +_boardPos, 1]]; + }; +} forEach _markerArray; + +// Delete original marker +deleteMarker _marker; diff --git a/addons/maptools/functions/fnc_isInsideMapTool.sqf b/addons/maptools/functions/fnc_isInsideMapTool.sqf index f6c633d885..ad80357411 100644 --- a/addons/maptools/functions/fnc_isInsideMapTool.sqf +++ b/addons/maptools/functions/fnc_isInsideMapTool.sqf @@ -4,32 +4,32 @@ * Return true if the position is inside the map marker (to allow dragging). * * Arguments: - * 0: x Position (in meters) - * 1: y Position (in meters) + * 0: x position (in meters) + * 1: y position (in meters) * * Return Value: - * Boolean + * Is inside map tool * * Example: - * [0, 5] call ACE_maptools_fnc_isInsideMapTool + * [0, 5] call ace_maptools_fnc_isInsideMapTool * * Public: No */ if (GVAR(mapTool_Shown) == 0) exitWith {false}; + private _textureWidth = [TEXTURE_WIDTH_IN_M, TEXTURE_WIDTH_IN_M / 2] select (GVAR(mapTool_Shown) - 1); -private _pos = [_this select 0, _this select 1, 0]; -private _relPos = _pos vectorDiff [GVAR(mapTool_pos) select 0, GVAR(mapTool_pos) select 1, 0]; -private _dirVector = [sin(GVAR(mapTool_angle)), cos(GVAR(mapTool_angle)), 0]; +private _relPos = _this vectorDiff GVAR(mapTool_pos); +private _dirVector = [sin GVAR(mapTool_angle), cos GVAR(mapTool_angle)]; // Projection of the relative position over the longitudinal axis of the map tool private _lambdaLong = _dirVector vectorDotProduct _relPos; + if (_lambdaLong < DIST_BOTTOM_TO_CENTER_PERC * _textureWidth) exitWith {false}; - -// Projection of the relative position over the trasversal axis of the map tool -private _lambdaTrasAbs = vectorMagnitude (_relPos vectorDiff (_dirVector vectorMultiply _lambdaLong)); if (_lambdaLong > DIST_TOP_TO_CENTER_PERC * _textureWidth) exitWith {false}; -if (_lambdaTrasAbs > DIST_LEFT_TO_CENTER_PERC * _textureWidth) exitWith {false}; -true +// Projection of the relative position over the transversal axis of the map tool +private _lambdaTransAbs = vectorMagnitude (_relPos vectorDiff (_dirVector vectorMultiply _lambdaLong)); + +_lambdaTransAbs <= DIST_LEFT_TO_CENTER_PERC * _textureWidth diff --git a/addons/maptools/functions/fnc_isInsidePlottingBoard.sqf b/addons/maptools/functions/fnc_isInsidePlottingBoard.sqf new file mode 100644 index 0000000000..e3e6467508 --- /dev/null +++ b/addons/maptools/functions/fnc_isInsidePlottingBoard.sqf @@ -0,0 +1,56 @@ +#include "..\script_component.hpp" +/* + * Author: LorenLuke + * Return if the position is inside the map marker (to allow dragging) or not. + * + * Arguments: + * 0: x position (in meters) + * 1: y position (in meters) + * + * Return Value: + * Where in the plotting board it is + * -1 - Nowhere, 0 - In the Board, 1 - In the Acrylic, 2 - In the Ruler + * + * Example: + * [0, 5] call ace_maptools_fnc_isInsidePlottingBoard + * + * Public: No + */ + +if (GVAR(plottingBoard_Shown) == 0) exitWith {-1}; + +private _relPos = _this vectorDiff GVAR(plottingBoard_pos); +private _dist = vectorMagnitude _relPos; + +private _isRuler = if (GVAR(plottingBoard_Shown) == 2) then { + // If it's within these bounds, it's going to be on the ruler + if (_dist <= PLOTTINGBOARD_RULERCENTER) exitWith {true}; + + private _rulerVector = [sin GVAR(plottingBoard_rulerAngle), cos GVAR(plottingBoard_rulerAngle)]; + private _dirRightVector = [_dirVector select 1, -(_dirVector select 0)]; + private _rulerAng = acos (_rulerVector vectorCos _relPos); + + if (cos _rulerAng > 0 && {(tan _rulerAng) * _dist < PLOTTINGBOARD_RULERHALFWIDTH}) exitWith {true}; + + _dist > PLOTTINGBOARD_RULERINNERCIRCLE && {_dist < PLOTTINGBOARD_RULEROUTERCIRCLE && {abs (_rulerAng * DEGTOMILS) < PLOTTINGBOAR_RULEROUTERHALFANGLE}} +} else { + false +}; + +if (_isRuler) exitWith {2}; + +// If it's within 3000 meters, it's going to be on the acrylic +if (_dist < PLOTTINGBOARD_RULEROUTERCIRCLE) exitWith {1}; + +private _dirVector = [sin GVAR(plottingBoard_angle), cos GVAR(plottingBoard_angle)]; +private _dirRightVector = [_dirVector select 1, -(_dirVector select 0)]; + +// Projection of the relative position over the longitudinal axis of the map tool +private _ang = _dirVector vectorCos _relPos; +private _ang2 = _dirRightVector vectorCos _relPos; + +private _relPosAdjusted = [_ang2 * _dist / PLOTTINGBOARD_DRAWRANGE, _ang * _dist / PLOTTINGBOARD_DRAWRANGE]; + +if ((_relPosAdjusted select 0 > 0) && (_relPosAdjusted select 0 < 1) && (abs (_relPosAdjusted select 1) < 1)) exitWith {0}; + +-1 diff --git a/addons/maptools/functions/fnc_openMapGpsUpdate.sqf b/addons/maptools/functions/fnc_openMapGpsUpdate.sqf index 4cfd9be238..6d18436625 100644 --- a/addons/maptools/functions/fnc_openMapGpsUpdate.sqf +++ b/addons/maptools/functions/fnc_openMapGpsUpdate.sqf @@ -1,34 +1,39 @@ #include "..\script_component.hpp" /* * Author: esteldunedain, PabstMirror - * update gps display, called from main map's draw + * Update GPS display, called from main map's draw. * * Arguments: - * 0: Map ctrl + * 0: Map control * * Return Value: * None * * Example: - * [findDisplay 12 displayCtrl 51] call ACE_maptools_fnc_openMapGpsUpdate; + * [findDisplay 12 displayCtrl 51] call ace_maptools_fnc_openMapGpsUpdate; * * Public: No */ params ["_mapCtrl"]; + private _mapDisplay = ctrlParent _mapCtrl; -if ((!GVAR(mapGpsShow)) || {!(call FUNC(canUseMapGPS))}) exitWith { +if (!GVAR(mapGpsShow) || {!(call FUNC(canUseMapGPS))}) exitWith { (_mapDisplay displayCtrl 913589) ctrlShow false; }; + (_mapDisplay displayCtrl 913589) ctrlShow true; if (CBA_missionTime < GVAR(mapGpsNextUpdate)) exitWith {}; + GVAR(mapGpsNextUpdate) = CBA_missionTime + 0.5; private _ctrl = _mapDisplay displayCtrl 913590; _ctrl ctrlSetText str (round (getDir ACE_player)); // Set Heading + _ctrl = _mapDisplay displayCtrl 913591; _ctrl ctrlSetText str (round ((getPosASL ACE_player) select 2) + EGVAR(common,mapAltitude)); // Set Altitude + _ctrl = _mapDisplay displayCtrl 913592; _ctrl ctrlSetText mapGridPosition ACE_player; // Set grid cords diff --git a/addons/maptools/functions/fnc_updateMapToolMarkers.sqf b/addons/maptools/functions/fnc_updateMapToolMarkers.sqf index 34642c5c68..1a6d83b698 100644 --- a/addons/maptools/functions/fnc_updateMapToolMarkers.sqf +++ b/addons/maptools/functions/fnc_updateMapToolMarkers.sqf @@ -1,56 +1,130 @@ #include "..\script_component.hpp" /* - * Author: esteldunedain - * Update the map tool markers, position, size, rotation and visibility. + * Author: esteldunedain, LorenLuke + * Update the map tool and plotting board markers. Update their position, size, rotation and visibility. * * Arguments: - * 0: The Map + * 0: Map control * * Return Value: * None * * Example: - * [CONTROL] call ACE_maptools_fnc_updateMapToolMarkers + * [CONTROL] call ace_maptools_fnc_updateMapToolMarkers * * Public: No */ -params ["_theMap"]; +params ["_mapCtrl"]; -if ((GVAR(mapTool_Shown) == 0) || {!("ACE_MapTools" in (ACE_player call EFUNC(common,uniqueItems)))}) exitWith {}; - -// open map tools in center of screen when toggled to be shown -if (GVAR(mapTool_moveToMouse)) then { - private _mousePosition = _theMap ctrlMapScreenToWorld getMousePosition; - GVAR(mapTool_pos) = _mousePosition; - GVAR(mapTool_moveToMouse) = false; // we only need to do this once after opening the map tool -}; - -private _rotatingTexture = ""; -private _textureWidth = 0; -if (GVAR(mapTool_Shown) == 1) then { - _rotatingTexture = QPATHTOF(data\mapToolRotatingNormal.paa); - _textureWidth = TEXTURE_WIDTH_IN_M; +if (GVAR(plottingBoard_Shown) == 0) then { + // Hide all plotting board markers when board is put away + { + if (_y select 4 != 0) then { + _x setMarkerAlpha 0; + _y set [4, 0]; + }; + } forEach GVAR(plottingBoard_markers); } else { - _rotatingTexture = QPATHTOF(data\mapToolRotatingSmall.paa); - _textureWidth = TEXTURE_WIDTH_IN_M / 2; + if !([ACE_player, "ACE_PlottingBoard"] call EFUNC(common,hasItem)) exitWith {}; + + if (GVAR(plottingBoard_moveToMouse)) then { + GVAR(plottingBoard_pos) = _mapCtrl ctrlMapScreenToWorld getMousePosition; + GVAR(plottingBoard_moveToMouse) = false; // we only need to do this once after opening the map tool + }; + + getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"]; + private _scaleX = 32 * PLOTTINGBOARD_TEXTUREWIDTH * CONSTANT_SCALE * (call FUNC(calculateMapScale)); + private _scaleY = _scaleX * ((_resWidth / _resHeight) / _aspectRatio); // handle bad aspect ratios + + _mapCtrl drawIcon [QPATHTOF(data\plottingBoardBack.paa), [1, 1, 1, 1], GVAR(plottingBoard_pos), _scaleX, _scaleY, GVAR(plottingBoard_angle), "", 0]; + _mapCtrl drawIcon [QPATHTOF(data\plottingBoardAcrylic.paa), [1, 1, 1, 1], GVAR(plottingBoard_pos), _scaleX, _scaleY, GVAR(plottingBoard_acrylicAngle), "", 0]; + + // Show ruler + if (GVAR(plottingBoard_Shown) == 2) then { + _mapCtrl drawIcon [QPATHTOF(data\plottingBoardRuler.paa), [1, 1, 1, 1], GVAR(plottingBoard_pos), _scaleX, _scaleY, GVAR(plottingBoard_rulerAngle), "", 0]; + }; + + private _marker = ""; + private _angle = GVAR(plottingBoard_acrylicAngle); + private _boardPos = GVAR(plottingBoard_pos); + private _count = -1; + private _rotatedPolyPos = []; + private _rotatedPos = []; + + { + _marker = _x; + _y params ["_markerPos", "_polyline", "_lastAngle", "_lastBoardPos", "_lastAlpha"]; + + // Show all plotting board markers when the board is shown + if (_lastAlpha != 1) then { + _marker setMarkerAlpha 1; + _y set [4, 1]; + }; + + // If nothing has changed, don't update marker + if (_angle == _lastAngle && {_boardPos isEqualTo _lastBoardPos}) then { + continue; + }; + + _count = count _polyline; + + // Rotate all points of polyline + if (_count >= 4) then { // polylines need at least 2 points (2 components per point) + _rotatedPolyline = []; + + for "_i" from 0 to _count - 1 step 2 do { + _rotatedPolyPos = [[0, 0], [_polyline select _i, _polyline select (_i + 1)], -_angle] call CBA_fnc_vectRotate2D; + _rotatedPolyline append (_rotatedPolyPos vectorAdd _boardPos); + }; + + _marker setMarkerPolyline _rotatedPolyline; + }; + + // Rotate marker position, regardless of marker type + _rotatedPos = [[0, 0], _markerPos, -_angle] call CBA_fnc_vectRotate2D; + + _marker setMarkerPos (_boardPos vectorAdd _rotatedPos); + + _y set [2, _angle]; + _y set [3, +_boardPos]; + } forEach GVAR(plottingBoard_markers); }; -if (GVAR(freedrawing)) then {[_theMap, _textureWidth] call FUNC(drawLinesOnRoamer);}; +if ((GVAR(mapTool_Shown) != 0) && {[ACE_player, "ACE_MapTools"] call EFUNC(common,hasItem)}) then { + // Open map tools in center of screen when toggled to be shown + if (GVAR(mapTool_moveToMouse)) then { + GVAR(mapTool_pos) = _mapCtrl ctrlMapScreenToWorld getMousePosition; + GVAR(mapTool_moveToMouse) = false; // we only need to do this once after opening the map tool + }; -// Update scale of both parts -getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"]; -private _scaleX = 32 * _textureWidth * CONSTANT_SCALE * (call FUNC(calculateMapScale)); -private _scaleY = _scaleX; + private _rotatingTexture = ""; + private _textureWidth = 0; -// Position of the fixed part -private _xPos = GVAR(mapTool_pos) select 0; -private _yPos = (GVAR(mapTool_pos) select 1) + _textureWidth * CENTER_OFFSET_Y_PERC; + if (GVAR(mapTool_Shown) == 1) then { + _rotatingTexture = QPATHTOF(data\mapToolRotatingNormal.paa); + _textureWidth = TEXTURE_WIDTH_IN_M; + } else { + _rotatingTexture = QPATHTOF(data\mapToolRotatingSmall.paa); + _textureWidth = TEXTURE_WIDTH_IN_M / 2; + }; -_theMap drawIcon [QPATHTOF(data\mapToolFixed.paa), [1,1,1,1], [_xPos,_yPos], _scaleX, _scaleY, 0, "", 0]; + if (GVAR(freedrawing)) then { + [_mapCtrl, _textureWidth] call FUNC(drawLinesOnRoamer); + }; -// Position and rotation of the rotating part -_xPos = (GVAR(mapTool_pos) select 0) + sin(GVAR(mapTool_angle)) * _textureWidth * CENTER_OFFSET_Y_PERC; -_yPos = (GVAR(mapTool_pos) select 1) + cos(GVAR(mapTool_angle)) * _textureWidth * CENTER_OFFSET_Y_PERC; + // Update scale of both parts + getResolution params ["_resWidth", "_resHeight", "", "", "_aspectRatio"]; + private _scaleX = 32 * _textureWidth * CONSTANT_SCALE * (call FUNC(calculateMapScale)); + private _scaleY = _scaleX * ((_resWidth / _resHeight) / _aspectRatio); // handle bad aspect ratios -_theMap drawIcon [_rotatingTexture, [1,1,1,1], [_xPos,_yPos], _scaleX, _scaleY, GVAR(mapTool_angle), "", 0]; + // Position of the fixed part + private _pos = GVAR(mapTool_pos) vectorAdd [0, _textureWidth * CENTER_OFFSET_Y_PERC]; + + _mapCtrl drawIcon [QPATHTOF(data\mapToolFixed.paa), [1, 1, 1, 1], _pos, _scaleX, _scaleY, 0, "", 0]; + + // Position and rotation of the rotating part + _pos = GVAR(mapTool_pos) vectorAdd ([sin GVAR(mapTool_angle), cos GVAR(mapTool_angle)] vectorMultiply (_textureWidth * CENTER_OFFSET_Y_PERC)); + + _mapCtrl drawIcon [_rotatingTexture, [1, 1, 1, 1], _pos, _scaleX, _scaleY, GVAR(mapTool_angle), "", 0]; +}; diff --git a/addons/maptools/functions/fnc_wipeMarkers.sqf b/addons/maptools/functions/fnc_wipeMarkers.sqf new file mode 100644 index 0000000000..5131e469a3 --- /dev/null +++ b/addons/maptools/functions/fnc_wipeMarkers.sqf @@ -0,0 +1,23 @@ +#include "../script_component.hpp" +/* + * Author: LorenLuke + * Delete all markers on the plotting board. + * + * Arguments: + * None + * + * Return Value: + * None + * + * Example: + * call ace_maptools_fnc_wipeMarkers + * + * Public: No + */ + +{ + deleteMarker _x; +} forEach (keys GVAR(plottingBoard_markers)); + +// Reset list +GVAR(plottingBoard_markers) = createHashMap; diff --git a/addons/maptools/initSettings.sqf b/addons/maptools/initSettings.inc.sqf similarity index 57% rename from addons/maptools/initSettings.sqf rename to addons/maptools/initSettings.inc.sqf index cbb8e9c1b8..172054ff77 100644 --- a/addons/maptools/initSettings.sqf +++ b/addons/maptools/initSettings.inc.sqf @@ -1,4 +1,4 @@ -private _category = format ["ACE %1", localize LSTRING(Name)]; +private _category = format ["ACE %1", LLSTRING(Name)]; [ QGVAR(rotateModifierKey), "LIST", @@ -15,3 +15,11 @@ private _category = format ["ACE %1", localize LSTRING(Name)]; true, 0 ] call CBA_fnc_addSetting; + +[ + QGVAR(plottingBoardAllowChannelDrawing), "LIST", + [LSTRING(allowChannelDrawing_displayName), LSTRING(allowChannelDrawing_description)], + _category, + [[0, 1], [LSTRING(allowDirectCommsOnly), LSTRING(allowDirectGroupComms)], 1], + 0 +] call CBA_fnc_addSetting; diff --git a/addons/maptools/script_component.hpp b/addons/maptools/script_component.hpp index 4710caa7a3..adbc1fb3f6 100644 --- a/addons/maptools/script_component.hpp +++ b/addons/maptools/script_component.hpp @@ -16,9 +16,19 @@ #include "\z\ace\addons\main\script_macros.hpp" -#define TEXTURE_WIDTH_IN_M 6205 -#define CENTER_OFFSET_Y_PERC 0.1606 -#define CONSTANT_SCALE 0.2 +#define DEGTOMILS 17.7777778 + +#define TEXTURE_WIDTH_IN_M 6205 +#define CENTER_OFFSET_Y_PERC 0.1606 +#define CONSTANT_SCALE 0.2 #define DIST_BOTTOM_TO_CENTER_PERC -0.33 -#define DIST_TOP_TO_CENTER_PERC 0.65 -#define DIST_LEFT_TO_CENTER_PERC 0.30 +#define DIST_TOP_TO_CENTER_PERC 0.65 +#define DIST_LEFT_TO_CENTER_PERC 0.30 + +#define PLOTTINGBOARD_DRAWRANGE 3000 +#define PLOTTINGBOARD_TEXTUREWIDTH 6000 +#define PLOTTINGBOARD_RULERCENTER 450 +#define PLOTTINGBOARD_RULERHALFWIDTH 100 +#define PLOTTINGBOARD_RULERINNERCIRCLE 2900 +#define PLOTTINGBOARD_RULEROUTERCIRCLE 3000 +#define PLOTTINGBOARD_RULEROUTERHALFANGLE 100 diff --git a/addons/maptools/stringtable.xml b/addons/maptools/stringtable.xml index 0d6cebe370..7e1d0cee97 100644 --- a/addons/maptools/stringtable.xml +++ b/addons/maptools/stringtable.xml @@ -12,7 +12,7 @@ Ferramentas de Mapa Térképészeti eszközök Инструменты карты - マップ ツール + マップツール 독도용 도구 地图工具 地圖工具 @@ -29,12 +29,32 @@ As Ferramentas de Mapa permitem que você meça distâncias e ângulos no mapa. A térképészeti eszközökkel távolságokat és szögeket tudsz mérni a térképen. Картографические инструменты позволяют измерять расстояния и углы на карте. - マップ ツールは地図上で距離や角度を測れます。 + マップツールは地図上で距離や角度を測れます。 독도용 도구는 지도상에서 거리나 각도를 잴 수 있게 해줍니다. 地图工具能够让你在地图上测量距离与角度 地圖工具能夠讓你在地圖上測量距離與角度 Harita Araçları, haritadaki mesafeleri ve açıları ölçmenize olanak tanır. + + Plotting Board + 플로팅 보드 + 標定盤 + Tavola di calcolo + Графическая доска + Planche traçante + Wurfparabel Kartenwerkzeug + Tablero de Trazado + + + 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. + Графическая доска - это картографический инструмент, предназначенный для использования при ведении непрямого огня с малой дистанции. + Une planche traçante est un outil cartographique conçu pour diriger des tirs indirects à courte distance. + Das Wurfparabel-Kartenwerkzeug ist ein Werkzeug, das für die Steuerung indirekten Feuers auf kurze Distanz entwickelt wurde. + El Tablero de Trazado es una herramienta de mapa utilizada para dirigir fuego indirecto de corto alcance. + Map Tools Herramientas de mapa @@ -46,7 +66,7 @@ Ferramentas de Mapa Térképészeti eszközök Инструменты карты - マップ ツール + マップツール 독도용 도구 地图工具 地圖工具 @@ -63,7 +83,7 @@ Ukryj narzędzia nawigacyjne Schovat pomůcky k mapě Скрыть инструменты - マップ ツールを隠す + マップツールを 隠す 독도용 도구 숨기기 隐藏地图工具 隱藏地圖工具 @@ -74,13 +94,13 @@ Zeige Kartenwerkzeug (normal) Mostrar herr. de mapa normal Montrer les outils de navigation (normaux) - Visualizza Strumenti Cartografici standard + Visualizza Strumento Cartografico Normale Mostrar Ferramenta de Mapa Padrão Térképészeti eszköz megjelenítése (normál méret) Pokaż normalne narzędzia nawigacyjne Zobrazit pomůcku k mapě (Velkou) Показать инструменты (средн. размер) - マップ ツールを表示する + マップツールを 表示する 보통 독도용 도구로 보기 显示地图工具 顯示地圖工具 @@ -91,13 +111,13 @@ Zeige Kartenwerkzeug (klein) Mostrar herr. de mapa pequeñas Montrer les outils de navigation (petits) - Visualizza Strumenti Cartografici piccoli + Visualizza Strumento Cartografico Piccolo Mostrar Ferramenta de Mapa Pequena Térképészeti eszköz megjelenítése (kicsinyített) Pokaż pomniejszone narzędzia nawigacyjne Zobrazit pomůcku k mapě (Malou) Показать инструменты (малый размер) - 小さいマップ ツールを表示する + 小さい マップツールを 表示する 작은 독도용 도구로 보기 显示小的地图工具 顯示小的地圖工具 @@ -108,13 +128,13 @@ Kartenwerkzeug nach Norden ausrichten Alinear herr. de mapa al norte Aligner les outils sur le nord - Allinea gli Strumenti Cartografici con il Nord + Allinea Strumento Cartografico verso Nord Alinhar Ferramenta de Mapa com o Norte Térképészeti eszköz Északhoz állítása Wyrównaj linijkę do północy Srovnat pomůcku k mapě na sever Выровнять инструменты на север - マップ ツールを北に合わせる + マップツールを 北に合わせる 독도용 도구를 북쪽으로 정렬 地图工具对准北方 地圖工具對準北方 @@ -125,13 +145,13 @@ Kartenwerkzeug am Kompass ausrichten Alinear herr. de mapa a la brújula Aligner les outils sur la boussole - Allinea gli Strumenti Cartografici con la bussola + Allinea Strumento Cartografico con la bussola Alinhar Ferramenta de Mapa com a Bússola Térképészeti eszköz iránytűhöz állítása Wyrównaj linijkę do kompasu Srovnat pomůcku k mapě ke kompasu Выровнять инструменты по компасу - マップ ツールを方位磁石に合わせる + マップツールを 方位磁石に合わせる 독도용 도구를 나침반에 정렬 地图工具对准指南针 地圖工具對準指北針 @@ -182,7 +202,7 @@ Направление: %1° Direzione: %1° Direção: %1 - 方位: %1° + 方向: %1° 방위: %1° 方位:%1° 方位: %1° @@ -192,11 +212,11 @@ Rotate Map Tools Key Touche de rotation des outils de navigation Клавиша поворота инструментов карты - マップ ツールの回転キー + マップツールの回転キー Klawisz obrotu narzędzi nawigacyjnych Taste zum Drehen des Kartenwerkzeugs 독도용 도구 돌리기 키 - Ruota Strumenti di Mappatura + Tasto per Ruotare Strumenti Cartografici 选转地图工具的按键 選轉地圖工具的按鍵 Tecla para girar Ferramentas de Mapa @@ -208,11 +228,11 @@ Modifier key to allow rotating map tools Touche modificatrice permettant la rotation des outils de navigation. Клавиша-модификатор, позволяющая поворачивать инструменты карты - マップ ツールを回転させるキーを編集できます。 + マップツールを回転させるキーを編集できます。 Modyfikator pozwalający na obracanie narzędzi nawigacyjnych Steuerungstaste, um Drehung des Kartenwerkzeugs zu ermöglichen. 독도용 도구를 돌리기 위한 키를 변경할 수 있습니다. - Tasto modifica per consentire strumenti di mappatura rotanti + Tasto modificatore per ruotare strumenti cartografici 修改旋转地图工具的按键 修改旋轉地圖工具的按鍵 Tecla de Modificador para permitir girar as ferramentas de mapa @@ -222,12 +242,12 @@ Draw straight lines with maptools - マップ ツールを使って直線を書く + マップツールを使って直線を書く Zeichne gerade Linien mit dem Kartenwerkzeug 독도용 도구로 직선 그리기 Rysuj proste linie przy użyciu narzędzi nawigacyjnych Tracer des lignes droites - Disegna linee dritte con gli strumenti di mappatura + Disegna linee dritte con gli strumenti cartografici 使用地图工具来绘制直线 使用地圖工具來繪製直線 Прямые линии с инструментами карты @@ -238,12 +258,12 @@ Draw on the edge of maptools to draw straight lines. Note: Must hover at midpoint to delete. - マップ ツールの端から直線を書きます。メモ: 線の中央ホバーすると削除します。 + マップツールの端に線を描くことで直線を描けるようにします。 備考: 削除するには線の中間点にカーソルを合わせる必要があります。 Zeichne gerade Linien am Rand des Kartenwerkzeugs. Hinweis: zum Löschen über den Mittelpunkt der Linie fahren 독도용 도구 가장자리에 직선을 그립니다. 주의: 삭제하기 위해선 선의 중앙에 가져다 대십시요 Przeciągnij po krawędzi narzędzi nawigacyjnych by narysować prostą linię. Uwaga: aby usunąć linię - nalezy ustawić kursor nad jej środkiem. Utilise le bord des outils de navigation pour tracer des lignes droites. Note : il faut pointer au milieu du trait pour pouvoir le supprimer. - Disegna sul bordo degli strumenti di mappatura per disegnare linee dritte. Nota: Deve spostarsi al centro per essere cancellato. + Disegna lungo il bordo degli strumenti cartografici per disegnare linee dritte. Nota: Dovrai puntare il centro delle linee per cancellarle. 使用地图工具的边缘来绘制直线。备注:要删除直线时,请把鼠标移动到该线条的中央即可删除该线。 使用地圖工具的邊緣來繪製直線。備註: 要刪除直線時,請把滑鼠移動到該線條的中央即可刪除該線 Рисуйте по краю инструмента карты, чтобы провести прямые линии. Примечание: при удалении линии размещайте курсор над ее серединой @@ -252,5 +272,207 @@ Düz çizgiler çizmek için maptools'un kenarına çizin. Not: Silmek için orta noktada fareyle üzerine gelmeniz gerekir. Dibujar sobre el borde de las herramientas de mapa para dibujar líneas rectas. Nota: Debe situarse en el punto intermedio para eliminarla. + + Allow Plotting Board Drawing channels + 標定盤への書き込みを許可するチャンネル + 플로팅 보드 그리기 채널 허용 + Canali ammessi su tavola di calcolo + Разрешить создание каналов на миллиметровой доске. + Canaux autorisés sur la planche traçante + Wurfparabel Kartenwerkzeug erlaubte Kanäle + Permitir Canales de Dibujado de Tablero de Trazado + + + Channels in which plotting board drawing is enabled. + どのチャンネルで標定盤の書き込みを有効化するか。 + 플로팅 보드 그리기가 활성화된 채널입니다. + Canali in cui si può disegnare sulla tavola di calcolo. + Каналы, в которых включено рисование на миллиметровой доске. + Canaux dans lesquels vous pouvez dessiner sur le planche traçante + Kanäle, in denen das Zeichnen mit dem Wurfparabel-Kartenwerkzeug auf der Karte erlaubt ist. + Canales en los que el tablero de trazado está habilitado. + + + Allow Direct Comms Only (Polylines Only) + 直接チャンネルのみ許可 (線のみ) + 직접교신만 허용 (선 긋기만) + Comunicazioni Dirette (solo linee) + Разрешать только прямую связь (только полилинии) + Communications directes uniquement (lignes uniquement) + Nur direkte Kommunikation zulassen (nur Polylinien) + Permitir Sólo Comunicaciones Directas (Sólo Polylineas) + + + Allow Direct/Group Comms (Polylines and Group Markers) + 直接/グループチャンネルを許可 (線とグループマーカー) + 직접교신/그룹무전망 허용 (선 긋기와 그룹 마커) + Comunicazioni dirette/gruppo (linee e marker) + Разрешить прямую/групповую связь (полилинии и групповые маркеры) + Autoriser les communications directes/de groupe (polylignes et marqueurs de groupe) + Direkte/Gruppenkommunikation zulassen (Polylinien und Gruppenmarkierungen) + Permitir Comunicaciones Directas/Grupales (Polylineas y Marcadores de Grupo) + + + Plotting Board + 標定盤 + 플로팅 보드 + Tavola di calcolo + Миллиметровая доска + Planche traçante + Wurfparabel Kartenwerkzeug + Tablero de Trazado + + + Plotting Board Acrylic + 標定盤の アクリル板 + 플로팅 보드 (아크릴) + Acrilico tavola di calcolo + Миллиметровая доска акрилловая + Planche traçante Acrylique + Wurfparabel Kartenwerkzeug Acryl + Tablero de Trazado Acrílico + + + Plotting Board Ruler + 標定盤の 定規 + 플로팅 보드 (자) + Righello tavola di calcolo + Линейка для миллиметровой доски + Règle de la planche traçante + Wurfparabel Kartenwerkzeug Lineal + Regla de Tablero de Trazado + + + To Plotting Board + 標定盤に + 플로팅 보드에 + Su tavola di calcolo + К миллиметровой доске. + Sur la planche traçante + Zum Wurfparabel Kartenwerkzeug + A Tablero de Trazado + + + To Plotting Board Acrylic + 標定盤の アクリル板に + 플로팅 보드 (아크릴)에 + Su acrilico tavola di calcolo + К миллиметровой доске акрилловой + Sur la planche traçante Acrylique + Zum Wurfparabel Kartenwerkzeug Acryl + A Tablero de Trazado Acrílico + + + To Plotting Board Ruler + 標定盤の 定規に + 플로팅 보드 (자)에 + Su righello tavola di calcolo + К линейке миллиметровой доски. + Sur la règle de la planche traçante + Zum Wurfparabel Kartenwerkzeug Lineal + A Regla de Tablero de Trazado + + + Wipe all markers off Plotting Board + 標定盤の 全マーカーを 拭き消す + 플로팅 보드에 있는 모든 마커 지우기 + Cancella tutti i disegni dalla tavola + Сотрите все маркеры с миллиметровой доски. + Effacer tous les dessins de la planche traçante + Alle Markierungen vom Wurfparabel Kartenwerkzeug entfernen + Borrar todas las marcas del Tablero de Trazado + + + Show Plotting Board + 標定盤を 表示 + 플로팅 보드 보이기 + Mostra tavola di calcolo + Показать миллиметровую доску. + Afficher la planche traçante + Zeige Wurfparabel Kartenwerkzeug + Mostrar Tablero de Trazado + + + Hide Plotting Board + 標定盤を 隠す + 플로팅 보드 숨기기 + Nascondi tavola di calcolo + Скрыть миллиметровую доску. + Masquer la planche traçante + Verstecke Wurfparabel Kartenwerkzeug + Ocultar Tablero de Trazado + + + Toggle Plotting Board Ruler + 標定盤の 定規を 表示切替 + 플로팅 보드 (자) 토글 + Mostra/Nascondi Righello + Переключить линейку миллиметровой доски. + Afficher/masquer la règle + Schalte das Lineal des Wurfparabel-Kartenwerkzeuges um + Alternar Regla de Tablero de Trazado + + + Align + Ausrichten + Alinear + Aligner + Allinea + Alinhar + Állítása + Wyrównaj + Srovnat + Выровнять + 맞춤 기준: + 向きを合わせる + + + To North + Nach Norden + Al norte + Sur le nord + Con il Nord + Com o Norte + Északhoz + Do północy + Na sever + На север + 북쪽으로 + 北に + + + To Compass + Am Kompass + A la brújula + Sur la boussole + Con la bussola + Com a Bússola + Iránytűhöz + Do kompasu + Ke kompasu + По компасу + 方位磁石に + 나침반으로 + + + Up + 上に + 위로 + Su + Вверх + Monter + Nach oben + Arriba + + + To Maptool + マップツールに + 독도용 도구로 + Su strumento cartografico + К инструментам карты + Outil cartographique + Zum Kartenwerkzeug + A Herramienta de Mapa + diff --git a/addons/marker_flags/CfgWeapons.hpp b/addons/marker_flags/CfgWeapons.hpp index b4c2f88125..13a1632f4f 100644 --- a/addons/marker_flags/CfgWeapons.hpp +++ b/addons/marker_flags/CfgWeapons.hpp @@ -14,7 +14,7 @@ class CfgWeapons { mapSize = 0.2; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.5; }; }; diff --git a/addons/marker_flags/XEH_preInit.sqf b/addons/marker_flags/XEH_preInit.sqf index 62febdc7cb..ed043fcb05 100644 --- a/addons/marker_flags/XEH_preInit.sqf +++ b/addons/marker_flags/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(flagCache) = createHashMap; diff --git a/addons/marker_flags/functions/fnc_placeFlag.sqf b/addons/marker_flags/functions/fnc_placeFlag.sqf index 74dc615588..5dd2abb376 100644 --- a/addons/marker_flags/functions/fnc_placeFlag.sqf +++ b/addons/marker_flags/functions/fnc_placeFlag.sqf @@ -18,13 +18,13 @@ */ params [["_player", objNull, [objNull]], ["_item", QGVAR(white), [""]]]; -TRACE_2("Placing flag", _player, _item); +TRACE_2("Placing flag",_player,_item); (GVAR(flagCache) get _item) params ["_vehicleClass"]; private _flag = _vehicleClass createVehicle [0, 0, 0]; -TRACE_1("Created flag", _flag); +TRACE_1("Created flag",_flag); // Set flag start height GVAR(objectHeight) = MAX_HEIGHT; diff --git a/addons/marker_flags/initSettings.sqf b/addons/marker_flags/initSettings.inc.sqf similarity index 100% rename from addons/marker_flags/initSettings.sqf rename to addons/marker_flags/initSettings.inc.sqf diff --git a/addons/marker_flags/stringtable.xml b/addons/marker_flags/stringtable.xml index fc817c0c67..31aab77e84 100644 --- a/addons/marker_flags/stringtable.xml +++ b/addons/marker_flags/stringtable.xml @@ -4,17 +4,20 @@ Marker Flags Markierungsfahnen + Bandiere segnaletiche Chorągiewki - 旗マーカー + マーカー旗 마킹용 깃발 标记旗 Флажки Banderas de señalizado Drapeaux de marquage + Bandeiras de marcação Place Anywhere Überall platzieren + Piazza ovunque どこでも設置可能 Umieść w dowolnym miejscu 아무 곳에나 배치 @@ -22,6 +25,7 @@ Размещать где угодно Colocar en cualquier lugar Placer partout + Colocar em qualquer lugar Place marker flag anywhere regardless of surface. @@ -32,27 +36,33 @@ Размещать флажки где угодно вне зависимости от поверхности. Permitir colocar las banderas de señalizado en cualquier lugar, al margen del tipo de superficie. Platzieren Sie die Markierungsfahne überall, unabhängig von der Oberfläche. + Piazza bandiere segnaletiche ovunque, indipendentemente dalla superficie. Place un drapeau de marquage n'importe où, quelle que soit la surface. + Permite colocar as bandeiras de marcação em qualquer lugar, independente do tipo de superfice Place Marker Flag Markierungsfahne platzieren + Piazza bandiera segnaletica Postaw chorągiewkę 마킹용 깃발 꽂기 Поставить флажок Colocar Bandera de señalizado - マーカーフラッグを置く + マーカー旗 を置く Placer le drapeau de marquage + Colocar Bandeira de Marcação Adjust height Höhe anpassen + Modifica altezza Dostosuj wysokość 높이 조정 Регулировать высоту Ajustar altura 高さを調整する Ajuster la hauteur + Ajustar altura Cancel @@ -90,90 +100,106 @@ Marker Flag (White) Markierungsfahne (Weiß) + Bandiera segnaletica (Bianca) Chorągiewka (Biała) - 旗マーカー (白) + マーカー旗 (白) 마킹용 깃발(하양) 标记旗(白) Флажок (белый) Bandera de señalizado (Blanca) Drapeau de marquage (Blanc) + Bandeira de Marcação (Branca) Marker Flag (Black) Markierungsfahne (Schwarz) + Bandiera segnaletica (Nera) Chorągiewka (Czarna) - 旗マーカー (黒) + マーカー旗 (黒) 마킹용 깃발(검정) 标记旗(黑) Флажок (чёрный) Bandera de señalizado (Negra) Drapeau de marquage (Noir) + Bandeira de Marcação (Preta) Marker Flag (Red) Markierungsfahne (Rot) + Bandiera segnaletica (Rossa) Chorągiewka (Czerwona) - 旗マーカー (赤) + マーカー旗 (赤) 마킹용 깃발(빨강) 标记旗(红) Флажок (красный) Bandera de señalizado (Roja) Drapeau de marquage (Rouge) + Bandeira de Marcação (Vermelha) Marker Flag (Green) Markierungsfahne (Grün) + Bandiera segnaletica (Verde) Chorągiewka (Zielona) - 旗マーカー (緑) + マーカー旗 (緑) 마킹용 깃발(초록) 标记旗(绿) Флажок (зелёный) Bandera de señalizado (Verde) Drapeau de marquage (Vert) + Bandeira de Marcação (Verde) Marker Flag (Blue) Markierungsfahne (Blau) + Bandiera segnaletica (Blu) Chorągiewka (Niebieska) - 旗マーカー (青) + マーカー旗 (青) 마킹용 깃발(파랑) 标记旗(蓝) Флажок (синий) Bandera de señalizado (Azul) Drapeau de marquage (Bleu) + Bandeira de Marcação (Azul) Marker Flag (Yellow) Markierungsfahne (Gelb) + Bandiera segnaletica (Gialla) Chorągiewka (Żółta) - 旗マーカー (黄) + マーカー旗 (黄) 마킹용 깃발(노랑) 标记旗(黄) Флажок (жёлтый) Bandera de señalizado (Amarilla) Drapeau de marquage (Jaune) + Bandeira de Marcação (Amarela) Marker Flag (Orange) Markierungsfahne (Orange) + Bandiera segnaletica (Arancione) Chorągiewka (Pomarańczowa) - 旗マーカー (橙) + マーカー旗 (橙) 마킹용 깃발(주황) 标记旗(橙) Флажок (оранжевый) Bandera de señalizado (Naranja) Drapeau de marquage (Orange) + Bandeira de Marcação (Laranja) Marker Flag (Purple) Markierungsfahne (Lila) + Bandiera segnaletica (Viola) Chorągiewka (Fioletowa) - 旗マーカー (紫) + マーカー旗 (紫) 마킹용 깃발(보라) 标记旗(紫) Флажок (фиолетовый) Bandera de señalizado (Púrpura) Drapeau de marquage (Violet) + Bandeira de Marcação (Roxa) diff --git a/addons/markers/XEH_postInit.sqf b/addons/markers/XEH_postInit.sqf index 25e8317b75..1ae489dd82 100644 --- a/addons/markers/XEH_postInit.sqf +++ b/addons/markers/XEH_postInit.sqf @@ -2,10 +2,10 @@ #include "script_component.hpp" // recieve remote marker data -[QGVAR(setMarkerNetwork), {_this call DFUNC(setMarkerNetwork)}] call CBA_fnc_addEventHandler; +[QGVAR(setMarkerNetwork), LINKFUNC(setMarkerNetwork)] call CBA_fnc_addEventHandler; // recieve marker data for JIP -[QGVAR(setMarkerJIP), {_this call DFUNC(setMarkerJIP)}] call CBA_fnc_addEventHandler; +[QGVAR(setMarkerJIP), LINKFUNC(setMarkerJIP)] call CBA_fnc_addEventHandler; // request marker data for JIP if (isMultiplayer && {!isServer} && {hasInterface}) then { @@ -32,7 +32,7 @@ GVAR(userPlacedMarkers) = []; if (_index < 0) exitWith { if (!isMultiplayer) exitWith {}; - WARNING_1("Could not find data for %1", _marker); + WARNING_1("Could not find data for %1",_marker); }; private _data = GVAR(allMapMarkersProperties) select _index; diff --git a/addons/markers/XEH_preInit.sqf b/addons/markers/XEH_preInit.sqf index 885a0a3068..142dedb89a 100644 --- a/addons/markers/XEH_preInit.sqf +++ b/addons/markers/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // init marker types if (isNil QGVAR(MarkersCache)) then { diff --git a/addons/markers/functions/fnc_onButtonClickConfirm.sqf b/addons/markers/functions/fnc_onButtonClickConfirm.sqf index 2822cd69f0..622a306e38 100644 --- a/addons/markers/functions/fnc_onButtonClickConfirm.sqf +++ b/addons/markers/functions/fnc_onButtonClickConfirm.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Freddo + * Author: Freddo, Daniël H., johnb43 * When the confirm button is pressed. * * Arguments: @@ -14,40 +14,100 @@ * * Public: No */ + params ["_buttonOk"]; private _display = ctrlParent _buttonOk; -private _description = _display displayctrl IDC_INSERT_MARKER; +private _description = _display displayCtrl IDC_INSERT_MARKER; private _aceTimestamp = _display displayCtrl IDC_ACE_INSERT_MARKER_TIMESTAMP; -// handle timestamp +// Handle timestamp if (cbChecked _aceTimestamp && {ACE_player call FUNC(canTimestamp)}) then { - private _time = daytime; + // Determine marker timestamp based on time settings + private _time = switch (GVAR(timestampTimezone)) do { + case 1: { + systemTime select [3] + }; + case 2: { + systemTimeUTC params ["", "", "", "_hour", "_min", "_sec", "_msec"]; - // add timestamp suffix + private _hourOffset = round GVAR(timestampUTCOffset); + _hour = _hour + _hourOffset; + + // Add or subtract minutes offset based on the negative or positive timezone + if (GVAR(timestampUTCMinutesOffset) != 0) then { + _min = if (_hourOffset < 0) then { _min - GVAR(timestampUTCMinutesOffset) } else { _min + GVAR(timestampUTCMinutesOffset) }; + + // Add/remove extra hours from minutes + _hour = _hour + floor (_min / 60); + _min = (_min % 60 + 60) % 60; // ensure that minutes are between 0 and 59 (included) + }; + + [(_hour % 24 + 24) % 24, _min, _sec, _msec] // ensure that hours are between 0 and 23 (included) + }; + default { + private _daytime = dayTime; + + private _hour = floor _daytime; + private _min = floor ((_daytime - _hour) * 60); + private _sec = floor ((((_daytime - _hour) * 60) - _min) * 60); + private _msec = floor ((((((_daytime - _hour) * 60) - _min) * 60) - _sec) * 1000); + + [_hour, _min, _sec, _msec] + }; + }; + + _time params ["_hour", "_min", "_sec", "_msec"]; + + // Add timestamp suffix private _periodPostfix = ""; + if (GVAR(timestampHourFormat) == 12) then { - if (floor _time == 0) exitWith { - _time = _time + 12; + if (_hour == 0) exitWith { + _hour = _hour + 12; _periodPostfix = " am"; }; - if (floor _time == 12) exitWith { + if (_hour == 12) exitWith { _periodPostfix = " pm"; }; - if (_time < 12) then { + if (_hour < 12) then { _periodPostfix = " am"; } else { - _time = _time - 12; + _hour = _hour - 12; _periodPostfix = " pm"; }; }; + private _format = switch (GVAR(timestampFormat)) do { + case "HH": {"%1"}; + case "HH:MM": {"%1:%2"}; + case "HH:MM:SS": {"%1:%2:%3"}; + case "HH:MM:SS:MM": { // milliseconds are displayed as 0 to 59 + _msec = [_msec * 60 / 1000, 2] call CBA_fnc_formatNumber; + + "%1:%2:%3:%4" + }; + case "HH:MM:SS.mmm": { // milliseconds are displayed as 0 to 999 + _msec = [_msec, 3] call CBA_fnc_formatNumber; + + "%1:%2:%3.%4" + }; + }; + + _time = format [ + _format, + [_hour, 2] call CBA_fnc_formatNumber, + [_min, 2] call CBA_fnc_formatNumber, + [_sec, 2] call CBA_fnc_formatNumber, + _msec + ]; + _description ctrlSetText format [ "%1 [%2%3]", ctrlText _description, - [_time, GVAR(timestampFormat)] call BIS_fnc_timeToString, + _time, _periodPostfix ]; }; diff --git a/addons/markers/functions/fnc_onLBSelChangedChannel.sqf b/addons/markers/functions/fnc_onLBSelChangedChannel.sqf index d8c2bc71fb..e7b696270f 100644 --- a/addons/markers/functions/fnc_onLBSelChangedChannel.sqf +++ b/addons/markers/functions/fnc_onLBSelChangedChannel.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: commy2, LinkIsGrim + * Author: commy2, LinkIsGrim, Avokadomos * When the channel list box is changed. * * Arguments: @@ -19,6 +19,4 @@ params ["_ctrl", "_index"]; TRACE_2("params",_ctrl,_index); -private _enabledChannels = false call FUNC(getEnabledChannels); - -setCurrentChannel (_enabledChannels select _index); +setCurrentChannel (parseNumber (_ctrl lbData _index)); diff --git a/addons/markers/functions/fnc_onMouseButtonDown.sqf b/addons/markers/functions/fnc_onMouseButtonDown.sqf index ce4d637400..f0130c7c9d 100644 --- a/addons/markers/functions/fnc_onMouseButtonDown.sqf +++ b/addons/markers/functions/fnc_onMouseButtonDown.sqf @@ -37,5 +37,5 @@ if (_type == "marker" && {_marker find "_USER_DEFINED" != -1 && {_marker call FU GVAR(moving) = true; _marker setMarkerAlphaLocal 0.5; - [FUNC(movePFH), 0, [_marker, _ctrlMap, _originalPos, _originalAlpha]] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(movePFH), 0, [_marker, _ctrlMap, _originalPos, _originalAlpha]] call CBA_fnc_addPerFrameHandler; }; diff --git a/addons/markers/functions/fnc_removeTimestamp.sqf b/addons/markers/functions/fnc_removeTimestamp.sqf index 073d9ce613..5d2c7c3c1f 100644 --- a/addons/markers/functions/fnc_removeTimestamp.sqf +++ b/addons/markers/functions/fnc_removeTimestamp.sqf @@ -43,8 +43,8 @@ private _index = 1; private _keepCheckingDigits = true; private _validTimestamp = true; while {_keepCheckingDigits} do { - if (!(_string select [_index, 1] in DIGITS)) exitWith { _validTimestamp = false; }; - if (!(_string select [_index+1, 1] in DIGITS)) exitWith { _validTimestamp = false; }; + if !(_string select [_index, 1] in DIGITS) exitWith { _validTimestamp = false; }; + if !(_string select [_index+1, 1] in DIGITS) exitWith { _validTimestamp = false; }; switch (_string select [_index+2, 1]) do { case (":"): { _index = _index + 3; @@ -54,7 +54,7 @@ while {_keepCheckingDigits} do { }; case (" "): { _keepCheckingDigits = false; - if (!(_string select [_index+3, 3] in ["am]", "pm]"])) then {_validTimestamp = false; }; + if !(_string select [_index+3, 3] in ["am]", "pm]"]) then {_validTimestamp = false; }; }; default { _keepCheckingDigits = false; diff --git a/addons/markers/functions/fnc_setMarkerJIP.sqf b/addons/markers/functions/fnc_setMarkerJIP.sqf index 8536b90a90..12dfe5de77 100644 --- a/addons/markers/functions/fnc_setMarkerJIP.sqf +++ b/addons/markers/functions/fnc_setMarkerJIP.sqf @@ -49,5 +49,4 @@ TRACE_2("params",_allMapMarkers,_allMapMarkersProperties); _x setMarkerDirLocal _dir; _x setMarkerSizeLocal [_scale, _scale]; }; - false -} count allMapMarkers; +} forEach allMapMarkers; diff --git a/addons/markers/initSettings.sqf b/addons/markers/initSettings.inc.sqf similarity index 61% rename from addons/markers/initSettings.sqf rename to addons/markers/initSettings.inc.sqf index ce8e8e0473..65bf17e8b6 100644 --- a/addons/markers/initSettings.sqf +++ b/addons/markers/initSettings.inc.sqf @@ -32,6 +32,37 @@ private _categoryName = format ["ACE %1", localize ELSTRING(map,Module_DisplayNa true ] call CBA_fnc_addSetting; +[ + QGVAR(timestampTimezone), "LIST", + [LSTRING(TimestampTimezone), LSTRING(TimestampTimezoneDescription)], + [_categoryName, LLSTRING(Module_DisplayName)], + [ + [0, 1, 2], + [LSTRING(TimestampTimezoneIngameTime), LSTRING(TimestampTimezoneSystemTime), LSTRING(TimestampTimezoneUTCTime)], + 0 + ], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(timestampUTCOffset), "SLIDER", + [LSTRING(TimestampUTCOffset), LSTRING(TimestampUTCOffsetDescription)], + [_categoryName, LLSTRING(Module_DisplayName)], + [-12, 14, 0, 0], + true +] call CBA_fnc_addSetting; + +[ + QGVAR(TimestampUTCMinutesOffset), "LIST", + [LSTRING(TimestampUTCMinutesOffset), LSTRING(TimestampUTCMinutesOffsetDescription)], + [_categoryName, LLSTRING(Module_DisplayName)], + [ + [0, 15, 30, 45], + [0, 15, 30, 45], + 0 + ] +] call CBA_fnc_addSetting; + [ QGVAR(timestampHourFormat), "LIST", [LSTRING(TimestampHourFormat), LSTRING(TimestampHourFormatDescription)], @@ -48,7 +79,8 @@ private _formatDescription = [ LLSTRING(TimestampFormatDescription1), LLSTRING(TimestampFormatDescription2), LLSTRING(TimestampFormatDescription3), - LLSTRING(TimestampFormatDescription4) + LLSTRING(TimestampFormatDescription4), + LLSTRING(TimestampFormatDescription5) ] joinString endl; [ @@ -56,8 +88,8 @@ private _formatDescription = [ [LSTRING(timestampFormat), _formatDescription], [_categoryName, LLSTRING(Module_DisplayName)], [ - ["HH", "HH:MM", "HH:MM:SS", "HH:MM:SS:MM"], - ["HH", "HH:MM", "HH:MM:SS", "HH:MM:SS:MM"], + ["HH", "HH:MM", "HH:MM:SS", "HH:MM:SS:MM", "HH:MM:SS.mmm"], + ["HH", "HH:MM", "HH:MM:SS", "HH:MM:SS:MM", "HH:MM:SS.mmm"], 1 ] ] call CBA_fnc_addSetting; diff --git a/addons/markers/stringtable.xml b/addons/markers/stringtable.xml index d288a1bc11..2c9dc1531b 100644 --- a/addons/markers/stringtable.xml +++ b/addons/markers/stringtable.xml @@ -6,11 +6,13 @@ Escala: %1 Échelle : %1 Масштаб: %1 - スケール: %1 + 大きさ: %1 Skala: %1 Skalierung: %1 + Scala: %1 规模:%1° 크기: %1 + Escala: %1 Direction: %1° @@ -23,7 +25,7 @@ Irány: %1° Direzione: %1° Direção %1 - 方位: %1° + 方向: %1° 방위: %1° 方位:%1° 方位: %1° @@ -36,9 +38,11 @@ 右クリックでリセット Naciśnij PPM żeby zresetować Rechte Maustaste zum Zurücksetzen + Tasto Destro per ripristinare 点击鼠标右键重置 오른쪽 클릭으로 재설정 Click botón derecho para restaurar + Clique com o botão direito para redefinir Markers @@ -59,7 +63,7 @@ Allow moving markers for Erlaube Marker zu bewegen für - 次ユーザーにマーカー移動を許可 + マーカー移動を許可する対象 마커 이동 허가 誰可以移動標誌 谁可以移动标识 @@ -74,11 +78,11 @@ Restricts which players are able to move markers while holding the Alt key. Beschränkt welche Spieler Marker mit gedrückter Alt-Taste bewegen können. - どのプレイヤーが Alt キーを押しながらマーカー移動をできるか制限できます。 + Altキーを押しながらマーカー移動をできるプレイヤーを制限します。 Alt 키를 누른 상태에서 마커를 움직일 수 있는 플레이어를 제한합니다. 設定誰可以透過按住Alt鍵來移動標誌 设定谁可以透过按住 Alt 键来移动标识。 - Limita quali giocatori possono spostare i marcatori mentre premono il tasto Alt. + Limita quali giocatori possono spostare i marcatori premendo il tasto Alt. Ogranicz którzy gracze mogą poruszać znacznikami podczas trzymania przycisku Alt. Устанавливает ограничение на перемещения маркеров игроками при помощи клавиши Alt Restringe quais jogadores podem mover os marcadores do mapa enquanto seguram a tecla ALT. @@ -187,23 +191,27 @@ Allow Timestamps Вкл. отображение времени на метках Permettre l'horodatage - タイムスタンプ許可 + タイムスタンプの許可 Permitir marcas de tiempo Zezwól na znaczniki czasu Erlaube Zeitstempel + Permetti marca temporale 允许时间戳 시간 표기 허용 + Permitir Marcação de Tempo Whether to allow timestamps to be automatically applied to markers Автоматическое отображение времени, когда поставлена метка Active une interface permettant d'apposer un horodatage sur les marqueurs. - マーカーへ自動的にタイムスタンプを付与するかどうかを設定できます。 + タイムスタンプをマーカーに自動的に適用することを許可するかどうか Permitir que las marcas de tiempo sean automáticamente aplicadas a los marcadores Zezwól na automatyczne stosowanie znaczników czasu do markerów Ob Zeitstempel automatisch auf Maker angewendet werden sollen. + Se i giocatori possono scegliere di aggiungere in automatico un marco temporale ai propri marcatori. 是否允许时间戳自动应用于标记 허용 시 마커를 내려놓음과 동시에 시간이 표기됩니다 + Permite que marcações de tempo sejam automaticamente aplicadas aos marcadores Timestamp @@ -213,30 +221,144 @@ Marca de tiempo Znacznik czasu Zeitstempel + Marca temporale 时间戳 시간 표기 + Marcação de Tempo Watch Required Необходимы часы Une montre est requise. - 時計の要求 + 時計が必要 Reloj requerido Wymagany zegarek Uhr benötigt + Necessario orologio 需要手表 시계 필요함 + Relógio necessário + + + Time Zone + Часовой пояс + Fuseau horaire + タイムゾーン + Zona horaria + Strefa czasowa + Zeitzone + Fuso orario + 时区 + 시간대 + + + Changes the time zone for the timestamp + Измените часовой пояс для метки времени + Modifiez le fuseau horaire pour l'horodatage + タイムスタンプのタイムゾーンを変更します + 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 + 更改时间戳的时区 + 타임스탬프의 시간대를 변경하십시오 + + + In-game Time + Время в игре + Heure de jeu + ゲーム内時間 + Hora del juego + Czas gry + Ingame-Zeit + Ora del gioco + 游戏内时间 + 게임 시간 + + + System Time + Системное время + Heure système + システム時間 + Hora del sistema + Czas systemowy + Systemzeit + Ora del sistema + 系统时间 + 시스템 시간 + + + UTC Time + Время UTC + Heure UTC + UTC時間 + Hora UTC + Czas UTC + UTC-Zeit + Tempo-UTC + UTC时间 + UTC 시간 + + + UTC Offset + Смещение UTC + Décalage UTC + UTCオフセット + Desplazamiento UTC + Przesunięcie UTC + UTC-Verschiebung + Deviazione-UTC + UTC偏移量 + UTC 오프셋 + + + Changes the time offset for the UTC timestamp + Измените смещение времени для метки времени UTC + Modifier le décalage horaire pour l'horodatage UTC + UTCタイムスタンプの時オフセットを変更します + 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 Минутное смещение + Décalage des minutes UTC + UTC分オフセット + Desplazamiento de minutos UTC + Przesunięcie minut UTC + UTC-Minutenversatz + Deviazione Minuti UTC + UTC分钟偏移量 + UTC 분 오프셋 + + + Change the minute offset for the UTC timestamp + Изменить минутное смещение для времени UTC + Modifier le décalage des minutes pour l'horodatage UTC + UTCタイムスタンプの分オフセットを変更します + 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 타임 스탬프의 분 오프셋을 변경하십시오 Timestamp Format Формат времени Horodatage - Format - タイムスタンプ形式 + タイムスタンプの形式 Formato de marca de tiempo Format znacznika czasu Format des Zeitstempels + Formato della marca temporale 时间戳格式 시간 표기 포맷 + Formato da Marcação de Tempo Changes the timestamp format @@ -246,19 +368,23 @@ Cambia el formato de marca de tiempo Zmienia format znacznika czasu Zeitstempel-Format anpassen + Modifica il formato dell'ora nella marca temporale 更改时间戳格式 시간 표기 포맷을 바꿉니다 + Altera a formatação da marcação de tempo "HH" - Hour "ЧЧ" - Час "HH" - Heures - "HH" - 時間 + "HH" - 時 "HH" - Hora "HH" - Godziny "HH" - Stunden + "HH" - Ore "HH"—时 "HH" - 시 + HH - Horas "MM" - Minute @@ -268,8 +394,10 @@ "MM" - Minuto "MM" - Minuty "MM" - Minuten + "MM" - Minuti "MM"—分 "MM" - 분 + MM - Minutos "SS" - Seconds @@ -279,19 +407,32 @@ "SS" - Segundos "SS" - Sekundy "SS" - Sekunden + "SS" - Secondi "SS"—秒 "SS" - 초 + SS - Segundos - "MM" - Milliseconds - "МС" - Миллисекунда - "MM" - Millisecondes - "MM" - ミリ秒 - "MM" - Milisegundos - "MM" - Milisekundy - "MS" - Milisekunden - "MS"—毫秒 - "MS" - 밀리초 + "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) + "MM" - Milisegundos (de 0 a 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) + "mmm" - Milisegundos (de 0 a 999) Timestamp Hour Format @@ -301,41 +442,49 @@ Formato de hora de marca de tiempo Format Godzinnych znaczników czasu Zeitstempel-Stundenformat + Formato ore delle marche temporali 时间戳小时格式 시간 표기 시간 포맷 + Sistema Horário das Marcações de Tempo 24-Hour Clock 24 часовой формат Format 24 heures - 24 時間表記 + 24時間表記 Reloj 24-Horas Zegar 24-godzinny 24-Stunden + 24-Ore 24小时制 24시간제 + 24 Horas 12-Hour Clock 12 часовой формат Format 12 heures - 12 時間表記 + 12時間表記 Reloj 12-Horas Zegar 12-godzinny 12-Stunden + 12-Ore 12小时制 12시간제 + 12 Horas Changes timestamp to use either 24-hour or 12-hour clock format Изменяет формат времени на маркере на 24 часовой, либо 12 часовой Permet de choisir le système d'horodatage souhaité, au format 12 ou 24 heures. - タイムスタンプの時刻を 24 時間か 12 時間表記のどちらかに変更できます。 + タイムスタンプの時刻を24時間表記か12時間表記かのどちらかに変更します Cambia que la marca de tiempo sea en formato de reloj 24-horas o 12-horas Zmienia znacznik czasu tak, aby używał formatu 24-godzinnego lub 12-godzinnego Ändert den Zeitstempel, um entweder das 24-Stunden- oder das 12-Stunden-Format zu verwenden + Determina se le marche temporali sui marcatori saranno in formato 24-Ore o 12-Ore. 改变时间戳以使用24小时或12小时的时钟格式 시간 표기를 24시간제 혹은 12시간제 에서 골라 표기합니다 + Altera a marcação de tempo para usar o formato de relógio 24-horas ou 12-horas 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/maverick/stringtable.xml b/addons/maverick/stringtable.xml index e50668ed7b..6bf1d80e04 100644 --- a/addons/maverick/stringtable.xml +++ b/addons/maverick/stringtable.xml @@ -5,7 +5,7 @@ AGM-65 Maverick L, Laser Guided Anti-Ground-Missile AGM-65 Maverick L, lasergelenkte Luft-Boden-Rakete - AGM-65 Maverick L, Guida Laser Missile Anti-Terra + AGM-65 Maverick L, Missile Aria-Terra Laserguidato AGM-65 マーベリック L、レーザー誘導対地ミサイル AGM-65"小牛"飛彈L型,雷射導引對地導彈 AGM-65"小牛"L型激光制导对地导弹 @@ -70,12 +70,14 @@ MAVL MAVL MAVL + MAVL MAVL MAVL MAVL MAVL MAVL MAVL + MAVL Kh-25ML, Laser Guided Air-to-Ground-Missile @@ -84,7 +86,7 @@ Kh-25ML,雷射導引對地導彈 Kh-25ML,激光制导空地导弹 Kh-25ML、レーザー誘導対地ミサイル - Kh-25ML, a Guida Laser Missile Aria-Terra + Kh-25ML, Missile Aria-Terra Laserguidato Kh-25ML, Kierowany laserowo pocisk powietrze-ziemia Х-25МЛ, ракета Воздух-Земля с лазерным наведением Kh-25ML, Míssil Ar para Chão Guiado a Laser diff --git a/addons/medical/XEH_preInit.sqf b/addons/medical/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/medical/XEH_preInit.sqf +++ b/addons/medical/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/medical/dev/test_hitpointConfigs.sqf b/addons/medical/dev/test_hitpointConfigs.sqf index 9de5c5e686..7bdeb189c2 100644 --- a/addons/medical/dev/test_hitpointConfigs.sqf +++ b/addons/medical/dev/test_hitpointConfigs.sqf @@ -21,23 +21,16 @@ INFO_1("Checking uniforms for correct medical hitpoints [%1 units]",count _units private _testPass = true; { private _typeOf = configName _x; - private _hitpoints = (configProperties [_x >> "HitPoints", "isClass _x", true]) apply {configName _x}; + private _hitpoints = (configProperties [_x >> "HitPoints", "isClass _x", true]) apply {toLowerANSI configName _x}; + private _expectedHitPoints = ["hitleftarm","hitrightarm","hitleftleg","hitrightleg","hithead","hitbody"]; + private _missingHitPoints = _expectedHitPoints select {!(_x in _hitpoints)}; + if (_missingHitPoints isNotEqualTo []) then { + WARNING_3("%1 missing ace hitpoints: %2 - class hitpoints: %3",_typeOf,_missingHitPoints,_hitpoints); + _testPass = false; + }; // _typeOf createUnit [position player, group player, "z = this"]; // deleteVehicle z; - - private _lastHitpoint = (_hitpoints param [(count _hitpoints) - 1, "#array"]); - if (_lastHitpoint != "ACE_HDBracket") then { - WARNING_2("%1 has bad last hitpoint: %2",_typeOf,_hitpoints); - _testPass = false; - }; - - if (((_hitpoints findIf {_x == "HitLeftArm"}) == -1) || {(_hitpoints findIf {_x == "HitRightArm"}) == -1} - || {(_hitpoints findIf {_x == "HitLeftLeg"}) == -1} || {(_hitpoints findIf {_x == "HitRightLeg"}) == -1} - || {(_hitpoints findIf {_x == "HitHead"}) == -1} || {(_hitpoints findIf {_x == "HitBody"}) == -1}) then { - WARNING_2("%1 missing ace hitpoints: %2",_typeOf,_hitpoints); - _testPass = false; - }; } forEach _units; _testPass diff --git a/addons/medical/dev/watchVariable.sqf b/addons/medical/dev/watchVariable.sqf index 0eb191e8dd..a0e064595a 100644 --- a/addons/medical/dev/watchVariable.sqf +++ b/addons/medical/dev/watchVariable.sqf @@ -10,10 +10,10 @@ GVAR(dev_watchVariableRunning) = true; if (!isNull _display) exitWith {"Paused"}; private _unit = cursorTarget; - if (!(_unit isKindOf "CAManBase")) then {_unit = cursorObject}; - if (!(_unit isKindOf "CAManBase")) then {_unit = ACE_player}; + if !(_unit isKindOf "CAManBase") then {_unit = cursorObject}; + if !(_unit isKindOf "CAManBase") then {_unit = ACE_player}; if ((_unit != ACE_player) && {IS_UNCONSCIOUS(ACE_player)}) then {_unit = ACE_player}; - if (!(_unit isKindOf "CAManBase")) exitWith {"No Unit?"}; + if !(_unit isKindOf "CAManBase") exitWith {"No Unit?"}; private _return = []; @@ -28,7 +28,7 @@ GVAR(dev_watchVariableRunning) = true; _return pushBack format ["State: %2", _color, _targetState]; private _hasStableVitals = ["N", "Y"] select ([_unit] call EFUNC(medical_status,hasStableVitals)); private _hasStableCondition = ["N", "Y"] select ([_unit] call EFUNC(medical_status,isInStableCondition)); - private _unconcFlag = if IS_UNCONSCIOUS(_unit) then {"[U]"} else {""}; + private _unconcFlag = ["", "[U]"] select IS_UNCONSCIOUS(_unit); private _timeLeft = _unit getVariable [QEGVAR(medical_statemachine,cardiacArrestTimeLeft), -1]; private _cardiactArrestFlag = if IN_CRDC_ARRST(_unit) then {format ["[CA %1]", _timeLeft toFixed 1]} else {""}; _return pushBack format ["[StableVitals: %1] [StableCon: %2] %3 %4", _hasStableVitals, _hasStableCondition, _unconcFlag, _cardiactArrestFlag]; @@ -38,7 +38,7 @@ GVAR(dev_watchVariableRunning) = true; private _woundBleeding = GET_WOUND_BLEEDING(_unit); private _bloodLoss = GET_BLOOD_LOSS(_unit); private _hemorrhage = GET_HEMORRHAGE(_unit); - private _isBleeding = if (IS_BLEEDING(_unit)) then {"Bleeding"} else {""}; + private _isBleeding = ["", "[Bleeding]"] select IS_BLEEDING(_unit); private _secondsToHeartstop = if (_bloodLoss != 0) then {format ["[Time Left: %1 sec]", (((_bloodVolume - BLOOD_VOLUME_CLASS_4_HEMORRHAGE) max 0) / _bloodLoss) toFixed 0]} else {""}; _return pushBack format ["Blood: %1 [Hemorrhage: %2] %3", _bloodVolume toFixed 3, _hemorrhage, _isBleeding]; _return pushBack format [" - [W: %1 T: %2] %3", _woundBleeding toFixed 4, _bloodLoss toFixed 4, _secondsToHeartstop]; @@ -60,7 +60,7 @@ GVAR(dev_watchVariableRunning) = true; // Damage: private _damage = _unit getVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0]]; - private _limping = if (_unit getVariable [QEGVAR(medical,isLimping), false]) then {"[ Limping ]"} else {""}; + private _limping = ["", "[ Limping ]"] select (_unit getVariable [QEGVAR(medical,isLimping), false]); _return pushBack format ["BodyPartDamage: [H: %1] [B: %2]", (_damage select 0) toFixed 2, (_damage select 1) toFixed 2]; _return pushBack format ["[LA:%1] [RA: %2] [LL:%3] [RL: %4]", (_damage select 2) toFixed 2, (_damage select 3) toFixed 2, (_damage select 4) toFixed 2, (_damage select 5) toFixed 2]; @@ -68,8 +68,8 @@ GVAR(dev_watchVariableRunning) = true; _return pushBack format ["[HHnd:%1] [HLeg: %2] %3", (_unit getHitPointDamage "HitHands") toFixed 2, (_unit getHitPointDamage "HitLegs") toFixed 2, _limping]; private _fractures = GET_FRACTURES(_unit); - private _canSprint = if (isSprintAllowed _unit) then {""} else {"[Sprint Blocked]"}; - private _forceWalk = if (isForcedWalk _unit) then {"[Forced Walking]"} else {""}; + private _canSprint = ["[Sprint Blocked]", ""] select (isSprintAllowed _unit); + private _forceWalk = ["", "[Forced Walking]"] select (isForcedWalk _unit); _return pushBack format ["Fractures: %1 %2%3", _fractures, _canSprint, _forceWalk]; diff --git a/addons/medical/functions/fnc_addDamageToUnit.sqf b/addons/medical/functions/fnc_addDamageToUnit.sqf index 23ac9f0990..e490399c4b 100644 --- a/addons/medical/functions/fnc_addDamageToUnit.sqf +++ b/addons/medical/functions/fnc_addDamageToUnit.sqf @@ -34,15 +34,15 @@ 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}; -if (isNull _unit || {!local _unit} || {!alive _unit}) exitWith {ERROR_2("addDamageToUnit - badUnit %1 [local %2]", _this, local _unit); false}; -if (_damageToAdd < 0) exitWith {ERROR_1("addDamageToUnit - bad damage %1", _this); false}; +if (_bodyPartIndex < 0) exitWith {ERROR_1("addDamageToUnit - bad selection %1",_this); false}; +if (isNull _unit || {!local _unit} || {!alive _unit}) exitWith {ERROR_2("addDamageToUnit - badUnit %1 [local %2]",_this,local _unit); false}; +if (_damageToAdd < 0) exitWith {ERROR_1("addDamageToUnit - bad damage %1",_this); false}; if (!_overrideInvuln && {!((isDamageAllowed _unit) && {_unit getVariable [QEGVAR(medical,allowDamage), true]})}) exitWith { - ERROR_1("addDamageToUnit - unit invulnerable %1", _this); false + ERROR_1("addDamageToUnit - unit invulnerable %1",_this); false }; // Extension is case sensitive and expects this format (different from ALL_BODY_PARTS) @@ -69,7 +69,7 @@ private _selectionSpecific = true; if (isClass _config) then { _selectionSpecific = (getNumber (_config >> "selectionSpecific")) == 1; } else { - WARNING_2("Damage type not in config [%1:%2]", _typeOfDamage, _config); + WARNING_2("Damage type not in config [%1:%2]",_typeOfDamage,_config); }; INFO_4("Debug AddDamageToUnit: Type [%1] - Selection Specific [%2] - HitPoint [%3 -> %4]",_typeOfDamage,_selectionSpecific,_startDmg select _bodyPartIndex,_endDmg select _bodyPartIndex); INFO_4("Pain Change [%1 -> %2] - BodyPartDamage Change [%3 -> %4]",_startPain,_endPain,_startDmg,_endDmg); diff --git a/addons/medical/functions/fnc_deserializeState.sqf b/addons/medical/functions/fnc_deserializeState.sqf index b85e0b31e2..b7846bf901 100644 --- a/addons/medical/functions/fnc_deserializeState.sqf +++ b/addons/medical/functions/fnc_deserializeState.sqf @@ -17,6 +17,11 @@ */ params [["_unit", objNull, [objNull]], ["_json", "{}", [""]]]; +// Don't run in scheduled environment +if (canSuspend) exitWith { + [FUNC(deserializeState), _this] call CBA_fnc_directCall +}; + if (isNull _unit) exitWith {}; if (!local _unit) exitWith { ERROR_1("unit [%1] is not local",_unit) }; diff --git a/addons/medical/functions/fnc_setUnconscious.sqf b/addons/medical/functions/fnc_setUnconscious.sqf index cf078ae64b..a1de71c36b 100644 --- a/addons/medical/functions/fnc_setUnconscious.sqf +++ b/addons/medical/functions/fnc_setUnconscious.sqf @@ -38,7 +38,7 @@ if (!local _unit) exitWith { }; if (_knockOut isEqualTo IS_UNCONSCIOUS(_unit)) exitWith { - WARNING_2("setUnconscious called with no change [Unit %1] [State [%2]", _unit, _knockOut); + WARNING_2("setUnconscious called with no change [Unit %1] [State [%2]",_unit,_knockOut); false }; diff --git a/addons/medical/initSettings.sqf b/addons/medical/initSettings.inc.sqf similarity index 100% rename from addons/medical/initSettings.sqf rename to addons/medical/initSettings.inc.sqf diff --git a/addons/medical/stringtable.xml b/addons/medical/stringtable.xml index ae61f8b429..1a6cb07dbb 100644 --- a/addons/medical/stringtable.xml +++ b/addons/medical/stringtable.xml @@ -11,7 +11,7 @@ ACE Médico ACE Médical ACE Orvosi Rendszer - ACE Medical + ACE Medica ACE 의료 ACE 医疗 ACE 醫療系統 @@ -25,25 +25,25 @@ Médico ACE Interfaz ACE-Medicsystem Interface ACE Zdravotnické Rozhraní - ACE Médico Interface + ACE Interface Médica ACE Médical Interface - ACE Medical Interfaccia + ACE Interfaccia Medica ACE 의료 인터페이스 ACE 医疗 界面 ACE 醫療系統 介面 ACE Medikal Arayüz - ACE 医療 インターフェイス + ACE 医療 インタフェース Unconscious Wake Up Chance Wahrscheinlichkeit um aufzuwachen - 気絶時の覚醒確率 + 無意識状態時の覚醒確率 Шанс очнуться при потере сознания Chance de reprendre connaissance Chance de recuperar consciência 從無意識中甦醒機率 ACE 从无意识中苏醒概率 - Chance di rialzarsi + Probabilità di rinvenire Pravděpodobnost probuzení se z bezvědomí Szansa na wybudzenie nieprzytomnego Posibilidad de recuperar la conciencia @@ -53,13 +53,13 @@ The probability that a person with stable vitals will wake up from unconsciousness (checked every 15 seconds). Wahrscheinlichkeit, dass eine bewusstlose Person mit stabilen Vitalwerten wieder aufwacht (Überprüfung alle 15 Sekunden) - 容体が安定しているユニットが意識回復する確率を設定します。(15 秒毎に確認) + 容体が安定しているユニットが無意識状態から意識回復する確率を設定します。(15 秒毎に確認) Вероятность, что стабилизированный юнит очнется от потери сознания (Проверяется каждые 15 сек) La probabilité pour qu'une unité inconsciente en état stable reprenne conscience spontanément (état vérifié toutes les 15 secondes). A probabilidade que uma unidade com vitais estabilizados possa recuperar consciências (verificado a cada 15 segundos) 生命跡象穩定的單位從無意識狀態中甦醒的機率(每十五秒確認一次) 生命迹象稳定的单位从无意识状态中苏醒的概率(每十五秒确认一次) - La probabilità che un'unità con i segni vitali stabili si risvegli dall'incoscienza (controllata ogni 15 secondi). + La probabilità che un'unità con segni vitali stabili si risvegli dall'incoscienza (controllata ogni 15 secondi). Pravděpodobnost, že se jednotka se stabilními životními známkami probudí z bezvědomí (zkoušeno každých 15 vteřin). Prawdopodobieństwo, że jednostka ze stabilnymi parametrami życiowymi obudzi się z nieprzytomności (sprawdzane co 15 sekund). La probabilidad de que una unidad estabilizada recupere la conciencia y se levante (se comprueba cada 15 segundos) @@ -73,20 +73,22 @@ 腎上腺素甦醒率加成 肾上腺素苏醒概率加成 Erhöhung der Aufwachüberprüfungsrate durch Epinephrin + Rinvenimento più veloce da Epinefrina アドレナリンによる覚醒確率上昇 Zvýšení pravděpodobnosti probuzení s Epinefrinem Увеличение шанса очнуться от адреналина Epinefrin Uyanma Şansı Artışı Aumento de probabilidad de despertarse por epinefrina 에피네프린 사용 시 추가 회복 확률 + Aumento da Chance de Acordar com Epinefrina When an unconscious patient has Epinephrine in their system, the time between spontaneous wake up checks is divided by this value. - 患者の体内に投与されたアドレナリンがある場合、\n覚醒計算の確率が上昇(値で除算)されます。 + 無意識状態の患者の体内に投与されたアドレナリンがある場合、 覚醒確率計算の実施間隔が値で除算されます。 增加因病患的循環系統裡面的腎上腺素自我甦醒的機率。 增加因病患的循环系统里面的肾上腺素自我苏醒的机率。 Augmente la fréquence des tests de réveil lorsque le patient a de l'épinéphrine dans son système sanguin.\n(L'épinéphrine n'accélère pas la reprise de conscience si la valeur est définie sur 1.) - Aumenta la frequenza dei controlli al risveglio spontaneo quando il paziente ha l'Epinefrina nel suo corpo + Quando un paziente svenuto ha Epinefrina in circolo, il tempo tra verifiche della probabilità di rinvenire viene diviso per questo valore. Zvyšuje jak často je proveden test na probuzení z bezvědomí pokud má pacient Epinefrin ve svém krevním oběhu. Zwiększa częstotliwość spontanicznych wybudzeń, gdy pacjent ma epinefrynę w swoim organizmie. Aumenta o quão frequentemente checagens de acordar acontecem quando o paciente possui epinefrina no seu sistema @@ -118,10 +120,10 @@ 控制裂開或者已包紮傷口是否會讓人跛腳。 控制裂开或者已包扎伤口是否会让人跛脚。 Permet de définir si les plaies ouvertes ou pansées font boiter une personne. - Controlla se le ferite aperte o bendate fanno zoppicare una persona. + Controlla se le ferite aperte o bendate fanno zoppicare un'unità. Nastavuje zda otevřená nebo zavázaná zranění způsobují kulhání. Kontroluje, czy otwarte lub zabandażowane rany powodują utykanie jednostki. - Controla se ferimentos abertos ou enfaixados causam a pessoa a mancar + Controla se ferimentos abertos ou atados causam a pessoa a mancar. Controla si las heridas abiertas o vendadas hacen que una persona cojee. Stellt ein, ob offene oder bandagierte Wunden eine Person zum Humpeln bringen. Контролирует хромоту в случае открытых или забинтованных ран. @@ -136,7 +138,7 @@ Mancar se possuir feridas abertas 傷口裂開時跛腳 伤口裂开时跛脚 - Zoppo per via delle ferite aperte + Zoppica per via di ferite aperte Kulhat s otevřeným zraněním Kuśtykanie przy otwartych ranach Cojera en heridas abiertas @@ -152,7 +154,7 @@ Mancar se possuir feridas abertas ou atadas 使裂開或者包紮過的傷口讓人跛腳 使裂开或者包扎过的伤口让人跛脚 - Zoppicare su ferite aperte o bendate + Zoppica per via di ferite aperte o bendate Kulhat s otevřeným i zavázaným zraněním Kuśtykanie przy otwartych ranach lub zabandażowanych ranach Cojera en heridas abiertas o vendadas @@ -178,14 +180,14 @@ Controls the effect of using splints to treat fractures.\nWhen disabled, injuries will not cause fractures. - 骨折の治療に副子を使用した際の効果を設定します。\n無効にすると、骨折しません。 + 骨折の治療に添え木を使用した際の効果を設定します。\n無効にすると、骨折しません。 控制是否讓固定版能夠治療骨折。\n當停用時,受傷時不會導致骨折發生。 控制是否让固定板能够治疗骨折。 \n当停用时,受伤时不会导致骨折发生。 Permet de définir le niveau d'efficacité des attelles pour le traitement des fractures.\nSi l'option est désactivée, les blessures ne causent pas de fractures. - Controlla l'effetto dell'utilizzo di stecche per curare le fratture. Quando disabilitato, le lesioni non causano fratture. + Controlla l'effetto dell'utilizzo di gessature per curare le fratture.\nSe disabilitato, le ferite non causano fratture. Nastavuje efekt dlahy při léčení zlomenin.\nPokud je tato možnost vypnuta, zranění nebudou způsobovat zlomeniny. Kontroluje efekt użycia szyn do leczenia złamań.\n Po wyłączeniu obrażenia nie powodują złamań. - Controla o efeito de uso de talas para tratar fraturas. \nQuando desabilitado, ferimentos não causam fraturas. + Controla o efeito de uso de talas para tratar fraturas.\nQuando desabilitado, ferimentos não causam fraturas. Controla el efecto del uso de férulas para tratar fracturas. \n Cuando está desactivado, las lesiones no causan fracturas. Kontrolliert den Effekt wenn Schienen verwendet werden, um Knochenbrüche zu behandeln.\nWenn diese Einstellung nicht aktiviert ist, verursachen Verletzungen keine Knochenbrüche. Управляет эффектом использования шин для лечения переломов.\nПри отключении травмы не вызывают переломов. @@ -195,12 +197,12 @@ Splints Fully Heal Fractures Шины полностью лечат перелом - 副子で骨折完治 + 添え木で骨折完治 Les attelles guérissent complètement les fractures - Tala cura fraturas completamente + Talas curam fraturas completamente 固定板完全治癒骨折 固定板完全治愈骨折 - Le gessature curano al massimo le fratture + Le gessature curano completamente le fratture Dlahy kompletně léčí zlomeniny Szyny leczą zupełnie złamania Férulas sanan completamente las fracturas @@ -211,12 +213,12 @@ Splints Heal, but Cannot Sprint Шины вылечивают, но не дают бегать - 副子で治癒可能、走れないように + 添え木で治癒可能、走れないように Les attelles guérissent les fractures, mais empêchent de sprinter - Talas curam (mas não consegue correr) + Talas curam, mas não permitem correr 固定版能治癒骨折,但無法奔跑 固定板能治愈骨折,但无法奔跑 - Le gessature curano, ma non puoi correre + Le gessature curano, ma non puoi scattare Dlahy léčí, ale zněmožňují sprintování Szyny leczą, ale uniemożliwiają sprint Las férulas sanan, pero no pueden correr @@ -227,7 +229,8 @@ Splints Heal, but Cannot Jog Les attelles guérissent les fractures, mais empêchent de courir - 副子で治癒可能、駆け足できないように + 添え木で治癒可能、駆け足できないように + Le gessature curano, ma non puoi correre Ateller İyileştirir, Ama Koşu Yapamaz Las férulas sanan, pero no pueden trotar Шины вылечивают, но не дают бежать трусцой @@ -235,12 +238,14 @@ Schiene heilt, aber verhindert Sprinten 부목이 치료는 하지만 빨리 걷지 못함 固定板能治愈骨折,但无法慢跑 + Talas curam, mas não permitem trotar Fracture Chance Chance de fracture 骨折確率 骨折概率 + Probabilità di frattura Šance na zlomeninu Шанс перелома Szansa na złamanie @@ -248,10 +253,12 @@ Probabilidad de fractura Wahrscheinlichkeit einer Fraktur 골절 확률 + Chance de Fratura The probability of a fracture causing wound resulting in a fracture. La probabilité pour qu'une blessure pouvant causer une fracture en crée effectivement une. + La probabilità che una ferita in grado di causare una frattura, causerà veramente una frattura. 骨折の原因となる負傷が骨折に至る確率を設定します。 骨折导致的伤口再次骨折的可能性。 Výška šance kdy zranění způsobující zlomeniny skutečně způsobí zlomeninu. @@ -261,6 +268,7 @@ La probabilidad de que una herida que pueda provocar una fractura, provoque una fractura. Die Wahrscheinlichkeit, dass eine Wunde, die eine Fraktur verursachen würde, tatsächlich zu einer Fraktur führt. 상처를 입을 때 골절에 얼마나 관여할지를 결정합니다. + A probabilidade de uma ferida passível de fratura causar uma fratura. Enabled for @@ -290,7 +298,7 @@ Sélectionne pour quelles unités les soins avancés seront actifs. Kiválasztható, mely egységek számára legyen engedélyezve a fejlett orvosi rendszer Seleziona per quali unità verrà abilitato il sistema medico avanzato - 選択されたユニットが、高度な医療が使えるようになります + 選択されたユニットが、高度な医療システムを使えるようになります 어느 인원에게 고급 의료 시스템을 적용시킬지 선택하십시요. 选择进阶医疗系统影响的物体 選擇進階醫療系統影響的對象 @@ -409,7 +417,7 @@ Медик Médico Orvosi - 治療 + 医療 의료 医疗设定 醫療設定 @@ -423,9 +431,9 @@ A distância de %1 está muito longe para tratamento La distancia hasta %1 se ha agrandado demasiado para el tratamiento %1 je příliš daleko, léčba není možná - Distanza da %1 è diventata troppo alta per permettere trattamento + Distanza da %1 è diventata troppo alta per permettere trattamenti %1 est trop loin pour être soigné. - %1 は治療出来ない距離まで離れた + %1 は離れすぎていて治療出来ない %1 부터의 거리가 너무 멀어 치료할 수 없습니다 设定当距离超过%1将不能使用治疗动作 設定當距離超過%1將不能使用治療動作 @@ -435,7 +443,7 @@ Open lid Deckel aufklappen フタを開ける - Apri lid + Apri coperchio 打開蓋子 打开盖子 뚜껑 열기 @@ -451,7 +459,7 @@ Close lid Deckel zuklappen フタを閉める - Chiudi lid + Chiudi coperchio 關閉蓋子 关闭盖子 뚜껑 닫기 diff --git a/addons/medical_ai/XEH_postInit.sqf b/addons/medical_ai/XEH_postInit.sqf index 778dafb72b..518d540478 100644 --- a/addons/medical_ai/XEH_postInit.sqf +++ b/addons/medical_ai/XEH_postInit.sqf @@ -1,7 +1,8 @@ #include "script_component.hpp" ["CBA_settingsInitialized", { - TRACE_1("settingsInitialized", GVAR(enabledFor)); + TRACE_1("settingsInitialized",GVAR(enabledFor)); + if (GVAR(enabledFor) == 0) exitWith {}; // 0: disabled if ((GVAR(enabledFor) == 1) && {!isServer} && {hasInterface}) exitWith {}; // 1: Don't Run on non-hc Clients @@ -19,6 +20,5 @@ _unit setVariable [QGVAR(lastSuppressed), CBA_missionTime]; }] call CBA_fnc_addClassEventHandler; - #include "stateMachine.sqf" - + #include "stateMachine.inc.sqf" }] call CBA_fnc_addEventHandler; diff --git a/addons/medical_ai/XEH_preInit.sqf b/addons/medical_ai/XEH_preInit.sqf index 774ef681f3..8cdc2ee6ad 100644 --- a/addons/medical_ai/XEH_preInit.sqf +++ b/addons/medical_ai/XEH_preInit.sqf @@ -6,13 +6,13 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // default time values for AI being ready to heal, used in fnc_isSafe if (isNil QGVAR(timeSafe_shoot)) then { GVAR(timeSafe_shoot) = 30; }; if (isNil QGVAR(timeSafe_hit)) then { GVAR(timeSafe_hit) = 30; }; if (isNil QGVAR(timeSafe_suppressed)) then { GVAR(timeSafe_suppressed) = 30; }; -GVAR(itemHash) = uinamespace getVariable QGVAR(itemHash); +GVAR(itemHash) = uiNamespace getVariable QGVAR(itemHash); ADDON = true; diff --git a/addons/medical_ai/XEH_preStart.sqf b/addons/medical_ai/XEH_preStart.sqf index 52e3374924..b4d795cbbf 100644 --- a/addons/medical_ai/XEH_preStart.sqf +++ b/addons/medical_ai/XEH_preStart.sqf @@ -13,7 +13,7 @@ private _itemHash = createHashMap; private _items = getArray (configFile >> "ace_medical_treatment_actions" >> _x >> "items"); if (_items isEqualTo []) then { ERROR_1("bad action %1",_x); }; private _itemClassname = configName (configFile >> "CfgWeapons" >> _items # 0); - private _treatment = if ((count _treatments) > 1) then { _x } else { "" }; + private _treatment = ["", _x] select ((count _treatments) > 1); _typeHash set [_itemClassname, _treatment]; } forEach _treatments; _itemHash set [_itemType, _typeHash]; diff --git a/addons/medical_ai/functions/fnc_canRequestMedic.sqf b/addons/medical_ai/functions/fnc_canRequestMedic.sqf index 685bd57f54..5064e1a732 100644 --- a/addons/medical_ai/functions/fnc_canRequestMedic.sqf +++ b/addons/medical_ai/functions/fnc_canRequestMedic.sqf @@ -4,13 +4,13 @@ * Checks if there is a medic available in the unit's group. * * Arguments: - * None + * Unit * * Return Value: * Can request medic * * Example: - * player call ACE_medical_ai_fnc_canRequestMedic + * player call ace_medical_ai_fnc_canRequestMedic * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_healSelf.sqf b/addons/medical_ai/functions/fnc_healSelf.sqf index 5747637995..60f2b83712 100644 --- a/addons/medical_ai/functions/fnc_healSelf.sqf +++ b/addons/medical_ai/functions/fnc_healSelf.sqf @@ -4,13 +4,13 @@ * Makes the unit heal itself. * * Arguments: - * None + * Unit * * Return Value: * None * * Example: - * call ACE_medical_ai_fnc_healSelf + * cursorObject call ace_medical_ai_fnc_healSelf * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_healUnit.sqf b/addons/medical_ai/functions/fnc_healUnit.sqf index ad867d2570..4f941efc0a 100644 --- a/addons/medical_ai/functions/fnc_healUnit.sqf +++ b/addons/medical_ai/functions/fnc_healUnit.sqf @@ -4,16 +4,17 @@ * Makes a medic heal the next unit that needs treatment. * * Arguments: - * None + * Unit * * Return Value: * None * * Example: - * call ACE_medical_ai_fnc_healUnit + * cursorObject call ace_medical_ai_fnc_healUnit * * Public: No */ + // Player will have to do this manually of course if ([_this] call EFUNC(common,isPlayer)) exitWith {}; // Can't heal other units when unconscious diff --git a/addons/medical_ai/functions/fnc_healingLogic.sqf b/addons/medical_ai/functions/fnc_healingLogic.sqf index fa35b49284..aff69d7865 100644 --- a/addons/medical_ai/functions/fnc_healingLogic.sqf +++ b/addons/medical_ai/functions/fnc_healingLogic.sqf @@ -11,7 +11,7 @@ * Nothing * * Example: - * [a, b] call ACE_medical_ai_fnc_healingLogic + * [cursorObject, cursorObject] call ace_medical_ai_fnc_healingLogic * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_isInjured.sqf b/addons/medical_ai/functions/fnc_isInjured.sqf index a163a4c808..51ae37caae 100644 --- a/addons/medical_ai/functions/fnc_isInjured.sqf +++ b/addons/medical_ai/functions/fnc_isInjured.sqf @@ -10,7 +10,7 @@ * Does unit need treatment * * Example: - * player call ACE_medical_ai_fnc_isInjured + * cursorObject call ace_medical_ai_fnc_isInjured * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_isSafe.sqf b/addons/medical_ai/functions/fnc_isSafe.sqf index 04da058ce0..21d59a15d6 100644 --- a/addons/medical_ai/functions/fnc_isSafe.sqf +++ b/addons/medical_ai/functions/fnc_isSafe.sqf @@ -10,7 +10,7 @@ * Is unit safe enough * * Example: - * call ACE_medical_ai_fnc_isSafe + * cursorObject call ace_medical_ai_fnc_isSafe * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_itemCheck.sqf b/addons/medical_ai/functions/fnc_itemCheck.sqf index 6d91594ce4..320ae62410 100644 --- a/addons/medical_ai/functions/fnc_itemCheck.sqf +++ b/addons/medical_ai/functions/fnc_itemCheck.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Checks if AI healer has items + * Checks if AI healer has items. * * Arguments: * 0: Healer @@ -13,7 +13,7 @@ * 2: Treatment (Optional) * * Example: - * [cursorObject, "@bandage"] call ACE_medical_ai_fnc_itemCheck + * [cursorObject, "@bandage"] call ace_medical_ai_fnc_itemCheck * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf index f412a718d8..cb142f0288 100644 --- a/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf +++ b/addons/medical_ai/functions/fnc_playTreatmentAnim.sqf @@ -12,14 +12,15 @@ * None * * Example: - * [bob, true, true] call ACE_medical_ai_fnc_playTreatmentAnim + * [cursorObject, true, true] call ace_medical_ai_fnc_playTreatmentAnim * * Public: No */ + params ["_unit", "_actionName", "_isSelfTreatment"]; TRACE_3("playTreatmentAnim",_unit,_actionName,_isSelfTreatment); -if (vehicle _unit != _unit) exitWith {}; +if (!isNull objectParent _unit) exitWith {}; private _configProperty = "animationMedic"; if (_isSelfTreatment) then { diff --git a/addons/medical_ai/functions/fnc_requestMedic.sqf b/addons/medical_ai/functions/fnc_requestMedic.sqf index 9e59181204..0ea2584fbf 100644 --- a/addons/medical_ai/functions/fnc_requestMedic.sqf +++ b/addons/medical_ai/functions/fnc_requestMedic.sqf @@ -4,13 +4,13 @@ * Sends a request to the units assigned medic to heal it. * * Arguments: - * None + * Unit * * Return Value: * None * * Example: - * call ACE_medical_ai_fnc_requestMedic + * cursorObject call ace_medical_ai_fnc_requestMedic * * Public: No */ diff --git a/addons/medical_ai/functions/fnc_wasRequested.sqf b/addons/medical_ai/functions/fnc_wasRequested.sqf index 3b6c1cf059..ffb9aa3780 100644 --- a/addons/medical_ai/functions/fnc_wasRequested.sqf +++ b/addons/medical_ai/functions/fnc_wasRequested.sqf @@ -4,13 +4,13 @@ * Checks if the unit was requested to treat another unit. * * Arguments: - * None + * Unit * * Return Value: * Was requested * * Example: - * call ACE_medical_ai_fnc_wasRequested + * cursorObject call ace_medical_ai_fnc_wasRequested * * Public: No */ diff --git a/addons/medical_ai/initSettings.sqf b/addons/medical_ai/initSettings.inc.sqf similarity index 100% rename from addons/medical_ai/initSettings.sqf rename to addons/medical_ai/initSettings.inc.sqf diff --git a/addons/medical_ai/stateMachine.sqf b/addons/medical_ai/stateMachine.inc.sqf similarity index 100% rename from addons/medical_ai/stateMachine.sqf rename to addons/medical_ai/stateMachine.inc.sqf diff --git a/addons/medical_ai/stringtable.xml b/addons/medical_ai/stringtable.xml index 5e4604f907..54f0c2714c 100644 --- a/addons/medical_ai/stringtable.xml +++ b/addons/medical_ai/stringtable.xml @@ -7,10 +7,10 @@ 衛生兵AI ИИ Медик Médecine IA - IA Médico + IA Médica AI 医疗兵 AI醫療兵 - Medico AI + IA Medica Zdravotnická AI Medyk AI Médico para IA @@ -20,7 +20,7 @@ AI will respond to injury and unconsciousness KI reagiert auf Verletzungen und Bewusstlosigkeit - AIが負傷者と気絶している人に対して行動するようになります。 + AIが負傷者と無意識状態の人に対して行動するようになります。 ИИ будет реагировать на травмы и потерю сознания Les unités IA seront sensibles aux blessures, ainsi qu'à la perte de connaissance. A IA irá responder a ferimentos e perdas de consciência @@ -37,7 +37,7 @@ Nur Server und HC Sólo Server y HC Только сервер и HC - サーバーと HC のみ + サーバーとHCのみ Tylko serwer i HC Seulement sur le serveur ou le HC Solo Server e HC @@ -52,17 +52,25 @@ Require Items Wymagane Przedmioty Erfordere Gegenstände + Richiede risorse mediche 아이템 필요 Items requis + Exigir Itens アイテムを要求 + Требуемые предметы + Requerir Objetos AI will only perform medical treatment if they have the necessary items in their inventory. AI będzie wykonywać zabiegi medyczne tylko wtedy, gdy ma w ekwipunku niezbędne przedmioty. Die KI führt nur dann medizinische Behandlungen durch, wenn sie die erforderlichen Gegenstände in ihrem Inventar hat. + L'IA effettua trattamenti medici solo se è equipaggiata delle risorse mediche necessarie. 소지품에 필요한 아이템이 있을 경우에만 인공지능이 치료를 진행합니다. 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のインベントリに必要なアイテムがある場合にのみ治療を実行します。 + Искусственный интеллект будет оказывать медицинскую помощь только в том случае, если в его инвентаре есть необходимые предметы. + La IA sólo realizará el tratamiento médico en caso de que dispongan de los objetos necesarios en su inventario. Auto Convert Items for AI @@ -70,7 +78,11 @@ 인공지능 아이템 자동 변환 Conversion automatique des items pour les IA Automatische Konvertierung von Gegenständen der KI + Conversione automatica di risorse mediche per IA + Conversão automática de itens para IA AIのアイテムを自動変換 + Автоматическое преобразование элементов для ИИ + Auto Convertir Objetos para la IA diff --git a/addons/medical_blood/XEH_postInit.sqf b/addons/medical_blood/XEH_postInit.sqf index 9ef55adf0e..b08921b441 100644 --- a/addons/medical_blood/XEH_postInit.sqf +++ b/addons/medical_blood/XEH_postInit.sqf @@ -1,9 +1,7 @@ #include "script_component.hpp" -GVAR(useAceMedical) = ["ace_medical"] call EFUNC(common,isModLoaded); - // To support public API regardless of component settings -[QGVAR(spurt), FUNC(spurt)] call CBA_fnc_addEventHandler; +[QGVAR(spurt), LINKFUNC(spurt)] call CBA_fnc_addEventHandler; if (isServer) then { GVAR(bloodDrops) = []; @@ -21,7 +19,7 @@ if (isServer) then { // Start the cleanup loop if (_index == 0) then { - [FUNC(cleanupLoop), [], GVAR(bloodLifetime)] call CBA_fnc_waitAndExecute; + [LINKFUNC(cleanupLoop), [], GVAR(bloodLifetime)] call CBA_fnc_waitAndExecute; }; }] call CBA_fnc_addEventHandler; }; diff --git a/addons/medical_blood/XEH_preInit.sqf b/addons/medical_blood/XEH_preInit.sqf index 3d10086703..93da039be5 100644 --- a/addons/medical_blood/XEH_preInit.sqf +++ b/addons/medical_blood/XEH_preInit.sqf @@ -6,24 +6,10 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" - -// Damage types which do not cause blood spurts -GVAR(noBloodDamageTypes) = createHashMapFromArray (call (uiNamespace getVariable QGVAR(noBloodDamageTypes))); +#include "initSettings.inc.sqf" // blood object model namespace -GVAR(models) = [] call CBA_fnc_createNamespace; - -{ - _x params ["_name", "_model"]; - - // createSimpleObject expects a path without the leading slash - if ((_model select [0,1]) isEqualTo "\") then { - _model = _model select [1]; - }; - - GVAR(models) setVariable [_name, _model]; -} forEach [ +GVAR(models) = createHashMapFromArray [ // higher number means bigger model ["blooddrop_1", QPATHTOF(data\ace_drop_1.p3d)], ["blooddrop_2", QPATHTOF(data\ace_drop_2.p3d)], diff --git a/addons/medical_blood/XEH_preStart.sqf b/addons/medical_blood/XEH_preStart.sqf index d051879f3c..e2683ff586 100644 --- a/addons/medical_blood/XEH_preStart.sqf +++ b/addons/medical_blood/XEH_preStart.sqf @@ -4,7 +4,4 @@ // Damage types which do not cause blood spurts private _noBloodDamageTypes = "getNumber (_x >> 'noBlood') == 1" configClasses (configFile >> "ACE_Medical_Injuries" >> "damageTypes"); -uiNamespace setVariable [ - QGVAR(noBloodDamageTypes), - compileFinal str (_noBloodDamageTypes apply {[configName _x, nil]}) -]; +uiNamespace setVariable [QGVAR(noBloodDamageTypes), compileFinal (_noBloodDamageTypes createHashMapFromArray [])]; diff --git a/addons/medical_blood/functions/fnc_createBlood.sqf b/addons/medical_blood/functions/fnc_createBlood.sqf index e6740ef459..fbff6cc3c6 100644 --- a/addons/medical_blood/functions/fnc_createBlood.sqf +++ b/addons/medical_blood/functions/fnc_createBlood.sqf @@ -21,7 +21,7 @@ params ["_type", "_position", "_source"]; TRACE_3("Creating blood",_type,_position,_source); -private _model = GVAR(models) getVariable _type; +private _model = GVAR(models) get _type; private _bloodDrop = createSimpleObject [_model, [0, 0, 0]]; _bloodDrop setDir random 360; diff --git a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf index 8dfc9c650b..53d5d2361b 100644 --- a/addons/medical_blood/functions/fnc_handleWoundReceived.sqf +++ b/addons/medical_blood/functions/fnc_handleWoundReceived.sqf @@ -22,13 +22,13 @@ params ["_unit", "_allDamages", "_shooter", "_damageType"]; (_allDamages select 0) params ["_damage"]; // Don't bleed if damage type does not cause bleeding -if (_damageType in GVAR(noBloodDamageTypes)) exitWith {}; +if (_damageType in (uiNamespace getVariable QGVAR(noBloodDamageTypes))) exitWith {}; // Don't bleed when players only and a non-player unit is wounded if (GVAR(enabledFor) == BLOOD_ONLY_PLAYERS && {!isPlayer _unit && {_unit != ACE_player}}) exitWith {}; // Don't bleed on the ground if in a vehicle -if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; +if (!isNull objectParent _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; private _bulletDir = if (isNull _shooter) then { random 360 // Cannot calculate the direction properly, pick a random direction diff --git a/addons/medical_blood/functions/fnc_init.sqf b/addons/medical_blood/functions/fnc_init.sqf index 86c0c668c1..6392a6e451 100644 --- a/addons/medical_blood/functions/fnc_init.sqf +++ b/addons/medical_blood/functions/fnc_init.sqf @@ -60,6 +60,6 @@ private _listCode = if (_mode == BLOOD_ONLY_PLAYERS) then { GVAR(stateMachine) = [_listCode, true] call CBA_statemachine_fnc_create; [GVAR(stateMachine), LINKFUNC(onBleeding), {}, {}, "Bleeding"] call CBA_statemachine_fnc_addState; -GVAR(woundReceivedEH) = [QEGVAR(medical,woundReceived), FUNC(handleWoundReceived)] call CBA_fnc_addEventHandler; +GVAR(woundReceivedEH) = [QEGVAR(medical,woundReceived), LINKFUNC(handleWoundReceived)] call CBA_fnc_addEventHandler; TRACE_3("Set up state machine and wounds event",_mode,GVAR(stateMachine),GVAR(woundReceivedEH)); diff --git a/addons/medical_blood/functions/fnc_isBleeding.sqf b/addons/medical_blood/functions/fnc_isBleeding.sqf index 2d57dcf73b..a21a50913a 100644 --- a/addons/medical_blood/functions/fnc_isBleeding.sqf +++ b/addons/medical_blood/functions/fnc_isBleeding.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -if (GVAR(useAceMedical)) exitWith { +if (GETEGVAR(medical,enabled,false)) exitWith { IS_BLEEDING(_unit); }; diff --git a/addons/medical_blood/functions/fnc_onBleeding.sqf b/addons/medical_blood/functions/fnc_onBleeding.sqf index 63ceb3bd29..4963aaa21d 100644 --- a/addons/medical_blood/functions/fnc_onBleeding.sqf +++ b/addons/medical_blood/functions/fnc_onBleeding.sqf @@ -22,10 +22,10 @@ params ["_unit"]; if !(_unit call FUNC(isBleeding)) exitWith {}; // Don't bleed on the ground if in a vehicle -if (vehicle _unit != _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; +if (!isNull objectParent _unit && {!(vehicle _unit isKindOf "StaticWeapon")}) exitWith {}; if (CBA_missionTime > (_unit getVariable [QGVAR(nextTime), -10])) then { - private _bloodLoss = (if (GVAR(useAceMedical)) then {GET_BLOOD_LOSS(_unit) * 2.5} else {getDammage _unit * 2}) min 6; + private _bloodLoss = ([damage _unit * 2, GET_BLOOD_LOSS(_unit) * 2.5] select GETEGVAR(medical,enabled,false)) min 6; _unit setVariable [QGVAR(nextTime), CBA_missionTime + 8 + random 2 - _bloodLoss]; TRACE_2("Creating blood drop for bleeding unit",_unit,_bloodLoss); diff --git a/addons/medical_blood/initSettings.sqf b/addons/medical_blood/initSettings.inc.sqf similarity index 100% rename from addons/medical_blood/initSettings.sqf rename to addons/medical_blood/initSettings.inc.sqf diff --git a/addons/medical_blood/stringtable.xml b/addons/medical_blood/stringtable.xml index 5320cab219..3167b38ef2 100644 --- a/addons/medical_blood/stringtable.xml +++ b/addons/medical_blood/stringtable.xml @@ -24,10 +24,10 @@ 피흘리기 활성화 Włącz ślady krwi na ziemi Activer les gouttes de sang - Abilita Perdite di Sangue + Abilita Chiazze di Sangue 开启血液滴落效果 開啟血液滴落效果 - Разрешить капли крови + Вкл. капли крови Permitir gotas de sangue Povolit kapky krve Habilitar manchas de sangre @@ -37,7 +37,7 @@ Enables the creation of blood drops when units are bleeding or take damage. ユニットが出血や負傷した時に、血痕を残すようにします。 Si une unité saigne, elle laissera des traces de sang derrière elle. - Разрешает создание капель крови при кровотечении или получении урона + Включает создание капель крови при кровотечении или получении урона Permitir a criação de gotas de sangue quando as unidades recebem ferimentos ou estão sangrando. 当单位失血或受伤的时,启用出血效果。 啟用出血效果當單位失血或受傷的時候。 @@ -45,7 +45,7 @@ Umożliwia tworzenie śladów krwi, gdy jednostki krwawią lub otrzymują obrażenia. Habilita la creación de sangrecuando la unidad está sangrando o recibe daño Kişiler kanarken veya hasar alırken kan damlası oluşumunu sağlar. - Abilita la creazione di chiazze di sangue quando un'unità sta sanguinando o viene ferita. + Abilita la formazione di chiazze di sangue quando un'unità sta sanguinando o viene ferita. Ermöglicht das Erstellen von Blutstropfen, wenn Einheiten am Bluten sind oder Schaden nehmen. 출혈이나 부상 시 핏자국이 생기는것을 활성화합니다. @@ -73,7 +73,7 @@ Define o limite máximo de objetos de gota de sangue que podem ser criados, quantidades excessivas podem causar lag de FPS. 设置最大可存在的血迹数量。过量会导致帧数低下或卡顿 設定最大可存在的血跡數量。太極端的數量會導致幀數低落或卡頓 - Imposta il numero massimo di chiazze di sangue che possono essere depositate, quantità eccessive possono causare del lag di FPS. + Imposta il numero massimo di chiazze di sangue che possono essere generate, quantità eccessive possono causare lag di FPS. Nastavuje maximum objektů krve na zemi, příliš mnoho může způsobit pokles FPS Definiuje maksymalną ilość śladów krwi, które mogą zostać stworzone, nadmierne ilości mogą powodować spadki FPS. Fija el límite de objetos de sangre que aparecerán, cantidades excesivas pueden causar caídas de FPS @@ -99,13 +99,13 @@ Controls the lifetime of blood drop objects. - 血痕オブジェクトの寿命を決定します。 + 血痕オブジェクトの寿命を制御します。 Définit la durée d'affichage des traces de sang. Управляет временем жизни объектов капель крови. Controla o tempo de vida que um objeto de gota de sangue tem. 控制血迹在地上的时长 控制血跡在地上的時長 - Controlla la durata delle chiazze di sangue. + Controlla la durata di permanenza delle chiazze di sangue. Nastavuje jak dlouho objekty krve na zemi vydrží. Kontroluje czas trwania śladów krwi. Controla el tiempo de vida que tendrán los objetos de sangre diff --git a/addons/medical_damage/XEH_preInit.sqf b/addons/medical_damage/XEH_preInit.sqf index 26445ad61a..344b9c81ee 100644 --- a/addons/medical_damage/XEH_preInit.sqf +++ b/addons/medical_damage/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" call FUNC(parseConfigForInjuries); diff --git a/addons/medical_damage/functions/fnc_interpolatePoints.sqf b/addons/medical_damage/functions/fnc_interpolatePoints.sqf index a84f079f30..b343417837 100644 --- a/addons/medical_damage/functions/fnc_interpolatePoints.sqf +++ b/addons/medical_damage/functions/fnc_interpolatePoints.sqf @@ -19,7 +19,7 @@ */ params ["_input", "_points", ["_randomRound", false]]; -if (count _points < 1) exitWith { +if (_points isEqualTo []) exitWith { //TODO: sensible default/error value 0 }; diff --git a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf index f2441b3704..4dfcbe840a 100644 --- a/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf +++ b/addons/medical_damage/functions/fnc_parseConfigForInjuries.sqf @@ -38,7 +38,7 @@ private _classID = 0; private _details = [_selections, _bleeding, _pain, _causeLimping, _causeFracture]; GVAR(woundDetails) set [_className, _details]; GVAR(woundDetails) set [_classID, _details]; - + GVAR(woundClassNames) pushBack _className; { GVAR(woundClassNamesComplex) set [10 * _classID + _forEachIndex, format ["%1%2", _className, _x]]; @@ -61,7 +61,7 @@ if (isClass (_damageTypesConfig >> "woundHandlers")) then { _defaultWoundHandlers = [_damageTypesConfig >> "woundHandlers"] call FUNC(parseWoundHandlersCfg); reverse _defaultWoundHandlers; }; -TRACE_1("Found default wound handlers", count _defaultWoundHandlers); +TRACE_1("Found default wound handlers",count _defaultWoundHandlers); // Collect all available damage types from the config { @@ -77,15 +77,15 @@ TRACE_1("Found default wound handlers", count _defaultWoundHandlers); private _thresholds = GET_ARRAY(_damageTypeSubClassConfig >> "thresholds",_thresholdsDefault); private _selectionSpecific = GET_NUMBER(_damageTypeSubClassConfig >> "selectionSpecific",_selectionSpecificDefault); - + private _woundHandlers = []; if (isClass (_damageTypeSubClassConfig >> "woundHandlers")) then { _woundHandlers = [_damageTypeSubClassConfig >> "woundHandlers"] call FUNC(parseWoundHandlersCfg); reverse _woundHandlers; - TRACE_2("Damage type found wound handlers", _className, count _woundHandlers); + TRACE_2("Damage type found wound handlers",_className,count _woundHandlers); } else { _woundHandlers = _defaultWoundHandlers; - TRACE_1("Damage type has no wound handlers, using default", _className); + TRACE_1("Damage type has no wound handlers, using default",_className); }; /* @@ -115,11 +115,11 @@ TRACE_1("Found default wound handlers", count _defaultWoundHandlers); if (_woundType == "woundHandlers") then {continue}; if (_woundType in GVAR(woundDetails)) then { private _weighting = GET_ARRAY(_x >> "weighting",[[ARR_2(0,1)]]); - private _dmgMulti = GET_NUMBER(_x >> "damageMultiplier", 1); - private _bleedMulti = GET_NUMBER(_x >> "bleedingMultiplier", 1); - private _sizeMulti = GET_NUMBER(_x >> "sizeMultiplier", 1); - private _painMulti = GET_NUMBER(_x >> "painMultiplier", 1); - private _fractureMulti = GET_NUMBER(_x >> "fractureMultiplier", 1); + private _dmgMulti = GET_NUMBER(_x >> "damageMultiplier",1); + private _bleedMulti = GET_NUMBER(_x >> "bleedingMultiplier",1); + private _sizeMulti = GET_NUMBER(_x >> "sizeMultiplier",1); + private _painMulti = GET_NUMBER(_x >> "painMultiplier",1); + private _fractureMulti = GET_NUMBER(_x >> "fractureMultiplier",1); _damageWoundDetails pushBack [_woundType, _weighting, _dmgMulti, _bleedMulti, _sizeMulti, _painMulti, _fractureMulti]; } else { WARNING_2("Damage type %1 refers to wound %2, but it doesn't exist: skipping.",_className,configName _x); diff --git a/addons/medical_damage/functions/fnc_woundReceived.sqf b/addons/medical_damage/functions/fnc_woundReceived.sqf index 52dbcba265..a7e3861dee 100644 --- a/addons/medical_damage/functions/fnc_woundReceived.sqf +++ b/addons/medical_damage/functions/fnc_woundReceived.sqf @@ -22,14 +22,13 @@ params ["_unit", "_allDamages", "_shooter", "_ammo"]; private _typeOfDamage = _ammo call FUNC(getTypeOfDamage); if (_typeOfDamage in GVAR(damageTypeDetails)) then { (GVAR(damageTypeDetails) get _typeOfDamage) params ["", "", "_woundHandlers"]; - + private _damageData = [_unit, _allDamages, _typeOfDamage]; { _damageData = _damageData call _x; - TRACE_1("Wound handler returned", _damageData); + TRACE_1("Wound handler returned",_damageData); if !(_damageData isEqualType [] && {(count _damageData) >= 3}) exitWith { - TRACE_1("Return invalid, terminating wound handling", _damageData); + TRACE_1("Return invalid, terminating wound handling",_damageData); }; } forEach _woundHandlers; - }; 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/functions/fnc_woundsHandlerVehiclecrash.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclecrash.sqf index 64ac637107..9aaaf4a382 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerVehiclecrash.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehiclecrash.sqf @@ -24,5 +24,5 @@ private _newDamages = _allDamages apply { [_x select 0, selectRandom ALL_BODY_PARTS, _x select 2]; }; -TRACE_1("Vehicle crash handled, passing damage", _newDamages); +TRACE_1("Vehicle crash handled, passing damage",_newDamages); [_unit, _newDamages, _typeOfDamage] //return diff --git a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf index 9c4f864f97..8f9af8262c 100644 --- a/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf +++ b/addons/medical_damage/functions/fnc_woundsHandlerVehiclehit.sqf @@ -26,12 +26,21 @@ if (count _allDamages > 1) exitWith {_this}; // damage to structural is low unless it's a very large explosion, in which case it is typically >= 1 private _damageToApply = (abs (_allDamages select 0 select 0)); -private _newDamages = []; +private _damageMap = createHashMap; +private _bodyPart = ""; +private _allBodyParts = ALL_BODY_PARTS; // micro-optimization here and above, don't recreate this array every time // hitpoints are randomized, more damage means more wounds in different body parts +// use a hashmap so we only create one entry in _newDamages per body part for "_i" from 1 to (_damageToApply * 6) do { - _newDamages pushBack [_damageToApply, selectRandom ALL_BODY_PARTS, _damageToApply] + _bodyPart = selectRandom _allBodyParts; + _damageMap set [_bodyPart, (_damageMap getOrDefault [_bodyPart, 0]) + _damageToApply]; }; -TRACE_1("Vehicle explosion handled, passing damage", _newDamages); +private _newDamages = []; +{ + _newDamages pushBack [_damageMap get _x, _x, _damageToApply]; +} forEach (keys _damageMap); // micro-optimization again, two 'get's is still faster than iterating over a hashmap + +TRACE_1("Vehicle explosion handled, passing damage",_newDamages); [_unit, _newDamages, _typeOfDamage] //return diff --git a/addons/medical_damage/initSettings.sqf b/addons/medical_damage/initSettings.inc.sqf similarity index 99% rename from addons/medical_damage/initSettings.sqf rename to addons/medical_damage/initSettings.inc.sqf index 0ce21319e2..229b086505 100644 --- a/addons/medical_damage/initSettings.sqf +++ b/addons/medical_damage/initSettings.inc.sqf @@ -3,7 +3,7 @@ "LIST", [LSTRING(fatalDamageSource_DisplayName), LSTRING(fatalDamageSource_Description)], [ELSTRING(medical,Category)], - [[0, 1, 2], [LSTRING(fatalDamageSource_vitalShotsOnly), LSTRING(fatalDamageSource_trauma), LSTRING(fatalDamageSource_both)], 0], + [[0, 1, 2], [LSTRING(fatalDamageSource_vitalShotsOnly), LSTRING(fatalDamageSource_trauma), LSTRING(fatalDamageSource_both)], 2], true ] call CBA_fnc_addSetting; diff --git a/addons/medical_damage/stringtable.xml b/addons/medical_damage/stringtable.xml index e8b2e57756..fa4e1c4ae4 100644 --- a/addons/medical_damage/stringtable.xml +++ b/addons/medical_damage/stringtable.xml @@ -18,9 +18,9 @@ Sets the amount of damage a player can receive before going unconscious (and dying if "Sum of Trauma" is enabled). - プレイヤーが気絶するまでに受けられるダメージ量を設定します。\n("外傷の合計"が有効な場合は死亡するまでに受けられるダメージ量) + プレイヤーが無意識状態に陥るまでに受けられるダメージ量を設定します。\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. 設定玩家在無意識前能承受多少傷害。 设置玩家在昏迷前可以承受的伤害量(如果启用了“创伤总和”,则会死亡)。 @@ -36,11 +36,11 @@ AI Critical Damage Threshold AIのクリティカルダメージしきい値 Seuil de dégât critique de l'IA - Порог критического урона AI + Порог критического урона ИИ Limite de Dano Crítico da IA AI重擊承受量 AI 临界伤害阈值 - Soglia dei danni critici dell AI + Soglia dei danni critici dell'IA Kritická míra poškození pro AI Próg Obrażeń Krytycznych AI Límite de daño crítico de la IA @@ -49,13 +49,13 @@ Sets the amount of damage an AI unit can receive before going unconscious (or dying when "Sum of Trauma" is enabled). - AIが気絶するまでに受けられるダメージ量を設定します。\n("外傷の合計"が有効な場合は死亡するまでに受けられるダメージ量) + 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 在昏迷前可以承受的伤害量(如果启用了“创伤总和”,则会死亡)。 - Imposta la quantità di danno che un'unità AI può ricevere prima di perdere conoscenza. + Imposta la quantità di danno che un'unità IA può ricevere prima di perdere conoscenza. Nastavuje kolik poškození AI může obdržet než upadne do bezvědomí. Definiuje ilość obrażeń jaką może przyjąć AI przed straceniem przytomności (oraz śmierci gdy "Suma urazów" jest włączona). Fijar la cantidad de daño que la IA puede recivir antes de caer inconsciente @@ -116,7 +116,7 @@ Large Scrape Großer Kratzer - Alta Scorticatura + Ampia Scorticatura Большая ссадина Grande écorchure Duże draśnięcie @@ -150,7 +150,7 @@ Minor Avulsion Kleine Avulsion - Minima Avulsione + Piccola Avulsione Малая Авульсия Petite avulsion Pomniejsza rana płatowa @@ -184,7 +184,7 @@ Large Avulsion Große Avulsion - Alta Avulsione + Grande Avulsione Большая Авульсия Grande avulsion Duża rana płatowa @@ -218,7 +218,7 @@ Minor Bruise Kleine Prellung - Minima Contusione + Piccola Contusione Слабый ушиб Petit hématome Pomniejsze stłuczenie @@ -252,7 +252,7 @@ Large Bruise Große Prellung - Alta Contusione + Grande Contusione Сильный ушиб Grand hématome Duże stłuczenie @@ -286,7 +286,7 @@ Minor Crushed Tissue Kleine Quetschverletzung - Minimo Tessuto Schiacciato + Poco Tessuto Schiacciato Слабая компрессионная травма Tissu légèrement écrasé Pomniejsze zgniecienie tkanek miękkich @@ -320,7 +320,7 @@ Large Crushed Tissue Große Quetschverletzung - Alto Tessuto Schiacciato + Molto Tessuto Schiacciato Сильная компрессионная травма Tissu fortement écrasé Duże zgniecienie tkanek miękkich @@ -473,7 +473,7 @@ Velocity Wound Ballistisches Trauma - Velocità Ferita + Ferita Balistica Огнестрельная рана Rana postrzałowa Plaie pénétrante @@ -490,7 +490,7 @@ Small Velocity Wound Kleines Ballistisches Trauma - Lenta Velocità Ferita + Piccola Ferita Balistica Малая огнестрельная рана Pomniejsza rana postrzałowa Herida de bala menor @@ -507,7 +507,7 @@ Medium Velocity Wound Mittleres Ballistisches Trauma - Media Velocità Ferita + Media Ferita Balistica Средняя огнестрельная рана Średnia rana postrzałowa Herida de bala media @@ -524,7 +524,7 @@ Large Velocity Wound Großes Ballistisches Trauma - Alta Velocità Ferita + Grande Ferita Balistica Большая огнестрельная рана Duża rana postrzałowa Herida de bala severa @@ -541,7 +541,7 @@ Puncture Wound Stichwunde - Puntura Ferita + Ferita Perforante Колотая рана Rana kłuta Blessure par perforation @@ -558,7 +558,7 @@ Minor Puncture Wound Kleine Stichwunde - Piccola Puntura Ferita + Piccola Ferita Perforante Малая колотая рана Pomniejsza rana kłuta Herida punzante menor @@ -575,7 +575,7 @@ Medium Puncture Wound Mittlere Stichwunde - Media Puntura Ferita + Media Ferita Perforante Средняя колотая рана Średnia rana kłuta Herida punzante media @@ -592,7 +592,7 @@ Large Puncture Wound Große Stichwunde - Grande Puntura Ferita + Grande Ferita Perforante Большая колотая рана Duża rana kłuta Herida punzante severa @@ -609,11 +609,11 @@ Fatal Damage Source Причина смертельного урона - 致命傷の原因 + 致命ダメージの原因 致命傷來源 致命伤来源 Cause de blessure mortelle - Fonte del danno fatale + Fonte di danni letali Zdroj smrtelné škody Źródło obrażeń krytycznych Fonte de Dano Fatal @@ -625,10 +625,10 @@ Determines what damage can be fatal Определяет какой урон будет смертельным - 致命傷となるダメージの種類を決定します。 + 致命となるダメージの種類を定義します。 決定何種傷害為致命 确定哪些伤害可能是致命的 - Determina quali danni possono essere fatali + Determina quali danni possono essere letali Détermine le type de blessures pouvant être fatales. Nastavuje jaké poškození může být smrtelné Określa jakie obrażenia mogą być śmiertelne @@ -641,14 +641,14 @@ Only large hits to vital organs Только серьезные попадания в жизненно важные органы - 重要臓器に大きなダメージを受けた時のみ + 重要臓器に大きな被弾があった時のみ 只有重要器官之重傷 只有重要器官受到重创 Grosses blessures sur organes vitaux Solo grandi colpi agli organi vitali Pouze zásahy do životně důležitých orgánů Tylko duże trafienia w ważne narządy - Apenas danos largos a órgãos vitais + Apenas danos graves a órgãos vitais Solo grandes heridas en organos vitales Sadece hayati organlara büyük vuruşlar Nur schwere Treffer an lebenswichtigen Organen @@ -676,10 +676,10 @@ 兩者都是 二者之一 Les deux - o + Entrambi Kterýkoliv ze dvou Zarówno - Ou + Ambos Ambos Ikisinden biri Beide @@ -690,49 +690,58 @@ 熱傷 Brûlure thermique Термический ожог + Ustione Termica Thermische Verbrennung Oparzenie 热灼伤 화상 Quemadura térmica + Queimadura Térmica Minor Thermal Burn 軽度の熱傷 Légère brûlure thermique + Leggera Ustione Termica Незначительный термический ожог Leichte thermische Verbrennung Pomniejsze oparzenie 轻微热灼伤 작은 화상 Quemadura térmica menor + Queimadura Térmica Leve Medium Thermal Burn 中度の熱傷 Brûlure thermique modérée + Media Ustione Termica Средний термический ожог Mittlere thermische Verbrennung Średnie oparzenie 中度热灼伤 꽤 큰 화상 Quemadura térmica media + Queimadura Térmica Média Major Thermal Burn 重度の熱傷 Sévère brûlure thermique + Severa Ustione Termica Сильный термический ожог Schwere thermische Verbrennung Duże oparzenie 重度热灼伤 심각한 화상 Quemadura térmica severa + Queimadura Térmica Grave Unit Damage Threshold Schwelle für Schaden Seuil de dégâts + Soglia di danni critici ユニットのダメージしきい値 Práh poškození Порог урона @@ -741,12 +750,14 @@ Umbral de daño de unidad 单位伤害阈值 유닛 피해 한계점 + Limite de Dano em Unidade Sets the amount of damage a unit can receive before going unconscious. (0 for mission default) Legt die Höhe des Schadens fest, den eine Einheit erhalten kann, bevor diese ohnmächtig wird. (0 für Misionsnormalwert) + Determina il livello di danni sopportabili da un'unità senza svenire. (0 per il valore predefinito dalla missione) Définit la quantité de dégâts que l'unité peut subir avant de perdre connaissance (ou mourir, si l'option "Somme des traumatismes" est sélectionnée).\n(0 utilise la valeur définie dans la mission.) - ユニットが気絶するまで許容できるダメージ値を設定できます。(ミッション開始時は0) + このユニットが無意識状態に陥るまでに受けられるダメージ量を設定します。 (ミッション標準は0) Určuje kolik poškození může jednotka utrpět než upadne do bezvědomí. (pro použití standardní hodnoty mise zadejte 0) Устанавливает количество урона, которое может получить юнит перед тем, как потерять сознание. (0 для значения миссии) Ustawia próg obrażeń jakie może otrzymać jednostka przed utratą przytomności. (0 jako ustawienie domyślne misji) @@ -754,68 +765,83 @@ Determina la cantidad de daño que puede recibir una unidad antes de quedar inconsciente (0 para predeterminado de misión) 设定一个单位在昏迷前所能承受的伤害量。(任务默认为0) 이 유닛이 얼마나 많은 피해를 받아야 기절할 지 정합니다. (0은 미션 기본 설정을 사용합니다) + Define a quantidade de dano que uma unidade pode receber antes de ficar inconsciente. (0 para o padrão da missão) Pain Unconscious Chance Шанс потерять сознание от боли Szansa na nieprzytomność przez ból - 痛みによる気絶確率 + Probabilità Svenimento da Dolore + 痛みによる無意識化確率 Probabilidad de inconsciencia por dolor Douleur - Chance d'évanouissement Chance für Bewusslosigkeit durch Schmerz 疼痛昏厥概率 고통으로 인한 기절 확률 + Chance de Inconsciência por Dor The probability of a person falling unconscious when their pain is above the tolerance threshold upon receiving damage. Шанс, что человек потеряет сознание, когда его боль выше допустимого порога при получении травмы. + La probabilità che un'unità perda i sensi quando il suo dolore è sopra la soglia critica ricevendo danni. Szansa że osoba straci przytomność gdy jej ból jest powyżej tolerowalnego progu podczas otrzymywania obrażeń. - ユニットがダメージを受けた時の痛みが許容しきい値を超えていた場合に気絶する確率を設定します。 + ユニットがダメージを受けた時の痛みが許容しきい値を超えていた場合に無意識状態に陥る確率を設定します。 La probabilidad de que una persona caiga inconsciente cuando su dolor está por encima del umbral al haber recibido daño. La probabilité pour qu'une personne perde connaissance lorsque la douleur ressentie est supérieure à son seuil de tolérance. Die Wahrscheinlichkeit, dass eine Person bewusstlos wird, wenn ihre Schmerzen bei einer Verwundung über der Toleranzschwelle liegen. 当一个人的疼痛超过承受能力的极限时,他陷入昏迷的概率。 고통 한계점을 넘을 시 기절하는 확률을 정합니다. + A probabilidade de uma pessoa ficar inconsciente quando sua dor está acima do limite de tolerância ao receber dano. Pain Unconscious Threshold Порог боли для потери сознания + Soglia Critica di Dolore Seuil d'inconscience par la douleur. - 気絶する痛みのしきい値 + 無意識状態に陥る痛みのしきい値 Próg Nieprzytomności od Bólu Schmerz-Bewusstlosigkeit-Grenze 고통 기절 한계점 + Limite de Dor Antes da Inconsciência + Umbral de Dolor de Inconsciencia Sets the threshold for severe pain, above which a person can fall unconscious upon receiving damage. Устанавливает количество боли от полученной травмы, при котором юнит может потерять сознание. + Determina la soglia per forte dolore, al di sopra di cui una persona può svenire se riceve danni. Définis le niveau de douleur à partir duquel une personne peut perdre connaissance. Cf PainUnconsciousChance. 激しい痛みのしきい値を設定します。このしきい値を超えた状態でダメージを受けると意識を失う可能性があります。 Ustawia próg silnego bólu, powyżej którego osoba może stracić przytomność po otrzymaniu obrażeń. Legt die Grenze für starke Schmerzen fest, oberhalb derer eine Person bei erlittenem Schaden bewusstlos werden kann. 사람이 데미지를 입었을 때 의식불명 상태가 될 수 있는 심각한 고통의 한계점을 설정합니다. + Define o limite para dor severa, acima do qual uma pessoa pode ficar inconsciente ao receber dano. + Establece el umbral para dolor severo, sobre el cual una persona puede caer inconsciente una vez reciba daño. Fatal Injury Death Chance Вероятность смерти от смертельной травмы Probabilidad de muerte por herida fatal + Probabilità di morte da ferita letale Blessure mortelle - Chance de décès Szana na śmierć przy śmiertelej ranie 致命傷による死亡確率 Tödliche Verletzung - Wahrscheinlichkeit des Todes 致命伤死亡概率 치명상 사망 확률 + Chance de Morte por Ferimento Fatal The chance of dying to a fatal injury. Шанс умереть от смертельной травмы. La probabilidad de morir a causa de una herida fatal. + La probabilità che una ferita letale provochi la morte dell'unità. La probabilité de mourir lors d'une "blessure mortelle".\nUne blessure mortelle est définie par des dommages importants à la tête ou au cœur. Szansa na śmierć po otrzymaniu śmiertelnej rany. 致命傷による死亡確率を設定します。 Die Wahrscheinlichkeit, an einer eigentlich tödlichen Verletzung zu sterben. 死于致命伤的概率。 치명상으로 인해 사망할 확률을 정합니다. + A chance de morrer para um ferimento fatal. diff --git a/addons/medical_engine/CfgMoves.hpp b/addons/medical_engine/CfgMoves.hpp index 7c99321887..34f0572479 100644 --- a/addons/medical_engine/CfgMoves.hpp +++ b/addons/medical_engine/CfgMoves.hpp @@ -1,4 +1,3 @@ - class CfgMovesBasic; class CfgMovesMaleSdr: CfgMovesBasic { class States { @@ -10,6 +9,11 @@ class CfgMovesMaleSdr: CfgMovesBasic { class DeadState; class UNCON_ANIM(1): DeadState { + // Prevents AI from moving torso and head when unconscious + aiming = "aimingNo"; + aimingBody = "aimingUpNo"; + head = "headNo"; + file = QPATHTO_T(data\ace_unconscious_1.rtm); }; diff --git a/addons/medical_engine/XEH_postInit.sqf b/addons/medical_engine/XEH_postInit.sqf index 6455904f95..ed66091498 100644 --- a/addons/medical_engine/XEH_postInit.sqf +++ b/addons/medical_engine/XEH_postInit.sqf @@ -6,34 +6,29 @@ [_new] call FUNC(updateDamageEffects); // Run on new controlled unit to update QGVAR(aimFracture) }, true] call CBA_fnc_addPlayerEventHandler; - ["CAManBase", "init", { params ["_unit"]; - // Check if last hit point is our dummy. - private _allHitPoints = getAllHitPointsDamage _unit param [0, []]; - reverse _allHitPoints; - while {(_allHitPoints param [0, ""]) select [0,1] == "#"} do { WARNING_1("Ignoring Reflector hitpoint %1", _allHitPoints deleteAt 0); }; + if (unitIsUAV _unit) exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; + if (getNumber (configOf _unit >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit);}; - if (_allHitPoints param [0, ""] != "ACE_HDBracket") then { - private _config = configOf _unit; - if (getText (_config >> "simulation") == "UAVPilot") exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; - if (getNumber (_config >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit)}; + private _allHitPoints = getAllHitPointsDamage _unit param [0, []]; + if ((GVAR(customHitpoints) arrayIntersect _allHitPoints) isNotEqualTo GVAR(customHitpoints)) exitWith { ERROR_1("Bad hitpoints for unit type ""%1""",typeOf _unit); - } else { - // Calling this function inside curly brackets allows the usage of - // "exitWith", which would be broken with "HandleDamage" otherwise. - _unit setVariable [ - QEGVAR(medical,HandleDamageEHID), - _unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}] - ]; }; + + // Calling this function inside curly brackets allows the usage of + // "exitWith", which would be broken with "HandleDamage" otherwise. + _unit setVariable [ + QEGVAR(medical,HandleDamageEHID), + _unit addEventHandler ["HandleDamage", {_this call FUNC(handleDamage)}] + ]; }, nil, [IGNORE_BASE_UAVPILOTS], true] call CBA_fnc_addClassEventHandler; #ifdef DEBUG_MODE_FULL [QEGVAR(medical,woundReceived), { params ["_unit", "_damages", "_shooter", "_ammo"]; - TRACE_4("wound",_unit,_damages, _shooter, _ammo); + TRACE_4("wound",_unit,_damages,_shooter,_ammo); //systemChat str _this; }] call CBA_fnc_addEventHandler; #endif @@ -89,7 +84,7 @@ }; }] call CBA_fnc_addEventHandler; -["CAManBase", "deleted", { +["CAManBase", "Deleted", { params ["_unit"]; TRACE_3("unit deleted",_unit,objectParent _unit,local _unit); if ((!isNull objectParent _unit) && {local objectParent _unit}) then { diff --git a/addons/medical_engine/XEH_preInit.sqf b/addons/medical_engine/XEH_preInit.sqf index 379b30da4b..035b9f4b05 100644 --- a/addons/medical_engine/XEH_preInit.sqf +++ b/addons/medical_engine/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // Define "Constants" variables (both are macros defined in script_macros_medical.hpp, look there for actual variable names) if (isNil QUOTE(SPONTANEOUS_WAKE_UP_INTERVAL)) then {SPONTANEOUS_WAKE_UP_INTERVAL = SPONTANEOUS_WAKE_UP_INTERVAL_DEFAULT}; @@ -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(CARDIAC_OUTPUT_MIN)) then {CARDIAC_OUTPUT_MIN = CARDIAC_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; @@ -39,11 +40,14 @@ GVAR(armorCache) = createHashMap; // with handle damage not returning full results. GVAR(fixedStatics) = []; -GVAR(animations) = [] call CBA_fnc_createNamespace; -GVAR(animations) setVariable [QUNCON_ANIM(faceUp), [QUNCON_ANIM(2),QUNCON_ANIM(2_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceDown), [QUNCON_ANIM(1),QUNCON_ANIM(3),QUNCON_ANIM(4),"unconscious",QUNCON_ANIM(9),QUNCON_ANIM(3_1),QUNCON_ANIM(4_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceLeft), [QUNCON_ANIM(7),QUNCON_ANIM(8),QUNCON_ANIM(1_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1)]]; -GVAR(animations) setVariable [QUNCON_ANIM(faceRight), [QUNCON_ANIM(5),QUNCON_ANIM(6),QUNCON_ANIM(10),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]]; +GVAR(animations) = createHashMapFromArray [ + [toLowerANSI QUNCON_ANIM(faceUp), [QUNCON_ANIM(2),QUNCON_ANIM(2_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]], + [toLowerANSI QUNCON_ANIM(faceDown), [QUNCON_ANIM(1),QUNCON_ANIM(3),QUNCON_ANIM(4),"unconscious",QUNCON_ANIM(9),QUNCON_ANIM(3_1),QUNCON_ANIM(4_1)]], + [toLowerANSI QUNCON_ANIM(faceLeft), [QUNCON_ANIM(7),QUNCON_ANIM(8),QUNCON_ANIM(1_1),QUNCON_ANIM(7_1),QUNCON_ANIM(8_1)]], + [toLowerANSI QUNCON_ANIM(faceRight), [QUNCON_ANIM(5),QUNCON_ANIM(6),QUNCON_ANIM(10),QUNCON_ANIM(5_1),QUNCON_ANIM(6_1)]] +]; + +GVAR(customHitpoints) = ["hitleftarm", "hitrightarm", "hitleftleg", "hitrightleg"]; private _fnc_fixStatic = { params ["_vehicle"]; @@ -83,4 +87,7 @@ addMissionEventHandler ["Loaded", { [] call FUNC(disableThirdParty); +// Future-proofing +EGVAR(medical,enabled) = true; // TODO: remove when medical enable setting is implemented + ADDON = true; diff --git a/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf b/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf index db522b2bf7..726a606344 100644 --- a/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf +++ b/addons/medical_engine/functions/fnc_applyAnimAfterRagdoll.sqf @@ -23,7 +23,7 @@ if !(IS_UNCONSCIOUS(_unit) && // do not run if unit is conscio {alive _unit && // do not run if unit is dead {isNull objectParent _unit}}) exitWith {}; // do not run if unit in any vehicle -private _animsArray = GVAR(animations) getVariable [_anim, [""]]; +private _animsArray = GVAR(animations) getOrDefault [toLowerANSI _anim, [""]]; private _random = (toArray (hashValue _unit)) param [0, 0]; private _index = _random % (count _animsArray); private _unconsciousAnimation = _animsArray select _index; 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/functions/fnc_handleDamage.sqf b/addons/medical_engine/functions/fnc_handleDamage.sqf index 6483f6de64..168203366c 100644 --- a/addons/medical_engine/functions/fnc_handleDamage.sqf +++ b/addons/medical_engine/functions/fnc_handleDamage.sqf @@ -1,9 +1,9 @@ #include "..\script_component.hpp" /* - * Author: commy2, kymckay + * Author: commy2, kymckay, LinkIsGrim * HandleDamage EH where wound events are raised based on incoming damage. * Be aware that for each source of damage, the EH can fire multiple times (once for each hitpoint). - * We store these incoming damages and compare them on our final hitpoint: "ace_hdbracket". + * We store these incoming damages and compare them on last iteration of the event (_context == 2). * * Arguments: * Handle damage EH @@ -13,15 +13,16 @@ * * Public: No */ -params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator", "_hitpoint"]; +params ["_unit", "_selection", "_damage", "_shooter", "_ammo", "_hitPointIndex", "_instigator", "_hitpoint", "_directHit", "_context"]; // HD sometimes triggers for remote units - ignore. if !(local _unit) exitWith {nil}; // Get missing meta info private _oldDamage = 0; +private _structuralDamage = _context == 0; -if (_hitPoint isEqualTo "") then { +if (_structuralDamage) then { _hitPoint = "#structural"; _oldDamage = damage _unit; } else { @@ -32,22 +33,30 @@ if (_hitPoint isEqualTo "") then { if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {_oldDamage}; private _newDamage = _damage - _oldDamage; + +// _newDamage == 0 happens occasionally for vehiclehit events (see line 80 onwards), just exit early to save some frametime +// context 4 is engine "bleeding". For us, it's just a duplicate event for #structural which we can ignore without any issues +if (_context != 2 && {_context == 4 || _newDamage == 0}) exitWith { + TRACE_4("Skipping engine bleeding or zero damage",_ammo,_newDamage,_directHit,_context); + _oldDamage +}; + // Get scaled armor value of hitpoint and calculate damage before armor // We scale using passThrough to handle explosive-resistant armor properly (#9063) // We need realDamage to determine which limb was hit correctly [_unit, _hitpoint] call FUNC(getHitpointArmor) params ["_armor", "_armorScaled"]; private _realDamage = _newDamage * _armor; -if (_hitPoint isNotEqualTo "#structural") then { +if (!_structuralDamage) then { private _armorCoef = _armor/_armorScaled; private _damageCoef = linearConversion [0, 1, GVAR(damagePassThroughEffect), 1, _armorCoef]; _newDamage = _newDamage * _damageCoef; }; -TRACE_4("Received hit",_hitpoint,_ammo,_newDamage,_realDamage); +TRACE_6("Received hit",_hitpoint,_ammo,_newDamage,_realDamage,_directHit,_context); -// Drowning doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs +// Drowning doesn't fire the EH for each hitpoint and never triggers _context=2 (LastHitPoint) // Damage occurs in consistent increments if ( - _hitPoint isEqualTo "#structural" && + _structuralDamage && {getOxygenRemaining _unit <= 0.5} && {_damage isEqualTo (_oldDamage + 0.005)} ) exitWith { @@ -59,14 +68,14 @@ if ( // Faster than (vehicle _unit), also handles dead units private _vehicle = objectParent _unit; +private _inVehicle = !isNull _vehicle; +private _environmentDamage = _ammo == ""; -// Crashing a vehicle doesn't fire the EH for each hitpoint so the "ace_hdbracket" code never runs +// Crashing a vehicle doesn't fire the EH for each hitpoint and never triggers _context=2 (LastHitPoint) // It does fire the EH multiple times, but this seems to scale with the intensity of the crash if ( EGVAR(medical,enableVehicleCrashes) && - {_hitPoint isEqualTo "#structural"} && - {_ammo isEqualTo ""} && - {!isNull _vehicle} && + {_environmentDamage && _inVehicle && _structuralDamage} && {vectorMagnitude (velocity _vehicle) > 5} // todo: no way to detect if stationary and another vehicle hits you ) exitWith { @@ -78,18 +87,15 @@ if ( // Receiving explosive damage inside a vehicle doesn't trigger for each hitpoint // This is the case for mines, explosives, artillery, and catasthrophic vehicle explosions -// Triggers twice, but that doesn't matter as damage is low if ( - _hitPoint isEqualTo "#structural" && - {!isNull _vehicle} && - {_ammo isNotEqualTo ""} && + (!_environmentDamage && _inVehicle && _structuralDamage) && { private _ammoCfg = configFile >> "CfgAmmo" >> _ammo; - GET_NUMBER(_ammoCfg >> "explosive", 0) > 0 || - {GET_NUMBER(_ammoCfg >> "indirectHit", 0) > 0} + GET_NUMBER(_ammoCfg >> "explosive",0) > 0 || + {GET_NUMBER(_ammoCfg >> "indirectHit",0) > 0} } ) exitwith { - TRACE_6("Vehicle hit",_unit,_shooter,_instigator,_damage,_newDamage,_damages); + TRACE_5("Vehicle hit",_unit,_shooter,_instigator,_damage,_newDamage); _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; @@ -99,9 +105,13 @@ if ( 0 }; -// This hitpoint is set to trigger last, evaluate all the stored damage values -// to determine where wounds are applied -if (_hitPoint isEqualTo "ace_hdbracket") exitWith { +// Damages are stored for last iteration of the HandleDamage event (_context == 2) +_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; + +// Ref https://community.bistudio.com/wiki/Arma_3:_Event_Handlers#HandleDamage +// Context 2 means this is the last iteration of HandleDamage, so figure out which hitpoint took the most real damage and send wound event +// Don't exit, as the last iteration can be one of the hitpoints that we need to keep _oldDamage for +if (_context == 2) then { _unit setVariable [QEGVAR(medical,lastDamageSource), _shooter]; _unit setVariable [QEGVAR(medical,lastInstigator), _instigator]; @@ -152,7 +162,7 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { // Environmental damage sources all have empty ammo string // No explicit source given, we infer from differences between them - if (_ammo isEqualTo "") then { + if (_environmentDamage) then { // Any collision with terrain/vehicle/object has a shooter // Check this first because burning can happen at any velocity if !(isNull _shooter) then { @@ -194,16 +204,9 @@ if (_hitPoint isEqualTo "ace_hdbracket") exitWith { QGVAR($HitLeftArm),QGVAR($HitRightArm),QGVAR($HitLeftLeg),QGVAR($HitRightLeg), QGVAR($#structural) ]; - - 0 }; -// Damages are stored for "ace_hdbracket" event triggered last -_unit setVariable [format [QGVAR($%1), _hitPoint], [_realDamage, _newDamage]]; - // Engine damage to these hitpoints controls blood visuals, limping, weapon sway // Handled in fnc_damageBodyPart, persist here -if (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) exitWith {_oldDamage}; - -// We store our own damage values so engine damage is unnecessary -0 +// For all other hitpoints, we store our own damage values, so engine damage is unnecessary +[0, _oldDamage] select (_hitPoint in ["hithead", "hitbody", "hithands", "hitlegs"]) diff --git a/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf b/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf index cc29e75cc1..8441df4ad8 100644 --- a/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf +++ b/addons/medical_engine/functions/fnc_lockUnconsciousSeat.sqf @@ -11,7 +11,6 @@ * * Public: No */ -if (missionNamespace getVariable [QGVAR(disableSeatLocking), false]) exitWith {}; params ["_unit"]; private _vehicle = objectParent _unit; @@ -20,6 +19,13 @@ TRACE_3("lockUnconsciousSeat",_unit,_vehicle,lifeState _unit); if (isNull _vehicle) exitWith {}; if (alive _unit && {lifeState _unit != "INCAPACITATED"}) exitWith {}; +private _disable = missionNamespace getVariable [QGVAR(disableSeatLocking), false]; +if (_disable isEqualTo true || { + _disable isEqualType [] && { + (_disable findIf {_vehicle isKindOf _x}) != -1 + } +}) exitWith {}; + switch (true) do { case (_unit isEqualTo (driver _vehicle)): { _vehicle lockDriver true; diff --git a/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf b/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf index 531f5d4062..4ed63253c7 100644 --- a/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf +++ b/addons/medical_engine/functions/fnc_setUnconsciousAnim.sqf @@ -33,14 +33,14 @@ if (_isUnconscious) then { }; // set animation inside vehicles - if (vehicle _unit != _unit) then { + if (!isNull objectParent _unit) then { private _unconAnim = _unit call EFUNC(common,getDeathAnim); TRACE_2("inVehicle - playing death anim",_unit,_unconAnim); [_unit, _unconAnim] call EFUNC(common,doAnimation); }; } else { // reset animation inside vehicles - if (vehicle _unit != _unit) then { + if (!isNull objectParent _unit) then { private _awakeAnim = _unit call EFUNC(common,getAwakeAnim); TRACE_2("inVehicle - playing awake anim",_unit,_awakeAnim); [_unit, _awakeAnim, 2] call EFUNC(common,doAnimation); diff --git a/addons/medical_engine/initSettings.sqf b/addons/medical_engine/initSettings.inc.sqf similarity index 100% rename from addons/medical_engine/initSettings.sqf rename to addons/medical_engine/initSettings.inc.sqf diff --git a/addons/medical_engine/script_macros_config.hpp b/addons/medical_engine/script_macros_config.hpp index 611a8ad356..4c276d7b18 100644 --- a/addons/medical_engine/script_macros_config.hpp +++ b/addons/medical_engine/script_macros_config.hpp @@ -20,13 +20,6 @@ // This used to take the armor values as parameters; it now inherits the values // of `armor`, `passThrough` and `explosionShielding` from the existing hitpoints // for vanilla consistency. -// "ACE_HDBracket" is a special hit point. It is designed in a way where the -// "HandleDamage" event handler will compute it at the end of every damage -// calculation step. This way we can figure out which hit point took the most -// damage from one projectile and should be receiving the ACE medical wound. -// the hit point itself should not take any damage -// It is important that the "ACE_HDBracket" hit point is the last in the config, -// but has the same selection as the first one (always "HitHead" for soldiers). #define ADD_ACE_HITPOINTS\ class HitLeftArm: HitHands {\ material = -1;\ @@ -47,15 +40,4 @@ };\ class HitRightLeg: HitLeftLeg {\ name = "leg_r";\ - };\ - class ACE_HDBracket {\ - armor = 1;\ - material = -1;\ - name = "head";\ - passThrough = 0;\ - radius = 1;\ - explosionShielding = 1;\ - visual = "";\ - minimalHit = 0;\ - depends = "HitHead";\ } diff --git a/addons/medical_engine/script_macros_medical.hpp b/addons/medical_engine/script_macros_medical.hpp index 56c1eec401..167765c576 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 CARDIAC_OUTPUT_MIN EGVAR(medical,const_minCardiacOutput) +#define CARDIAC_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 352b252865..cf19713202 100644 --- a/addons/medical_engine/stringtable.xml +++ b/addons/medical_engine/stringtable.xml @@ -9,8 +9,10 @@ Włącz obrażenia od kolizji pojazdu 車両衝突ダメージを有効化 Aktiviere Verletzungen durch Fahrzeugunfälle + Abilita danni da schianti del veicolo 启用车辆碰撞损坏 차량 충돌 피해 활성화 + Habilitar Dano por Colisão de Veículo Controls whether crew receives damage from vehicle collisions. @@ -18,10 +20,12 @@ Controla si la tripulación recibe daño debido a colisiones en vehículo. Définit si les passagers à bord des véhicules peuvent être blessés en cas d'accident. Kontroluje czy załoga pojazdu otrzyma obrażenia podczas kolizji pojazdu. - 車両が衝突をすると乗員がダメージを受けるかどうかを決定します。 + 車両が衝突をすると乗員がダメージを受けるかどうかを制御します。 Kontrolliert, ob Besatzung eines Fahrzeugs Schaden durch Unfälle erleiden soll + Determina se i passeggeri di un veicolo subiranno danni da schianti o incidenti. 控制乘员是否受到车辆碰撞的伤害。 차량 충돌로 인해 탑승인원들이 피해를 받을 지 결정합니다. + Controla se a tripulação recebe dano de colisões de veículos. Armor PassThrough Effect @@ -29,7 +33,11 @@ 방어구 PassThrough 효과 Effet de pénétration d'armure Effekt des Panzerungsdurchschlags + Fattore di Trapasso Armatura + Efeito de Penetração de Blindagem 装甲貫通効果 + Эффект сквозного прохождения брони + Efecto de Atravesar Armadura 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! @@ -37,7 +45,11 @@ 최종 데미지에 대한 방어구의 'PassThrough' 효과를 조정합니다. GL 리그에 사용되는 것과 같은 높은 방호값을 덜 효과적으로 만듭니다\n3.16.0 이전의 방어구 동작에는 0%를 사용하십시오.\n당신이 뭘 하고 있는지 알고 있는 경우에만 이걸 설정하세요! Contrôle l'effet de la "pénétration" de l'armure sur les dégâts finaux. Rend les valeurs d'armures élevées, comme celles utilisées dans les gilets GL, moins efficaces.\nUtilisez 0% pour le comportement des armures des versions antérieures à 3.16.0.\nNe modifiez la valeur que si vous savez ce que vous faîtes ! Steuert den Effekt des „Durchschlagens“ von Panzerung auf den Gesamtschaden. Macht hohe Panzerungswerte, wie sie in GL-Westen verwendet werden, weniger effektiv.\nVerwende 0% für das Panzerungsverhalten vor 3.16.0.\nÄndere den Wert nur, wenn du weißt, was du tust! + 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\Прикасайтесь к этому, только если знаете, что делаете! + Controla el efecto de 'passThrough' de armadura en el daño final. Hace que los valores altos de armadura, como los usados en los chalecos GL, sean menos efectivos.\nUsar 0% para comportamiento de armadura en versiones anteriores a 3.16.0.\nSólo modifica esto si sabes lo que estás haciendo! diff --git a/addons/medical_feedback/XEH_postInit.sqf b/addons/medical_feedback/XEH_postInit.sqf index 96d15dbf21..f01394e919 100644 --- a/addons/medical_feedback/XEH_postInit.sqf +++ b/addons/medical_feedback/XEH_postInit.sqf @@ -30,7 +30,7 @@ GVAR(bloodTickCounter) = 0; [false] call FUNC(initEffects); [true] call FUNC(handleEffects); -[FUNC(handleEffects), 1, false] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(handleEffects), 1, false] call CBA_fnc_addPerFrameHandler; ["ace_unconscious", { params ["_unit", "_unconscious"]; @@ -104,7 +104,7 @@ GVAR(bloodTickCounter) = 0; if (ACE_player distance _unit > _distance) exitWith {}; - if (vehicle _unit == _unit) then { + if (isNull objectParent _unit) then { // say3D waits for the previous sound to finish, so use a dummy instead private _dummy = "#dynamicsound" createVehicleLocal [0, 0, 0]; _dummy attachTo [_unit, [0, 0, 0], "camera"]; diff --git a/addons/medical_feedback/XEH_preInit.sqf b/addons/medical_feedback/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/medical_feedback/XEH_preInit.sqf +++ b/addons/medical_feedback/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/medical_feedback/initSettings.sqf b/addons/medical_feedback/initSettings.inc.sqf similarity index 100% rename from addons/medical_feedback/initSettings.sqf rename to addons/medical_feedback/initSettings.inc.sqf diff --git a/addons/medical_feedback/stringtable.xml b/addons/medical_feedback/stringtable.xml index 4d11665a16..d1ef189611 100644 --- a/addons/medical_feedback/stringtable.xml +++ b/addons/medical_feedback/stringtable.xml @@ -42,7 +42,7 @@ Selecione o tipo de efeito de dor. 選擇哪一個視覺效果用於回饋疼痛 选择反馈的疼痛效果类型。 - Seleziona il tipo di effetto del dolore usato. + Seleziona il tipo di effetto causato dal dolore. Nastavuje který efekt bolesti bude používán. Wybiera rodzaj efektu bólu. Selecciona el tipo de efecto de dolor @@ -69,7 +69,7 @@ Pulsing Blur Wiederkehrende Unschärfe - ボケの強弱 + ぼかしの強弱 Пульсирующее размытие Pulsations floues Borrão Pulsante @@ -105,7 +105,7 @@ 只有在強烈疼痛時使用 仅在剧烈疼痛下启用 Juste un fort effet douloureux - Solo elevato effetto di dolore + Solo effetto di elevato dolore Pouze efekt vysoké bolesti Tylko efekt mocnego bólu Apenas efeito de dor alta @@ -119,6 +119,7 @@ Low Blood Volume Effect Type Визуальный эффект низкого объема крови Effet de faible volume sanguin + Effetto di poco sangue 低血液量時効果の種類 Efekt pro nízké množství krve Efekt po utracie znacznej ilości krwi @@ -127,11 +128,13 @@ Effektart für "Niedriges Blutvolumen" 低血容量影响类型 혈액량 부족 시 효과 종류 + Tipo de efeito por volume baixo de sangue Selects the used low blood volume effect type. Выбирает тип визуализации эффекта низкого объема крови. Permet de choisir quel effet provoque un faible volume sanguin. + Seleziona il tipo di effetto causato da un volume di sangue molto ridotto. 低血液量時の画面効果を選択できます。 Nastavuje který efekt pro nízké množství krve bude používán. Wybiera efekt ktory będzie pokazywany po utracie znacznej ilości krwi. @@ -140,11 +143,13 @@ Wählt die verwendete Effektart für niedriges Blutvolumen. 选择低血容量下的效果类型。 혈액량이 부족할 때 어떤 효과로 나타낼지 결정합니다. + Seleciona o tipo de efeito visual quando o volume de sangue está baixo. Color Fading Потеря цветности Atténuation des couleurs + Sbiadimento dei colori 退色 Ztráta barev Zanikanie kolorów @@ -153,11 +158,13 @@ Farbverblassen 褪色 색바램 + Atenuação de cores Icon Иконка Icône + Icona アイコン Ikona Ikona @@ -166,11 +173,13 @@ Symbol 图标 아이콘 + Ícone Icon + Color Fading Иконка + Потеря цветности Icône + Atténuation des couleurs + Icona + Sbiadimento dei colori アイコンと退色 Ikona + Ztráta barev Ikona + Zanikanie kolorów @@ -179,6 +188,7 @@ Symbol + Farbverblassen 图标+褪色 아이콘 및 색바램 + Ícone + Atenuação de cores @@ -208,7 +218,7 @@ Ativa gritos para unidades feridas Si cette option est activée, les unités blessées crieront, voire hurleront sous l'effet de la douleur. Engedélyezi a sérült egységek kiáltásait - Abilita Grida da parte delle unità ferite + Abilita Grida da parte di unità ferite 負傷したユニットが悲鳴をあげるようにします。 부상당한 인원이 소리지르는 것을 활성화합니다 启用伤者的惨叫声 @@ -218,24 +228,28 @@ Enable Fracture/Tourniquet/Splint Indicators Вкл. индикаторы переломов/жгутов/шин - 骨折/止血帯/副子の表記を有効化 + 骨折/止血帯/添え木の表記を有効化 Indicateurs de fractures/garrots/attelles Fraktur-/Tourniquet-/Schienen-Indikatoren aktivieren + Abilita indicatori di Frattura/Gessatura/Laccio Emostatico Włącz wskaźniki złamań/stazy/szyny 启用骨折/止血带/夹板指示器 골절/지혈대/부목 표시 활성화 Habilitar indicadores de Fractura/Torniquete + Habilitar indicadores de Fratura/Torniquete/Tala Enables indicators for fractures and applied tourniquets and splints over the Stance Indicator. Включает индикацию переломов, наложенных шин и жгутов поверх индикатора положения тела. - 体勢インジケータに骨折や副子、止血帯の有無を表示するかどうかを設定できます。 + 体勢インジケータに骨折や添え木、止血帯の有無を表示するかどうかを設定できます。 Affiche des icônes au niveau de l'indicateur de posture, indiquant si le personnage souffre de fractures ou si des garrots ou des attelles sont appliqués. Aktiviert Indikatoren für Frakturen mit angelegte Tourniquets und Schienen über dem Haltungsindikator. + Abilita indicatori per la presenza di fratture, gessature o lacci emostatici applicati sopra l'indicatore di postura. Włącza wskaźniki złamań oraz założonej staz/szyn przy ikonie stanu postawy 在姿态指示器上启用骨折、应用止血带和夹板指示器。 자세 표시기 옆에 골절, 지혈대, 부목의 여부를 표시합니다. Habilita los indicadores para fracturas y torniquetes apllicados y férulas sobre el indicador de posición del personaje. + Habilita indicadores para fraturas, torniquetes e talas sobre o indicador de posição do personagem. diff --git a/addons/medical_gui/CfgVehicles.hpp b/addons/medical_gui/CfgVehicles.hpp index 370015688d..502039325a 100644 --- a/addons/medical_gui/CfgVehicles.hpp +++ b/addons/medical_gui/CfgVehicles.hpp @@ -57,7 +57,7 @@ class CfgVehicles { }; class ACE_UnloadPatient { displayName = CSTRING(UnloadPatient); - condition = QUOTE((_target getVariable [ARR_2('ACE_isUnconscious',false)] || {!alive _target}) && {!isNull objectParent _target} && {isNull objectParent _player}); + condition = QUOTE([ARR_2(_player,_target)] call EFUNC(medical_treatment,canUnloadUnit)); exceptions[] = {"isNotDragging", "isNotCarrying", "isNotInside"}; statement = QUOTE([ARR_2(_player,_target)] call EFUNC(medical_treatment,unloadUnit)); icon = QPATHTOF(ui\cross.paa); diff --git a/addons/medical_gui/XEH_postInit.sqf b/addons/medical_gui/XEH_postInit.sqf index f2777f6fd4..2b7fb8ce52 100644 --- a/addons/medical_gui/XEH_postInit.sqf +++ b/addons/medical_gui/XEH_postInit.sqf @@ -21,7 +21,7 @@ GVAR(selfInteractionActions) = []; [QEGVAR(interact_menu,newControllableObject), { params ["_type"]; // string of the object's classname - if (!(_type isKindOf "CAManBase")) exitWith {}; + if !(_type isKindOf "CAManBase") exitWith {}; { _x set [0, _type]; _x call EFUNC(interact_menu,addActionToClass); @@ -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/XEH_preInit.sqf b/addons/medical_gui/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/medical_gui/XEH_preInit.sqf +++ b/addons/medical_gui/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; 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_canOpenMenu.sqf b/addons/medical_gui/functions/fnc_canOpenMenu.sqf index f89ee64031..fc2ac3879e 100644 --- a/addons/medical_gui/functions/fnc_canOpenMenu.sqf +++ b/addons/medical_gui/functions/fnc_canOpenMenu.sqf @@ -1,6 +1,6 @@ #include "..\script_component.hpp" /* - * Author: Glowbal, mharis001 + * Author: Glowbal, mharis001, johnb43 * Checks if the player can open the Medical Menu for the target. * * Arguments: @@ -18,8 +18,14 @@ params ["_player", "_target"]; -alive _player -&& {!IS_UNCONSCIOUS(_player)} -&& {!isNull _target} -&& {_player distance _target < GVAR(maxDistance) || {vehicle _player == vehicle _target}} -&& {GVAR(enableMedicalMenu) == 1 || {GVAR(enableMedicalMenu) == 2 && {vehicle _player != _player || {vehicle _target != _target}}}} +// If in Zeus +if (!isNull findDisplay 312) exitWith { + !isNull _target && + {missionNamespace getVariable [QGVAR(enableZeusModule), true]} && + {GVAR(enableMedicalMenu) > 0} +}; + +_player call EFUNC(common,isAwake) && +{!isNull _target} && +{_player distance _target < GVAR(maxDistance) || {vehicle _player == vehicle _target}} && +{GVAR(enableMedicalMenu) == 1 || {GVAR(enableMedicalMenu) == 2 && {vehicle _player != _player || {vehicle _target != _target}}}} diff --git a/addons/medical_gui/functions/fnc_collectActions.sqf b/addons/medical_gui/functions/fnc_collectActions.sqf index 818decb017..1620b2c5cb 100644 --- a/addons/medical_gui/functions/fnc_collectActions.sqf +++ b/addons/medical_gui/functions/fnc_collectActions.sqf @@ -22,8 +22,8 @@ GVAR(actions) = []; private _configName = configName _x; private _displayName = getText (_x >> "displayName"); private _category = getText (_x >> "category"); - private _condition = compile format [QUOTE([ARR_4(ACE_player, GVAR(target), %1 select GVAR(selectedBodyPart), '%2')] call DEFUNC(medical_treatment,canTreatCached)), ALL_BODY_PARTS, _configName]; - private _statement = compile format [QUOTE([ARR_4(ACE_player, GVAR(target), %1 select GVAR(selectedBodyPart), '%2')] call DEFUNC(medical_treatment,treatment)), ALL_BODY_PARTS, _configName]; + private _condition = compile format [QUOTE([ARR_4(ACE_player,GVAR(target),%1 select GVAR(selectedBodyPart),'%2')] call DEFUNC(medical_treatment,canTreatCached)), ALL_BODY_PARTS, _configName]; + private _statement = compile format [QUOTE([ARR_4(ACE_player,GVAR(target),%1 select GVAR(selectedBodyPart),'%2')] call DEFUNC(medical_treatment,treatment)), ALL_BODY_PARTS, _configName]; private _items = getArray (_x >> "items"); GVAR(actions) pushBack [_displayName, _category, _condition, _statement, _items]; @@ -32,7 +32,7 @@ GVAR(actions) = []; if ("ace_dragging" call EFUNC(common,isModLoaded)) then { GVAR(actions) pushBack [ - localize ELSTRING(dragging,Drag), "drag", + LELSTRING(dragging,Drag), "drag", {ACE_player != GVAR(target) && {[ACE_player, GVAR(target)] call EFUNC(dragging,canDrag)}}, { GVAR(pendingReopen) = false; @@ -41,7 +41,7 @@ if ("ace_dragging" call EFUNC(common,isModLoaded)) then { ]; GVAR(actions) pushBack [ - localize ELSTRING(dragging,Carry), "drag", + LELSTRING(dragging,Carry), "drag", {ACE_player != GVAR(target) && {[ACE_player, GVAR(target)] call EFUNC(dragging,canCarry)}}, { GVAR(pendingReopen) = false; diff --git a/addons/medical_gui/functions/fnc_countTreatmentItems.sqf b/addons/medical_gui/functions/fnc_countTreatmentItems.sqf index 102d996bb3..ac7c4857e6 100644 --- a/addons/medical_gui/functions/fnc_countTreatmentItems.sqf +++ b/addons/medical_gui/functions/fnc_countTreatmentItems.sqf @@ -38,16 +38,31 @@ if (ACE_player != GVAR(target)) then { // Vehicle private _medicVehicle = objectParent ACE_player; private _patientVehicle = objectParent GVAR(target); -private _vehicle = if (!isNull _medicVehicle) then {_medicVehicle} else {_patientVehicle}; +private _vehicle = [_patientVehicle, _medicVehicle] select (!isNull _medicVehicle); 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_handleToggle.sqf b/addons/medical_gui/functions/fnc_handleToggle.sqf index 5ec0f8d7d0..48232790c1 100644 --- a/addons/medical_gui/functions/fnc_handleToggle.sqf +++ b/addons/medical_gui/functions/fnc_handleToggle.sqf @@ -15,16 +15,18 @@ * Public: No */ + // If in Zeus, ignore + if (!isNull findDisplay 312) exitWith {}; + // Find new target to switch to -private _target = if ( +private _target = [ + ACE_player, + GVAR(previousTarget) +] select ( GVAR(target) == ACE_player && {[ACE_player, GVAR(previousTarget)] call EFUNC(common,canInteractWith)} && {[ACE_player, GVAR(previousTarget)] call FUNC(canOpenMenu)} -) then { - GVAR(previousTarget); -} else { - ACE_player; -}; +); // Exit if new target is same as old if (GVAR(target) == _target) exitWith {}; diff --git a/addons/medical_gui/functions/fnc_menuPFH.sqf b/addons/medical_gui/functions/fnc_menuPFH.sqf index 803d03e070..b3d51c2dc9 100644 --- a/addons/medical_gui/functions/fnc_menuPFH.sqf +++ b/addons/medical_gui/functions/fnc_menuPFH.sqf @@ -16,7 +16,10 @@ */ // Check if menu should stay open for target -if !([ACE_player, GVAR(target), ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith) && {[ACE_player, GVAR(target)] call FUNC(canOpenMenu)}) then { +if !( + ([ACE_player, GVAR(target), ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith) || {!isNull findDisplay 312}) && // Allow player to look at himself when unconsious and in Zeus + {[ACE_player, GVAR(target)] call FUNC(canOpenMenu)} +) then { closeDialog 0; // Show hint if distance condition failed if ((ACE_player distance GVAR(target) > GVAR(maxDistance)) && {vehicle ACE_player != vehicle GVAR(target)}) then { diff --git a/addons/medical_gui/functions/fnc_onMenuOpen.sqf b/addons/medical_gui/functions/fnc_onMenuOpen.sqf index e77d92bddd..12b27b60d9 100644 --- a/addons/medical_gui/functions/fnc_onMenuOpen.sqf +++ b/addons/medical_gui/functions/fnc_onMenuOpen.sqf @@ -41,7 +41,7 @@ if (GVAR(menuPFH) != -1) exitWith { TRACE_1("Menu PFH already running",GVAR(menuPFH)); }; -GVAR(menuPFH) = [FUNC(menuPFH), 0, []] call CBA_fnc_addPerFrameHandler; +GVAR(menuPFH) = [LINKFUNC(menuPFH), 0, []] call CBA_fnc_addPerFrameHandler; // Hide categories if they don't have any actions (airway) private _list = [ 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.sqf b/addons/medical_gui/initSettings.inc.sqf similarity index 94% rename from addons/medical_gui/initSettings.sqf rename to addons/medical_gui/initSettings.inc.sqf index a0418ca74e..dfcbe48925 100644 --- a/addons/medical_gui/initSettings.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 edb3e73f60..3f816aa39b 100644 --- a/addons/medical_gui/stringtable.xml +++ b/addons/medical_gui/stringtable.xml @@ -9,7 +9,7 @@ GUI 界面 界面 - GUI + Interfaccia Grafica GUI Graficzny Interfejs Użytkownika Interfaz gráfica @@ -20,13 +20,13 @@ Enable Medical Actions Aktiviere Sanitätsaktionen - 治療インタラクションの有効化 - Разрешить Медицинские действия + 医療インタラクションの有効化 + Вкл. медицинские действия Activer les actions médicales Ativar Ações Médicas 啟用醫療行為 启用医疗措施 - Attivare azioni mediche + Attiva azioni mediche Povolit zdravotnické akce Włącza opcje medyczne Habilitar acciones médicas @@ -36,13 +36,13 @@ Enables medical actions for the Interaction Menu and selects their style. Aktiviert die Sanitätsaktionen für das Interaktionsmenü und legt das Aussehen fest - インタラクションメニューから選択した表示方式で医療行為をできるようになります。 + インタラクション メニューから選択した表示方式で医療行為をできるようになります。 Включает медицинские действия для меню взаимодействия и выбирает их стиль. Permet d'afficher les actions médicales dans le menu d'interaction, et de définir leur style visuel. Ativa as ações médicas para o menu de interação e seleciona seus estilos. 為互動選單啟用醫療行為以及選擇其風格。 为交互式菜单启用医疗操作,并选择其样式。 - Abilita le azioni mediche per il Menu Interazione e seleziona il loro stile. + Abilita le azioni mediche nel Menù Interazioni e scegli il loro stile. Povolit zdravotnické akce pro menu interakcí a vybrat jejich styl. Umożliwia akcje medyczne w menu interakcji i wybiera ich styl. Habilita acciones médicas para el menú de interacción y selecciona su estilo. @@ -59,7 +59,7 @@ Seleção (3d) Választékok (3D) 3D výběr - Selezione (3D) + Selezioni (3D) 選択 (3D) 선택 (3d) 选择(3D) @@ -86,7 +86,7 @@ Enable Medical Self Actions Medizinische Selbst-Interaktionen anzeigen - 治療セルフインタラクションの有効化 + 医療セルフ・インタラクションの有効化 Разрешить Медицинские действия на себе Activer les actions médicales sur soi-même Ativar ações médicas em si mesmo @@ -102,13 +102,13 @@ Enables medical actions for the Self Interaction Menu. Medizinische Interaktionen bei Selbst-Interaktionen anzeigen - セルフインタラクションメニューで医療行為をできるようになります。 + セルフ・インタラクション メニューで医療行為をできるようになります。 Включает медицинские действия для меню взаимодействия с собой. Active les actions médicales du menu d'interaction personnel. Ativa as ações médicas do menu de interação pessoal. 為自我互動選單啟用醫療行為。 为自我交互菜单启用医疗操作。 - Abilita il menu per le interazioni mediche personali + Abilita il menù per le interazioni mediche personali Povoluje zdravotnické akce v menu vlastních interakcí. Umożliwia działania medyczne w menu własnej interakcji. Activa las acciones médicas para el menú de interacción personal @@ -119,12 +119,12 @@ Enable Medical Menu Aktiviere das Sanitätsmenü 医療メニューを有効化 - Разрешить Медицинское меню + Вкл. медицинское меню Activer le menu médical Ativar Menu Médico 啟用醫療選單 启用医疗菜单 - Abilita il menu medico + Abilita il menù medico Povolit Zdravotnické menu Włącz Menu Medyczne Activar menú médico @@ -134,13 +134,13 @@ Enables the use of the Medical Menu through the keybind or interaction menu. Aktiviere die Nutzung des Sanitätsmenüs durch eine Tastenkombination oder durch das Interaktionsmenü - 割り当てられたキーかインタラクションメニューから医療メニューを使えるようになります。 + 割り当てられたキーかインタラクション メニューから医療メニューを使えるようになります。 Позволяет использовать Медицинское меню через связку клавиш или меню взаимодействия. Permet l'utilisation du menu médical via le menu d'interaction ou l'appui d'une touche. Ativa o uso do Menu Médico através da Tecla ou Menu de Interação. 啟用以互動選單或者按鍵綁定所呼出的高效醫療選單 通过按键绑定或交互菜单启用医疗菜单。 - Abilita l'uso del Menu Medico attraverso il menu tastiera o il menu di interazione. + Abilita l'uso del Menù Medico attraverso il menù tastiera o il menu di interazione. Povoluje používání Zdravotnického menu klávesovou zkratku nebo skrze menu interakcí. Umożliwia korzystanie z menu medycznego poprzez skrót lub menu interakcji. Activa el uso del menú médico a través de la tecla o del menú de interacción @@ -151,12 +151,12 @@ Reopen Medical Menu Sanitätsmenü wieder öffnen 医療メニューの再表示 - Открывать меню после лечения + Медицинское меню после лечения Rouvrir le menu médical Reabrir Menu Médico 醫療選單二度開啟 重新打开医疗菜单 - Riaprire il menù medico + Riapri il menù medico Znovu otevřít Zdravotnické menu Otwiera ponownie menu medyczne Reabrir menú médico @@ -167,12 +167,12 @@ Reopen the Medical Menu after successful treatment. Öffne das Sanitätsmenü nach einer Behandlung 治療の完了後に、再度医療メニューを開きます。 - Открывает Медицинское меню после успешного лечения + Открывает медицинское меню после успешного лечения Réouvre le menu médical suite à l'application d'un soin. Reabrir Menu Médico após um tratamento com sucesso 當治療完成後二度打開醫療選單 治疗成功后,重新打开医疗菜单。 - Riaprire il menu medico dopo il trattamento con successo. + Riapri il menù medico dopo un trattamento eseguito con successo. Otevře Zdravotnické menu po úspěšném dokončení zdravotnické akce. Otwiera ponownie menu medyczne po udanym leczeniu. Reabrir menú médico después de completar un tratamiento @@ -188,7 +188,7 @@ Distância Máxima 最大醫療距離 最大医疗距离 - Massima distanza + Distanza Massima Maximální vzdálenost Maksymalny dystans Distancia máxima @@ -198,13 +198,13 @@ Maximum distance from which the Medical Menu can be opened. Maximale Entfernung, um das Sanitätsmenü zu öffnen. - 治療メニューを開いたままにできる最大距離を決定します。 + 医療メニューを開いたままにできる最大距離。 Максимальное расстояние, с которого можно открыть Медицинское меню. Définit la distance (en mètres) à partir de laquelle il n'est plus possible d'activer le menu médical pour traiter un patient. A Distância máxima do paciente para que o Menu Médico possa ser aberto. 設定距離多遠以內可以對目標使用醫療選單 设定距离多远以内可以对目标使用医疗菜单 - Distanza massima da cui si può aprire il Menu Medico. + Distanza massima da cui si può aprire il Menù Medico. Maximální vzdálenost ze které je možné otevřít Zdravotnické menu. Maksymalny dystans w którym menu medyczne może zostać otwarte. Distancia máxima desde el paciente para que el menú pueda ser abierto @@ -214,9 +214,10 @@ Show Triage Level in Interaction Menu Couleur de triage dans le menu d'interaction - インタラクションにトリアージ レベル表示 + 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ü 在交互式菜单中显示分诊级别 @@ -225,6 +226,7 @@ Shows the patient's triage level by changing the color of the main and medical menu actions. Modifie la couleur du menu d'interactions et du sous-menu médical en fonction de la fiche de triage du patient. + Modifica il colore di interazioni e menù medico a seconda del livello di triage. メニューと医療メニューの色を変更し、患者のトリアージ レベルを表示します。 Mostrar el nivel de triado en el paciente cambiando el color de acciones de menú principales y médicas Отображает установленную группу карты медицинской сортировки (триажа), изменяя цвет действий основного и медицинского меню. @@ -244,7 +246,7 @@ Медик Médico Orvosi - 治療 + 医療 치료 医疗 醫療 @@ -260,7 +262,7 @@ Zdravotnická nabídka Menù Medico Menu médical - 治療メニュー + 医療メニュー 의료 메뉴 医疗菜单 醫療選單 @@ -276,7 +278,7 @@ Otevřít zdravotnickou nabídku Apri Menù Medico Ouvir le menu médical - 治療メニューを開く + 医療メニューを開く 의료 메뉴 열기 打开医疗菜单 開起醫療選單 @@ -287,16 +289,22 @@ Podgląd Informacji Medycznych 의료 정보 보기 Aperçu des informations médicales + Sbircia Info Mediche Medizinische Info anzeigen 医療情報一時表示 + Просмотр медицинской информации + Ojear Información Médica Medical Peek Duration Czas Trwania Podglądu Medycznego 의료 정보 보기 지속 시간 Durée de l'aperçu des informations médicales + Durata di sbirciamento di info mediche Dauer zum Anzeigen der medizinischen Info - 医療情報一時表示の長さ + 医療情報一時表示の表示時間 + Продолжительность медицинского осмотра + Duración del Ojear Información Médica How long the medical info peek remains open after releasing the key. @@ -304,7 +312,10 @@ 키를 놓은 후 의료 정보가 열린 상태로 유지되는 시간입니다. Durée d'affichage des informations médicales après avoir relâché la touche. 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. 医療情報一時表示キーを放してからどれだけ長く情報表示するか。 + Как долго окно просмотра медицинской информации остается открытым после отпускания клавиши. + Durante cuánto tiempo la información médica ojeada permanece abierta una ves se deje de apretar la tecla. Load Patient @@ -446,7 +457,7 @@ Pokaż kartę segregacyjną Ver cartão de triagem Zkontrolovat štítek - Guarda Triage Card + Guarda Scheda Triage トリアージカードを見る 부상자 카드 보기 查看分诊卡 @@ -478,7 +489,7 @@ Bandaże / Złamania Bandagens / Fraturas Bandáž / Zlomeniny - Bendaggi/Fratture + Bendaggi / Fratture 包帯 / 骨折 붕대 / 골절 包扎/骨折 @@ -494,7 +505,7 @@ Leki Medicação Léky - Medicazione + Medicazioni 投薬 약물 치료 药物 @@ -555,7 +566,10 @@ 자신으로 전환 Passer à soi-même Wechseln zu selbst + Passa a te stesso 自分に切り替え + Переключиться на себя + Cambiar a uno mismo Switch to target @@ -563,7 +577,10 @@ 대상으로 전환 Passer à la cible Wechseln zu Ziel + Passa al paziente 相手に切り替え + Переключиться на цель + Cambiar al objetivo Head @@ -815,7 +832,7 @@ Existem %2 ferimentos abertos %1 Jsou zde %2 %1 otevřené rány Ci sono %2 %1 Ferite Aperte - 開いた状態の%1が%2個あります + 開いた状態の %1 が %2 個ある 여기 %2 %1 크기의 열린 상처가 있다 有 %2 处未处理的 %1 伤口 有 %2 %1 開放性傷口 @@ -830,8 +847,8 @@ Widzisz 1 otwartą ranę o %1 rozmiarze Existe 1 %1 ferimento aberto Je zde 1 %1 otevřená rána - C'è 1 %1 Ferita Aperta - 開いた状態の%1が1個あります + C'è una %1 Ferita Aperta + 開いた状態の %1 が 1 個ある 여기 %1 크기의 열린 상처가 있다 有 1 处未处理的 %1 伤口 有 1 %1 開放性傷口 @@ -846,8 +863,8 @@ Widzisz częściowo otwartą ranę o %1 rozmiarze Existe um ferimento parcial aberto %1 Je zde částečně %1 otevřená rána - C'è 1 parziale %1 Ferita Aperta - 開いた状態の部分的な%1があります + C'è una parziale %1 Ferita Aperta + 開いた状態の 部分的な %1 がある 여기 부분적으로 %1 크기의 상처가 있다 有未完全处理的 %1 伤口 有部分 %1 開放性傷口 @@ -863,7 +880,7 @@ Existem %2 ferimentos %1 tratados Jsou zde %2 %1 ovázané rány Ci sono %2 %1 Ferite Bendate - 包帯を巻いた%1が%2個あります + 包帯を巻いた %1 が %2 個ある 여기에 붕대를 감은 %2 %1 크기의 상처가 있다 有 %2 处包扎过的 %1 伤口 有 %2 %1 包紮過傷口 @@ -878,8 +895,8 @@ Widzisz 1 zabandażowaną ranę o %1 rozmiarze Existe 1 ferimento %1 tratado Je zde 1 %1 ovázaná rána - C'è 1 %1 Ferita Bendata - 包帯を巻いた%1が1個あります + C'è una %1 Ferita Bendata + 包帯を巻いた %1 が 1 個ある 여기에 붕대를 감은 %1 크기의 상처가 있다 有 1 处包扎过的 %1 伤口 有 1 %1 包紮過傷口 @@ -894,8 +911,8 @@ Widzisz 1 częściowo zabandażowaną ranę o %1 rozmiarze Existe um ferimento parcial tratado %1 Je zde částěčně %1 ovázaná rána - C'è 1 parziale %1 Ferita Bendata - 包帯を巻いた部分的な%1があります + C'è una parziale %1 Ferita Bendata + 包帯を巻いた 部分的な %1 がある 여기 부분적으로 붕대질한 %1 크기의 상처가 있다 有未包扎完全的 %1 伤口 有部分 %1 包紮過傷口 @@ -987,7 +1004,10 @@ 출혈 없음 Pas de saignement Keine Blutung + Nessuna emorragia 出血はしていない + Кровотечения нет + Sin sangrado Slow bleeding @@ -995,7 +1015,10 @@ 느린 출혈 Saignement lent Langsame Blutung + Debole emorragia 出血は穏やか + Медленное кровотечение + Sangrado lento Moderate bleeding @@ -1003,7 +1026,10 @@ 중간 출혈 Saignement modéré Mäßige Blutung + Emorraggia moderata 出血はそこそこ速い + Умеренное кровотечение + Sangrado moderado Severe bleeding @@ -1011,7 +1037,10 @@ 심한 출혈 Saignement grave Schwere Blutung + Forte emorragia 出血は激しい + Сильное кровотечение + Sangrado severo Massive bleeding @@ -1019,7 +1048,10 @@ 과다 출혈 Saignement massif Massive Blutung + Gravissima emorragia 出血は酷く多い + Огромное кровотечение + Sangrado masivo in Pain @@ -1030,7 +1062,7 @@ W bólu Com dor v bolestech - in Dolore + Dolorante 痛みがある 고통 疼痛中 @@ -1046,7 +1078,7 @@ Stracił dużo krwi Perdeu muito sangue Ztratil hodně krve - Perso molto Sangue + Ha perso molto Sangue 大量失血した 많은 피를 흘림 失血 @@ -1072,7 +1104,7 @@ Splint Applied Наложена шина - 副子を当てている + 添え木を当てた Attelle appliquée Tala Aplicada 已使用固定板 @@ -1091,7 +1123,10 @@ 피를 잃지 않음 Pas de perte de sang Kein Blutverlust + Nessuna perdita di sangue 失血なし + Потери крови нет + Sin pérdida de sangre @@ -1200,7 +1235,7 @@ Štítek Fiche de triage Orvosi lap - Triage Card + Scheda Triage Cartão de Triagem トリアージカード 부상자 분류 카드 @@ -1228,6 +1263,7 @@ Patient Info Informacje o pacjencie Informations patient + Informazioni sul paziente Информация о пациенте 伤员信息 患者情報 @@ -1239,8 +1275,9 @@ Blood Loss Colors Цвета кровопотери - 失血量カラー + 失血量の色 Couleurs des hémorragies + Colori di emorragie Farben für Blutverlust Kolory utraty krwi 失血颜色 @@ -1252,6 +1289,7 @@ Цвета кровопотери, которые используются в Медицинском интерфейсе. Градиент из 10 цветов. 医療 GUI 内で失血量を 10 段階の色で表します。 Couleurs utilisées pour afficher les hémorragies dans l'interface médicale. Dégradé de 10 couleurs. + Definisce i 10 gradienti di colori usati per indicare perdite di sangue nel menù medico Farben für Blutverlust, die in dem Medizinischen Menü verwendet werden. 10-Farben Farbverlauf. Kolory używane do wyświetlania krwawienia w interfejsie medycznym. Gradient 10 kolorów. 失血颜色,用于医学图形用户界面。10种渐变颜色。 @@ -1261,8 +1299,9 @@ Blood Loss Color %1 Цвет кровопотери %1 - 失血量カラー %1 + 失血量の色 %1 Hémorragies - couleur %1 + Emorragia - colore %1 Blutverlustfarbe %1 Krwawienie - kolor %1 失血颜色 %1 @@ -1272,8 +1311,9 @@ Damage Colors Цвета урона - 負傷カラー + 負傷の色 Couleur des dégâts + Colori di danni Farben für Schaden Kolory obrażeń 负伤颜色 @@ -1285,6 +1325,7 @@ Цвета урона, которые используются в Медицинском интерфейсе. Градиент из 10 цветов. 医療 GUI 内で負傷を 10 段階の色で表します。 Couleurs utilisées pour afficher les dégâts dans l'interface médicale. Dégradé de 10 couleurs. + Definisce i 10 gradienti di colori usati per indicare danni nel menù medico Farben für Schaden, die in dem medizinischen Menü verwendet werden. 10-Farben Farbverlauf. Kolory używane do wyświetlania obrażeń w interfejsie medycznym. Gradient 10 kolorów. 负伤颜色,用于医学图形用户界面。10种渐变颜色。 @@ -1294,8 +1335,9 @@ Damage Color %1 Цвет урона %1 - 負傷カラー %1 + 負傷の色 %1 Dégâts - couleur %1 + Danni - colore %1 Schadensfarbe %1 Obrażenia - kolor %1 负伤颜色 %1 @@ -1305,6 +1347,7 @@ Show Blood Loss Blutverlust anzeigen + Mostra perdita di sangue 혈액 손실 표시 Pokaż utratę krwi 失血量の表示 @@ -1316,6 +1359,7 @@ Show qualitative blood loss in the injury list. Qualitativen Blutverlust in der Verletzungsliste anzeigen. + Mostra quantità di sangue persa nella lista delle ferite. 부상 목록에 혈액 손실량을 표시합니다. Pokaż jakościową utratę krwi na liście ran. 負傷リストに段階的な失血量を表示します。 @@ -1324,14 +1368,50 @@ 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 + 出血状態の表示 + 출혈 상태 표시 + Afficher l'état des saignements + Показать состояние кровотечения + + + 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 + 患者が出血しているかどうかを表示します。オプションで出血速度も表示します + 환자가 출혈 중인지 여부를 표시합니다(선택적으로 출혈 속도 포함) + Indique si le patient saigne, éventuellement avec le taux de saignement + Показывает, есть ли у пациента кровотечение, опционально с указанием частоты + + + Show Bleeding Rate + Mostrar tasa de sangrado + Blutungsrate anzeigen + Mostra rateo di sanguinamento + Mostrar taxa de sangramento + 出血速度の表示 + 출혈 속도 표시 + Afficher le taux de saignement + Показать частоту кровотечения + Peek Medical Info on Hit Podgląd Informacji Medycznych po Zranieniu 맞을 시 의료 정보 보기 点击查看医疗信息 Aperçu des informations médicales lors d'une blessure + Mostra info mediche se colpito Zeige medizinische Info beim Treffer an - 受傷時の医療情報一時表示 + 被弾時の医療情報一時表示 + Показать медицинскую информацию о попадании + Ojear Información Médica en Impacto Temporarily show medical info when injured. @@ -1339,8 +1419,11 @@ 부상을 입었을 때 일시적으로 의료 정보를 표시합니다. 受伤时暂时显示医疗信息。 Afficher temporairement les informations médicales lors d'une blessure. + Mostra temporaneamente le info mediche quando si viene feriti. Bei Verletzungen vorübergehend medizinische Info anzeigen. - 受傷時に医療情報を一時的に表示します。 + 被弾時に医療情報を一時的に表示します。 + Временно показывать медицинскую информацию при травме. + Temporalmente muestra la información médica cuando es herido. Medical Peek Duration on Hit @@ -1348,8 +1431,11 @@ 맞을 시 의료 정보 보기 지속 시간 击中时的医疗信息显示持续时间 Durée de l'aperçu des informations médicales lors d'une blessure + Durata di info mediche quando colpito Dauer der Anzeige bei einem Treffer. - 受傷時の医療情報一時表示の長さ + 被弾時の医療情報一時表示の表示時間 + Продолжительность медицинского осмотра при попадании + Duración de Ojear la Información Médica cuando hay Impacto How long the medical info peek remains open after being injured. @@ -1357,28 +1443,37 @@ 부상을 입은 후에도 의료 정보가 열린 상태로 지속되는 시간입니다. 受伤后医疗信息会开放多长时间? Durée de l'affichage des informations médicales lors d'une blessure. + Quanto tempo verranno visualizzate le info mediche quando si viene feriti. Wie lange die medizinische Info nach einer Verletzung angezeigt wird. - 受傷した後に医療情報の一時表示をどれだけ長く表示するか。 + 被弾時の医療情報の一時表示をどれだけ長く表示するか。 + Как долго окно просмотра медицинской информации остается открытым после получения травмы. + Durante cuánto tiempo la información médica ojeada permanece abierta una tras haber sido herido. Show Trauma Sustained Mostrar Traumatismo Sofrido - 外傷の表示 + 外傷状態の表示 Pokaż Doznane Urazy Zeigen Sie das erlittene Trauma + Mostra trauma sofferto 외상 지속 표시 显示遭受的创伤 Afficher les traumatismes subis + Показать полученную травму + Mostrar Trauma Sostenido Show trauma sustained in the injury list. Mostrar traumatismo sofrido na lista de feridas. - 負傷リストに外傷を表示する。 + 負傷リストに外傷状態を表示する。 Pokaż odniesione obrażenia na liście obrażeń. Zeigen Sie das erlittene Trauma in der Verletzungsliste an. + Mostra il trauma ricevuto nella lista delle ferite. 부상 목록에 발생한 외상을 표시합니다. 在伤情表上显示创伤 Afficher les traumatismes subis dans la liste des blessures. + Показать полученную травму в списке травм. + Mostrar trauma sostenido en la lista de heridas Body Part Outline Color @@ -1386,8 +1481,11 @@ 신체부위 윤곽선 색상 身体部位轮廓颜色 Couleur des contours des parties du corps + Colore del contorno di parti del corpo Umrissfarbe des Körperteils - 身体部位の輪郭表示カラー + 身体部位の輪郭表示の色 + Цвет контура части тела + Color de Contorno de las Partes del Cuerpo Color of outline around selected body part. @@ -1395,8 +1493,11 @@ 선택한 신체부위 주위의 윤곽선 색상입니다. 选定身体部位周围的轮廓颜色。 Couleur des contours autour des parties du corps sélectionnées. + Colore del contorno della parte del corpo selezionata. Farbe des Umrisses um das ausgewählten Körperteil. 選択した身体部位の輪郭表示の色。 + Цвет контура вокруг выбранной части тела. + Color del contorno alrededor de la parte del cuerpo seleccionada. Minor Trauma @@ -1404,9 +1505,12 @@ 軽度の外傷 Niewielki Uraz Kleineres Trauma + Trauma piccolo 약한 외상 轻微创伤 Traumatisme mineur + Незначительная травма + Trauma Menor Major Trauma @@ -1414,9 +1518,12 @@ 中度の外傷 Poważny Uraz Großes Trauma + Trauma grande 중간 외상 中度创伤 Traumatisme majeur + Серьезная травма + Trauma mayor Severe Trauma @@ -1424,9 +1531,12 @@ 重度の外傷 Ciężki Uraz Schweres Trauma + Trauma severo 강한 외상 重度创伤 Traumatisme grave + Тяжелая травма + Trauma Severo Chronic Trauma @@ -1434,9 +1544,12 @@ 重篤な外傷 Przewlekły Uraz Chronisches Trauma + Trauma cronico 심각한 외상 慢性创伤 Traumatisme chronique + Хроническая травма + Trauma Crónico L @@ -1444,8 +1557,11 @@ L G + Sx L + Лево + I R @@ -1453,8 +1569,11 @@ R D + Dx R + Право + D in your inventory @@ -1462,8 +1581,11 @@ 개: 당신의 소지품 在你的库存中 dans votre inventaire + Nel proprio inventario im Inventar - あなたのインベントリ内 + 個あなたが保有 + в вашем инвентаре + en tu inventario in patient's inventory @@ -1471,8 +1593,11 @@ 개: 환자의 소지품 在病人库存中 dans l'inventaire du patient + Nell'inventario del paziente im Inventar des Patienten - 患者のインベントリ内 + 個患者が保有 + в инвентаре пациента + en el inventario del paciente in vehicle's inventory @@ -1481,7 +1606,10 @@ dans l'inventaire du véhicule 개: 차량의 소지품 im Inventar des Fahrzeuges - 車両のインベントリ内 + Nell'inventario del veicolo + 個車両内に保有 + в инвентаре транспорта + en el inventario del vehículo No effect until tourniquet removed @@ -1489,7 +1617,10 @@ Aucun effet jusqu'à ce que le garrot soit retiré 지혈대를 제거할 때까지 효과 없음 Keine Wirkung, bis das Tourniquet entfernt wurde + Nessun effetto fino alla rimozione del laccio emostatico 止血帯を外すまで効果を発揮しません + Никакого эффекта до тех пор, пока жгут не будет снят + Sin efecto hasta que se quita el torniquete Show Tourniquet Warning @@ -1497,7 +1628,10 @@ Afficher l'avertissement du garrot 지혈 경고 표시 Tourniquet-Warnung anzeigen + Mostra avviso di laccio emostatico 止血帯の警告を表示 + Показать предупреждение о наложении жгута + Mostrar Advertencia de Torniquete Show a warning tooltip when a tourniquet will interfere with a medical action. @@ -1505,7 +1639,10 @@ Affiche un avertissement lorsqu'un garrot interfère avec une action médicale. 지혈대가 의료 조치를 방해할 경우 경고 툴팁을 표시합니다. Zeigt einen Hinweis an, wenn ein Tourniquet eine medizinische Maßnahme beeinträchtigt. + Mostra un avviso se un laccio emostatico impedisce un trattamento medico. 止血帯が医療行為を妨げる場合には、警告ツールチップを表示します。 + Показать всплывающую подсказку с предупреждением, когда жгут помешает медицинскому вмешательству. + Muestra un mensaje de advertencia cuando un torniquete interfiera con una acción médica. diff --git a/addons/medical_gui/ui/painkillers.paa b/addons/medical_gui/ui/painkillers.paa new file mode 100644 index 0000000000..3c5da9b30b Binary files /dev/null and b/addons/medical_gui/ui/painkillers.paa differ diff --git a/addons/medical_statemachine/CfgEventHandlers.hpp b/addons/medical_statemachine/CfgEventHandlers.hpp index 98c29f77dc..b9150d8564 100644 --- a/addons/medical_statemachine/CfgEventHandlers.hpp +++ b/addons/medical_statemachine/CfgEventHandlers.hpp @@ -10,6 +10,12 @@ class Extended_PreInit_EventHandlers { }; }; +class Extended_PostInit_EventHandlers { + class ADDON { + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); + }; +}; + class Extended_Respawn_EventHandlers { class CAManBase { class ADDON { diff --git a/addons/medical_statemachine/XEH_postInit.sqf b/addons/medical_statemachine/XEH_postInit.sqf new file mode 100644 index 0000000000..a7c7740a39 --- /dev/null +++ b/addons/medical_statemachine/XEH_postInit.sqf @@ -0,0 +1,14 @@ +#include "script_component.hpp" + +["ace_killed", { // global event + params ["_unit"]; + + // Prevent second ragdoll of uncon units when they're killed + if ( + IS_UNCONSCIOUS(_unit) && !isAwake _unit // uncon and not ragdolling + && {isPlayer _unit || {_unit getVariable [QGVAR(AIUnconsciousness), GVAR(AIUnconsciousness)]}} + ) then { + _unit enableSimulation false; + [{_this enableSimulation true}, _unit, 2] call CBA_fnc_waitAndExecute; + }; +}] call CBA_fnc_addEventHandler; diff --git a/addons/medical_statemachine/XEH_preInit.sqf b/addons/medical_statemachine/XEH_preInit.sqf index d77d8067a8..65621f775b 100644 --- a/addons/medical_statemachine/XEH_preInit.sqf +++ b/addons/medical_statemachine/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" EGVAR(medical,STATE_MACHINE) = (configFile >> "ACE_Medical_StateMachine") call CBA_statemachine_fnc_createFromConfig; diff --git a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf index 537c356651..8be1d358df 100644 --- a/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf +++ b/addons/medical_statemachine/functions/fnc_enteredStateDeath.sqf @@ -25,6 +25,7 @@ if (isNull _unit || {!isNil {_unit getVariable QEGVAR(medical,causeOfDeath)}}) e TRACE_4("enteredStateDeath",_this,_thisOrigin,_thisTransition,CBA_missionTime); private _causeOfDeath = format ["%1:%2", _thisOrigin, _thisTransition]; +private _source = _unit getVariable [QEGVAR(medical,lastDamageSource), objNull]; private _instigator = _unit getVariable [QEGVAR(medical,lastInstigator), objNull]; -[_unit, _causeOfDeath, _instigator] call EFUNC(medical_status,setDead); +[_unit, _causeOfDeath, _source, _instigator] call EFUNC(medical_status,setDead); diff --git a/addons/medical_statemachine/initSettings.sqf b/addons/medical_statemachine/initSettings.inc.sqf similarity index 100% rename from addons/medical_statemachine/initSettings.sqf rename to addons/medical_statemachine/initSettings.inc.sqf diff --git a/addons/medical_statemachine/stringtable.xml b/addons/medical_statemachine/stringtable.xml index aa30396617..2b828d506e 100644 --- a/addons/medical_statemachine/stringtable.xml +++ b/addons/medical_statemachine/stringtable.xml @@ -26,7 +26,7 @@ Décès si blessure mortelle (joueurs) Smrtelná zranění hráčů Śmiertelne Obrażenia Gracza - Lesioni mortali del giocatore + Ferite letali su giocatori Oyuncu Ölümcül Yaralanmaları Tödliche Spielerverletzungen Смертельные травмы игрока @@ -42,7 +42,7 @@ Détermine si les joueurs décèdent en cas de blessure mortelle. Une blessure mortelle est définie par des dommages importants à la tête ou au cœur. Oyuncuların ölümcül yaralanmaları ne zaman alabileceğini kontrol eder. Ölümcül bir yaralanma, kafaya veya vücuda önemli hasar verir. Nastavuje zda hráči mohou utrpět smrtelné zranění. Smrtelné zranění je utrpěto významným poškozením hlavy nebo trupu. - Controlla quando i giocatori possono ricevere infortuni mortali. Una lesione mortale è causata da un danno significativo alla testa o al busto. + Controlla quando i giocatori possono ricevere infortuni mortali. Una ferita letale è causata da un danno significativo alla testa o al torso. Definiuje, kiedy gracze mogą otrzymać śmiertelne obrażenia. Śmiertelne obrażenia są spowodowane znacznym uszkodzeniem głowy lub torsu. Legt fest, wann Spieler tödliche Verletzungen erleiden können. Eine tödliche Verletzung wird bei erheblichem Schaden an Kopf oder Torso verursacht. Определяет, могут ли игроки получить смертельные травмы. Смертельная травма вызывается значительным повреждением головы или туловища. @@ -58,7 +58,7 @@ Décès si blessure mortelle (IA) Smrtelná zranění AI Śmiertelne obrażenia AI. - AI Lesioni mortali + Ferite letali su IA AI Ölümcül Yaralanmaları Tödliche KI-Verletzungen Смертельные травмы ИИ @@ -68,13 +68,13 @@ Controls when AI can receive fatal injuries. A fatal injury is caused by significant damage to the head or troso.\nWhen set to "Always", this effectively produces "AI Instant Death" behaviour as AI will immediately die from any fatal injury.\nNOTE: Any mode other than "Always" requires AI Unconsciousness to be enabled. Controla quando a IA pode receber lesões fatais. Uma lesão fatal é causada por um dano significante na cabeça ou tronco.\nQuando definido para "Sempre", isso efetivamente causa a "Morte Instantânea da IA", pois a IA irá imediatamente morrer para qualquer lesão fatal.\nNOTA: Qualquer opção além de "Sempre" requer que Inconsciência de IA esteja ativada. - AIが致命傷を受けた時の挙動を管理できます。頭部や胸部に受ける大きなダメージは致命傷になります。\n"常に"に設定されていると、いかなる致命傷でも "AIの即死" 効果が生まれます。\n注: "常に"以外のモードではAIの無意識化を有効化させる必要があります。 + AIが致命傷を受けた時の挙動を管理できます。頭部や胸部に受ける大きなダメージは致命傷になります。\n"常に"に設定されていると、いかなる致命傷でも"AIの即死"効果が生まれます。\n注: "常に"以外のモードでは"AIの無意識状態化"を有効化させる必要があります。 控制當AI受致命傷時是否能救起。致命傷是指對頭部或身體造成可觀傷害所造成的。\n當設置為"總是"時,這會使其與"AI 瞬間死亡"同一個效果,在AI受到致命傷時瞬間死亡。\n備註:選了"總是"以外的選項的話必須開啟「AI無意識」的選項。 控制当 AI 受致命伤时是否能救起。致命伤是指对头部或躯干遭受重大伤害。\n当设置为"总是"时,这将有效地产生"AI 即时死亡"行为,因为 AI 将立即死于任何致命伤。\n注意:"总是"以外的任何模式都需要启用 AI 无意识。 Détermine si les unités IA décèdent en cas de blessure mortelle. Une blessure mortelle est définie par des dommages importants à la tête ou au cœur.\nSi réglé sur "Toujours", cela produit effectivement un comportement de "Mort instantanée" car les unités IA mourront immédiatement de toute blessure mortelle.\nNOTE : Tout mode autre que "Toujours" nécessite l'activation de l'option "Inconscience IA". AI'nın ölümcül yaralanmaları ne zaman alabileceğini kontrol eder. Ölümcül bir yaralanma, kafa veya vücudun önemli hasar görmesinden kaynaklanır. \"Her zaman" olarak ayarlandığında, AI herhangi bir ölümcül yaralanmadan hemen öleceği için bu etkili bir şekilde "AI Anında Ölüm" davranışı üretir.\ NOT: "Her zaman" "Yapay Zeka Bilinci'nin etkinleştirilmesini gerektirir. Nastavuje zda AI může utrpět smrtelné zranění. Smrtelné zranění je utrpěto významným poškozením hlavy nebo trupu.\nPokud je tato možnost nastavena na "Vždy", efektivně nastává stav "Povolit okamžitou smrt AI", protože AI okamžitě zemře při jakémkoliv smrtelném zranění.\nPOZNÁMKA: Jakýkoliv jiný stav než "Vždy" potřebuje zapnutou možnost "Bezvědomí AI". - Controlla quando l'IA può ricevere ferite mortali. Una lesione mortale è causata da un danno significativo alla testa o al torso.\nSe impostato su "Sempre", questo produce efficacemente il comportamento "Morte istantanea AI", poiché l'IA morirà immediatamente a causa di qualsiasi lesione mortale.\nNOTA: Qualsiasi modalità diversa da "Sempre" richiede l'attivazione dell'Incoscienza AI. + Controlla quando l'IA può ricevere infortuni mortali. Una ferita letale è causata da un danno significativo alla testa o al torso.\nSe impostato su "Sempre", questo produce efficacemente il comportamento "Morte istantanea AI", poiché l'IA morirà immediatamente a causa di qualsiasi lesione mortale.\nNOTA: Qualsiasi modalità diversa da "Sempre" richiede l'attivazione dell'Incoscienza IA. Definiuje, kiedy AI może otrzymać śmiertelne obrażenia. Śmiertelne obrażenia są spowodowane znacznym uszkodzeniem głowy lub torsu.\n Ustawienie "Zawsze" powoduje "Natychmiastową śmierć AI", ponieważ AI natychmiast umiera z powodu śmiertelnych obrażeń.\n UWAGA: Każdy inny tryb niż "Zawsze" wymaga włączenia nieprzytomności AI. Legt fest, wann KI-Einheiten tödliche Verletzungen erleiden können. Eine tödliche Verletzung wird bei erheblichem Schaden an Kopf oder Körper verursacht.\nWenn "Immer" eingestellt ist, erzeugt diese Einstellung das "KI Sofort-Tod" Verhalten. KI-Einheiten sterben sofort durch jede tödliche Verletzung.\nBEACHTE: Eine andere Einstellung als "Immer" bedingt, dass "KI-Bewusstlosigkeit" verwendet wird. Определяет могут ли игроки получить смертельные травмы. Смертельная травма вызывается значительным повреждением головы или туловища.\nКогда установлено «Всегда», это вызывает поведение «Мгновенной смерти ИИ», так как ИИ немедленно умрет от любой смертельной травмы.\nПРИМЕЧАНИЕ: Любой режим, кроме «Всегда», требует включения функции «Потеря сознания». @@ -92,7 +92,7 @@ Inconscience IA AI eszméletlenség Incoscienza IA - AIの気絶 + AIの無意識状態化 인공지능 기절 AI 无意识 AI無意識 @@ -101,13 +101,13 @@ Controls whether AI can go unconscious instead of immediately dying.\nThis setting works together with the "AI Fatal Injuries" setting since, going into cardiac arrest requires that the unit is able to go unconscious.\nHowever, these settings are separated because units can go unconscious from critical vitals resulting from non-fatal injuries.\nIn essence, this means that in order to enable cardiac arrest for AI units, this setting must be enabled. Controla se a IA pode ficar inconsciente ao invés de morrer imediatamente.\nEssa configuração funciona com "Lesões Fatais de IA", pois para uma unidade ter uma parada cardíaca é necessário que a IA possa fica inconsciente.\nContudo, essas configurações são separadas pois unidades podem ficar inconscientes por vitais críticos causados por ferimentos não-fatais.\nEssencialmente, isso significa que para ativar uma parada cardíaca em IA, essa configuração precisa estar ativa. - AIが即死する代わりに気絶するかどうかを決定できます。\nこれは "AIの致命傷" 設定と連動します。これはAIの心停止を起こすにはユニットが気絶する必要がある為です。\nしかしながら、これらの設定はユニットが非致死性の負傷により重体となって気絶できるよう分離されています。\n本質的にはこの設定はAIユニットの心停止を可能にするものであり、有効化されておくべきです。 + AIが即死する代わりに無意識状態化するかどうかを制御します。\nこれは "AIの致命傷" 設定と連動します。何故ならば、ユニットを心停止させるためには無意識状態に陥る必要がある為です。\nしかし、これらの設定は、致命的ではない負傷の経過による重症状態化でユニットが無意識状態に陥ることが出来るようにするため、分割されています。\n要するに、AIユニットの心停止を有効にするには、この設定を有効にする必要があるということです。 控制AI是否能進入無意識狀態而非立刻原地死亡。\n這個選項會與「AI致命傷」的選項聯動,使單位心搏停止的話必須先讓其無意識。\n然而,兩個設定分開之原因是使單位能因從非致命傷的攻擊情況下進入生命危險的狀態。\n簡單來說,你想要讓AI單位有心搏停止可能的話,該選項必須啟用。 控制 AI 是否可以进入昏迷状态而不是立即死亡。\n这个设置与"AI 致命伤"设置一起工作,因为进入心脏骤停需要单位能够昏迷。\n然而,这些设置是分开的,因为单位可能会因非致命伤害导致的关键生命体征而昏迷过去。\n从本质上讲,这意味着为了使 AI 单位的心脏骤停,必须启用此设置。 Définit si les unités IA peuvent perdre connaissance au lieu de mourir immédiatement.\nCe paramètre fonctionne conjointement avec l'option "Décès si blessure mortelle (IA)" car, pour qu'une unité IA subisse un arrêt cardiaque, elle doit également pouvoir perdre connaissance.\nCependant, ces paramètres sont séparés car les unités peuvent s'évanouir suite à des signes vitaux critiques résultant de blessures non mortelles.\nEn résumé, cela signifie que ce paramètre doit absolument être activé pour qu'une unité IA puisse entrer en état d'arrêt cardiaque. Nastavuje zda AI může upadnout do bezvědomí namísto okamžité smrti.\nToto nastavení funguje společně s "Smrtelná zranění AI" protože srdeční zástava potřebuje možnost upadnout do bezvědomí.\nTyto možnosti jsou separované, protože jednotky mohou upadnout do bezvědomí kvůli kritickému stavu způsobenému ne smrtelnými zraněními.\nV podstatě to znamená, že pokud chcete zapnout srdeční zástavu pro AI, tato možnost musí být zapnutá. Definiuje, czy AI może stracić przytomność zamiast natychmiast zginąć.\n Ta opcja działa razem z ustawieniem "Śmiertelne urazy AI", ponieważ przejście do zatrzymania akcji serca wymaga, aby jednostka mogła stracić przytomność.\n Jednak te ustawienia są rozdzielone, ponieważ jednostki mogą stracić przytomność z powodu krytycznych czynności życiowych powstałych w wyniku urazów innych niż śmiertelne.\n W istocie oznacza to, że aby umożliwić zatrzymanie akcji serca dla jednostek AI, to ustawienie musi być włączone. - Controlla se l'IA può perdere i sensi invece di morire immediatamente. Questa impostazione funziona insieme all'impostazione "AI Fatal Injuries" poiché, per andare in arresto cardiaco, è necessario che l'unità sia in grado di perdere i sensi. Tuttavia, queste impostazioni sono separate perché le unità possono perdere i sensi da segni vitali critici derivanti da lesioni non mortali. + Controlla se l'IA può perdere i sensi invece di morire immediatamente. Questa impostazione funziona insieme all'impostazione "Ferite letali IA" poiché, per andare in arresto cardiaco, è necessario che l'unità sia in grado di perdere i sensi. Tuttavia, queste impostazioni sono separate perché le unità possono perdere i sensi da segni vitali critici derivanti da ferite non letali. Kontrolliert, ob KI bewusstlos werden kann anstatt sofort zu sterben.\nDiese Einstellung funktioniert zusammen mit der Einstellung "Tödliche KI-Verletzungen". Denn wenn eine Einheit einen Herzstillstand erleiden soll, muss diese auch in der Lage sein, bewusstlos zu werden.\nDennoch sind diese beiden Einstellungen voneinander getrennt, da Einheiten auch durch kritische Vitalwerte bewusstlos werden können, die durch nicht tödliche Verletzungen aufgetreten sind.\nZusammengefasst bedeutet das, dass wenn KI-Einheiten einen Herzstillstand erleiden sollen, diese Einstellung aktiviert sein muss. Управляет тем, может ли ИИ потерять сознание, вместо того, чтобы немедленно умереть.\nЭтот параметр работает вместе с параметром «Смертельные раны ИИ», поскольку при остановке сердца требуется, чтобы юнит мог потерять сознание.\nОднако эти настройки разделены, потому что юниты могут потерять сознание из-за критических ранений жизненно важных органов, полученных в результате несмертельных травм.\nВ сущности, это означает, что для включения остановки сердца для ИИ этот параметр должен быть включен. Yapay zekanın hemen ölmek yerine bilinçsiz duruma geçip geçemeyeceğini kontrol eder. \ Bu ayar, "Yapay Zeka Ölümcül Yaralanmalar" ayarı ile birlikte çalışır, çünkü kalp durması, ünitenin bilinçsiz duruma geçebilmesini gerektirir. \ Özünde, bunun anlamı şudur: AI birimleri için kalp durmasını etkinleştirirseniz, bu ayar etkinleştirilmelidir. @@ -132,13 +132,13 @@ Controls how long it takes to die from cardiac arrest. - どのくらいの時間、心停止すると死亡するかを決定します。 + どのくらいの時間、心停止すると死亡するかを制御します。 Définit le temps qu'il faut pour mourir d'un arrêt cardiaque. Контролирует, сколько времени требуется, чтобы умереть от остановки сердца. Controla o tempo necessário para morrer para uma parada cardíaca. 控制心搏停止後多久死亡 控制心脏骤停后多久单位死亡 - Controlla quanto tempo ci vuole per morire di arresto cardiaco. + Determina quanto tempo ci vuole per morire di arresto cardiaco. Nastavuje po jak dlouhé době pacient zemře kvůli srdeční zástavě. Definiuje czas potrzebny na śmierć z powodu zatrzymania akcji serca. Bestimmt die Dauer bis zum Tod durch Herzstillstand. @@ -166,8 +166,9 @@ Bleedout During Cardiac Arrest Кровотечение во время остановки сердца Ausbluten im Herzstillstand + Dissanguamento in arresto cardiaco Saignement durant l'arrêt cardiaque - 心停止中の失血 + 心停止中の失血死 Desangrado durante parada cardíaca Wykrwawienie podczas zatrzymanej akcji serca 心脏骤停期间失血情况 @@ -177,8 +178,9 @@ Controls whether a person can die in cardiac arrest by blood loss before the cardiac arrest time runs out. Определяет, можно ли умереть от потери крови во время остановки сердца, даже если время жизни при остановке сердца еще не истекло. Legt fest, ob man während des Herzstillstands durch Blutverlust sterben kann, auch wenn die Überlebenszeit im Herzstillstand noch nicht ausgelaufen ist. + Determina se è possibile morire per eccessiva perdita di sangue anche se non è ancora scaduto il 'tempo d'arresto cardiaco'. Définit si un joueur en arrêt cardiaque peut mourir par exsanguination, avant que la durée de l'arrêt cardiaque définie ci-dessus ne soit écoulée. - 心停止時間を超え死亡する前に、失血による心停止で死亡するかどうかを決定します。 + 心停止中の失血によって心停止時間よりも早く死亡するかどうかを制御します。 COntrola si una persona puede morir en parada cardíaca por causa de pérdida de sangre antes de que se termine el contador de parada cardíaca Kontroluje czy śmierć osoby może nastąpić poprzez wykrwawienie zanim wyczerpię się Czas Zatrzymania Akcji Serca. 控制单位是否会在心脏骤停时间耗完之前因失血过多而死亡。 diff --git a/addons/medical_status/XEH_preInit.sqf b/addons/medical_status/XEH_preInit.sqf index c6343dcb63..82146d82e1 100644 --- a/addons/medical_status/XEH_preInit.sqf +++ b/addons/medical_status/XEH_preInit.sqf @@ -6,15 +6,14 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // Add vanilla killed EH to unit to set correct killer ["CAManBase", "init", { params ["_unit"]; - private _config = configOf _unit; - if (getText (_config >> "simulation") == "UAVPilot") exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; - if (getNumber (_config >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit)}; + if (unitIsUAV _unit) exitWith {TRACE_1("ignore UAV AI",typeOf _unit);}; + if (getNumber ((configOf _unit) >> "isPlayableLogic") == 1) exitWith {TRACE_1("ignore logic unit",typeOf _unit)}; // Hopefully this EH gets added first as it can only effect other EH called after it private _ehIndex = _unit addEventHandler ["Killed", {_this call FUNC(handleKilled)}]; diff --git a/addons/medical_status/functions/fnc_addMedicationAdjustment.sqf b/addons/medical_status/functions/fnc_addMedicationAdjustment.sqf index 4c101c7521..8770eaf0ae 100644 --- a/addons/medical_status/functions/fnc_addMedicationAdjustment.sqf +++ b/addons/medical_status/functions/fnc_addMedicationAdjustment.sqf @@ -7,10 +7,10 @@ * 0: The Unit * 1: Medication * 2: Time in system for the adjustment to reach its peak - * 3: Duration the adjustment will have an effect - * 4: Heart Rate Adjust - * 5: Pain Suppress Adjust - * 6: Flow Adjust + * 3: Duration the adjustment will have an effect + * 4: Heart Rate Adjust + * 5: Pain Suppress Adjust + * 6: Flow Adjust * * Return Value: * None diff --git a/addons/medical_status/functions/fnc_getBloodLoss.sqf b/addons/medical_status/functions/fnc_getBloodLoss.sqf index 8ff0fbff3b..c2a6604679 100644 --- a/addons/medical_status/functions/fnc_getBloodLoss.sqf +++ b/addons/medical_status/functions/fnc_getBloodLoss.sqf @@ -23,4 +23,10 @@ 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)) +private _bloodLoss = (_woundBleeding * (_cardiacOutput max CARDIAC_OUTPUT_MIN) * EGVAR(medical,bleedingCoefficient)); + +private _eventArgs = [_unit, _bloodLoss]; // Pass by reference + +[QGVAR(getBloodLoss), _eventArgs] call CBA_fnc_localEvent; + +_eventArgs select 1 // return 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_setDead.sqf b/addons/medical_status/functions/fnc_setDead.sqf index 9dfc07d114..138948c038 100644 --- a/addons/medical_status/functions/fnc_setDead.sqf +++ b/addons/medical_status/functions/fnc_setDead.sqf @@ -7,6 +7,7 @@ * 0: The unit * 1: Reason for death * 2: Killer + * 3: Instigator * * Return Value: * None @@ -14,13 +15,16 @@ * Public: No */ -params ["_unit", ["_reason", "#setDead"], ["_instigator", objNull]]; -TRACE_3("setDead",_unit,_reason,_instigator); +params ["_unit", ["_reason", "#setDead"], ["_source", objNull], ["_instigator", objNull]]; +TRACE_4("setDead",_unit,_reason,_source,_instigator); // No heart rate or blood pressure to measure when dead _unit setVariable [VAR_HEART_RATE, 0, true]; _unit setVariable [VAR_BLOOD_PRESS, [0, 0], true]; +// Clear uncon variable just to be safe +_unit setVariable [VAR_UNCON, nil, true]; + _unit setVariable [QEGVAR(medical,causeOfDeath), _reason, true]; // Send a local event before death @@ -34,7 +38,7 @@ if (_unitState isNotEqualTo "Dead") then { // (#8803) Reenable damage if disabled to prevent having live units in dead state // Keep this after death event for compatibility with third party hooks -if !(isDamageAllowed _unit) then { +if (!isDamageAllowed _unit) then { WARNING_1("setDead executed on unit with damage blocked - %1",_this); _unit allowDamage true; }; @@ -42,6 +46,6 @@ if !(isDamageAllowed _unit) then { // Kill the unit without changing visual apperance private _prevDamage = _unit getHitPointDamage "HitHead"; -_unit setHitPointDamage ["HitHead", 1, true, _instigator]; +_unit setHitPointDamage ["HitHead", 1, true, _source, _instigator]; -_unit setHitPointDamage ["HitHead", _prevDamage]; +_unit setHitPointDamage ["HitHead", _prevDamage, true, _source, _instigator]; diff --git a/addons/medical_status/functions/fnc_setUnconsciousState.sqf b/addons/medical_status/functions/fnc_setUnconsciousState.sqf index 3071ae0d14..5981343c18 100644 --- a/addons/medical_status/functions/fnc_setUnconsciousState.sqf +++ b/addons/medical_status/functions/fnc_setUnconsciousState.sqf @@ -50,6 +50,7 @@ if (_active) then { _unit call EFUNC(common,throwWeapon); }; }; + // Unlock controls for copilot if unit is pilot of aircraft if (vehicle _unit isKindOf "Air" && {_unit == driver vehicle _unit}) then { TRACE_1("pilot of air vehicle - unlocking controls",vehicle _unit); @@ -57,18 +58,17 @@ if (_active) then { _unit action ["UnlockVehicleControl", vehicle _unit]; }; - // Disable AI aiming - if (!isPlayer _unit && {_unit checkAIFeature "WEAPONAIM"}) then { - _unit disableAI "WEAPONAIM"; - _unit setVariable [QGVAR(reenableWeaponAim), true, true]; + // 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]; - // Reenable AI aiming - if (_unit getVariable [QGVAR(reenableWeaponAim), false]) then { - _unit enableAI "WEAPONAIM"; + if (_unit getVariable [QGVAR(reenableRadioProtocol), false]) then { + _unit enableAI "RADIOPROTOCOL"; }; }; diff --git a/addons/medical_status/initSettings.sqf b/addons/medical_status/initSettings.inc.sqf similarity index 100% rename from addons/medical_status/initSettings.sqf rename to addons/medical_status/initSettings.inc.sqf diff --git a/addons/medical_status/stringtable.xml b/addons/medical_status/stringtable.xml index 50112a7214..ea3f77429b 100644 --- a/addons/medical_status/stringtable.xml +++ b/addons/medical_status/stringtable.xml @@ -88,13 +88,13 @@ IV Transfusion Flow Rate Transfusions Fließrate - IV 輸血の流量 + IV 輸液の流量 Скорость внутривенного переливания Débit de transfusion IV Velocidade de Transferência de Sangue 點滴輸血流量 点滴输血流量 - IV Portata della trasfusione + Velocità di trasfusione EV Rychlost IV transfuze Natężenie Przepływu Transfuzji IV IV Flujo de transfusión @@ -104,13 +104,13 @@ 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 輸液パックから輸液が流出する速度を制御します。 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毫升/秒)乘上流量(該係數)。 控制从点滴输入人体的液体流量多快。静脉输液袋容积变化的计算方法是:\n时间间隔(秒)x点滴每秒速度(4.1667毫升/秒)x流量(该系数)。 - Controlla la velocità con cui il fluido esce dalle sacche per flebo. La variazione di volume delle sacche IV è calcolata come:\intervallo di tempo (s) * variazione iv al secondo (4,1667 mL/s) * portata (questo coefficiente). + Determina la velocità con cui il fluido esce dalle sacche per flebo. La variazione di volume delle sacche EV è calcolata come:\intervallo di tempo (s) * variazione EV al secondo (4,1667 mL/s) * velocità (questo coefficiente). Nastavuje jak rychle tekutiny vytékají z IV sáčku. Zbývající objem IV sáčku je vypočítáván následovně:\nčasový interval (s) * změna iv za sekundu (4,1667 mL/s) * rychlost toku (tento koeficient). Kontroluje, jak szybko płyn wypływa z worków IV. Zmiana objętości worka IV jest obliczana jako:\n przedział czasowy * zmiana iv na sekundę (4,1667 mL/s) * natężenie przepływu (ten współczynnik). Controla la rapidez con que fluye el líquido de las bolsas intravenosas. El cambio de volumen de la bolsa IV se calcula como: \n intervalo (s) de tiempo * cambio iv por segundo (4.1667 mL/s) * velocidad de flujo (este coeficiente). @@ -121,17 +121,23 @@ Weapon Drop Chance Szansa Upuszczenia Broni Wahrscheinlichkeit, die Waffe fallen zu lassen + Probabilità di far cadere l'arma 무기 떨어뜨릴 확률 Risque de perte d'arme 武器を落とす確率 + Шанс выпадения оружия + Probabilidad de Soltar Arma Chance for a player to drop their weapon when going unconscious.\nHas no effect on AI. Szansa na upuszczenie broni przez gracza, przy utracie przytomności. \nNie ma wpływu na AI. Chance für einen Spieler, seine Waffe fallen zu lassen, wenn er bewusstlos wird.\nHat keine Auswirkung auf die KI. + Probabilità che un giocatore faccia cadere l'arma attualmente selezionata quando sviene.\nNon ha effetto sulle IA. 플레이어가 기절할 때 무기를 떨어뜨릴 확률입니다.\nAI는 영향을 받지 않습니다. Pourcentage de chances pour un joueur de lâcher son arme lorsqu'il perd connaissance.\nAucun effet sur les IA. プレーヤーが意識を失ったときに武器を落とす可能性。\nAI には影響しません。 + Шанс для игрока выронить свое оружие, когда он теряет сознание.\nНе влияет на ИИ + Probabilidad del jugador de soltar su arma cuando quedan inconscientes.\nNo tiene efecto sobre la IA. diff --git a/addons/medical_treatment/ACE_Medical_Treatment.hpp b/addons/medical_treatment/ACE_Medical_Treatment.hpp index eeeacf700f..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,14 +604,17 @@ class ADDON { hrIncreaseHigh[] = {-15, -35}; timeInSystem = 120; timeTillMaxEffect = 15; - maxDose = 6; + maxDose = 5; incompatibleMedication[] = {}; }; class PainKillers { - painReduce = 0.1; - timeInSystem = 600; + painReduce = 0.35; + hrIncreaseLow[] = {-5, -10}; + hrIncreaseNormal[] = {-5, -15}; + hrIncreaseHigh[] = {-5, -17}; + timeInSystem = 420; timeTillMaxEffect = 60; - maxDose = 10; + maxDose = 5; incompatibleMedication[] = {}; viscosityChange = 5; }; diff --git a/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp b/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp index 99a477c3f5..4058132e3d 100644 --- a/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp +++ b/addons/medical_treatment/ACE_Medical_Treatment_Actions.hpp @@ -141,6 +141,19 @@ class GVAR(actions) { litter[] = {{"ACE_MedicalLitter_epinephrine"}}; }; + // - Generic Medication --------------------------------------------------- + class Painkillers: Morphine { + displayName = CSTRING(Administer_Painkillers); + displayNameProgress = CSTRING(Administering_Painkillers); + icon = QPATHTOEF(medical_gui,ui\painkillers.paa); + allowedSelections[] = {"Head"}; + medicRequired = 0; + items[] = {"ACE_painkillers"}; + treatmentTime = 4; + sounds[] = {{QPATHTO_R(sounds\Pills.ogg),1,1,50}}; + litter[] = {{"Land_PainKillers_F"}}; // just use BI's model as litter + }; + // - IV Bags -------------------------------------------------------------- class BloodIV: BasicBandage { displayName = CSTRING(Actions_Blood4_1000); 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 c9144704b5..4f922eb199 100644 --- a/addons/medical_treatment/CfgVehicles.hpp +++ b/addons/medical_treatment/CfgVehicles.hpp @@ -284,6 +284,16 @@ class CfgVehicles { MACRO_ADDITEM(ACE_bodyBag,1); }; }; + class ACE_painkillersItem: Item_Base_F { + scope = 2; + scopeCurator = 2; + displayName = CSTRING(painkillers_Display); + author = "Alganthe"; + vehicleClass = "Items"; + class TransportMagazines { + MACRO_ADDMAGAZINE(ACE_painkillers,1); + }; + }; // Medical supply crates class ThingX; @@ -303,6 +313,9 @@ 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_morphine,25); @@ -346,6 +359,9 @@ 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); diff --git a/addons/medical_treatment/CfgWeapons.hpp b/addons/medical_treatment/CfgWeapons.hpp index 9406d89a28..7b31e10bee 100644 --- a/addons/medical_treatment/CfgWeapons.hpp +++ b/addons/medical_treatment/CfgWeapons.hpp @@ -31,7 +31,7 @@ class CfgWeapons { descriptionUse = CSTRING(Bandage_Basic_Desc_Use); ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.6; }; }; class ACE_packingBandage: ACE_ItemCore { @@ -44,7 +44,7 @@ class CfgWeapons { descriptionUse = CSTRING(Packing_Bandage_Desc_Use); ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.6; }; }; class ACE_elasticBandage: ACE_ItemCore { @@ -57,7 +57,7 @@ class CfgWeapons { descriptionUse = CSTRING(Bandage_Elastic_Desc_Use); ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.6; }; }; class ACE_tourniquet: ACE_ItemCore { @@ -241,7 +241,7 @@ class CfgWeapons { descriptionUse = CSTRING(QuikClot_Desc_Use); ACE_isMedicalItem = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.6; }; }; class ACE_personalAidKit: ACE_ItemCore { diff --git a/addons/medical_treatment/XEH_PREP.hpp b/addons/medical_treatment/XEH_PREP.hpp index 9222b0bd8b..709c97952f 100644 --- a/addons/medical_treatment/XEH_PREP.hpp +++ b/addons/medical_treatment/XEH_PREP.hpp @@ -13,6 +13,7 @@ PREP(canStitch); PREP(canTreat); PREP(canTreatCached); PREP(canTreat_holsterCheck); +PREP(canUnloadUnit); PREP(checkBloodPressure); PREP(checkBloodPressureLocal); PREP(checkPulse); diff --git a/addons/medical_treatment/XEH_preInit.sqf b/addons/medical_treatment/XEH_preInit.sqf index 68b80b5d0d..e6210a7372 100644 --- a/addons/medical_treatment/XEH_preInit.sqf +++ b/addons/medical_treatment/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" #define ARSENAL_CATEGORY_ICON (["\A3\ui_f\data\igui\cfg\actions\heal_ca.paa", QPATHTOEF(medical_gui,data\categories\bandage_fracture.paa)] select (["ace_medical_gui"] call EFUNC(common,isModLoaded))) @@ -14,27 +14,23 @@ PREP_RECOMPILE_END; // adjusting these is trail and error // if the animation is cut of ingame, increase these values // if the unit idles too much, decrease them -GVAR(animDurations) = [] call CBA_fnc_createNamespace; - -{ - GVAR(animDurations) setVariable _x; -} forEach [ - ["AinvPknlMstpSlayWnonDnon_medic", 7.5], - ["AinvPpneMstpSlayWnonDnon_medic", 7], - ["AinvPknlMstpSlayWrflDnon_medic", 7], - ["AinvPpneMstpSlayWrflDnon_medic", 9.5], - ["AinvPknlMstpSlayWlnrDnon_medic", 9], - ["AinvPknlMstpSlayWpstDnon_medic", 9.5], - ["AinvPpneMstpSlayWpstDnon_medic", 10], - ["AinvPknlMstpSlayWnonDnon_medicOther", 8.5], - ["AinvPpneMstpSlayWnonDnon_medicOther", 8.5], - ["AinvPknlMstpSlayWrflDnon_medicOther", 7], - ["AinvPpneMstpSlayWrflDnon_medicOther", 9], - ["AinvPknlMstpSlayWlnrDnon_medicOther", 9], - ["AinvPknlMstpSlayWpstDnon_medicOther", 10], - ["AinvPpneMstpSlayWpstDnon_medicOther", 8.5], - ["AinvPknlMstpSnonWnonDnon_medic1", 10], - ["AinvPknlMstpSnonWnonDr_medic0", 12] +GVAR(animDurations) = createHashMapFromArray [ + ["ainvpknlmstpslaywnondnon_medic", 7.5], + ["ainvppnemstpslaywnondnon_medic", 7], + ["ainvpknlmstpslaywrfldnon_medic", 7], + ["ainvppnemstpslaywrfldnon_medic", 9.5], + ["ainvpknlmstpslaywlnrdnon_medic", 9], + ["ainvpknlmstpslaywpstdnon_medic", 9.5], + ["ainvppnemstpslaywpstdnon_medic", 10], + ["ainvpknlmstpslaywnondnon_medicother", 8.5], + ["ainvppnemstpslaywnondnon_medicother", 8.5], + ["ainvpknlmstpslaywrfldnon_medicother", 7], + ["ainvppnemstpslaywrfldnon_medicother", 9], + ["ainvpknlmstpslaywlnrdnon_medicother", 9], + ["ainvpknlmstpslaywpstdnon_medicother", 10], + ["ainvppnemstpslaywpstdnon_medicother", 8.5], + ["ainvpknlmstpsnonwnondnon_medic1", 10], + ["ainvpknlmstpsnonwnondr_medic0", 12] ]; // class names of medical facilities (config case) diff --git a/addons/medical_treatment/XEH_preStart.sqf b/addons/medical_treatment/XEH_preStart.sqf index 27f8f2d9c2..420bffaf71 100644 --- a/addons/medical_treatment/XEH_preStart.sqf +++ b/addons/medical_treatment/XEH_preStart.sqf @@ -2,4 +2,4 @@ #include "XEH_PREP.hpp" -call FUNC(scanMedicalItems) +call FUNC(scanMedicalItems); diff --git a/addons/medical_treatment/config.cpp b/addons/medical_treatment/config.cpp index d0ecbddaef..3782645019 100644 --- a/addons/medical_treatment/config.cpp +++ b/addons/medical_treatment/config.cpp @@ -11,8 +11,8 @@ ACE_PATCH_NOT_LOADED(ADDON,PATCH_SKIP) class CfgPatches { class ADDON { name = COMPONENT_NAME; - units[] = {"ACE_fieldDressingItem","ACE_packingBandageItem","ACE_elasticBandageItem","ACE_tourniquetItem","ACE_splintItem","ACE_morphineItem","ACE_adenosineItem","ACE_epinephrineItem","ACE_plasmaIVItem","ACE_bloodIVItem","ACE_salineIVItem","ACE_quikClotItem","ACE_personalAidKitItem","ACE_surgicalKitItem","ACE_sutureItem","ACE_bodyBagItem","ACE_medicalSupplyCrate","ACE_medicalSupplyCrate_advanced"}; - weapons[] = {"ACE_fieldDressing","ACE_packingBandage","ACE_elasticBandage","ACE_tourniquet","ACE_splint","ACE_morphine","ACE_adenosine","ACE_epinephrine","ACE_plasmaIV","ACE_plasmaIV_500","ACE_plasmaIV_250","ACE_bloodIV","ACE_bloodIV_500","ACE_bloodIV_250","ACE_salineIV","ACE_salineIV_500","ACE_salineIV_250","ACE_quikclot","ACE_personalAidKit","ACE_surgicalKit","ACE_suture","ACE_bodyBag","ACE_bodyBag_blue","ACE_bodyBag_white"}; + units[] = {"ACE_fieldDressingItem","ACE_packingBandageItem","ACE_elasticBandageItem","ACE_tourniquetItem","ACE_splintItem","ACE_painkillersItem","ACE_morphineItem","ACE_adenosineItem","ACE_epinephrineItem","ACE_plasmaIVItem","ACE_bloodIVItem","ACE_salineIVItem","ACE_quikClotItem","ACE_personalAidKitItem","ACE_surgicalKitItem","ACE_sutureItem","ACE_bodyBagItem","ACE_medicalSupplyCrate","ACE_medicalSupplyCrate_advanced"}; + weapons[] = {"ACE_fieldDressing","ACE_packingBandage","ACE_elasticBandage","ACE_tourniquet","ACE_splint","ACE_painkillers","ACE_morphine","ACE_adenosine","ACE_epinephrine","ACE_plasmaIV","ACE_plasmaIV_500","ACE_plasmaIV_250","ACE_bloodIV","ACE_bloodIV_500","ACE_bloodIV_250","ACE_salineIV","ACE_salineIV_500","ACE_salineIV_250","ACE_quikclot","ACE_personalAidKit","ACE_surgicalKit","ACE_suture","ACE_bodyBag","ACE_bodyBag_blue","ACE_bodyBag_white"}; requiredVersion = REQUIRED_VERSION; requiredAddons[] = {"ace_medical_status", "ace_medical_damage", "ace_apl"}; author = ECSTRING(common,ACETeam); @@ -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..8657936a66 100644 --- a/addons/medical_treatment/functions/fnc_bandage.sqf +++ b/addons/medical_treatment/functions/fnc_bandage.sqf @@ -8,6 +8,10 @@ * 1: Patient * 2: Body Part * 3: Treatment + * 4: Item User + * 5: Used Item + * 6: Create litter + * 7: Bandage effectiveness coefficient (default: 1) * * Return Value: * None @@ -18,8 +22,11 @@ * Public: No */ -params ["_medic", "_patient", "_bodyPart", "_classname"]; +_this set [7, _this param [7, 1]]; // set 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..2c59540fd1 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, [0]]]; +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 1f18e2b6c1..3b643afa2b 100644 --- a/addons/medical_treatment/functions/fnc_canTreat.sqf +++ b/addons/medical_treatment/functions/fnc_canTreat.sqf @@ -10,7 +10,7 @@ * 3: Treatment * * Return Value: - * Can Treat + * Can treat * * Example: * [player, cursorObject, "Head", "SurgicalKit"] call ace_medical_treatment_fnc_canTreat @@ -22,17 +22,14 @@ params ["_medic", "_patient", "_bodyPart", "_classname"]; private _config = configFile >> QGVAR(actions) >> _classname; -isClass _config -&& {_patient isKindOf "CAManBase"} -&& {_medic != _patient || {GET_NUMBER_ENTRY(_config >> "allowSelfTreatment") == 1}} -&& {[_medic, GET_NUMBER_ENTRY(_config >> "medicRequired")] call FUNC(isMedic)} -&& {[_medic, _patient, _config] call FUNC(canTreat_holsterCheck)} -&& { - private _selections = getArray (_config >> "allowedSelections") apply {toLower _x}; - "all" in _selections || {_bodyPart in _selections} +// Conditions that apply, regardless of curator status +( + isClass _config +) && { + _patient isKindOf "CAManBase" } && { - private _items = getArray (_config >> "items"); - _items isEqualTo [] || {[_medic, _patient, _items] call FUNC(hasItem)} + private _selections = getArray (_config >> "allowedSelections") apply {toLowerANSI _x}; + "all" in _selections || {_bodyPart in _selections} } && { GET_FUNCTION(_condition,_config >> "condition"); @@ -46,19 +43,34 @@ isClass _config _condition } && { - switch (GET_NUMBER_ENTRY(_config >> "treatmentLocations")) do { - case TREATMENT_LOCATIONS_ALL: {true}; - case TREATMENT_LOCATIONS_VEHICLES: { - IN_MED_VEHICLE(_medic) || {IN_MED_VEHICLE(_patient)} - }; - case TREATMENT_LOCATIONS_FACILITIES: { - IN_MED_FACILITY(_medic) || {IN_MED_FACILITY(_patient)} - }; - case TREATMENT_LOCATIONS_VEHICLES_AND_FACILITIES: { - IN_MED_VEHICLE(_medic) || {IN_MED_VEHICLE(_patient)} || {IN_MED_FACILITY(_medic)} || {IN_MED_FACILITY(_patient)} - }; - default {false}; - }; -} && { - ((getNumber (_config >> "allowedUnderwater")) == 1) || {!([_medic] call ace_common_fnc_isSwimming)} + // If in Zeus, the rest of the condition checks can be omitted + (_medic isEqualTo player && {!isNull findDisplay 312}) || { + // Conditions that apply when not in Zeus + ( + _medic != _patient || {GET_NUMBER_ENTRY(_config >> "allowSelfTreatment") == 1} + ) && { + [_medic, GET_NUMBER_ENTRY(_config >> "medicRequired")] call FUNC(isMedic) + } && { + [_medic, _patient, _config] call FUNC(canTreat_holsterCheck) + } && { + private _items = getArray (_config >> "items"); + _items isEqualTo [] || {[_medic, _patient, _items] call FUNC(hasItem)} + } && { + switch (GET_NUMBER_ENTRY(_config >> "treatmentLocations")) do { + case TREATMENT_LOCATIONS_ALL: {true}; + case TREATMENT_LOCATIONS_VEHICLES: { + IN_MED_VEHICLE(_medic) || {IN_MED_VEHICLE(_patient)} + }; + case TREATMENT_LOCATIONS_FACILITIES: { + IN_MED_FACILITY(_medic) || {IN_MED_FACILITY(_patient)} + }; + case TREATMENT_LOCATIONS_VEHICLES_AND_FACILITIES: { + IN_MED_VEHICLE(_medic) || {IN_MED_VEHICLE(_patient)} || {IN_MED_FACILITY(_medic)} || {IN_MED_FACILITY(_patient)} + }; + default {false}; + }; + } && { + !(_medic call EFUNC(common,isSwimming)) || {getNumber (_config >> "allowedUnderwater") == 1} + } + } } diff --git a/addons/medical_treatment/functions/fnc_canUnloadUnit.sqf b/addons/medical_treatment/functions/fnc_canUnloadUnit.sqf new file mode 100644 index 0000000000..f1a15f04f9 --- /dev/null +++ b/addons/medical_treatment/functions/fnc_canUnloadUnit.sqf @@ -0,0 +1,22 @@ +#include "..\script_component.hpp" +/* + * Author: LinkIsGrim + * Checks if unit can be unloaded. + * + * Arguments: + * 0: Unloader + * 1: Target + * + * Return Value: + * Can Unload + * + * Example: + * [player, bob] call ace_medical_treatment_fnc_canUnloadUnit + * + * Public: No + */ + +params ["_unloader", "_target"]; + +!isNull objectParent _target && +{!(lifeState _target in ["HEALTHY", "INJURED"])} diff --git a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf index 737a40c0ca..bb3efedc22 100644 --- a/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf +++ b/addons/medical_treatment/functions/fnc_checkPulseLocal.sqf @@ -21,8 +21,16 @@ params ["_medic", "_patient", "_bodyPart"]; private _heartRate = 0; -if (alive _patient && {!([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo))}) then { - _heartRate = GET_HEART_RATE(_patient); +if !([_patient, _bodyPart] call FUNC(hasTourniquetAppliedTo)) then { + _heartRate = switch (true) do { + case (alive _patient): { + GET_HEART_RATE(_patient) + }; + case (alive (_patient getVariable [QEGVAR(medical,CPR_provider), objNull])): { + random [25, 30, 35] // fake heart rate because patient is dead and off state machine + }; + default { 0 }; + }; }; private _heartRateOutput = LSTRING(Check_Pulse_Output_5); @@ -31,7 +39,7 @@ private _logOutput = LSTRING(Check_Pulse_None); if (_heartRate > 1) then { if (_medic call FUNC(isMedic)) then { _heartRateOutput = LSTRING(Check_Pulse_Output_1); - _logOutput = format ["%1", round _heartRate]; + _logOutput = str round _heartRate; } else { _heartRateOutput = LSTRING(Check_Pulse_Output_2); _logOutput = LSTRING(Check_Pulse_Weak); diff --git a/addons/medical_treatment/functions/fnc_checkResponse.sqf b/addons/medical_treatment/functions/fnc_checkResponse.sqf index dc76b1dbfb..ca95fcb1d1 100644 --- a/addons/medical_treatment/functions/fnc_checkResponse.sqf +++ b/addons/medical_treatment/functions/fnc_checkResponse.sqf @@ -22,6 +22,11 @@ params ["_medic", "_patient"]; private _output = if (_patient call EFUNC(common,isAwake)) then { LSTRING(Check_Response_Responsive) } else { + if (GVAR(advancedDiagnose) == 3) exitWith { + if (IN_CRDC_ARRST(_patient)) exitWith { LSTRING(Check_Response_CardiacArrestDirect) }; + if (!alive _patient) exitWith { LSTRING(Check_Response_DeadDirect) }; + LSTRING(Check_Response_UnresponsiveDirect) + }; if ((GVAR(advancedDiagnose) == 2) && {IN_CRDC_ARRST(_patient)}) exitWith { LSTRING(Check_Response_CardiacArrest) }; if ((GVAR(advancedDiagnose) == 2) && {!alive _patient}) exitWith { LSTRING(Check_Response_Dead) }; LSTRING(Check_Response_Unresponsive) diff --git a/addons/medical_treatment/functions/fnc_cprLocal.sqf b/addons/medical_treatment/functions/fnc_cprLocal.sqf index 228774b2f6..e6b1299027 100644 --- a/addons/medical_treatment/functions/fnc_cprLocal.sqf +++ b/addons/medical_treatment/functions/fnc_cprLocal.sqf @@ -24,9 +24,14 @@ TRACE_2("cprLocal",_medic,_patient); private _bloodVolume = GET_BLOOD_VOLUME(_patient); private _successChance = linearConversion [BLOOD_VOLUME_CLASS_4_HEMORRHAGE, BLOOD_VOLUME_CLASS_2_HEMORRHAGE, _bloodVolume, GVAR(cprSuccessChanceMin), GVAR(cprSuccessChanceMax), true]; if ((random 1) < _successChance) then { + // If SpO2 is too low, it will make HR skyrocket to the point where patient goes back into CA + // Allow 3rd party mods to disable this mechanic + if (missionNamespace getVariable [QGVAR(setSpO2UponCPRSuccess), true] && {GET_SPO2(_patient) < DEFAULT_SPO2 / 2}) then { + _patient setVariable [VAR_SPO2, DEFAULT_SPO2 / 2, true]; + }; + TRACE_2("CPR random success",_bloodVolume,_successChance); [QEGVAR(medical,CPRSucceeded), _patient] call CBA_fnc_localEvent; } else { TRACE_2("CPR random fail",_bloodVolume,_successChance); }; - 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..42c5866a9a 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]; @@ -72,12 +77,12 @@ _patient setVariable [QEGVAR(medical,bodyPartDamage), [0,0,0,0,0,0], true]; // wakeup needs to be done after achieving stable vitals, but before manually reseting unconc var if IS_UNCONSCIOUS(_patient) then { - if (!([_patient] call EFUNC(medical_status,hasStableVitals))) then { ERROR_2("fullheal [unit %1][state %2] did not restore stable vitals",_patient,_state); }; + if !([_patient] call EFUNC(medical_status,hasStableVitals)) then {ERROR_2("fullheal [unit %1][state %2] did not restore stable vitals",_patient,_state);}; TRACE_1("Waking up",_patient); [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; _state = GET_SM_STATE(_patient); TRACE_1("after WakeUp",_state); - if IS_UNCONSCIOUS(_patient) then { ERROR_2("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state); }; + if IS_UNCONSCIOUS(_patient) then {ERROR_2("fullheal [unit %1][state %2] failed to wake up patient",_patient,_state);}; }; // Generic medical admin 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_handleBandageOpening.sqf b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf index 69a6118099..b90198f0eb 100644 --- a/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf +++ b/addons/medical_treatment/functions/fnc_handleBandageOpening.sqf @@ -36,7 +36,7 @@ if (isClass (_config >> _bandage)) then { _reopeningMinDelay = getNumber (_config >> "reopeningMinDelay"); _reopeningMaxDelay = getNumber (_config >> "reopeningMaxDelay") max _reopeningMinDelay; } else { - WARNING_2("No config for bandage [%1] config base [%2]", _bandage, _config); + WARNING_2("No config for bandage [%1] config base [%2]",_bandage,_config); }; if (isClass (_config >> _className)) then { @@ -54,7 +54,7 @@ if (isClass (_config >> _className)) then { _reopeningMaxDelay = getNumber (_woundTreatmentConfig >> "reopeningMaxDelay") max _reopeningMinDelay; }; } else { - WARNING_2("No config for wound type [%1] config base [%2]", _className, _config); + WARNING_2("No config for wound type [%1] config base [%2]",_className,_config); }; TRACE_5("configs",_bandage,_className,_reopeningChance,_reopeningMinDelay,_reopeningMaxDelay); 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_isInMedicalFacility.sqf b/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf index 2d4468d2c4..d04c1497bd 100644 --- a/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf +++ b/addons/medical_treatment/functions/fnc_isInMedicalFacility.sqf @@ -21,7 +21,7 @@ params ["_unit"]; private _fnc_check = { private _position = _unit modelToWorldVisual [0, 0, eyePos _unit select 2]; - CHECK_OBJECTS(lineIntersectsWith [ARR_3(_position, _position vectorAdd [ARR_3(0, 0, 10)], _unit)]) || {CHECK_OBJECTS(_unit nearObjects 7.5)} + CHECK_OBJECTS(lineIntersectsWith [ARR_3(_position,_position vectorAdd [ARR_3(0,0,10)],_unit)]) || {CHECK_OBJECTS(_unit nearObjects 7.5)} }; [[], _fnc_check, _unit, QGVAR(inMedicalFacilityCache), IN_MEDICAL_FACILITY_CACHE_EXPIRY] call EFUNC(common,cachedCall); 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..0b23b365e8 100644 --- a/addons/medical_treatment/functions/fnc_medicationLocal.sqf +++ b/addons/medical_treatment/functions/fnc_medicationLocal.sqf @@ -19,6 +19,9 @@ // todo: move this macro to script_macros_medical.hpp? #define MORPHINE_PAIN_SUPPRESSION 0.6 +// 0.2625 = 0.6/0.8 * 0.35 +// 0.6 = basic medication morph. pain suppr., 0.8 = adv. medication morph. pain suppr., 0.35 = adv. medication painkillers. pain suppr. +#define PAINKILLERS_PAIN_SUPPRESSION 0.2625 params ["_patient", "_bodyPart", "_classname"]; TRACE_3("medicationLocal",_patient,_bodyPart,_classname); @@ -36,13 +39,17 @@ if (!GVAR(advancedMedication)) exitWith { case "Epinephrine": { [QEGVAR(medical,WakeUp), _patient] call CBA_fnc_localEvent; }; + case "Painkillers": { + private _painSuppress = GET_PAIN_SUPPRESS(_patient); + _patient setVariable [VAR_PAIN_SUPP, (_painSuppress + PAINKILLERS_PAIN_SUPPRESSION) min 1, true]; + }; }; }; TRACE_1("Running treatmentMedicationLocal with Advanced configuration for",_patient); // 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 +66,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 +83,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_treatment.sqf b/addons/medical_treatment/functions/fnc_treatment.sqf index 0c89820eb4..5f6df40e31 100644 --- a/addons/medical_treatment/functions/fnc_treatment.sqf +++ b/addons/medical_treatment/functions/fnc_treatment.sqf @@ -52,90 +52,100 @@ private _userAndItem = if (GET_NUMBER_ENTRY(_config >> "consumeItem") == 1) then [objNull, ""]; // Treatment does not require items to be consumed }; -_userAndItem params ["_itemUser", "_usedItem"]; +_userAndItem params ["_itemUser", "_usedItem", "_createLitter"]; -// Get treatment animation for the medic -private _medicAnim = if (_medic isEqualTo _patient) then { - getText (_config >> ["animationMedicSelf", "animationMedicSelfProne"] select (stance _medic == "PRONE")); -} else { - getText (_config >> ["animationMedic", "animationMedicProne"] select (stance _medic == "PRONE")); -}; +private _isInZeus = !isNull findDisplay 312; -_medic setVariable [QGVAR(selectedWeaponOnTreatment), weaponState _medic]; +if (_medic isNotEqualTo player || {!_isInZeus}) then { + // Get treatment animation for the medic + private _medicAnim = if (_medic isEqualTo _patient) then { + getText (_config >> ["animationMedicSelf", "animationMedicSelfProne"] select (stance _medic == "PRONE")); + } else { + getText (_config >> ["animationMedic", "animationMedicProne"] select (stance _medic == "PRONE")); + }; -// Adjust animation based on the current weapon of the medic -private _wpn = ["non", "rfl", "lnr", "pst"] param [["", primaryWeapon _medic, secondaryWeapon _medic, handgunWeapon _medic] find currentWeapon _medic, "non"]; -_medicAnim = [_medicAnim, "[wpn]", _wpn] call CBA_fnc_replace; + _medic setVariable [QGVAR(selectedWeaponOnTreatment), weaponState _medic]; -// This animation is missing, use alternative -if (_medicAnim == "AinvPknlMstpSlayWlnrDnon_medic") then { - _medicAnim = "AinvPknlMstpSlayWlnrDnon_medicOther"; -}; + // Adjust animation based on the current weapon of the medic + private _wpn = ["non", "rfl", "lnr", "pst"] param [["", primaryWeapon _medic, secondaryWeapon _medic, handgunWeapon _medic] find currentWeapon _medic, "non"]; + _medicAnim = [_medicAnim, "[wpn]", _wpn] call CBA_fnc_replace; -// Determine the animation length -private _animDuration = GVAR(animDurations) getVariable _medicAnim; -if (isNil "_animDuration") then { - WARNING_2("animation [%1] for [%2] has no duration defined",_medicAnim,_classname); - _animDuration = 10; -}; + // This animation is missing, use alternative + if (_medicAnim == "AinvPknlMstpSlayWlnrDnon_medic") then { + _medicAnim = "AinvPknlMstpSlayWlnrDnon_medicOther"; + }; -// These animations have transitions that take a bit longer... -if (weaponLowered _medic) then { - _animDuration = _animDuration + 0.5; + // Determine the animation length + private _animDuration = GVAR(animDurations) get toLowerANSI _medicAnim; + if (isNil "_animDuration") then { + WARNING_2("animation [%1] for [%2] has no duration defined",_medicAnim,_classname); + _animDuration = 10; + }; - // Fix problems with lowered weapon transitions by raising the weapon first - if (currentWeapon _medic != "" && {_medicAnim != ""}) then { - _medic action ["WeaponInHand", _medic]; + // These animations have transitions that take a bit longer... + if (weaponLowered _medic) then { + _animDuration = _animDuration + 0.5; + + // Fix problems with lowered weapon transitions by raising the weapon first + if (currentWeapon _medic != "" && {_medicAnim != ""}) then { + _medic action ["WeaponInHand", _medic]; + }; + }; + + if (binocular _medic != "" && {binocular _medic == currentWeapon _medic}) then { + _animDuration = _animDuration + 1; + }; + + // Play treatment animation for medic and determine the ending animation + if (vehicle _medic == _medic && {_medicAnim != ""}) then { + // Speed up animation based on treatment time (but cap max to prevent odd animiations/cam shake) + private _animRatio = _animDuration / _treatmentTime; + TRACE_3("setAnimSpeedCoef",_animRatio,_animDuration,_treatmentTime); + + // Don't slow down animation too much to prevent it looking funny. + if (_animRatio < ANIMATION_SPEED_MIN_COEFFICIENT) then { + _animRatio = ANIMATION_SPEED_MIN_COEFFICIENT; + }; + + // Skip animation enitrely if progress bar too quick. + if (_animRatio > ANIMATION_SPEED_MAX_COEFFICIENT) exitWith {}; + + [QEGVAR(common,setAnimSpeedCoef), [_medic, _animRatio]] call CBA_fnc_globalEvent; + + // Play animation + private _endInAnim = "AmovP[pos]MstpS[stn]W[wpn]Dnon"; + + private _pos = ["knl", "pne"] select (stance _medic == "PRONE"); + private _stn = "non"; + + if (_wpn != "non") then { + _stn = ["ras", "low"] select (weaponLowered _medic); + }; + + _endInAnim = [_endInAnim, "[pos]", _pos] call CBA_fnc_replace; + _endInAnim = [_endInAnim, "[stn]", _stn] call CBA_fnc_replace; + _endInAnim = [_endInAnim, "[wpn]", _wpn] call CBA_fnc_replace; + + [_medic, _medicAnim] call EFUNC(common,doAnimation); + [_medic, _endInAnim] call EFUNC(common,doAnimation); + _medic setVariable [QGVAR(endInAnim), _endInAnim]; + + if (!isNil QEGVAR(advanced_fatigue,setAnimExclusions)) then { + EGVAR(advanced_fatigue,setAnimExclusions) pushBack QUOTE(ADDON); + }; + }; + + // Play a random treatment sound globally if defined + private _soundsConfig = _config >> "sounds"; + + if (isArray _soundsConfig) then { + (selectRandom (getArray _soundsConfig)) params ["_file", ["_volume", 1], ["_pitch", 1], ["_distance", 10]]; + playSound3D [_file, objNull, false, getPosASL _medic, _volume, _pitch, _distance]; }; }; -if (binocular _medic != "" && {binocular _medic == currentWeapon _medic}) then { - _animDuration = _animDuration + 1; -}; - -// Play treatment animation for medic and determine the ending animation -if (vehicle _medic == _medic && {_medicAnim != ""}) then { - // Speed up animation based on treatment time (but cap max to prevent odd animiations/cam shake) - private _animRatio = _animDuration / _treatmentTime; - TRACE_3("setAnimSpeedCoef",_animRatio,_animDuration,_treatmentTime); - - // Don't slow down animation too much to prevent it looking funny. - if (_animRatio < ANIMATION_SPEED_MIN_COEFFICIENT) then { - _animRatio = ANIMATION_SPEED_MIN_COEFFICIENT; - }; - - // Skip animation enitrely if progress bar too quick. - if (_animRatio > ANIMATION_SPEED_MAX_COEFFICIENT) exitWith {}; - - [QEGVAR(common,setAnimSpeedCoef), [_medic, _animRatio]] call CBA_fnc_globalEvent; - - // Play animation - private _endInAnim = "AmovP[pos]MstpS[stn]W[wpn]Dnon"; - - private _pos = ["knl", "pne"] select (stance _medic == "PRONE"); - private _stn = "non"; - - if (_wpn != "non") then { - _stn = ["ras", "low"] select (weaponLowered _medic); - }; - - _endInAnim = [_endInAnim, "[pos]", _pos] call CBA_fnc_replace; - _endInAnim = [_endInAnim, "[stn]", _stn] call CBA_fnc_replace; - _endInAnim = [_endInAnim, "[wpn]", _wpn] call CBA_fnc_replace; - - [_medic, _medicAnim] call EFUNC(common,doAnimation); - [_medic, _endInAnim] call EFUNC(common,doAnimation); - _medic setVariable [QGVAR(endInAnim), _endInAnim]; - - if (!isNil QEGVAR(advanced_fatigue,setAnimExclusions)) then { - EGVAR(advanced_fatigue,setAnimExclusions) pushBack QUOTE(ADDON); - }; -}; - -// Play a random treatment sound globally if defined -if (isArray (_config >> "sounds")) then { - selectRandom getArray (_config >> "sounds") params ["_file", ["_volume", 1], ["_pitch", 1], ["_distance", 10]]; - playSound3D [_file, objNull, false, getPosASL _medic, _volume, _pitch, _distance]; +if (_isInZeus) then { + _treatmentTime = _treatmentTime * GVAR(treatmentTimeCoeffZeus); }; GET_FUNCTION(_callbackStart,_config >> "callbackStart"); @@ -145,18 +155,18 @@ if (_callbackProgress isEqualTo {}) then { _callbackProgress = {true}; }; -[_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem] call _callbackStart; +[_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter] call _callbackStart; -["ace_treatmentStarted", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem]] call CBA_fnc_localEvent; +["ace_treatmentStarted", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter]] call CBA_fnc_localEvent; [ _treatmentTime, - [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem], + [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter], FUNC(treatmentSuccess), FUNC(treatmentFailure), getText (_config >> "displayNameProgress"), _callbackProgress, - ["isNotInside", "isNotSwimming"] + ["isNotInside", "isNotSwimming", "isNotInZeus"] ] call EFUNC(common,progressBar); true diff --git a/addons/medical_treatment/functions/fnc_treatmentFailure.sqf b/addons/medical_treatment/functions/fnc_treatmentFailure.sqf index 64d18fa830..7b3278b2a5 100644 --- a/addons/medical_treatment/functions/fnc_treatmentFailure.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentFailure.sqf @@ -11,6 +11,7 @@ * 3: Treatment * 4: Item User * 5: Used Item + * 6: Create Litter * * Return Value: * None @@ -19,11 +20,15 @@ */ params ["_args"]; -_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem"]; +_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem", "_createLitter"]; // 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 @@ -49,4 +54,4 @@ GET_FUNCTION(_callbackFailure,configFile >> QGVAR(actions) >> _classname >> "cal _args call _callbackFailure; -["ace_treatmentFailed", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem]] call CBA_fnc_localEvent; +["ace_treatmentFailed", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter]] call CBA_fnc_localEvent; diff --git a/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf b/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf index 96f0d11ead..0c39f7646e 100644 --- a/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf +++ b/addons/medical_treatment/functions/fnc_treatmentSuccess.sqf @@ -11,6 +11,7 @@ * 3: Treatment * 4: Item User * 5: Used Item + * 6: Create Litter * * Return Value: * None @@ -19,7 +20,8 @@ */ params ["_args"]; -_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem"]; +_args params ["_medic", "_patient", "_bodyPart", "_classname", "_itemUser", "_usedItem", "_createLitter"]; +TRACE_7("",_medic,_patient,_bodyPart,_classname,_itemUser,_usedItem,_createLitter); // Switch medic to end animation immediately private _endInAnim = _medic getVariable QGVAR(endInAnim); @@ -45,7 +47,7 @@ GET_FUNCTION(_callbackSuccess,configFile >> QGVAR(actions) >> _classname >> "cal _args call _callbackSuccess; // Call litter creation handler -_args call FUNC(createLitter); +if (_createLitter) then { _args call FUNC(createLitter); }; // Emit local event for medical API -["ace_treatmentSucceded", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem]] call CBA_fnc_localEvent; +["ace_treatmentSucceded", [_medic, _patient, _bodyPart, _classname, _itemUser, _usedItem, _createLitter]] call CBA_fnc_localEvent; diff --git a/addons/medical_treatment/functions/fnc_useItem.sqf b/addons/medical_treatment/functions/fnc_useItem.sqf index 08fc860569..33ac9f98f4 100644 --- a/addons/medical_treatment/functions/fnc_useItem.sqf +++ b/addons/medical_treatment/functions/fnc_useItem.sqf @@ -10,7 +10,7 @@ * 2: Items * * Return Value: - * User and Item + * User and Item and Litter Created * * Example: * [player, cursorObject, ["bandage"]] call ace_medical_treatment_fnc_useItem @@ -20,25 +20,44 @@ params ["_medic", "_patient", "_items"]; +if (_medic isEqualTo player && {!isNull findDisplay 312}) exitWith { + [_medic, _items select 0] +}; + 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, false] breakOut "Main"; + }; + case (_x in _vehicleMagazines): { + [_unitVehicle, _x] call EFUNC(common,adjustMagazineAmmo); + [_unit, _x, false] breakOut "Main"; + }; + case (_x in _unitItems): { + _unit removeItem _x; + [_unit, _x, true] breakOut "Main"; + }; + case (_x in _unitMagazines): { + private _magsStart = count magazines _unit; + [_unit, _x] call EFUNC(common,adjustMagazineAmmo); + private _magsEnd = count magazines _unit; + [_unit, _x, (_magsEnd < _magsStart)] breakOut "Main"; + }; }; } forEach _items; } forEach _useOrder; -[objNull, ""] +[objNull, "", false] diff --git a/addons/medical_treatment/initSettings.sqf b/addons/medical_treatment/initSettings.inc.sqf similarity index 96% rename from addons/medical_treatment/initSettings.sqf rename to addons/medical_treatment/initSettings.inc.sqf index 0193a44546..d080965eb9 100644 --- a/addons/medical_treatment/initSettings.sqf +++ b/addons/medical_treatment/initSettings.inc.sqf @@ -3,7 +3,7 @@ "LIST", [LSTRING(AdvancedDiagnose_DisplayName), LSTRING(AdvancedDiagnose_Description)], [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], - [[0, 1, 2], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrest)], 1], + [[0, 1, 2, 3], [ELSTRING(common,Disabled), ELSTRING(common,Enabled), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrest), LSTRING(AdvancedDiagnose_DiagnoseCardiacArrestDirect)], 1], true ] call CBA_fnc_addSetting; @@ -305,6 +305,14 @@ true ] call CBA_fnc_addSetting; +[ + QGVAR(treatmentTimeCoeffZeus), + "SLIDER", + [LSTRING(TreatmentTimeCoeffZeus_DisplayName), LSTRING(TreatmentTimeCoeffZeus_Description)], + [ELSTRING(medical,Category), LSTRING(SubCategory_Treatment)], + [0, 10, 1, 2] +] call CBA_fnc_addSetting; + [ QGVAR(allowBodyBagUnconscious), "CHECKBOX", diff --git a/addons/medical_treatment/sounds/Pills.ogg b/addons/medical_treatment/sounds/Pills.ogg new file mode 100644 index 0000000000..7fbe550554 Binary files /dev/null and b/addons/medical_treatment/sounds/Pills.ogg differ diff --git a/addons/medical_treatment/stringtable.xml b/addons/medical_treatment/stringtable.xml index a0d9d6e0e2..383048626a 100644 --- a/addons/medical_treatment/stringtable.xml +++ b/addons/medical_treatment/stringtable.xml @@ -36,7 +36,7 @@ Advanced Diagnose Erweiterte Diagnose - アドバンスド診断 + 高度な診断 Расширенная Диагностика Diagnostic avancé Diagnóstico Avançado @@ -57,7 +57,7 @@ Ativa as opções de Verificar Pulso, Verificar Pressão Sanguínea e Verificar Resposta, ao invés do diagnóstico geral. 啟用檢查脈搏、血壓以及病患反應的動作而非一般的診斷動作。\n當停用時,CPR只會在需要時出現。\n當這個選項啟用時必須診斷病患是否無意識或者心搏停止。 启用后,可以检查脉搏、血压和反应治疗,而不是通用诊断。\n禁用时,心肺复苏操作将仅在适当时显示。\n此设置操作启用后必须需要先确定一个人是失去知觉还是心脏骤停。 - Abilita le azioni di controllo del polso, controllo della pressione sanguigna e controllo della risposta al trattamento invece dell'azione generica Diagnose.\ Se disabilitata, l'azione di RCP sarà mostrata solo quando l'esecuzione della RCP è appropriata.\Le azioni abilitate da questa impostazione sono necessarie per determinare se una persona è in stato di incoscienza o in arresto cardiaco. + Abilita le azioni di controllo del polso, controllo della pressione sanguigna e controllo della risposta al trattamento invece dell'azione generica 'Diagnosi'.\ Se disabilitata, l'azione di RCP sarà mostrata solo quando l'esecuzione della RCP è appropriata.\Le azioni abilitate da questa impostazione sono necessarie per determinare se una persona è in stato di incoscienza o in arresto cardiaco. Povoluje kontrolu srdečního tepu, krevního tlaku a reakce pacienta namísto univerzální diagnózy.\nKdyž je tato možnost vypnuta, CPR akce bude dostupná pouze pokud je vhodné ji provést.\nAkce které tato možnost zapíná jsou nutné k určení zda je pacient v bezvědomí nebo má srdeční zástavu. Włącza opcje sprawdzania Pulsu, Ciśnienia Tętniczego Krwi i Reakcje Na Ból, zamiast bardziej ogólnej akcji Diagnozuj.\n Po wyłączeniu tej opcji akcja RKO będzie wyświetlana tylko wtedy, gdy jej wykonanie będzie odpowiednie.\n Opcja, która włącza to ustawienie jest potrzebna do ustalenia, czy osoba jest nieprzytomna lub ma zatrzymanie krążenia. Ermöglicht die 'Überprüfe Puls', 'Überprüfe Blutdruck' und 'Überprüfe Reaktionen' Behandlungsaktionen anstatt der einfachen 'Diagnose' Behandlungsaktion.\nWenn diese Einstellung nicht aktiviert ist, wird die "HLW"-Aktion nur angezeigt, wenn die Anwendung von HLW angemessen ist.\nDie Aktionen, die das Aktivieren dieser Einstellung ermöglicht, werden benötigt um zu bestimmen, ob eine Person bewusstlos ist oder einen Herzstillstand erleidet. @@ -70,16 +70,25 @@ 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 已启用 & 可以诊断死亡/心搏骤停 - 활성화 및 사망/심정지 진찰가능 + 활성화 및 사망/심정지 진찰 가능 Habilitado y poder diagnosticar Muerte/Parada cardíaca + Abilitato e può diagnosticare Morte/Arresto Cardiaco + + + Enabled & Can Diagnose Death/Cardiac Arrest [Directly] + 有効 & 死亡/心停止状態を診断可能 [直接的に] + Включено и может диагностировать смерть/остановку сердца [Напрямую] + 활성화 및 사망/심정지 진찰 가능 [직접] + Aktiviert & kann Tod/Herzstillstand diagnostizieren [Direkt] + Abilitato e può diagnosticare Morte/Arresto Cardiaco [Esplicito] Advanced Medication Erweiterte Medikation - アドバンスド医薬品 + 高度な医薬品 Расширенные Лекарства Médication avancée Medicação Avançada @@ -110,7 +119,7 @@ Advanced Bandages Erweiterte Bandagen - アドバンスド包帯 + 高度な包帯 Расширенная Перевязка Pansements avancés Ataduras Avançadas @@ -126,7 +135,7 @@ Enables treatment actions for different bandage types instead of the generic Bandage action.\nAdditionally, the reopening of bandaged wounds can also be enabled. Ermöglicht Behandlungsaktionen für verschiedene Bandagentypen anstelle der gewöhnlichen Bandageaktionen. - 有効化すると通常の包帯動作に代わり、様々な種類がある包帯で治療ができます。\nまた、創傷の再解放も有効化できます。 + 有効化すると通常の包帯動作に代わり、様々な種類がある包帯で治療ができます。\nまた、創傷の再開放も有効化できます。 Active différents types de bandages, à choisir judicieusement en fonction des plaies. Включает действия для разных типов повязок, вместо общего действия «Перевязка». Ativa o uso de tipos diferentes de ataduras ao invés de apenas a atadura básica. @@ -149,6 +158,7 @@ Etkinleştirildi ve Yeniden Açılabilir Habilitada y pueden reabrirse Aktiviert und können sich wieder öffnen + Attivi e possono riaprirsi 已启用 & 可以伤口开裂 활성화 및 붕대 풀림 구현 @@ -156,10 +166,11 @@ Wound Reopening Coefficient Coefficient de réouverture des plaies Wundwiederöffnungskoeffizient + Coefficiente di riapertura ferite Koeficient opětovného otevření rány Коэф. повторного открытия раны Współczynnik ponownego otwierania ran - 再開放係数 + 創傷再開放係数 Yara Yeniden Açılma Katsayısı Coeficiente de reapertura de heridas 伤口开裂系数 @@ -169,10 +180,11 @@ Coefficient for controlling the wound reopening chance. The final reopening chance is determined by multiplying this value with the specific reopening chance for the wound type and bandage used. Coefficient de contrôle des chances de réouverture de la plaie. La chance de réouverture finale est déterminée en multipliant cette valeur par la chance de réouverture spécifique pour le type de plaie et le bandage utilisés. Koeffizient zur Kontrolle der Wundöffnungswahrscheinlichkeit. Die endgültige Wiedereröffnungschance wird bestimmt, indem dieser Wert mit der spezifischen Wiedereröffnungschance für den verwendeten Wundtyp und Verband multipliziert wird. + Coefficiente che controlla la probabilità di riapertura delle ferite. La probabilità finale viene determinata moltiplicando questo valore con la probabilità di riapertura specifica del tipo di ferita e benda usata. Koeficient pro řízení šance na opětovné otevření rány. Konečná šance na opětovné otevření se stanoví vynásobením této hodnoty specifickou šancí na opětovné otevření pro použitý typ rány a obvaz. Коэффициент контроля вероятности повторного открытия раны. Окончательный шанс повторного открытия определяется путем умножения этого значения на определенный шанс повторного открытия для используемого типа раны и повязки. Współczynnik kontroluje szanse na ponowne otworzenie rany. Końcowa szansa na otworzenie jest ustalana przez pomnożenie tej wartości z wartością szansy na otworzenie rany dla typu rany oraz typu bandaża. - 傷が再開放する確率の係数を設定できます。再開放は、この数値と傷の種類、そして使用した包帯に応じて左右されます。 + 創傷が再開放する確率の係数を設定できます。再開放は、この数値と傷の種類、そして使用した包帯に応じて左右されます。 Yaranın yeniden açılma şansını kontrol etme katsayısı. Son yeniden açılma şansı, bu değerin kullanılan yara tipi ve bandaj için spesifik yeniden açılma şansı ile çarpılmasıyla belirlenir. Coeficiente que controla la probabilidad de reapertura de heridas. La probabilidad final de reapertura de heridas queda determinada multiplicando este valor por la probabilidad específica del tipo de herida y venda usada. 用于控制伤口开裂概率的系数。最终的重开放概率=该值x伤口类型x所使用的绷带的具体开裂概率。 @@ -180,10 +192,11 @@ Clear Trauma - 外傷の削除 + 外傷を取り除く Soigner les blessures Очистить рану Traumata entfernen + Rimuovi Trauma Leczenie ran 清理创伤 상처 제거 @@ -191,10 +204,11 @@ Controls when hitpoint damage from wounds is healed. - 治療後に負傷箇所にある外傷の状態を決定できます。 + 治療後に負傷箇所にある外傷の状態を制御できます。 Définit à quel moment les blessures sont entièrement soignées. Определяет, когда исцеляется урон от ран. Steuert, wann Trefferpunktschaden von Wunden geheilt wird. + Controlla quando vengono guariti i danni ricevuti da ferite. Kontroluje kiedy punkty obrażeń od odniesionych ran są w pełni wyleczone. 控制伤口治疗后确定受伤部位的受伤情况。 상처가 언제 제거되는 지를 결정합니다. @@ -206,6 +220,7 @@ Après bandage После перевязки Nach dem Bandagieren + Dopo il bendaggio Po zabandażowaniu 包扎后 붕대 묶은 후 @@ -213,10 +228,11 @@ After Stitch - 縫合後 + 縫合した後 Après suture После наложения швов Nach dem Nähen + Dopo la cucitura Po zszyciu 缝合后 상처 봉합 후 @@ -230,7 +246,7 @@ Aumenta a qualidade do tratamento quando dentro de veículos ou instalações médicas. Destreinados se tornam médicos, médicos se tornam doutores. 在醫療設施或者載具旁時增加醫療能力。未受訓練的將會成為醫療兵,醫療兵將會成為軍醫。 在医疗设施或载具旁时提升医疗训练。未受训练者将会成为医疗兵,医疗兵将会晋升为军医。 - Aumentare la formazione medica quando si è in veicoli o strutture mediche. Se non addestrato diventa medico, il medico diventa dottore. + Aumenta la formazione medica quando si è in veicoli o strutture mediche. Se non addestrato diventa medico, se medico diventa dottore. Zvyšuje zdravotnickou úroveň v zdravotnických objektech a vozidlech. Nevycvičení se stávají mediky a medici se stávají doktory. Zwiększ wyszkolenie medyczne w pojazdach lub obiektach medycznych. Niewytrenowana jednostka zostaje medykiem, medyk zostaje lekarzem. Verbessere 'Fähigkeiten-Level' in medizinischen Fahrzeugen oder Einrichtungen. Untrainiert wird zu Sanitäter, Sanitäter wird zu Arzt. @@ -246,7 +262,7 @@ Permitir Compartilhar Itens Médicos 允許共享設備 允许共享装备 - Consentire la condivisione di attrezzature + Consenti la condivisione di risorse Povolit sdílení vybavení Zezwalaj na współdzielenie sprzętu Erlaube geteilte Ausrüstung @@ -256,13 +272,13 @@ Controls whether medical equipment can be shared between the patient and the medic. - 患者と衛生兵との間で医療品の共有をするかどうかを決定します。 + 患者と救護者との間で医療品の共有をするかどうかを制御します。 Définit si l'équipement médical du médecin et du patient sont mis en commun, et quel matériel est à utiliser en priorité, le cas échéant. Контролирует, можно ли разделить медикаменты между пациентом и врачом. Controla se um item médico pode ser compartilhado entre médico e paciente. 控制是否病患與醫療兵之間能否共享醫療物資 控制伤员和医疗兵之间是否可以共享医疗装备。 - Controlla se le attrezzature mediche possono essere condivise tra il paziente e il medico. + Controlla se le risorse mediche possono essere condivise tra il paziente e il medico. Nastavuje zda jak je zdravotnické vybavení sdíleno mezi medikem a pacientem. Kontroluje, czy sprzęt medyczny ma być dzielony między pacjentem a medykiem. Legt fest, ob medizinische Ausrüstung zwischen Patient und Sanitäter geteilt werden kann. @@ -272,13 +288,13 @@ Patient's Equipment First - 患者の装備を先に使用 + 患者の装備を優先 Matériel du patient d'abord Сначала медикаменты пациента Usar do Paciente Primeiro 優先使用患者的醫療物資 优先消耗伤员装备 - L'attrezzatura del paziente prima di tutto + Prima le risorse del paziente Prvně pacientovo vybavení Najpierw sprzęt pacjenta Ausrüstung des Patienten zuerst @@ -288,13 +304,13 @@ Medic's Equipment First - 衛生兵の装備を先に使用 + 救護者の装備を優先 Matériel du médecin d'abord Сначала медикаменты врача Usar do Médico Primeiro 優先使用醫療兵的醫療物資 优先消耗医疗兵装备 - Prima le attrezzature mediche + Prima le risorse del medico Prvně medikovo vybavení Najpierw sprzęt medyka Ausrüstung des Sanitäters zuerst @@ -305,22 +321,24 @@ Autoinjector Treatment Time Durée d'interaction - Auto-injecteurs - 注射器の使用時間 + 自動注射器の所要時間 Tiempo de tratamiento de autoinyección Время ввода автоинъектора Czas aplikacji autostrzykawki Behandlungszeit des Autoinjektors + Tempo di utilizzo dell'autoiniettore 自动注射器治疗时间 주사기 사용 시간 Time, in seconds, required to administer medication using an autoinjector. Définit le temps nécessaire à l'administration d'une substance auto-injectable (en secondes). - 注射器の使用に掛かる時間 (秒) を決定します。 + 自動注射器の使用に掛かる時間。 (秒単位) Tiempo, en segundos, requerido para administrar medicación utilizando un autoinyectador. Время, необходимое для введения медикаментов автоинъектором (в секундах). Czas w sekundach potrzebny do aplikacji medykamentów za pomocą autostrzykawki. Zeit in Sekunden, die benötigt wird, um Medikamente mittels Autoinjektor zu verabreichen. + Tempo in secondi richiesto per ricevere medicina da un autoiniettore. 使用自动注射器给药所需的时间(秒) 초 단위로 주사기를 사용하는데 걸리는 시간을 정합니다. @@ -328,7 +346,8 @@ Tourniquet Treatment Time Durée d'interaction - Garrots Tourniquet-Behandlungszeit - 止血帯の使用時間 + Tempo d'uso del Laccio Emostatico + 止血帯の所要時間 Tiempo de tratamiento de torniquete Время наложения/снятия жгута Czas aplikacji stazy @@ -339,7 +358,8 @@ Time, in seconds, required to apply/remove a tourniquet. Définit le temps nécessaire à l'application ou au retrait d'un garrot (en secondes). Zeit in Sekunden, die benötigt wird, um ein Tourniquet anzuwenden. - 止血帯の使用/取り外しに掛かる時間 (秒) を決定します。 + Tempo in secondi richiesto per mettere/rimuovere un laccio emostatico. + 止血帯の使用/取り外しに掛かる時間。 (秒単位) Tiempo, en segundos, requerido para aplicar/quitar un torniquete. Время, необходимое для наложения/снятия жгута (в секундах). Czas w sekundach potrzebny do założenia/zdjęcia stazy. @@ -350,9 +370,10 @@ IV Bag Treatment Time Durée d'interaction - IVs IV Beutelbehandlungszeit - 点滴の使用時間 + Tempo di inserimento EV + 点滴の所要時間 Tiempo de tratamiento de bolsa de IV - Время применения пакета внутривенного переливания + Время внутривенного переливания Czas aplikacji IV 静脉输液袋治疗时间 수액용기 사용 시간 @@ -361,7 +382,8 @@ Time, in seconds, required to administer an IV bag. Définit le temps nécessaire à la pose d'une perfusion IV (en secondes). Zeit in Sekunden, die benötigt wird, um einen Infusionsbeutel aufzutragen. - 点滴の投与に掛かる時間 (秒) を決定します。 + Tempo in secondi richiesto per applicare una Flebo Endovenosa. + 点滴の投与に掛かる時間。 (秒単位) Tiempo, en segundos, requerido para administrar una bolsa de IV. Время, необходимое для применения пакета внутривенного переливания (в секундах). Czas w sekundach potrzebny na aplikację transfuzji IV. @@ -372,7 +394,8 @@ Splint Treatment Time Durée d'interaction - Attelles Schienenbehandlungszeit - 副子の使用時間 + Tempo di Gessatura + 添え木の所要時間 TIempo de tratamiento de férula Время наложения шины Czas aplikacji szyny @@ -383,7 +406,8 @@ Time, in seconds, required to apply a splint. Définit le temps nécessaire à l'application d'une attelle (en secondes). Zeit in Sekunden, die zum Anbringen einer Schiene benötigt wird. - 副子の使用に掛かる時間 (秒) を決定します。 + Tempo in secondi richiesto per applicare una gessatura. + 添え木の使用に掛かる時間。 (秒単位) TIempo, en segundos, requerido para aplicar una férula. Время, необходимое для наложения шины (в секундах). Czas w sekundach potrzebny na aplikację szyny. @@ -394,7 +418,8 @@ Body Bag Use Time Durée d'interaction - Housses mortuaires Anwendungszeit für Leichensack - 死体袋の使用時間 + Tempo della sacca per corpi + 遺体袋の所要時間 TIempo de uso de bolsa para cuerpos Время использования мешка для трупов Czas użycia worka na ciało @@ -405,7 +430,8 @@ Time, in seconds, required to put a patient in a body bag. Définit le temps nécessaire à la mise en housse d'un corps (en secondes). Zeit in Sekunden, die benötigt wird, um einen Leichensack aufzutragen. - 死体袋の使用に掛かる時間 (秒) を決定します。 + Tempo in secondi richiesto per mettere un deceduto in una sacca per corpi. + 遺体袋の使用に掛かる時間。 (秒単位) Tiempo, en segundos, requerido para poner a un paciente en una bolsa para cuerpos. Время, необходимое для того чтобы упаковать труп в мешок (в секундах). Czas w sekundach potrzebny na spakowanie ciała do worka na ciało. @@ -418,7 +444,10 @@ Czas Kopania Grobu Durée pour creuser une tombe Zeit zum Graben von Gräbern + Tempo di scavo tomba 墓掘りの所要時間 + Время рытья могилы + Tiempo de Cavado de Tumba Time, in seconds, required to dig a grave for a body. @@ -426,7 +455,10 @@ Czas, w sekundach wymagany do wykopania grobu. Durée, en secondes, requise pour creuser une tombe pour un corps. Zeit (in Sekunden), die benötigt wird, um ein Grab für einen Leichnam auszuheben. - 遺体の墓を掘るのに掛かる時間 (秒) を決定します。 + Tempo in secondi richiesto per seppellire un morto. + 遺体の墓を掘るのに掛かる時間。 (秒単位) + Время в секундах, необходимое для того, чтобы выкопать могилу для тела. + Tiempo, en segundos, requerido para cavar una tumba para un cuerpo. Allow Epinephrine @@ -434,10 +466,10 @@ Permitir Epinefrina Ograniczenia użycia adrenaliny Épinéphrine autorisée pour - Permette epinefrina + Permetti Epinefrina Povolit epinefrin Permitir Epinefrina - Разрешить Адреналин + Доступ к Адреналину アドレナリンの許可 에피네프린 사용 허가 允许使用肾上腺素 @@ -446,7 +478,7 @@ Training level required to use epinephrine. - アドレナリンの使用に訓練レベルを必要とさせます。 + アドレナリンの使用に必要な医療スキルのレベルを設定します。 Définit la qualification médicale requise pour utiliser l'épinéphrine. Уровень подготовки, необходимый для использования Адреналина. É necessária uma qualificação médica para usar epinefrina. @@ -466,11 +498,11 @@ Ubicaciones epinefrina Miejsca użycia epinefryny Lieux épinéphrine - Ubicazione epinefrina + Luoghi Epinefrina Oblast pro použití epinefrinu Localizações de Epinefrina Места использования Адреналина - アドレナリンの使用可能場所 + アドレナリンの使用可能な場所 에피네프린 사용 장소 肾上腺素使用地点 腎上腺素使用地點 @@ -478,13 +510,13 @@ Controls where epinephrine can be used. - アドレナリンが使える場所を決定します。 + アドレナリンが使える場所を制御します。 Définit les lieux où l'usage d'épinéphrine est autorisé. Контролирует, где можно использовать Адреналин. Controla onde Epinefrina pode ser utilizada. 控制何處能使用腎上腺素 控制何地能使用肾上腺素。 - Controlli dove si può usare l'Epinefrina. + Controlla dove si può usare l'Epinefrina. Nastavuje kde může být epinefrin použit Kontroluje, gdzie można stosować epinefrynę. Legt fest, wo Epinephrin genutzt werden kann. @@ -494,7 +526,7 @@ Allow PAK - Использование Аптечки + Доступ к Аптечке Ograniczenia użycia apteczek osobistych Permitir EPA Erlaube Erste-Hilfe-Set @@ -502,8 +534,8 @@ Permitir Kit de Primeiros Socorros (KPS) Trousse sanitaire autorisée pour Elsősegélycsomag engedélyezése - Consenti Kit di Pronto Soccorso - 個人用応急処置キットの許可 + Consenti PAK + PAKの許可 개인응급키트 사용 허가 允许使用个人急救包 允許使用個人急救包 @@ -511,13 +543,13 @@ Training level required to use a PAK. - 個人用応急処置キットの使用に訓練レベルを必要とさせます。 + PAKの使用に必要な医療スキルのレベルを設定します。 Définit la qualification médicale requise pour utiliser la trousse sanitaire. Уровень подготовки, необходимый для использования Аптечки. É necessária uma qualificação médica para usar KPS 要受過何種程度的醫療訓練才可以使用個人急救包 使用个人急救包所需的医疗水平。 - Livello di formazione richiesto per l'utilizzo di un PAK. + Livello di formazione richiesto per l'utilizzo di un Kit di Pronto Soccorso (PAK). Úroveň výcviku pro použití osobní lékárničky (PAK). Poziom wyszkolenia wymagany do korzystania z apteczek osobistych. 'Fähigkeiten-Level', das benötigt wird, um ein Erste-Hilfe-Set zu nutzen. @@ -535,8 +567,8 @@ Localizações do KPS Lieux trousse sanitaire Elsősegélycsomag helyek - Locazioni Kit Pronto Soccorso - 個人用応急処置キットの使用可能場所 + Luoghi PAK + PAKの使用可能な場所 개인응급키트 사용 장소 个人急救包使用地点 個人急救包使用地點 @@ -544,13 +576,13 @@ Controls where a PAK can be used. - 個人用応急処置キットが使える場所を決定します。 + PAKが使える場所を制御します。 Définit les lieux où l'usage de la trousse sanitaire est autorisé. Контролирует, где можно использовать Аптечку. Controla onde o KPS pode ser utilizado. 控制何處能使用個人急救包 控制何地能使用个人急救包。 - Controlla dove può essere usato un PAK. + Controlla dove può essere usato un Kit di Pronto Soccorso (PAK). Nastavuje kde může být osobní lékárnička (PAK) použita. Kontroluje, gdzie można korzystać z apteczek osobistych. Kontrolliert, wo ein Erste-Hilfe-Set benutzt werden kann. @@ -560,13 +592,13 @@ Consume PAK - 個人用応急処置キットの消費 + PAKの消費 Trousse sanitaire consommable Израсходовать Аптечку KPS Descartável 個人急救包為消耗品 个人急救包会被消耗 - Consumare PAK + Consuma PAK Spotřebuj osobní lékárničku (PAK) Zużycie apteczek osobistych Verbrauche Erste-Hilfe-Set @@ -576,13 +608,13 @@ Controls whether a PAK should be consumed after use. - 個人用応急処置キットの使用後に消費するかどうかを決定します。 + PAKの使用後に消費するかどうかを制御します。 Définit si la trousse sanitaire doit être à usage unique. Контролирует, следует ли израсходовать Аптечку после использования. Controla se o KPS deve ser descartado/consumido após o uso. 設定個人急救包是否為消耗品 设置个人急救包是否会被消耗 - Controlla se un PAK deve essere consumato dopo l'uso. + Controlla se un PAK viene consumato dopo l'uso. Nastavuje zda má být osobní lékárnička (PAK) spotřebována po použití. Kontroluje, czy apteczka osobista powinna być zużyta po użyciu. Kontrolliert, ob ein Erste-Hilfe-Set nach der Benutzung verbraucht werden soll. @@ -592,13 +624,13 @@ Self PAK Usage - Utilizzo del kit di pronto soccorso su se stessi + Utilizzo del PAK su se stessi Erste-Hilfe-Set Selbstanwendung 自我使用急救包 自我使用急救包 Utilisation de la trousse sanitaire sur soi-même Używanie apteczki osobistej na sobie - 個人用応急処置キットの自己使用 + PAKの自己使用 Samo-použití osobní lékárničky (PAK) Использование аптечки на себе Kendi PAK Kullanımı @@ -607,13 +639,13 @@ Enables the use of PAKs to heal oneself. - Abilita l'utilizzo del kit di pronto soccorso su se stessi. + Abilita l'utilizzo del Kit di Pronto Soccorso (PAK) su se stessi. Erlaubt die Benutzung des Erste-Hilfe-Sets, um sich selbst zu heilen. 啟用個人急救包能對自己使用。 启用自身能使用个人急救包。 Définit si le joueur peut utiliser la trousse sanitaire pour se soigner lui-même. Pozwala na użycie apteczki osobistej na sobie - 個人用応急処置キットを使って、自分を治療できるようにします。 + PAKを使って、自分を治療できるようにします。 Umožňuje použít osobní lékárničku (PAK) na sama sebe. Позволяют использовать аптечку на себе в одиночку. Kendini iyileştirmek için PAK'ların kullanılmasını sağlar. @@ -622,7 +654,7 @@ Time Coefficient PAK - 個人用応急処置キットの時間係数 + PAKの所要時間係数 Coefficient de temps pour la trousse sanitaire Контролирует, следует ли израсходовать Аптечку после использования. Coeficiente de Tempo do KPS @@ -638,13 +670,13 @@ Modifies how long a PAK takes to apply.\nThe treatment time is based on the total body part damage multiplied by this coefficient, with a minimum of 10 seconds. - 個人用応急処置キットの使用にかかる時間を変更できます。\n総治療時間は最低でも 10 秒間で、この係数と体全体に負ったダメージによって決まります。 + PAKの使用に掛かる時間を変更できます。\n総治療時間は最低でも 10 秒間で、この係数と体全体に負ったダメージによって決まります。 Modifie le temps nécessaire à l'application de la trousse sanitaire.\nLa durée est calculée en multipliant ce coefficient par les dommages totaux du patient, avec un minimum de 10 secondes. Изменяет быстроту применения Аптечки.\nВремя лечения зависит от общего повреждения частей тела, умноженного на данный коэффициент (минимум 10 сек.). Modifica quanto tempo o KPS leva para ser aplicado.\nO tempo de tratamento é baseado no total de dano do corpo, multiplicado por esse coeficiente, com um mínimo de 10 segundos. 修改個人急救包要使用多久才能完成。\n醫療時間是依照全身的肢體狀況並乘上該係數而決定的,至少十秒。 修改个人急救包应用时间。 \n治疗时间=全身的总伤害x该系数,至少十秒。 - Il tempo di trattamento si basa sul danno totale della parte del corpo moltiplicato per questo coefficiente, con un minimo di 10 secondi. + Il tempo di trattamento del PAK si basa sul danno totale della parte del corpo, moltiplicato per questo coefficiente, con un minimo di 10 secondi. Upravuje jak dlouho trvá léčba pomocí osobní lékárničky (PAK).\nDoba léčby závisí na celkovém poškození částí těla vynásobeném tímto koeficientem, přičemž minimum je 10 vteřin. Zmienia czas potrzebny na zastosowanie apteczki osobistej.\n Czas leczenia jest oparty na całkowitym uszkodzeniu części ciała pomnożonym przez ten współczynnik, wynosi minimum 10 sekund. Modifiziert, wie lange ein Erste-Hilfe-Set für die Anwendung benötigt.\nDie Behandlungszeit basiert auf der Anzahl des Gesamtkörperschadens multipliziert mit diesem Koeffizienten, mit einen Minimum von 10 Sekunden. @@ -654,13 +686,13 @@ Allow Surgical Kit - 手術用キットを許可 + 手術キットを許可 Trousse chirurgicale autorisée pour - Разрешить Хирургический набор + Доступ к Хирургическому набору Permitir Kit Cirúrgico 允許使用手術包 允许使用手术包 - Permettere il kit chirurgico + Permetti il Kit Chirurgico Povolit sešívací sadu Ograniczenia Użycia Zestawu Chirurgicznego Erlaube Operations-Set @@ -670,13 +702,13 @@ Training level required to use a surgical kit. - 手術用キットの使用に訓練レベルを必要とさせます。 + 手術キットの使用に必要な医療スキルのレベルを設定します。 Définit la qualification médicale requise pour utiliser la trousse chirurgicale. Уровень медицинской подготовки, необходимый для использования Хирургического набора. É necessária uma qualificação médica para usar Kit Cirúrgico 要受過多少程度的醫療訓練才能使用手術包。 使用手术包所需的医疗水平。 - Livello di formazione richiesto per l'utilizzo di un kit chirurgico. + Livello di formazione richiesto per l'utilizzo di un Kit Chirurgico. Úroveň výcviku pro použití sešívací sady. Poziom wyszkolenia wymagany do korzystania z Zestawu Chirurgicznego. 'Fähigkeiten-Level', das benötigt wird um ein Operations-Set zu nutzen. @@ -686,13 +718,13 @@ Locations Surgical Kit - 手術用キットの使用可能場所 + 手術キットの使用可能な場所 Lieux trousse chirurgicale Места использования Хирургического набора Locais para Kit Cirúrgico 手術包使用地點 手术包使用地点 - Luoghi Kit chirurgico + Luoghi Kit Chirurgico Nastavuje kde může být sešívací sada použita Miejsca użycia Zestawu Chirurgicznego Orte für Operations-Set @@ -702,13 +734,13 @@ Controls where a surgical kit can be used. - 手術用キットが使える場所を決定します。 + 手術キットが使える場所を制御します。 Définit les lieux où l'usage de la trousse chirurgicale est autorisé. Контролирует, где можно использовать Хирургический набор Controle onde o Kit Cirúrgico pode ser utilizado. 控制何處能使用手術包 控制何地能使用手术包 - Controlla dove può essere usato un kit chirurgico. + Controlla dove può essere usato un Kit Chirurgico. Nastavuje zda má být sešívací sada spotřebována po použití. Kontroluje, gdzie można użyć Zestawu Chirurgicznego. Legt fest, wo ein Operations-Set genutzt werden kann. @@ -718,13 +750,13 @@ Consume Surgical Kit - 手術用キットの消費 + 手術キットの消費 Trousse chirurgicale consommable Израсходовать Хирургический набор Kit Cirúrgico Consumível 手術包為消耗品 手术包是否被消耗 - Consumare Kit Chirurgico + Consuma Kit Chirurgico Spotřebuj sešívací sadu Zużycie Zestawów Chirurgicznych Verbrauche Operations-Set @@ -734,11 +766,13 @@ What should be consumed after use. Legt fest, ob etwas nach der Anwendung verwendet werden soll. + Controlla se un Kit Chirurgico viene consumato dopo l'uso. Qué debe ser consumido despues de su uso. - 手術用キットの使用後に消費するかどうかを決定します。 + 使用後に何を消費するか設定します。 Co powinno zostać zużyte po zastosowaniu. 봉합키트를 1회성 소모품으로 설정할 지 여부를 결정합니다. Ce qui doit être consommé après l'utilisation. + Контролирует, следует ли израсходовать Хирургический набор или нить после использования Self Stitching @@ -747,11 +781,11 @@ 自己縫合 自我縫合 自我缝合 - Auto cucitura + Auto Cucitura Samo-zašívání Zszywanie własnych ran Selbstnähen - Зашивание своей раны + Зашитие своей раны Auto cosido 봉합키트 자가 사용 @@ -759,12 +793,12 @@ Enables the use of surgical kits to stitch oneself. Autorise l'utilisation de la trousse chirugicale sur soi-même. Permite o uso de Kit Cirúrgico em si mesmo. - 手術用キットを使い自らを縫合できるようにします。 + 手術キットを使い自らを縫合できるようにします。 啟用是否能自己使用手術包來縫合自己的傷口。 启用是否能够使用手术包进行自我缝合。 Umožňuje použití sešívací sady na sebe sama. Umożliwia użycie Zestawu Chirurgicznego na sobie. - Permette l'uso di kit chirurgici per ricucirsi. + Permette di ricucire se stesso con un Kit Chirurgico. Ermöglicht die Benutzung des Operations-Sets, um sich selbst zu nähen. Включает использование хирургического набора на себе. Permite el uso de kits quirúrgicos sobre uno mismo @@ -773,22 +807,24 @@ Wound Stitch Time Durée d'interaction - Sutures - 縫合時間 + 縫合の所要時間 Tiempo de sutura de herida Время зашивания ран Czas szycia rany Benötigte Zeit, um Wunden zu nähen + Tempo di suturazione ferita. 伤口缝合时间 상처 봉합 시간 Time, in seconds, required to stitch a single wound. Définit le temps nécessaire à la suture d'une plaie (en secondes). - 縫合に掛かる時間 (秒) を決定します。 + 縫合に掛かる時間。 (秒単位) Tiempo, en segundos, requerido para suturar una única herida. Время, необходимое для зашивания одной раны (в секундах). Czas w sekundach potrzebny na zaszycie pojedyńczej rany. Zeit in Sekunden, um eine einzelne Wunde zu nähen. + Tempo in secondi richiesto per suturare una singola ferita. 缝合一个伤口所需的时间(秒) 초 단위로, 한 상처를 봉합하는데 걸리는 시간을 설정합니다. @@ -796,7 +832,7 @@ Self IV Transfusion Eigennutzung von Bluttransfusionen Внутривенное переливание на себе - 自己 IV 輸血 + 自己 IV 輸液 Pose d'IV sur soi-même Autotransfusão de IV 自我注射點滴 @@ -811,36 +847,38 @@ Enables the use of IV transfusions on oneself. Erlaube Bluttransfusionen an sich selbst zu benutzen Позволяет использовать внутривенные переливания на себе - 自らに対して IV 輸血を可能にします。 + 自らに対して IV 輸液を可能にします。 Active la possibilité de s'auto-poser des IVs. Permite utilizar bolsas de IV para transfusão em si mesmo 啟用是否能對自己注射點滴 启用是否能够自我静脉输液 Umožňuje aplikovat IV transfuze na sama sebe. Pozwala przetoczyć płyny IV samemu sobie - Abilita la trasfusione in endovena su se stessi. + Abilita l'applicazione di Fleboclisi Endovenose su se stessi. Habilita el uso de las transfusiones IV sobre uno mismo 수액용기를 사용자 본인에게 쓸 수 있는지를 정합니다. Allow Unconscious Body Bag Housse mortuaire - Autoriser patients inconscients - 無意識者を死体袋に + 無意識者の遺体袋への収容許可 Permitir bolsa para cuerpos inconsciente - Разрешить упаковывать пациентов без сознания в мешки для трупов + Упаковка без сознания в мешки для трупов Nieprzytomni w worku na ciało Erlaube Benutzung des Leichensackes mit bewusstlosen Personen + Permetti di insaccare un paziente svenuto 允许昏迷者装入尸袋 기절 인원 시체 운반용 부대에 옮기기 Enables placing an unconscious patient in a body bag. Active la possibilité de placer des patients inconscients dans les housses mortuaires.\nAttention : le cas échéant cela provoquera la mort du patient. - 気絶しているプレイヤーを死体袋へ入れられるかどうかを決定します。 + 無意識状態のプレイヤーを遺体袋へ入れることが出来る様にします。 Permitir colocar a un paciente inconsciente en una bolsa para cuerpos. Разрешает упаковывать пациентов без сознания в мешки для трупов. Zezwalaj na pakowanie nieprzytomnych osób do worka na ciało. Aktiviert, Bewusstlose in Leichensack zu legen. + Permette l'uso della sacca per morti anche su pazienti che sono solo svenuti (causa la morte del paziente) 能够将昏迷的伤员装入尸袋中。 기절 상태의 인원을 시체 운반용 부대에 옮겨 담을 수 있는 지를 정합니다. @@ -849,67 +887,79 @@ Zezwalaj na kopanie grobów 무덤 파기 허용 Erlaube Graben von Gräbern + Permetti scavo di tombe Permitir cavar tumbas Autoriser le creusement de tombes 墓掘りを許可 + Рытье могил Enables digging graves to dispose of corpses. Umożliwia kopanie grobów w celu pozbycia się zwłok. 시체를 처리하기 위해 무덤을 파는 것을 허용합니다. Erlaubt das Graben von Gräbern um Leichen zu entsorgen. + Permette lo scavo di tombe per seppellire cadaveri. Habilita cavar tumbas para deshacerse de los cadáveres. Active la possibilité de creuser des tombes pour enterrer les cadavres. 墓を掘って死体を処理できるようになります。 + Позволяет рыть могилы для захоронения трупов. Only if dead Tylko kiedy martwy 죽었을 때에만 Nur wenn tot + Solo se morti Solo si está muerto Uniquement s'il est mort 死体のみ + Только если мертв Create Grave Markers Erstelle Grabmal + Crea lapide Crear Tumba Utwórz Nagrobek 무덤 마커 생성 Créer des pierres tombales 墓標を作成 + Надгробные знаки Enables the creation of grave markers when digging graves. Erstellt Grabmale beim Graben von Gräbern. + Permette la creazione di una lapide su una tomba scavata. Habilita la creación de Tumbas al cavar tumbas. Umożliwia tworzenie nagrobków podczas kopania grobów. 무덤을 파낼 때 무덤 마커를 표시할 수 있습니다. Active la création de pierres tombales lors de l'enterrement de cadavres. 墓を掘った際、墓標を作成できるようにします。 + Позволяет создавать надгробные знаки при рытье могил. Allow IV Transfusion Erlaube Bluttransfusionen + Permetti Fleboclisi EV Zezwalaj na przetaczanie płynów IV Pose de perfusions autorisée pour 允許操作點滴 允许静脉输液 - IV 輸血の制限 + IV 輸液の制限 Povolit IV transfuzi - Разрешить внутривенное переливание + Доступ к внутривенному переливанию Permitir transfusión de IV 수액용기 사용 허가 Training level required to transfuse IVs. 'Fähigkeiten-Level', das benötigt wird, um Blut zu transfundieren. + Formazione richiesta per applicare Fleboclisi Endovenose. Poziom wyszkolenia potrzebny aby móc przetaczać płyny IV. Définit la qualification médicale requise pour poser des perfusions intraveineuses. 要有何種醫療水準才可注射點滴。 静脉输液所需的医疗水平。 - IV 輸血を行うのに訓練済レベルを要求とします。 + IV 輸液を行うのに必要な医療スキルのレベルを設定します。 Úroveň výcviku nutná pro IV transfuzi. Уровень навыка, требуемый для осуществления внутривенного переливания. Nivel de capacitación requerido para transfusiones de IV. @@ -917,23 +967,25 @@ Locations IV Transfusion - IV 輸血の場所制限 + IV輸液の可能な場所 Ubicación para transfusiones IV Lieux perfusions IV - Места введения пакетов внутривенного переливания + Места внутривенного переливания Miejsca do transfuzji IV Orte an denen IV-Transfusionen angelegt werden können + Luoghi Fleboclisi EV 静脉输液地点 수액용기 사용 장소 Controls where IV transfusions can be performed. - IV 輸血を行える場所を決定できます。 + IV 輸液を行える場所を制御します。 Controla dónde pueden ser realizadas las transfusiones IV. Définit les lieux où la pose de perfusions est autorisée. - Определяет к каким частям тела разрешено применять пакеты внутренного переливания. + Контролирует, где можно использовать внутревенное переливание. Kontroluje w jakich miejscach można robić transfuzje IV. Kontrolliert, wo IV-Transfusionen durchgeführt werden können. + Luoghi in cui è possibile applicare Fleboclisi Endovenose. 控制何地可以静脉输液 수액용기를 사용할 수 있는 장소를 정합니다. @@ -955,13 +1007,13 @@ Controls whether vanilla medical items are converted to ACE Medical items, removed only, or ignored. Legt fest, ob Standard Medic-Equipment in ACE-Equipment umgewandelt oder entfernt wird - ゲーム標準の医療アイテムをACE医療アイテムへ変換するか、削除するか、そのままにするかを決定します。 + ゲーム標準の医療アイテムをACE医療アイテムへ変換するか、削除するか、そのままにするかを制御します。 Détermine si les objets médicaux vanilla sont convertis en objets médicaux ACE, s'ils sont simplement retirés, ou s'ils sont ignorés. Определяет, что делать с ванильными медикаментами: преобразовать в медикаменты ACE, удалить или проигнорировать. Controla se itens médicos vanilla serão convertidos para itens do ACE, removidos ou ignorados. 控制是否轉換原版的醫療物資成ACE的醫療物資,或者單純移除或無視。 控制是否转换原版的医疗物品成 ACE 的医疗物品,或者单纯移除/无视。 - Controlla se gli articoli medicali vanilla vengono convertiti in articoli medicali ACE, rimossi o ignorati. + Controlla se gli oggetti medicali vanilla vengono convertiti in oggetti medicali ACE, rimossi o ignorati. Nastavuje zda zdravotnické předměty ze základní hry budou přeměněny na ACE předměty, odstraněny nebo ignorovány. Kontroluje, czy podstawowe przedmioty medyczne z Arma są konwertowane na przedmioty medyczne ACE, tylko usuwane lub ignorowane. Controla si los artículos médicos básicos se convierten en artículos médicos de ACE, solo se eliminan o se ignoran. @@ -975,7 +1027,7 @@ Apenas Remover 單純移除 仅移除 - Rimuovere solo + Rimuovi solo Pouze odstranit Tylko Usuwaj Nur Entfernen @@ -1007,7 +1059,7 @@ Permite a criação de lixo médico durante o tratamento. 啟用醫療後剩下的醫療用廢棄物。 启用在治疗后能够产生医疗垃圾。 - Permette la creazione di rifiuti al momento del trattamento. + Abilita la creazione di rifiuti al momento del trattamento. Umožňuje vytvořit odpadky při léčbě. Umożliwia tworzenie śmieci po przeprowadzaniu zabiegu. Ermöglicht das Produzieren von Abfall während einer Behandlung. @@ -1053,7 +1105,7 @@ Duração de Lixo 醫療用廢棄物時長 医疗垃圾寿命 - Tempo rifiuti + Tempo di presenza rifiuti Životnost odpadků Czas trwania Śmieci Abfall Anzeigedauer @@ -1063,7 +1115,7 @@ Controls the lifetime of litter objects, in seconds. -1 is forever. - 廃棄物の寿命を秒で決定できます。-1 にすると恒久的になります。 + 廃棄物の寿命を秒単位で制御します。-1 にすると恒久的になります。 Définit la durée d'affichage des détritus, en secondes. Durée illimitée : -1. Управляет временем жизни объектов мусора в секундах. -1 означает Навсегда. Controla o tempo de vida de objetos de lixo criados em segundos. -1 é para sempre. @@ -1164,6 +1216,7 @@ Szansa na powodzenie CPR - Minimum 心肺蘇生(CPR)の最低成功確率 HLW Minimale Erfolgschance + RCP - Prob. Successo Minima 心肺复苏的最低成功率 최소 심폐소생술 성공 가능성 RCP posibilidad mínima de resultado satisfactorio @@ -1175,6 +1228,7 @@ Szansa na powodzenie CPR - Maksimum 心肺蘇生(CPR)の最高成功確率 HLW Maximale Erfolgschance + RCP - Prob. Successo Massima 心肺复苏的最高成功率 최대 심폐소생술 성공 가능성 RCP posibilidad máxima de resultado satisfactorio @@ -1182,6 +1236,7 @@ Minimum probability that performing CPR will restore heart rhythm.\nThis minimum value is used when the patient has at least "Lost a fatal amount of blood".\nAn interpolated probability is used when the patient's blood volume is between the minimum and maximum thresholds. Probabilité minimale de rétablir un rythme cardiaque suite à une RCP.\nCette valeur minimale est définie pour un patient à l'état "A perdu une quantité critique de sang".\nUne interpolation est faite entre la chance minimale et maximale, en fonction du volume sanguin du patient. + Probabilità minima di successo per una RCP nel ristabilire il battito cardiaco.\nQuesto valore minimo è usato quando il paziente ha perso almeno una 'quantità fatale di sangue', una probabilità intermedia è usata per volumi di sangue intermedi. Минимальная вероятность того, что выполнение искусственного дыхания восстановит сердечный ритм.\nЭто минимальное значение используется, когда пациент, по крайней мере, получил статус "Фатальная кровопотеря".\n Интерполированная вероятность используется, когда объем крови пациента находится между минимальным и максимальным порогами. Minimalna wartość szansy na to że CPR przywróci bicie serca.\nTa minimalna wartość jest używana gdy pacjent ma status "Stracił krytyczną ilość krwi".\nInterpolowana wartość szansy jest używana gdy pacjent ma poziom krwi będący pomiędzy minimum a maksimum. 心肺蘇生(CPR)を行うことで脈拍が回復する最低成功確率を設定します。\nこの値は患者が"致命的な程失血している"時に使用されます。\n患者の血液量が最低値と最大値の間だった場合は、補完確率が適用されます。 @@ -1193,6 +1248,7 @@ Maximum probability that performing CPR will restore heart rhythm.\nThis maximum value is used when the patient has at most "Lost some blood".\nAn interpolated probability is used when the patient's blood volume is between the minimum and maximum thresholds. Probabilité maximale de rétablir un rythme cardiaque suite à une RCP.\nCette valeur maximale est définie pour un patient à l'état "A perdu une faible quantité de sang".\nUne interpolation est faite entre la chance minimale et maximale, en fonction du volume sanguin du patient. + Probabilità massima di successo per una RCP nel ristabilire il battito cardiaco.\nQuesto valore massimo è usato quando il paziente ha perso meno di 'un po' di sangue', una probabilità intermedia è usata per volumi di sangue intermedi. Максимальная вероятность того, что выполнение искусственного дыхания восстановит сердечный ритм.\nЭто максимальное значение используется, когда пациент, по крайней мере, получил статус "Фатальная кровопотеря".\n Интерполированная вероятность используется, когда объем крови пациента находится между минимальным и максимальным порогами. Maksymalna wartość szansy na to że CPR przywróci bicie serca.\nTa maksymalna wartość jest używana gdy pacjent ma status "Stracił trochę krwi".\nInterpolowana wartość szansy jest używana gdy pacjent ma poziom krwi będący pomiędzy minimum a maksimum. 心肺蘇生(CPR)を行うことで脈拍が回復する最高成功確率を設定します。\nこの値は患者が"いくらか失血している"時以上の場合に使用されます。\n患者の血液量が最低値と最大値の間だった場合は、補完確率が適用されます。 @@ -1204,7 +1260,8 @@ CPR Treatment Time RCP - Durée d'interaction - 心肺蘇生(CPR)の動作時間 + RCP - Durata di interazione + 心肺蘇生(CPR)の所要時間 Tiempo de tratamiento de RCP Время проведения СЛР Czas potrzebny na wykonanie CPR @@ -1215,7 +1272,8 @@ Time, in seconds, required to perform CPR on a patient. Définit le temps nécessaire à la mise en œuvre d'une RCP (en secondes). - 心肺蘇生(CPR)にかかる時間 (秒) を決定します。 + Tempo in secondi richiesto per effettuare RCP su un paziente. + 心肺蘇生(CPR)に掛かる時間。 (秒単位) Tiempo, en segundos, requerido para realizar RCP en un paciente. Время, необходимое для проведения сердечно-лёгочной реанимации (СЛР) (в секундах). Czas w sekundach jaki jest potrzebny do wykonania CPR na pacjencie. @@ -1239,13 +1297,13 @@ Controls whether weapons must be holstered / lowered in order to perform medical actions.\nExcept Exam options allow examination actions (checking pulse, blood pressure, response) at all times regardless of this setting. - 何らかの治療をするには武器を下げるか収めるかどうかを決定します。\nなお次の診断行動は設定で例外できます: 脈拍の確認、血圧の確認、反応の確認 + 何らかの治療をするには武器を下げるか収める必要があるかを設定します。\nなお次の診断行動は設定で例外できます: 脈拍の確認、血圧の確認、反応の確認 控制是否要先放下或把武器放入武器套才能做出醫療行為。\n除了診斷 - 允許未放下或未放入的情況下進行一連串的診斷(檢查脈搏,血壓,反應)。 控制是否要先放下或把武器放起才能做出医疗行为。\n除了诊断—允许未放下或未收起的情况下进行一连串的诊断(检查脉搏,血压,反应)。 Définit si les armes doivent être rengainées ou abaissées avant de pouvoir effectuer des actes médicaux.\nLes options "sauf examens" autorisent les examens (vérification du pouls, de la tension artérielle, de l'état de conscience) en toutes circonstances. Nastavuje zda musí být zbraň schovaná/snížená pro provádění zdravotnických úkonů.\nKromě Diagnózy - Umožňuje diagnostické akce (kontrola srdečního tepu, tlaku krve a reakci pacienta) vždy bez ohledu na nastavení schování zbraně. Kontroluje, czy broń musi być schowana/opuszczona w celu wykonania leczenia pacjenta.\n Za wyjątkiem diagnozowania - umożliwia wykonywanie czynności kontrolnych (sprawdzanie tętna, ciśnienia krwi, reakcji) przez cały czas, niezależnie od ustawienia Wymagana broń w kaburze. - Controlla se le armi devono essere tenute nella fondina / abbassate per poter eseguire le azioni mediche.\Except Exam - Permette azioni di esame (controllo del polso, della pressione sanguigna, della risposta) in ogni momento indipendentemente dall'impostazione della fondina richiesta. + Controlla se le armi devono essere tenute nella fondina / abbassate per poter eseguire le azioni mediche.\Eccetto l'esame - Permette azioni di esame (controllo del polso, della pressione sanguigna, della risposta) in ogni momento indipendentemente dall'impostazione della fondina richiesta. Kontrolliert, ob Waffen geholstert/gesenkt werden müssen, um medizinische Aktionen durchzuführen.\nAusgenommen die eingestellten Untersuchungsoptionen erlauben Diagnose-Aktionen (Überprüfung von Puls, Blutdruck, Reaktion) jederzeit. Нужно ли убирать оружие для проведения медицинских действий.\nОпция «Проверка разрешена» разрешает проверять пульс, кровяное давление или реакцию независимо от этого параметра. Controla si las armas deben estar enfundadas / bajadas para realizar acciones médicas. \n Excepto Las opciones de examen permiten acciones de examen (control del pulso, presión arterial, respuesta) en todo momento, independientemente de esta configuración. @@ -1257,7 +1315,7 @@ 放低或者收起 放低或者收起 Abaisser ou rengainer - Abbassato o con fondina + Abbassato o nella fondina Snížena nebo Schována Opuszczona lub w kaburze Gesenkt oder Geholstert @@ -1271,7 +1329,7 @@ 放低或者收起(除了診斷) 放低或者收起(除了诊断) Abaisser ou rengainer (sauf examens) - Abbassato o con la fondina (eccetto l'esame) + Abbassato o nella fondina (eccetto l'esame) Snížena nebo Schována (kromě Diagnózy) Opuszczona lub w kaburze (oprócz diagnozowania) Gesenkt oder Geholstert (Ausnahme Untersuchung) @@ -1285,7 +1343,7 @@ 只能收起 只能收起 Rengainer seulement - Solo con la fondina + Solo nella fondina Pouze Schována Tylko w Kaburze Nur geholstert @@ -1299,7 +1357,7 @@ 只能收起(除了診斷) 只能收起(除了诊断) Rengainer seulement (sauf examens) - Solo fondina (eccetto esame) + Solo nella fondina (eccetto esame) Pouze Schována (kromě Diagnózy) Tylko w Kaburze (oprócz diagnozowania) Nur geholstert (Ausnahme Untersuchung) @@ -1317,7 +1375,7 @@ [ACE] Caixa com suprimentos médicos [ACE] Caisse médicale (basique) [ACE] Orvosi láda (Alap) - [ACE] Cassa Rifornimenti Medici (Basico) + [ACE] Cassa Rifornimenti Medici (Basici) [ACE] 医療物資箱 (ベーシック) [ACE] 의료 물자 (기본) [ACE] 医疗补给箱(基础) @@ -1334,7 +1392,7 @@ [ACE] Caixa com suprimentos médicos (Avançados) [ACE] Caisse médicale (avancée) [ACE] Orvosi láda (Fejlett) - [ACE] Cassa Rifornimenti Medici (Avanzato) + [ACE] Cassa Rifornimenti Medici (Avanzati) [ACE] 医療物資箱 (アドバンスド) [ACE] 의료 물자 (고급) [ACE] 医疗补给箱(高级) @@ -1344,13 +1402,13 @@ Whether or not the object will be a medical vehicle. Czy pojazd ma być pojazdem medycznym? - L'oggetto in questione sarà un veicolo medico o meno. + Se l'oggetto in questione sarà un veicolo medico. Legt fest, ob das Objekt ein Sanitätsfahrzeug ist. Es un vehículo médico? Définit s'il s'agit d'un véhicule sanitaire. Se o objeto será ou não um veículo médico Будет ли объект считаться медицинским транспортом. - どれでも、またはオブジェクトを医療車両として割り当てます。 + 車両をを医療車両として割り当てます 이 물체는 의료 차량이 됩니다. 是否使该载具为医疗载具? 是否使該載具為醫療載具? @@ -1366,7 +1424,7 @@ Lékařský výcvik Treino médico Медицинская подготовка - 医療訓練 + ユニットの医療スキルのレベルを定義します。 의료 훈련 医疗训练 醫療訓練 @@ -1382,8 +1440,8 @@ É médico Qualification médicale Orvos-e - E' Medico - 衛生兵に + È Medico + 衛生兵にする 의무병 是医疗兵 是醫療兵 @@ -1399,8 +1457,8 @@ Ez a modul engedélyezi az orvosi jelző hozzárendelését kiválasztott egységekhez. Этот модуль позволяет назначить класс медика выбранным юнитам. Este módulo permite asignar la clase médico a las unidades seleccionadas. - Questo modulo ti permette di assegnare la classe Medico alle unità selezionate. - 選択されたユニットを衛生兵として指定します。 + Questo modulo ti permette di assegnare la classe di Medico alle unità selezionate. + このモジュールは選択されたユニットを衛生兵として指定します。 이 모듈로 선택한 유닛을 의무병으로 만들 수 있습니다. 本模块可让被同步的单位成为医疗兵 本模塊可讓被同步的單位成為醫療兵 @@ -1434,7 +1492,7 @@ Infirmier Hagyományos orvos Medico Regolare - 通常の衛生兵 + 一般衛生兵 의무병 普通医疗兵 普通醫療兵 @@ -1450,8 +1508,8 @@ É um veículo médico Est un véhicule sanitaire Orvosi jármű-e - E' Veicolo Medico - 医療車両に + È Veicolo Medico + 医療車両とする 의료 차량 是医疗载具 是醫療載具 @@ -1467,8 +1525,8 @@ É uma instalação médica Est une installation sanitaire Orvosi létesítmény-e - E' Struttura Medica - 医療施設に + È Struttura Medica + 医療施設とする 의료시설 是医疗设施 是醫療設施 @@ -1485,7 +1543,7 @@ Définit l'objet comme étant une installation sanitaire. Egy objektum orvosi létesítményként való regisztrálása Registra un oggetto come struttura medica - オブジェクトを医療施設として割り当てる + オブジェクトを医療施設として割り当てます 물체를 의료시설로 등록합니다 指定一个物体作为医疗设施 指定一個物件作為醫療設施 @@ -1501,7 +1559,7 @@ Médecin (uniquement en médecine avancée) Doktor (csak fejlett orvosok) Dottore (Solo Medici Avanzati) - 医師 (アドバンスド医療のみ) + 医師 (上級衛生兵のみ) 군의관 (오직 고급 의료에서만) 军医(只限进阶医疗系统) 軍醫 (只限進階醫療系統) @@ -1532,9 +1590,9 @@ Bandaż (jałowy) Obvaz (Standardní) Kötszer (Általános) - Bendaggio (base) + Bendaggio (Base) Bandagem(Básico) - 包帯 (緊急圧迫) + 包帯 (緊急圧迫止血) 붕대 (기본) 绷带(基础型) 基礎繃帶 @@ -1551,7 +1609,7 @@ Usato per coprire una ferita Usado para cobrir um ferimento Slouží k překrytí poranění - 傷を覆うために使用 + 傷を覆うために使用される 상처를 덮을 때 씁니다 用于覆盖伤口 用於覆蓋傷口 @@ -1565,10 +1623,10 @@ Pansement utilisé pour couvrir une blessure lorsque le saignement a été stoppé. Opatrunek materiałowy, używany do przykrywania ran, zakładany na ranę po zatamowaniu krwawienia. Egy különleges anyagú kötszer sebek betakarására, amelyet a vérzés elállítása után helyeznek fel. - Una benda apposita, utilizzata per coprire una ferita, la quale viene applicata su di essa una volta fermata l'emorragia. + Un bendaggio fatto apposta per coprire una ferita una volta fermata l'emorragia. Uma curativo, material específico para cobrir um ferimento que é aplicado assim que o sangramento é estancando. Obvaz je vhodným způsobem upravený sterilní materiál, určený k překrytí rány, případně k fixaci poranění. - 包帯(被覆材)とは、傷口を覆うためもので、傷口の上に貼ると出血を食い止める。 + 包帯(被覆材)、これは傷口を覆うためもので、傷口の上に貼ると出血を食い止める。 드레싱, 출혈을 막고서 상처를 덮기위해 쓰는 물건입니다. 用于覆盖伤口以防止出血,透过敷料的止血剂来让出血慢慢停止 用於覆蓋傷口以防止出血, 透過敷料的止血劑來讓出血慢慢停止 @@ -1582,7 +1640,7 @@ Bande compressive Bandaż (uciskowy) Nyomókötszer - Bendaggio compressivo + Bendaggio (Compressivo) Bandagem de Compressão Obvaz (Tlakový) 包帯 (弾性) @@ -1599,10 +1657,10 @@ Utilisée pour panser les moyennes et grosses plaies, et freiner le saignement. Używany w celu opatrywania średnich i dużych ran oraz tamowania krwawienia. Dobrze radzi sobie z tamowaniem ran płatowych oraz postrzałowych. Közepestől nagyig terjedő sebek betakarására és vérzés elállítására használt kötszer - Usato su ferite medie o larghe per fermare emorragie. + Usato su ferite medie o grandi per fermare emorragie. Usado para o preenchimento de cavidades geradas por ferimentos médios e grandes e estancar o sangramento. Používá se k zastavení středních až silnějších krvácení - 中程度から大きな傷の手当てと止血に使用 + 中程度から大きな傷の手当てと止血に使用される 중형 또는 대형 상처를 채우고 출혈을 막기 위해 쓰입니다, 用于包扎中到大型伤口,并防止出血 用於包紮中到大型傷口, 並防止出血 @@ -1615,7 +1673,7 @@ Pansement utilisé pour enrayer le saignement et faciliter la cicatrisation de la plaie.\nComprimer une blessure est une option intéressante en cas de grands polytraumatismes. Opatrunek stosowany w celu zatrzymania krwawienia i osłony większych ran. Egy kötszerfajta, melyet a sebek nyomására használnak a vérzés elállítása és sebgyógyulás érdekében. A nyomókötés egy lehetőség nagyobb polytraumatikus sérülések esetén. - Un bendaggio usato per coprire la ferita, fermare il sanguinamento e facilitarne la guarigione. Questa tecnica è opzionale su ferite multiple. + Un bendaggio usato per coprire la ferita, fermare il sanguinamento e facilitarne la guarigione. Comprimere la ferita è una delle opzioni per gestire ferite politraumatiche. Ein Verband, um die Wunde abzudecken und die Wundheilung zu fördern. Wunden abdecken ist eine Option bei größeren Polytraumen Uma bandagem usada para preencher o ferimento para estancar o sangramento e facilitar a cicatrização. Preenchimento de feridas é uma opção em ferimentos de politrauma grandes. Tlakový obvaz se skládá se ze sterilní krycí vrstvy, na kterou je přiložena silná vrstva savého materiálu stlačující cévu v ráně a která je přitlačována k ráně a připevněna obinadlem. Slouží k zastavení silnějších krvácení. @@ -1634,7 +1692,7 @@ Bandaż (elastyczny) Obvaz (Elastický) Rögzító kötszer - Benda (elastica) + Benda (Elastica) Bandagem (Elástica) 包帯 (伸縮) 붕대 (압박) @@ -1667,7 +1725,7 @@ Elastyczna opaska podtrzymująca opatrunek oraz usztywniająca okolice stawów. Brinda una compresión uniforme y ofrece soporte extra a una zona lesionada Egyenletes nyomást és támogatást biztosít a sebesült felületnek. - Permette di comprimere e aiutare la zone ferita. + Consente compressione uniforme e supporto aggiuntivo della zona ferita. Esta bandagem pode ser utilizada para comprimir o ferimento e diminuir o sangramento e garantir que o ferimento não abra em movimento. Hodí se k fixačním účelům a to i v oblastech kloubů. 負傷部位を均等に圧迫し、保護する。 @@ -1685,7 +1743,7 @@ Staza taktyczna (CAT) Škrtidlo (CAT) Érszorító (CAT) - Laccio emostatico (CAT) + Laccio Emostatico (CAT) Torniquete (CAT) 止血帯 (CAT) 지혈대 [CAT] @@ -1701,7 +1759,7 @@ Zmniejsza ubytek krwi z kończyn w przypadku krwawienia. Nie może być noszony zbyt długo ze względu na narastający ból z kończyny. Verringert den Blutverlust Lelassítja a vérvesztést vérzés esetén - Rallenta la perdita di sangue in caso di sanguinamento + Rallenta la perdita di sangue da un arto Reduz a velocidade da perda de sangue Zpomaluje ztráty krve při krvácení 出血時の失血を抑える @@ -1718,7 +1776,7 @@ Opaska uciskowa CAT służy do tamowanie krwotoków w sytuacji zranienia kończyn z masywnym krwawieniem tętniczym lub żylnym. Ein Hilfsmittel, das Druck auf Venen und Arterien ausübt und so den Blutfluss verringert. Egy szűkítőeszköz, mely a vénás és artériás nyomás keringés helyi összenyomására szolgál, ezzel lelassítva vagy megállítva az adott területen a vérkeringést. Ez csökkenti a vérvesztés mértékét. - Un laccio emostatico usato per comprimere le vene e arterie per bloccare o rallentare la circolazione del sangue e quindi rallentare dissanguamenti. + Un laccio emostatico usato per comprimere le vene e arterie per bloccare o rallentare la circolazione del sangue in un arto e quindi rallentare dissanguamenti. A aparelho que comprime as artérias e veias para diminuir a perda de sangue. Zařízení používané ke stlačení venózního a arteriálního oběhu. V důsledku dochází ke zpomalení toku krve a tedy i snížení ztrát krve. 静脈と動脈の循環を圧迫するために使用される収縮装置で、実質的に血流を抑制または減速させ、血液の損失を減少させる。 @@ -1730,7 +1788,7 @@ Splint Шина - 副子 + 添え木 Attelle Tala 固定板 @@ -1768,7 +1826,7 @@ Autostrzykawka z morfiną Auto-morfin Morfium autoinjektor - Autoiniettore di morfina + Autoiniettore di Morfina Auto-injetor de morfina モルヒネ自動注射器 자동주사기 (모르핀) @@ -1787,7 +1845,7 @@ Usato per combattere il dolore. Usado para combater dores moderadas e severas Slouží k tlumení středně těžkých a těžkých bolestí - 中等度から重度の痛みに対処するために使用 + 中等度から重度の痛みに対処するために使用される 심한 통증을 완화하는데 쓰입니다 用于削减中度至重度疼痛 減低中度至重度的疼痛感 @@ -1814,7 +1872,7 @@ Asenosina auto-inyectable Autostrzykawka z adenozyną Auto-injecteur d'adénosine - Autoiniettore di adenosina + Autoiniettore di Adenosina Auto-adenosine Auto-injetor de Adenosina Аденозин в пневмошприце @@ -1830,11 +1888,11 @@ Utilizada para contrarrestar los effectos de la Epinefrina Adenozyna. Stosowana do zwalczania efektów działania adrenaliny. Utilisé pour contrer les effets de l'épinéphrine. - Usato per contrastare l'effetto dell'epinefrina + Usato per contrastare l'effetto dell'Epinefrina Slouží jako protiváha Adrenalinu Usado para combater os efeitos da Epinefrina Используется для купирования эффектов адреналина - アドレナリンの作用に対抗するために使用 + アドレナリンの作用に対抗するために使用される 에피네프린 대응책으로 쓰입니다 用于中和肾上腺素的影响 用來對付腎上腺素的影響 @@ -1845,7 +1903,7 @@ Medicamento usado para contrarrestar los efectos de la Epinefrina. Organiczny związek chemiczny z grupy nukleozydów. Skuteczna w leczeniu częstoskurczu komorowego. Działa rozszerzająco na naczynia krwionośne. Un composé utilisé pour contrer les effets de l'épinéphrine. - Medicamento usato per contrastare l'effetto dell'epinefrina + Medicamento usato per contrastare l'effetto dell'Epinefrina Droga používaná k tlumení efektu Adrenalinu Uma droga usada para combater os efeitos da Epinefrina Препарат используется для купирования эффектов адреналина @@ -1863,7 +1921,7 @@ Atropin-Autoinjektor Auto-atropine Atropin autoinjektor - Autoiniettore di atropina + Autoiniettore di Atropina Auto-injetor de Atropina アトロピン自動注射器 자동주사기 (아트로핀) @@ -1882,7 +1940,7 @@ Usato in situazioni con gas nervino. Usado em casos de ataque QBRN Používá se v přítomnosti nervových plynů - 核兵器・生物兵器・化学兵器による汚染環境下で使用 + 核・生物・化学兵器(NBC)による汚染環境下で使用される 화생방 상황에 쓰입니다 使用于核生化污染的情况 使用於核生化汙染的情況 @@ -1898,7 +1956,7 @@ E' un farmaco usato in ambito militare in scenari con presenza di gas nervino. Uma droga usada por militares em casos de ataque QBRN. Atropin slouží jako protijed na otravu organofosfátovými insekticidy (diazinon) a nervovými plyny. - 軍が核兵器・生物兵器・化学兵器による汚染環境下で使用する薬物。 + 核・生物・化学兵器(NBC)による汚染環境下で軍が使用する薬品。 화생방 상황에 쓰이는 군용 약품 军用神经解毒针,用来应付核生化污染的情况。 軍用神經解毒針, 用來應付核生化汙染的情況. @@ -1912,7 +1970,7 @@ Epiniphrin-Autoinjektor Auto-adrenalin Epinefrin autoinjektor - Autoiniettore di adrenalina + Autoiniettore di Epinefrina Auto-injetor de epinefrina アドレナリン自動注射器 자동주사기 (에피네프린) @@ -1963,7 +2021,7 @@ Plasma EV (1000ml) Plasma IV (1000ml) Krevní plazma (1000ml) - 血しょう IV (1000ml) + 血漿 IV (1000ml) 혈장 IV (1000ml) 血浆(1000毫升) 血漿 (1000毫升) @@ -2011,7 +2069,7 @@ Plasma EV (500ml) Plasma IV (500ml) Krevní plazma (500ml) - 血しょう IV (500ml) + 血漿 IV (500ml) 혈장 IV (500ml) 血浆(500毫升) 點滴 (血漿 500毫升) @@ -2028,7 +2086,7 @@ Plasma EV (250ml) Plasma IV (250ml) Krevní plazma (250ml) - 血しょう IV (250ml) + 血漿 IV (250ml) 혈장 IV (250ml) 血浆(250毫升) 點滴 (血漿 250毫升) @@ -2126,7 +2184,7 @@ Sól fizjologiczna IV (1000ml) Kochsalzlösung (1000ml) 0,9%-os sósvíz-infúzió (1000ml) - Soluzione salina EV (1˙000ml) + Soluzione salina EV (1000ml) Soro IV (1000ml) Fyziologický roztok (1000ml) 生理食塩水 IV (1000ml) @@ -2158,7 +2216,7 @@ Un agent médical permettant de reconstituer le volume sanguin.\nÀ administrer par perfusion intraveineuse. Używany w medycynie w formie płynu infuzyjnego jako środek nawadniający i uzupełniający niedobór elektrolitów, podawany dożylnie (IV). Egy orvosi térfogat-helyreállító készítmény, melyet intravénás módon lehet a szervezetbe juttatni. - Una soluzione medica per ripristinare il volume del sangue introdotta tramite trasfusione EV. + Una soluzione medica per ripristinare il volume del sangue, introdotta tramite trasfusione EV. Ein medizinisches Volumenersatzmittel, dass durch einen intravenösen Zugang in den Blutkreislauf verabreicht wird. Uma reposição temporaria para restaurar a pressão arterial perdida por perda de sangue. Fyziologický roztok se využívá nejčastěji jako infuze při dehydrataci organismu. @@ -2209,7 +2267,7 @@ Opatrunek QuikClot ACS Bandage (QuikClot) Általános zárókötszer (QuikClot) - Bendaggio emostatico (QuikClot) + Bendaggio Emostatico (QuikClot) Bandagem básica (Coagulante) Hemostatický obvaz (QuikClot) 包帯 (クイッククロット) @@ -2225,7 +2283,7 @@ Proszkowy opatrunek adsorbcyjny przeznaczony do tamowania zagrażających życiu krwawień średniej i dużej intensywności. Bandage mit Gerinnungsmittel QuikClot kötszer - Bendaggio emostatico (QuikClot) + Bendaggio Emostatico (QuikClot) Bandagem com agente coagulante Hemostatický obvaz (QuikClot) クイッククロット包帯 @@ -2258,10 +2316,10 @@ Apteczka osobista Persönliches Erste-Hilfe-Set Elsősegélycsomag - Pronto soccorso personale + Kit di Pronto Soccorso (PAK) Kit De Primeiros Socorros Pessoal Osobní lékárnička (PAK) - 個人用応急処置キット + 個人用治療キット (PAK) 개인응급키트 个人急救包 個人急救包 @@ -2278,7 +2336,7 @@ Include vario materiale medico per trattamenti avanzati. Inclui vários tratamentos materiais para custura e tratamento avançado Osobní lékárnička obsahuje zdravotnický materiál umožňující šití a pokročilejší ošetřování raněných - 縫合や高度な処置に必要とされる、様々な治療器具が含まれています。 + 縫合や高度な処置に必要とされる様々な治療器具が含まれている 봉합 및 고급 조치에 필요한 다양한 치료 도구가 있습니다. 包含各种医疗套件,以及进阶伤口系统需要的缝合用品 包含各種醫療套件, 以及進階傷口系統需要的縫合用品 @@ -2295,7 +2353,7 @@ Kit de primeiros socorros para sutura ou tratamentos avançados Osobní lékárnička obsahuje zdravotnický materiál umožňující šití a pokročilejší ošetřování raněných v poli Pronto soccorso personale da campo per mettersi i punti o per trattamenti avanzati. - 戦場で縫合や高度な処置に必要とされる、様々な治療器具が含まれています。 + 個人用治療キット (PAK) は戦場での縫合や高度な処置に必要です 야전에서 봉합 및 고급 조치를 위한 개인응급키트 个人急救包可用于战地缝合手术或进阶伤口系统使用 個人急救包可用於戰地縫合手術或進階醫療用 @@ -2311,8 +2369,8 @@ Elsősegélycsomag használata Usar o kit de primeiros socorros Použít osobní lékárničku (PAK) - Usa il pronto soccorso personale - 個人用応急処置キットを使う + Usa il Kit di Pronto Soccorso (PAK) + 個人用治療キットを使う 개인응급키트 사용 使用个人急救包 使用個人急救包 @@ -2329,7 +2387,7 @@ Kit chirurgico Kit Cirurgico Chirurgická sada - 手術用キット + 手術キット 봉합 키트 手术包 手術包 @@ -2346,7 +2404,7 @@ Kit chirurgico per trattamenti avanzati sul campo. Kit Cirurgico para uso de tratamento médico avançado em campo Chirurgická sada určená k pokročilejším zdravotnickým zákrokům v poli - 手術用キットは戦場で高度な処置をする為に使われます。 + 手術キットは戦場で高度な処置をする為に用いる 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) 用於在戰場上為傷口進行縫合 @@ -2363,7 +2421,7 @@ Kit chirurgico per trattamenti avanzati sul campo. Kit Cirurgico para uso de tratamento médico avançado em campo. Chirurgická sada určená k pokročilejším zdravotnickým zákrokům v poli - 手術用キットは戦場で高度な処置をする為に使われます。 + 手術キットは戦場で高度な処置をする為に用いる 야전 상황에서 고급 의료 처치를 위해 사용되는 봉합 키트 用于在战场上为伤口进行缝合(需要开启进阶伤口系统) 用於在戰場上為傷口進行縫合 @@ -2379,8 +2437,8 @@ Usar equipo quirúrgico Sebészeti készlet használata Použít chirurgickou sadu - Usar kit cirúrgico - 手術用キットを使う + Usar Kit Cirúrgico + 手術キットを使う 봉합키트 사용하기 使用手术包 使用手術包 @@ -2389,29 +2447,35 @@ Suture Naht + Sutura Sutura 糸付縫合針 Szew 봉합술 Suture + Нить Surgical Suture for stitching injuries. Chirurgisches Nahtmaterial zum Nähen von Wunden. + Sutura chirurgica per cucire ferite. Sutura quirúrjica para heridas de puntos. 傷害縫合用の外科糸付縫合針。 Szew chirurgiczny do zszywania ran. 상처를 꿰메는 수술용 봉합술. Suture chirurgicale pour suturer les blessures. + Хирургическая нить для зашивания травм. Surgical Suture for stitching injuries. Chirurgisches Nahtmaterial zum Nähen von Wunden. + Sutura chirurgica per cucire ferite. Sutura quirúrjica para heridas de puntos. 傷害縫合用の外科糸付縫合針。 Szew chirurgiczny do zszywania ran. 상처를 꿰메는 수술용 봉합술. Suture chirurgicale pour suturer les blessures. + Хирургическая нить для зашивания травм. Bodybag @@ -2424,7 +2488,7 @@ Sacca per corpi Saco para cadáver Pytel na mrtvoly - 死体袋 + 遺体袋 시체 운반용 부대 尸袋 屍袋 @@ -2438,10 +2502,10 @@ Worek do pakowania zwłok Ein Leichensack für Tote Egy hullazsák a holttestek számára - Una sacca nera per trasportare cadaveri. + Una sacca per trasportare cadaveri. Um saco para corpos mortos Pytel na mrtvoly - 死体袋は死体を入れる為に使います。 + 死体のための遺体袋 시체를 운반할 때 쓰는 가방입니다 用于装尸体 用來裝屍體用 @@ -2455,10 +2519,10 @@ Worek do pakowania zwłok Ein Leichensack für Tote Egy hullazsák a holttestek számára - Una sacca nera per trasportare cadaveri. + Una sacca per trasportare cadaveri. Um saco para corpos mortos. Pytel na mrtvoly - 死体袋は死体を入れる為に使います。 + 死体のための遺体袋 시체를 운반할 때 쓰는 가방입니다 用于装尸体 用來裝屍體用 @@ -2487,7 +2551,7 @@ Inyectar Adenosina Wstrzyknij adenozynę Adénosine - Inietta andenosina + Inietta Adenosina Aplikovat adenosine Injetar Adenosina Ввести аденозин @@ -2506,7 +2570,7 @@ Atropine Ввести атропин Atropin beadása - Inietta atropina + Inietta Atropina Injetar Atropina アトロピンを注射 아트로핀 주사하기 @@ -2524,7 +2588,7 @@ Ввести адреналин Epinefrin beadása Injetar Epinefrina - Inietta adrenalina + Inietta Epinefrina アドレナリンを注射 에피네프린 주사하기 注射肾上腺素 @@ -2541,7 +2605,7 @@ Morphine Morfium beadása Injetar Morfina - Inietta morfina + Inietta Morfina モルヒネを注射 모르핀 주사하기 注射吗啡 @@ -2559,7 +2623,7 @@ Infúzió (vér) Transfundir Sangue Trasfusione di sangue - 輸血用血液を投与 + 血液を投与 혈액 수혈 输入血液 輸血液 @@ -2576,7 +2640,7 @@ Infúzió (vérplazma) Trasfusione di plasma Transfundir Plasma - 血しょうを投与 + 血漿を投与 혈장 수혈 输入血浆 輸血漿 @@ -2745,7 +2809,7 @@ Injection (morphine)... Morfium beadása... Injetando Morfina... - Inietto la morfina... + Iniettando Morfina... モルヒネを投与しています・・・ 모르핀 주사 중... 正在注射吗啡... @@ -2762,7 +2826,7 @@ Injection (épinéphrine)... Epinefrin beadása... Injetando Epinefrina... - Inietto l'adrenalina... + Iniettando Epinefrina... アドレナリンを投与しています・・・ 에피네프린 주사 중... 正在注射肾上腺素... @@ -2775,7 +2839,7 @@ Inyectando Adenosina... Wstrzykiwanie adenozyny... Injection (adénosine)... - Inietto l'andenosina + Iniettando Adenosina... Aplikuji adenosine... Injetando Adenosina... Введение аденозина... @@ -2794,7 +2858,7 @@ Injection (atropine)... Введение атропина... Atropin beadása... - Inietto l'atropina... + Iniettando Atropina... Injetando Atropina アトロピンを投与しています・・・ 아트로핀 주사 중... @@ -2813,7 +2877,7 @@ Infúzió vérrel... Transfundindo Sangue... Effettuo la trasfusione di sangue... - 輸血用血液を投与しています・・・ + 血液を投与しています・・・ 혈액 수혈 중... 正在输入血液... 輸血液中 ... @@ -2828,7 +2892,7 @@ Transfusion (solution saline)... Переливание физраствора... Infúzió sós vizzel... - Effettuo la rasfusione di soluzione salina + Effettuo la trasfusione di soluzione salina Transfundindo Soro... 生理食塩水を投与しています・・・ 생리식염수 수혈 중... @@ -2845,9 +2909,9 @@ Transfusion (plasma)... Переливание плазмы... Infúzió vérplazmával... - Effettu la trasfusione di plasma... + Effettuo la trasfusione di plasma... Transfundindo Plasma... - 血しょうを投与しています・・・ + 血漿を投与しています・・・ 혈장 수혈 중... 正在输入血浆... 輸血漿中 ... @@ -2860,7 +2924,7 @@ Bandażowanie... Obvazuji... Pansement... - Sto bendando... + Bendando... Bekötözés... Atando... Перевязывание... @@ -2879,8 +2943,8 @@ Pose du garrot... Наложение жгута... Érszorító felhelyezése... - Sto applicando il laccio emostatico... - Applicando Torniquete + Applicando il laccio emostatico... + Aplicando Torniquete... 止血帯を巻いています・・・ 지혈대 적용 중... 正在使用止血带... @@ -2896,9 +2960,9 @@ Bandaż jałowy Pansement individuel Zárókötszer - Bendaggio rapido + Bendaggio Rapido Curativo de Campo - 包帯を巻く (緊急圧迫包帯) + 緊急圧迫止血包帯 붕대 (기본) 绷带(基础型) 基礎繃帶 @@ -2910,11 +2974,11 @@ Компресионный пакет Bandaż uciskowy Nyomókötszer - Bendaggio compressivo + Bendaggio Compressivo Bandage compressif Bandagem de Compressão Obvaz Tlakový - 包帯を巻く (弾性包帯) + 弾性包帯 붕대 (거즈) 绷带(包扎型) 包紮繃帶 @@ -2929,9 +2993,9 @@ Bandaż elastyczny Bandage extensible Rögzitő kötszer - Bendaggio elastico + Bendaggio Elastico Bandagem Elástica - 包帯を巻く (伸縮包帯) + 伸縮包帯 붕대 (압박) 绷带(弹性型) 彈性繃帶 @@ -2946,9 +3010,9 @@ QuikClot Bandage hémostatique QuikClot - QuikClot (polvere emostatica) + Bendaggio Emostatico (QuikClot) QuikClot - 包帯を巻く (クイッククロット) + クイッククロット 붕대 (퀵 클롯) 绷带(止血型) 止血粉 @@ -2979,7 +3043,7 @@ Sprawdź ciśnienie krwi Prendre la tension Vérnyomás megmérése - Controlla pressionsa sanguigna + Controlla pressione sanguigna Checar Pressão Arterial 血圧を確認 혈압 확인 @@ -3013,9 +3077,9 @@ Staza Garrot Érszorító - Laccio emostatico + Laccio Emostatico Torniquete - 止血帯を巻く + 止血帯 지혈대 止血带 軍用止血帶 @@ -3041,7 +3105,7 @@ Apply Splint Наложить Шину - 副子を当てる + 添え木を当てる Poser une attelle Aplicar Tala 套上固定板 @@ -3057,7 +3121,7 @@ Applying Splint... Накладывается Шина... - 副子を当てています・・・ + 添え木を当てています・・・ Application de l'attelle... Aplicando Tala... 套用固定板中... @@ -3115,7 +3179,7 @@ Újraélesztés CPR RCP - 心肺蘇生(CPR)する + 心肺蘇生(CPR) 심폐소생술 心肺复苏(CPR) 心肺復甦術 @@ -3147,7 +3211,7 @@ Sang en IV (1000 ml) Podat krev. transfúzi (1000ml) Vér adása intravénásan (1000ml) - Effettua trasfusione sangue EV (1˙000ml) + Effettua trasfusione Sangue EV (1000ml) Administrar Sangue IV (1000ml) 血液 IV (1000ml) を投与 IV 혈액 수혈 (1000ml) @@ -3164,7 +3228,7 @@ Sang en IV (500 ml) Podat krev. transfúzi (500ml) Vér adása intravénásan (500ml) - Effettua trasfusione sangue EV (500ml) + Effettua trasfusione Sangue EV (500ml) Administrar Sangue IV (500ml) 血液 IV (500ml) を投与 IV 혈액 수혈 (500ml) @@ -3181,7 +3245,7 @@ Sang en IV (250 ml) Podat krev. transfúzi (250ml) Vér adása intravénásan (250ml) - Effettua trasfusione sangue EV (250ml) + Effettua trasfusione Sangue EV (250ml) Administrar Sangue IV (250ml) 血液 IV (250ml) を投与 IV 혈액 수혈 (250ml) @@ -3198,9 +3262,9 @@ Plasma en IV (1000 ml) Podat plazmu (1000ml) Vérplazma adása intravénásan (1000ml) - Effettua trasfusione plasma EV (1˙000ml) + Effettua trasfusione Plasma EV (1˙000ml) Administrar Plasma IV (1000ml) - 血しょう IV (1000ml) を投与 + 血漿 IV (1000ml) を投与 IV 혈장 수혈 (1000ml) 静脉注射血浆(1000毫升) 輸血漿 (1000毫升) @@ -3215,9 +3279,9 @@ Plasma en IV (500 ml) Podat plazmu (500ml) Vérplazma adása intravénásan (500ml) - Effettua trasfusione plasma EV (500ml) + Effettua trasfusione Plasma EV (500ml) Administrar Plasma IV (500ml) - 血しょう IV (500ml) を投与 + 血漿 IV (500ml) を投与 IV 혈장 수혈 (500ml) 静脉注射血浆(500毫升) 輸血漿 (500毫升) @@ -3232,9 +3296,9 @@ Plasma en IV (250 ml) Podat plazmu (250ml) Vérplazma adása intravénásan (250ml) - Effettua trasfusione plasma EV (250ml) + Effettua trasfusione Plasma EV (250ml) Administrar Plasma IV (250ml) - 血しょう IV (250ml) を投与 + 血漿 IV (250ml) を投与 IV 혈장 수혈 (250ml) 静脉注射血浆(250毫升) 輸血漿 (250毫升) @@ -3249,7 +3313,7 @@ Solution saline en IV (1000 ml) Podaz fyz. roztok (1000ml) Sós víz adása intravénásan (1000ml) - Effettua trasfusione salina EV (1˙000ml) + Effettua trasfusione Salina EV (1000ml) Administrar Soro IV (1000ml) 生理食塩水 IV (1000ml) を投与 IV 생리식염수 수혈 (1000ml) @@ -3266,7 +3330,7 @@ Solution saline en IV (500 ml) Podaz fyz. roztok (500ml) Sós víz adása intravénásan (500ml) - Effettua trasfusione salina EV (500ml) + Effettua trasfusione Salina EV (500ml) Administrar Soro IV (500ml) 生理食塩水 IV (500ml) を投与 IV 생리식염수 수혈 (500ml) @@ -3283,7 +3347,7 @@ Solution saline en IV (250 ml) Podaz fyz. roztok (250ml) Sós víz adása intravénásan (250ml) - Effettua trasfusione salina EV (250ml) + Effettua trasfusione Salina EV (250ml) Administrar Soro IV (250ml) 生理食塩水 IV (250ml) を投与 IV 생리식염수 수혈 (250ml) @@ -3386,7 +3450,7 @@ Normális légzés Respiro normale Respiração normal - 正常な呼吸をしている + 呼吸は正常 정상 호흡 呼吸正常 呼吸正常 @@ -3401,7 +3465,7 @@ Brak oddechu Nedýchá Nincs légzés - Mancanza di respiro + Assenza di respiro Não respira 呼吸をしていない 호흡 불가 @@ -3435,7 +3499,7 @@ Prawie brak oddechu Skoro nedýchá Alig van légzés - Respira a fatica + Quasi nessuna respirazione Quase não respira ほとんど呼吸をしていない 호흡이 없음 @@ -3448,8 +3512,11 @@ Nie odczuwa bólu 고통 없음 Pas de douleur + Nessun dolore Kein Schmerz 痛みはない + Нет боли + Sin dolor In mild pain @@ -3459,7 +3526,7 @@ Légère douleur Com dor leve 中度疼痛中 - Con un dolore leggero + Con dolore leggero V mírných bolestech W łagodnym bólu Con dolor leve @@ -3490,7 +3557,7 @@ Douleur intense Com dor intensa 嚴重疼痛中 - Con un forte dolore + Con forte dolore Ve velkých bolestech W silnym bólu Con dolor severo @@ -3506,7 +3573,7 @@ Staza [CAT] Škrtidlo [CAT] Érszorító [CAT] - Laccio emostatico [CAT] + Laccio Emostatico [CAT] Torniquete [CAT] 止血帯 [CAT] 지혈대 [CAT] @@ -3514,29 +3581,64 @@ 軍用止血帶 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] + Принимается физраствор [%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] + Принимается кровь [%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] + Принимается плазма [%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 Brak podpiętego IV 수혈 없음 Pas de transfusion + Nessuna Flebo EV Kein IV IV なし + Нет капельницы + Sin IV Blood Pressure @@ -3575,7 +3677,7 @@ %1 checked Blood Pressure: %2 %1 kontrollierte Blutdruck: %2 - %1 controllata pressione sanguigna: %2 + %1 ha controllato pressione sanguigna: %2 %1 проверил артериальное давление: %2 %1 a mesuré la tension : %2. %1 sprawdził ciśnienie krwi: %2 @@ -3583,8 +3685,8 @@ %1 ellenőrizte a vérnyomást: %2 %1 zkontroloval krevní tlak: %2 %1 verificou pressão arterial: %2 - %1 が測定した血圧: %2 - %1 (이)가 혈압을 측정했습니다: %2 + %1 が血圧を確認: %2 + %1(이)가 혈압을 측정했습니다: %2 %1 测得血压为 %2 已由%1確認血壓: %2 @@ -3616,7 +3718,7 @@ Der Blutdruck liegt bei %2/%3 A Pressão Arterial é de %2/%3 Naměřil si krevní tlak u %2/%3 - 血圧は %2/%3 + 計測した血圧数は %2/%3 でした 혈압이 %2/%3 입니다 血压为 %2/%3 血壓為%2/%3 @@ -3633,7 +3735,7 @@ La pressione sanguigna è bassa Pressão Arterial baixa Naměřil si nízký krevní tlak - 血圧は低い + 血圧が 低い ことを確認した 혈압이 매우 낮습니다 血压低 發現到低血壓 @@ -3650,7 +3752,7 @@ La pressione sanguigna è normale Pressão Arterial normal Naměřil si normální krevní tlak - 血圧は正常 + 血圧が 正常 なことを確認した 혈압이 정상입니다 血压正常 發現到正常血壓 @@ -3667,7 +3769,7 @@ La pressione sanguigna è alta Pressão Arterial Alta Naměřil si vysoký krevní tlak - 血圧は高い + 血圧が 高い ことを確認した 혈압이 매우 높습니다 血压高 發現到高血壓 @@ -3684,7 +3786,7 @@ La pressione sanguigna è assente Sem Pressão Arterial Nenaměřil si žádný krevní tlak - 血圧はありません + 血圧が ない ことを確認した 혈압이 잡히지 않습니다 血压为零 量不到血壓 @@ -3698,10 +3800,10 @@ Nie udało Ci się sprawdzić ciśnienia krwi Du konntest keinen Blutdruck feststellen Nem sikerült a vérnyomás megmérése - Manca strumento per misurare pressione sanguigna + Non puoi misurare la pressione sanguigna Você falhou em aferir a Pressão Arterial Nedokázal si změřit krevní tlak - 血圧を測るのに失敗した + 血圧の計測に失敗した 혈압을 측정하는데 실패했습니다 无法测得血压 檢查血壓的動作失敗 @@ -3828,7 +3930,7 @@ %1 checked Heart Rate: %2 %1 kontrollierte Herzfrequenz: %2 - %1 Controllata Frequenza Cardiaca: %2 + %1 ha controllato il polso: %2 %1 проверил пульс: %2 %1 a vérifié le pouls : %2. %1 sprawdził tętno: %2 @@ -3836,8 +3938,8 @@ %1 ellenőrizte a szívverés-számot: %2 %1 zkontroloval srdeční tep: %2 %1 verificou a frequência cardíaca: %2 - %1 が測定した心拍数: %2 - %1 (이)가 맥박을 측정했습니다: %2 + %1 が心拍を確認: %2 + %1(이)가 맥박을 측정했습니다: %2 %1 测得心率为 %2 已由%1確認心跳: %2 @@ -3920,8 +4022,8 @@ Il battito cardiaco è %2 A Frequência Cardíaca é de %2 Nahmatal jsi srdeční tep u %2 - 心拍数は %2 - 맥박이 %2 입니다 + 計測した心拍数は %2 でした + 맥박은 %2 입니다 心率为 %2 心跳為%2 @@ -3936,7 +4038,7 @@ Hai riscontrato un debole battito cardiaco Frequência Cardíaca baixa Nahmatal jsi slabý srdeční puls - 心拍は弱い + 心拍が 弱い ことを確認した 약한 맥박입니다 心率微弱 心跳微弱 @@ -3953,7 +4055,7 @@ Hai riscontrato un forte battito cardiaco Frequência Cardíaca normal Nahmatal jsi silný srdeční puls - 心拍は強い + 心拍が 強い ことを確認した 강한 맥박입니다 心率过快 心跳過快 @@ -3970,7 +4072,7 @@ Hai riscontrato un normale battito cardiaco Frequência Cardíaca alta Nahmatal jsi normální srdeční puls - 心拍は正常 + 心拍が 正常 なことを確認した 보통 맥박입니다 心率正常 心跳正常 @@ -3987,7 +4089,7 @@ Hai riscontrato una assenza di battito cardiaco Sem Frequência Cardíaca Žádný puls - 心拍はありません + 心拍が ない ことを確認した 맥박을 찾을 수가 없습니다 无法测得心率 量不到心跳 @@ -4036,8 +4138,8 @@ %1 è cosciente %1 está respondendo %1 odpovídá - %1 は反応あり - %1 은 반응이 있습니다 + %1 は反応している + %1은(는) 반응이 있습니다 %1 有反应 %1 有反應 %1 tepki veriyor @@ -4053,34 +4155,60 @@ %1 non risponde %1 não está respondendo %1 neodpovídá - %1 の反応なし - %1 은 반응이 없습니다 + %1 は反応していない + %1은(는) 반응이 없습니다 %1 没有反应 %1 沒有反應 %1 tepki vermiyor + + %1 is unconscious + %1 は意識がない + %1 находится без сознания + %1은(는) 의식불명입니다 + %1 ist bewusstlos + %1 è privo di sensi + %1 is not responsive, taking shallow gasps and convulsing %1 est inconscient, respire par intermittence et convulse. %1 jest nieresponsywny, ma płytki oddech oraz jest w konwulsjach - %1 は反応せず、浅い呼吸とけいれんをしている + %1 は反応していない、 浅く呻きながら痙攣している %1 reagiert nicht, schnappt nach Luft und verkrampft + %1 non risponde, ha convulsioni e prende respiri deboli %1没有反应,微软的喘着气和抽搐 %1 은 반응이 없고, 얕은 헐떡임과 경련증세를 보입니다 %1 не реагирует на раздражители, поверхностно дышит, в конвульсиях %1 no responde, dando pequeñas bocanadas y convulsionando + + %1 is in cardiac arrest + %1 は心停止している + У %1 произошла остановка сердца + %1은(는) 심정지 상태입니다 + %1 ist im Herzstillstand + %1 è in arresto cardiaco + %1 is not responsive, motionless and cold %1 est inconscient, inanimé et froid. %1 jest nieresponsywny, nieruchomy oraz zimny - %1 は反応せず、動かず冷たくなっている + %1 は反応していない、 動かず冷たくなっている %1 reagiert nicht, ist regungslos und kalt + %1 non risponde, è immobile e freddo %1没有反应,一动不动,身体冰凉 %1 은 반응이 없고, 움직임이 없으며 차갑습니다 %1 не реагирует на раздражители, не шевелится и холодный %1 no responde, sin movimiento y frío + + %1 is dead + %1 は死亡している + %1 мертв + %1은(는) 사망했습니다 + %1 ist tod + %1 è morto + You checked %1 Вы осмотрели раненого %1 @@ -4109,7 +4237,7 @@ A páciens, %1,<br/>%2.<br/>%3.<br/>%4 Pacient %1<br/>je %2.<br/>%3.<br/>%4 Paciente %1<br/>é %2.<br/>%3.<br/>%4 - 患者 %1<br/>は %2.<br/>%3.<br/>%4 + 患者 %1 は<br/>%2している。<br/>%3。<br/>%4。 환자 %1<br/>는 %2.<br/>%3.<br/>%4 伤员 %1 <br/> %2 <br/> %3 <br/> %4 傷者 %1<br/>is %2.<br/>%3.<br/>%4 @@ -4159,7 +4287,7 @@ Valamennyi vért vesztett Ztratil trochu krve Ele perdeu um pouco de sangue - 患者は出血している + 彼は出血している 적은 양의 피를 잃었다 他轻微失血 他流失一些血液 @@ -4176,7 +4304,7 @@ Ztratil hodně krve Ele perdeu muito sangue Ha perso molto sangue - 患者は大量失血している + 彼は大量失血している 많은 양의 피를 잃었다 他大量失血 他流失大量血液 @@ -4193,7 +4321,7 @@ Nem vesztett vért Neztratil žádnou krev Ele não perdeu sangue - 患者は失血していない + 彼は失血していない 피를 잃지 않았다 他没有失血 他並沒有失血 @@ -4201,7 +4329,7 @@ He is in pain - Sente dolori + Sente dolore Испытывает боль Er hat Schmerzen Il souffre @@ -4210,7 +4338,7 @@ Fájdalmai vannak Je v bolestech Ele está com dor - 患者は痛みを感じている + 彼は痛みを感じている 통증이 있다 他感到疼痛 他感到疼痛中 @@ -4218,7 +4346,7 @@ He is not in pain - Non sente dolori + Non sente dolore Не испытывает боли Er hat keine Schmerzen Il ne souffre pas @@ -4227,7 +4355,7 @@ Nincsenek fájdalmai Nemá žádné bolesti Ele não está com dor - 患者は痛みを感じていない + 彼は痛みを感じていない 통증이 없다 他没有感到疼痛 他沒感到疼痛中 @@ -4244,7 +4372,7 @@ verbunden Enfaixado Obvázaný - 包帯 + 包帯を巻いた 붕대 감음 包扎 繃帶 @@ -4261,7 +4389,7 @@ Du verbindest %1 (%2) Você aplica bandagem no paciente %1 (%2) Obvazuješ %1 (%2) - %1 (%2) 包帯を使った + あなたは %1 (%2) に包帯を使用した %1 (%2) 붕대를 감았다 你正在使用 %2 包扎 %1 你正在對 %1 (%2) 包紮繃帶中 @@ -4327,7 +4455,7 @@ Controlli le vie respiratorie di %1 Você entuba o %1 Ošetřuješ dýchací cesty %1 - %1 の気道を診断する + あなたは %1 の気道を処置した %1의 기도를 확보했다 你正在治疗 %1 的呼吸道 你治療 %1 的呼吸道 @@ -4361,7 +4489,7 @@ %1 ti sta trattando le vie respiratorie %1 está te entubando %1 ošetřuje tvoje dýchací cesty - %1 はあなたの気道を見ている + %1 があなたの気道を治療中 %1 (이)가 나의 기도를 확보 중이다 %1 正在治疗你的呼吸道 %1 正在治療你的呼吸道 @@ -4411,7 +4539,7 @@ Déposer Elengedés Soltar - Rrilascia + Rilascia 離す 내려놓기 放下 @@ -4479,7 +4607,7 @@ %1<br/>caricato su<br/>%2 %1<br/>berakodva ide:<br/>%2 %1<br/>загружен в<br/>%2 - %1<br/>は<br/>%2へ積み込まれました + %1 は<br/>%2 へ<br/>積み込まれました %1<br/>(은)는<br/>%2 에 실림 %1<br/>裝載至<br/>%2 %1<br/>装载至<br/>%2 @@ -4495,7 +4623,7 @@ Hai scaricato<br/>%1 da<br/>%2 1%<br/>kirakodva ebből:<br/>%2 %1<br/>разгружен из<br/>%2 - <br/>%1が<br/>%2から降ろされました + %1 が<br/>%2 から<br/>降ろされました %1<br/>(은)는<br/>%2 에서 내려짐 從<br/>%2卸載<br/>%1 从<br/>%2卸载<br/>%1 @@ -4509,7 +4637,9 @@ Colocar corpo dentro do saco para cadáver preto Umístit tělo do černého pytle na mrtvoly Vücudu siyah ceset torbasına yerleştir - 黒い死体袋に入れる + 遺体袋 (黒) に入れる + 시체를 검은 시체가방에 놓기 + Положить тело в черный мешок для тела Place body in blue bodybag @@ -4520,7 +4650,9 @@ Colocar corpo dentro do saco para cadáver azul Umístit tělo do modrého pytle na mrtvoly Vücudu mavi ceset torbasına yerleştir - 青い死体袋に入れる + 遺体袋 (青) に入れる + 시체를 파란 시체가방에 놓기 + Положить тело в синий мешок для тела Place body in white bodybag @@ -4531,7 +4663,9 @@ Colocar corpo dentro do saco para cadáver branco Umístit tělo do bílého pytle na mrtvoly Vücudu beyaz ceset torbasına yerleştir - 白い死体袋に入れる + 遺体袋 (白) に入れる + 시체를 흰 시체가방에 놓기 + Положить тело в белый мешок для тела Placing body in bodybag... @@ -4544,7 +4678,7 @@ Stai mettendo il corpo nella sacca... Colocando corpo dentro do saco para cadáver... Umisťuji tělo do pytle na mrtvoly... - 死体袋へ入れています・・・ + 遺体袋へ入れています・・・ 시체 운반용 부대에 담는 중... 正在将尸体装入尸袋... 將屍體放入屍袋中... @@ -4556,7 +4690,10 @@ Wykop grób na ciało Enterrer le corps Grabe ein Grab für den Leichnam + Scava tomba per cadavere 墓を掘る + Выкопать могилу для тела + Cavar tumba para cuerpo Digging grave for body... @@ -4564,7 +4701,10 @@ Kopanie grobu... Enterrement du corps... Grab für Leichnam ausheben ... + Scavando tomba per cadavere... 墓を掘っています + Рытьё могилы для тела... + Cavando tumba para cuerpo... %1 has bandaged patient @@ -4577,7 +4717,7 @@ %1 ha bendato il paziente %1 aplicou bandagem no paciente %1 již obvázal pacienta - %1 は包帯を巻いた + %1 が包帯を巻いた %1 (이)가 붕대를 감아줬다 %1 已包扎伤员 %1 已包紮傷者 @@ -4592,7 +4732,7 @@ %1 провел сердечно-легочную реанимацию %1 realicó RCP %1 a fait une RCP. - %1 は心肺蘇生(CPR)をした + %1 が心肺蘇生(CPR)を実施 %1 (이)가 심폐소생술을 실시했다 %1 已进行心肺复苏 %1 已執行心肺復甦術 @@ -4608,7 +4748,7 @@ %1 ha usato %2 %1 usou %2 %1 použil %2 - %1 は %2 を使った + %1 が%2を使用した %1 (이)가 %2 을 썼다 %1 已使用 %2 %1 已使用 %2 @@ -4625,7 +4765,7 @@ %1 ha somministrato una EV %1 aplicou um intravenoso %1 již aplikoval IV - %1 はIVを投与した + %1 がIVを投与した %1 (이)가 IV를 실시했다 %1 已进行静脉注射 %1 已經給予靜脈注射液 @@ -4642,7 +4782,7 @@ %1 ha applicato un laccio emostatico %1 aplicou um torniquete %1 použil škrtidlo - %1 は止血帯を巻いた + %1 が止血帯を巻いた %1 (이)가 지혈대를 적용했다 %1 已使用止血带 %1 已經綁上止血帶 @@ -4656,7 +4796,7 @@ %1 已套用固定板 %1 ha applicato una gessatura %1 použil dlahu - %1 は副子を当てた + %1 が添え木を当てた %1 założył szynę %1 aplicada una férula %1 hat eine Schiene angelegt @@ -4671,10 +4811,10 @@ %1 utilizou KPS %1 používá PAK %1 использовал аптечку - %1 ha usato Kit Pronto Soccorso Personale + %1 ha usato Kit di Pronto Soccorso (PAK) %1 usó Kit de Primeros Auxilios %1 a utilisé une trousse sanitaire. - %1 は個人用応急処置キットを使った + %1 が個人用治療キットを使用した %1 (이)가 개인응급키트를 사용했다 %1 已使用个人急救包 %1 已使用了個人急救包 @@ -4719,7 +4859,7 @@ Sehr leicht verwundet: B. lekko ranny Царапины - Ferito lievemente + Lievemente Ferito Muy levemente herido Très légèrement blessé Nagyon enyhén sérült @@ -4735,7 +4875,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 @@ -4788,9 +4928,9 @@ Нет жгута на этой части тела! Não existe nenhum torniquete nesta parte do corpo! Žádné škrtidlo na této části těla! - Non c'è nessun laccio emostatico su questa parte del corpo! + Nessun laccio emostatico su questa parte del corpo! Il n'y a pas de garrot sur ce membre ! - この部位には止血帯がない! + この部位に止血帯はありません! 이 부위에는 지혈대가 없습니다! 该部位没有使用止血带! 這部位沒有止血帶! @@ -4800,6 +4940,7 @@ The body twitched and may not be dead! Тело дернулось и, возможно, пациент жив! L'unité a bougé et n'est peut-être pas morte ! + Il cadavere si è mosso e potrebbe essere ancora vivo! 身体が痙攣している、まだ死んでないようだ! ¡El cuerpo se retorció y puede que no esté muerto! Ciało drgnęło i może nie być martwe! @@ -4813,7 +4954,10 @@ 묘비 이름 확인 Vérifier le nom sur la pierre tombale Überprüfe Name auf dem Grabstein + Controlla nome sulla lapide 墓石の名前を確認 + Проверьте имя на надгробии + Comprobar nombre en la lápida Bandage Rollover @@ -4821,7 +4965,10 @@ Verbandüberschlag 붕대 모두 감기 Pansement de plaies multiples + Srotolamento Bendaggi 包帯の繰り越し + Перевязка множественных ран + Vendaje múltiple If enabled, bandages can close different types of wounds on the same body part.\nBandaging multiple injuries will scale bandaging time accordingly. @@ -4829,7 +4976,10 @@ Wenn diese Option aktiviert ist, können Verbände verschiedene Arten von Wunden am selben Körperteil schließen.\nBeim Verbinden mehrerer Verletzungen wird die Verbandszeit entsprechend skaliert. 활성화된 경우 붕대로 동일한 신체 부위에 있는 다른 유형의 상처를 막을 수 있습니다.\n여러 부상을 붕대로 감으면 붕대 감는 시간이 그만큼 늘어납니다. 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При перевязке нескольких повреждений время перевязки будет увеличено соответствующим образом. + Si se habilita, las vendas pueden cerrar diferentes tipos de heridas en la misma parte del cuerpo.n\Vendar múltiples heridas escala el tiempo de vendado acorde. Bandage Effectiveness Coefficient @@ -4837,7 +4987,10 @@ Verbandswirksamkeitskoeffizient 붕대 효과 계수 Coefficient d'efficacité des bandages + Coefficiente di efficacia bendaggi 包帯有効性係数 + Коэф. эффективности повязки + Coeficiente de Efectividad de Vendado Determines how effective bandages are at closing wounds. @@ -4845,12 +4998,16 @@ Bestimmt, wie wirksam Bandagen beim Verschließen von Wunden sind. 붕대가 상처를 치료하는 데 얼마나 효과적으로 지속되는지 결정합니다. Défini l'efficacité des bandages à refermer des plaies. - 包帯が傷をふさぐのにどれだけ効果的かを決定します。 + Determina quanto i bendaggi sono efficaci nel chiudere le ferite. + 包帯が傷をふさぐのにどれだけ効果的かを定義します。 + Определяет, насколько эффективны бинты при закрытии ран. + Determina como de efectivos son los vendajes cerrando heridas. Medical Items Przedmioty Medyczne Matériel médical + Oggetti Medici 의료 물품 Orvosi felszerelés Медицинские предметы @@ -4860,5 +5017,81 @@ 医療品 Objetos médicos + + Zeus Treatment Time Coefficient + Coeff. di tempo per trattamenti Zeus + Zeit-Koeffizient für Zeus Behandlungen + Zeus治療時間係数 + 제우스 치료 시간 계수 + Коэф. времени обработки Zeus + Coeff. de temps + Coeficiente de Tiempo del Tratamiento de Zeus + + + Multiply all treatment times with this coefficient when in Zeus. + Moltiplica il tempo di ogni trattamento per questo coefficiente quando si è Zeus. + Dauer von Behandlungen als Zeus wird mit diesem Koeffizienten multipliziert. + Zeus操作中は、すべての治療時間にこの係数を掛けます。 + 제우스일 때 모든 치료 시간에 이 계수를 곱합니다. + Умножьте все время лечения на этот коэффициент, когда вы находитесь в Zeus. + Coefficient de temps de traitement Zeus + Multiplica los tiempos de tratamientos por este coeficiente cuando se está en Zeus + + + Painkillers + Léky proti bolesti + Schmerztabellen + Болеутоляющее + Środki przeciwbólowe + Antidolorifici + Analgésicos + Analgésiques + 止痛藥 + 鎮痛剤 + 진통제 + Analgésicos + 止痛药 + Ağrı kesici + + + Administer Painkillers + Somministra Antidolorifici + Ввести обезболивающие + 鎮痛剤を投与 + 진통제 투여 + Administrer des analgésiques + Verabreiche Schmerztabletten + Administrar Analgésicos + + + Administering Painkillers... + Somministrando Antidolorifici... + Использование обезболивающего... + 鎮痛剤を投与しています・・・ + 진통제 투여 중... + Administration d'analgésiques... + Verabreiche Schmerztablette... + Administrando Analgésicos... + + + Over-the-counter analgesic used to combat light to moderate pain experiences. + Antidolorifici senza prescrizione, usati per alleviare dolore leggero o moderato. + Безрецептурный анальгетик, используемый для борьбы с легкими и умеренными болевыми ощущениями. + 軽度から中程度の痛みに対処するために使用される市販の鎮痛薬。 + 가벼운 통증부터 중간 정도의 통증을 퇴치하는 데 사용되는 일반의약품 진통제입니다. + Analgésique sans ordonnance utilisé pour lutter contre les douleurs légères à modérées. + Rezeptfreies Analgetikum zur Bekämpfung leichter bis mittelschwerer Schmerzen. + Analgésico sin receta médica usado para aplacar dolores de ligeros a moderados. + + + Over-the-counter analgesic used to combat light to moderate pain experiences. + Antidolorifici senza prescrizione, usati per alleviare dolore leggero o moderato. + Безрецептурный анальгетик, используемый для борьбы с легкими и умеренными болевыми ощущениями. + 軽度から中程度の痛みに対処するために使用される市販の鎮痛薬。 + 가벼운 통증부터 중간 정도의 통증을 퇴치하는 데 사용되는 일반의약품 진통제입니다. + Analgésique sans ordonnance utilisé pour lutter contre les douleurs légères à modérées. + Rezeptfreies Analgetikum zur Bekämpfung leichter bis mittelschwerer Schmerzen. + Analgésico sin receta médica usado para aplacar dolores de ligeros a moderados. + diff --git a/addons/medical_treatment/ui/painkillers_ca.paa b/addons/medical_treatment/ui/painkillers_ca.paa new file mode 100644 index 0000000000..15036c85cb Binary files /dev/null and b/addons/medical_treatment/ui/painkillers_ca.paa differ 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..0390a9ad07 100644 --- a/addons/medical_vitals/functions/fnc_updateHeartRate.sqf +++ b/addons/medical_vitals/functions/fnc_updateHeartRate.sqf @@ -37,22 +37,22 @@ 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; - if (_bloodVolume < BLOOD_VOLUME_CLASS_2_HEMORRHAGE) then { - _targetBP = _targetBP * (_bloodVolume / DEFAULT_BLOOD_VOLUME); - }; - _targetHR = DEFAULT_HEART_RATE; if (_bloodVolume < BLOOD_VOLUME_CLASS_3_HEMORRHAGE) then { + private _targetBP = 107 * (_bloodVolume / DEFAULT_BLOOD_VOLUME); _targetHR = _heartRate * (_targetBP / (45 max _meanBP)); }; 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..2fe7336dc0 --- /dev/null +++ b/addons/medical_vitals/stringtable.xml @@ -0,0 +1,36 @@ + + + + + Vitals + Vitais + Parametri Vitali + Жизненно-важные органы + バイタル + 생명 + Paramètres vitaux + Vitalwerte + Vitales + + + Enable SpO2 Simulation + Abilita simulazione SpO2 + Включить имитацию SpO2 + SpO2シミュレーションを有効化 + 산소포화도 시뮬레이션 활성화 + Activer la simulation de la SpO2 + SpO2-Simulation aktivieren + Habilitar Simulación 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. + Позволяет имитировать насыщение кислородом, обеспечивая переменную частоту сердечных сокращений и потребность в кислороде в зависимости от физической активности и высоты над уровнем моря. Требуется для управления дыхательными путями. + 酸素飽和度シミュレーションを有効にし、身体活動や標高に基づいて変動する心拍数と酸素要求量の機能を提供します。 気道管理に必要です。 + 산소포화도 시뮬레이션을 활성화하여 신체 활동과 고도에 따라 다양한 심박수와 산소 요구량을 제공합니다. 기도 관리에 필요합니다. + Permet de simuler la saturation en oxygène, de modifier la fréquence cardiaque et la consommation d'oxygène en fonction de l'activité physique et de l'altitude. Nécessaire pour la gestion des voies respiratoires. + Aktiviert die Simulation der Sauerstoffsättigung und bietet variable Herzfrequenz und Sauerstoffbedarf basierend auf körperlicher Aktivität und Geländehöhe. Erforderlich für das Atemwegsmanagement. + Habilita la saturación de oxígeno, utilizando la demanda de oxígeno y ritmo cardíaco basado en la actividad física y la altitud. Requerido para el Manejo de las Vías Aéreas. + + + diff --git a/addons/microdagr/XEH_clientInit.sqf b/addons/microdagr/XEH_clientInit.sqf index 8a5db92e0b..c17914ad4b 100644 --- a/addons/microdagr/XEH_clientInit.sqf +++ b/addons/microdagr/XEH_clientInit.sqf @@ -35,7 +35,7 @@ private _closeCode = { }, ""] call CBA_fnc_addKeybind; //Add Eventhandler: -[QEGVAR(vector,rangefinderData), {_this call FUNC(recieveRangefinderData)}] call CBA_fnc_addEventHandler; +[QEGVAR(vector,rangefinderData), LINKFUNC(recieveRangefinderData)] call CBA_fnc_addEventHandler; //Global Variables to default: GVAR(gpsPositionASL) = [0,0,0]; diff --git a/addons/microdagr/XEH_preInit.sqf b/addons/microdagr/XEH_preInit.sqf index b46948b0bb..610dc0ed81 100644 --- a/addons/microdagr/XEH_preInit.sqf +++ b/addons/microdagr/XEH_preInit.sqf @@ -9,6 +9,6 @@ PREP_RECOMPILE_END; //Functions that are called for each draw of the map: GVAR(miniMapDrawHandlers) = []; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/microdagr/functions/fnc_mapOnDrawEH.sqf b/addons/microdagr/functions/fnc_mapOnDrawEH.sqf index 30a0c6ad6e..86415a1914 100644 --- a/addons/microdagr/functions/fnc_mapOnDrawEH.sqf +++ b/addons/microdagr/functions/fnc_mapOnDrawEH.sqf @@ -60,7 +60,7 @@ if (GVAR(currentApplicationPage) == 1) then { _size = 32 * _mapSize; { _x params ["_wpName", "_wpPos"]; - private _alpha = if (_forEachIndex == GVAR(currentWaypoint)) then {1} else {0.5}; + private _alpha = [0.5, 1] select (_forEachIndex == GVAR(currentWaypoint)); _theMap drawIcon [QUOTE(PATHTO_R(images\icon_mapWaypoints.paa)), [1,1,1,_alpha], _wpPos, _size, _size, 0, '', 0 ]; } forEach _waypoints; }; diff --git a/addons/microdagr/initSettings.sqf b/addons/microdagr/initSettings.inc.sqf similarity index 85% rename from addons/microdagr/initSettings.sqf rename to addons/microdagr/initSettings.inc.sqf index 8810939302..aacc5fd24b 100644 --- a/addons/microdagr/initSettings.sqf +++ b/addons/microdagr/initSettings.inc.sqf @@ -15,7 +15,5 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(itemName) [LSTRING(WaypointPrecision_DisplayName), LSTRING(WaypointPrecision_Description)], _category, [[1, 2, 3], [LSTRING(WaypointPrecision_medium), LSTRING(WaypointPrecision_close), LSTRING(WaypointPrecision_exact)], 2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(waypointPrecision), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // require mission restart + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/microdagr/stringtable.xml b/addons/microdagr/stringtable.xml index 720a463e38..c9bd546afc 100644 --- a/addons/microdagr/stringtable.xml +++ b/addons/microdagr/stringtable.xml @@ -29,7 +29,7 @@ MicroDAGR fejlett GPS vevőegység Ricevitore GPS avanzato MicroDAGR Receptor GPS avançado MicroDAGR - MicroDAGR は改良された GPS 受信機です + MicroDAGRは改良された高度なGPS受信機です 마이크로DAGR 고급 위성항법 수신기 微型军用高级防御 GPS 接收器 微型軍用高級防禦GPS接收器 @@ -45,7 +45,7 @@ Szögmértékegység: Unità angolare: Unidade Angular: - 角度の種類: + 角度の単位: 각도의 단위: 角密位: 角密位: @@ -61,7 +61,7 @@ Fok Gradi Graus - 角度 + 각도 @@ -93,7 +93,7 @@ Útvonalpontok mutatása a térképen: Mostra waypoint sulla mappa: Mostrar Waypoints no mapa: - 地図へウェイポイントを表示: + 地図にウェイポイントを表示: 웨이포인트를 지도에 보이기: 显示路径点在地图上: 顯示路徑點在地圖上: @@ -109,7 +109,7 @@ Вкл. Encendido Be - 有効 + オン 켜기 开启 開啟 @@ -126,7 +126,7 @@ Выкл. Apagado Ki - 無効 + オフ 끄기 关闭 關閉 @@ -141,7 +141,7 @@ Koordinaten eingeben: Napiš souřadnice: Add meg a rácskoordinátákat: - Introduci griglia coordinate: + Inserisci coordinata-griglia: Digite as Coords. do Grid 座標を入力: 输入网格座标: @@ -159,7 +159,7 @@ [%1] neve Nome di [%1] Nome do [%1] - [%1] の名前 + [%1] の名称 [%1] 의 이름 名称 [%1] 名稱 [%1] @@ -223,7 +223,7 @@ Irányszög Azimut Direção na bússola - 方位磁石での方位 + 方位磁石 방위 指南针方位 指北針方位 @@ -253,7 +253,7 @@ Punkty trasy Points de passage Útvonalpontok - waypoints + Waypoints Waypoints ウェイポイント 웨이포인트 @@ -269,9 +269,9 @@ Podłącz do Connecter Csatlakozás - Collega a + Collega a Conectar à - 次に接続 + 接続 연결 连接到 連接到 @@ -285,7 +285,7 @@ Nastavení Ustawienia Beállítások - Impostaizoni + Impostazioni Opções 設定 설정 @@ -301,9 +301,9 @@ UstawPT ChoixWP UP Beállítása - Definisci WayPoints + Definisci WayPoint Definir WP - WP設定 + WPセット 웨이포인트 설정 设置路径点 設置路徑點 @@ -351,13 +351,13 @@ MicroDAGR kijelzési mód váltása Alterna modalità display MicroDAGR Alternar Modo de Display do MicroDAGR - MicroDAGR の表示モード + MicroDAGR の表示モード切り替え 마이크로DAGR 화면 모드 토글 切换微型军用 GPS 接收器显示模式 切換微型軍用GPS接收器顯示模式 - Show MicoDAGR + Show MicroDAGR Zeige MicroDAGR Mostrar MicroDAGR Показать MicroDAGR @@ -381,7 +381,7 @@ Otwórz MicroDAGR Configurer MicroDAGR MicroDAGR konfigurálása - ConfiguraMicroDAGR + Configura MicroDAGR Configurar MicroDAGR MicroDAGR を設定 마이크로DAGR 설정하기 @@ -446,8 +446,8 @@ Définit le type d'information à afficher sur la carte du MicroDAGR. Mennyi térképadatot tartalmaz a MicroDAGR Сколько данных должно отображаться на карте MicroDAGR - Quanti dati sono trasferiti nella mappa del MicroDAGR - MicroDAGR で表示する地図情報を決定します + Quanti dati cartografici sono mostrati sulla mappa del MicroDAGR + MicroDAGR で表示される地図の情報量 얼마나 많은 데이터를 마이크로DAGR가 보여주는지를 결정합니다 有多少地图数据会显示在微型军用 GPS 接收器 有多少地圖數據會顯示在微型軍用GPS接收器 @@ -462,7 +462,7 @@ Image satellite + Bâtiments Teljes műholdas + épületek Спутник + Здания - Satellite Completo + Edifici + Satellitare Completo + Edifici 完全な衛星画像と建物 위성 사진 + 건물 完整卫星画面 + 建筑物位置 @@ -494,7 +494,7 @@ Néant (carte désactivée) Semmi (nem használható a térképnézet) Не показывать (запрещает использовать режим карты) - Nessuno (Non puoi usare la vista mappa) + Nessuno (Non puoi usare la visuale mappa) なし (地図表示を使えません) 없음 (지도를 볼 수 없음) 无(无法检视地图) @@ -518,8 +518,8 @@ Controls how precise the waypointdistance can be displayed Legt die Genauigkeit der Entfernung von Wegpunkten fest - Controlla quanto precisamente può essere visualizzato il waypoint a distanza - 表示されるウェイポイントの精度を設定します + Controlla quanto è precisa la distanza indicata dal waypoint + ウェイポイント距離の表示精度を制御します。 Kontroluje jak precyzyjnie może być wyświetlany dystans PT Управляет точностью отображения расстояний маршрутных точек Controla o quão preciso pode exibir o waypoint de distância @@ -588,8 +588,8 @@ Définit la quantité de données présentes dans le MicroDAGR.\nMoins de données force la carte à afficher moins d'informations sur la minimap. Meghatárroza a MicroDAGR objektumok térképének tartalmát. A kevesebb adat korlátozza a térképnézeti módot az eszközön. Контролирует, сколько данных должно отображаться на карте устройств MicroDAGR. Ограничивает объем отображаемых данных на миникарте. - Controlla quanti dati sono presenti negli oggetti MicroDAGR. Meno dati costringono la vista mappa a mostrare meno informazioni nella minimappa. - アイテム上で表示されるデータ量を決定します。設定を減らすと地図上での情報が少なくなります。 + Controlla quanti dati cartografici vengono caricati sui MicroDAGR. Meno dati permetteranno la visualizzazione di meno informazioni sulla minimappa. + microDAGRの項目に入力されるデータの量を制御します。データを少なくすると、マップビューが制限され、ミニマップの表示量が少なくなります。 마이크로DAGR에 얼마나 많은 데이터가 들어있는지 정합니다. 적을 수록 지도상에도 비춰지는게 적어집니다. 设定有多少数据会显示在微型军用 GPS 接收器上。这些资料的多寡会反映在迷你地图的显示上。 設定有多少數據會顯示在微型軍用GPS接收器上。這些資料的多寡會反映在迷你地圖的顯示上。 @@ -601,6 +601,7 @@ MicroDAGR - Mode précédent MicroDAGR - 前のモードに MicroDAGR - vorheriger Modus + MicroDAGR - Modalità Precedente MicroDAGR - Poprzedni Tryb 微型 GPS 接收器—上一个模式 마이크로DAGR - 이전 모드 @@ -612,6 +613,7 @@ MicroDAGR - Mode suivant MicroDAGR - 次のモードに MicroDAGR - nächster Modus + MicroDAGR - Modalità Successiva MicroDAGR - Kolejny Tryb 微型 GPS 接收器—下一个模式 마이크로DAGR - 다음 모드 diff --git a/addons/minedetector/XEH_postInit.sqf b/addons/minedetector/XEH_postInit.sqf index 0b8a521155..f5f5de0ca8 100644 --- a/addons/minedetector/XEH_postInit.sqf +++ b/addons/minedetector/XEH_postInit.sqf @@ -1,19 +1,10 @@ #include "script_component.hpp" // Create a dictionary to store detector configs -GVAR(detectorConfigs) = call CBA_fnc_createNamespace; +GVAR(detectorConfigs) = createHashMap; -// Create a dictionary of detectable classnames -GVAR(detectableClasses) = call CBA_fnc_createNamespace; - -private _detectableClasses = call (uiNamespace getVariable [QGVAR(detectableClasses), {[]}]); //See XEH_preStart.sqf -{ - GVAR(detectableClasses) setVariable [_x, true]; -} forEach _detectableClasses; -TRACE_1("built cache",count allVariables GVAR(detectableClasses)); - -[QGVAR(enableDetector), FUNC(enableDetector)] call CBA_fnc_addEventHandler; -[QGVAR(disableDetector), FUNC(disableDetector)] call CBA_fnc_addEventHandler; +[QGVAR(enableDetector), LINKFUNC(enableDetector)] call CBA_fnc_addEventHandler; +[QGVAR(disableDetector), LINKFUNC(disableDetector)] call CBA_fnc_addEventHandler; // Shows detector and mine posistions in 3d when debug is on #ifdef DEBUG_MODE_FULL diff --git a/addons/minedetector/XEH_preStart.sqf b/addons/minedetector/XEH_preStart.sqf index 48f003d08e..046c037364 100644 --- a/addons/minedetector/XEH_preStart.sqf +++ b/addons/minedetector/XEH_preStart.sqf @@ -15,5 +15,5 @@ private _detectableClasses = []; }; } forEach (configProperties [configFile >> "CfgAmmo", "isClass _x", true]); -TRACE_1("compiled",count _detectableClasses); -uiNamespace setVariable [QGVAR(detectableClasses), compileFinal str _detectableClasses]; +TRACE_1("built cache",count _detectableClasses); +uiNamespace setVariable [QGVAR(detectableClasses), compileFinal (_detectableClasses createHashMapFromArray [])]; diff --git a/addons/minedetector/functions/fnc_enableDetector.sqf b/addons/minedetector/functions/fnc_enableDetector.sqf index b673176086..55b58dcf3a 100644 --- a/addons/minedetector/functions/fnc_enableDetector.sqf +++ b/addons/minedetector/functions/fnc_enableDetector.sqf @@ -31,4 +31,4 @@ if (_unit == ACE_player) then { [QGVAR(detectorEnabled), [_unit, _detectorType]] call CBA_fnc_localEvent; private _config = [_detectorType] call FUNC(getDetectorConfig); -[FUNC(detectorLoop), 0.05, [_unit, _detectorType, _config, CBA_missionTime - 0.25]] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(detectorLoop), 0.05, [_unit, _detectorType, _config, CBA_missionTime - 0.25]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/minedetector/functions/fnc_getDetectedObject.sqf b/addons/minedetector/functions/fnc_getDetectedObject.sqf index 6827e59c99..7811b3eaaa 100644 --- a/addons/minedetector/functions/fnc_getDetectedObject.sqf +++ b/addons/minedetector/functions/fnc_getDetectedObject.sqf @@ -38,18 +38,16 @@ private _mine = objNull; private _distance = -1; { - private _objectType = typeOf _x; - - _isDetectable = GVAR(detectableClasses) getVariable _objectType; - if (isNil "_isDetectable" || {(getModelInfo _x) select 0 == "empty.p3d"}) then { - _isDetectable = false; + if ((getModelInfo _x) select 0 == "empty.p3d") then { + continue; }; - // If a nun-null object was detected exit the search - if (_isDetectable && {!isNull _x}) exitWith { + // If an object was detected, exit the search + if ((typeOf _x) in (uiNamespace getVariable QGVAR(detectableClasses))) exitWith { + _isDetectable = true; _distance = _detectorPointAGL distance _x; _mine = _x; - TRACE_3("return", _isDetectable, _mine, _distance); + TRACE_3("return",_isDetectable,_mine,_distance); }; } forEach _nearestObjects; diff --git a/addons/minedetector/functions/fnc_getDetectorConfig.sqf b/addons/minedetector/functions/fnc_getDetectorConfig.sqf index fe7a888ebf..a5566cbfbf 100644 --- a/addons/minedetector/functions/fnc_getDetectorConfig.sqf +++ b/addons/minedetector/functions/fnc_getDetectorConfig.sqf @@ -19,18 +19,15 @@ params ["_detectorType"]; if (_detectorType isEqualTo "") exitWith {[]}; -private _detectorConfig = GVAR(detectorConfigs) getVariable _detectorType; -if (isNil "_detectorConfig") then { +GVAR(detectorConfigs) getOrDefaultCall [_detectorType, { private _cfgEntry = (configFile >> "ACE_detector" >> "detectors" >> _detectorType); if (isClass _cfgEntry) then { - _detectorConfig = [ + [ _detectorType, getNumber (_cfgEntry >> "radius"), getArray (_cfgEntry >> "sounds") ]; } else { - _detectorConfig = []; + [] }; - GVAR(detectorConfigs) setVariable [_detectorType, _detectorConfig]; -}; -_detectorConfig +}, true] diff --git a/addons/minedetector/stringtable.xml b/addons/minedetector/stringtable.xml index 3f6eca652b..95fab779dd 100644 --- a/addons/minedetector/stringtable.xml +++ b/addons/minedetector/stringtable.xml @@ -6,7 +6,7 @@ Détecteur de métaux Детектор металла Detektor kovů - 地雷探知機 + 金属探知機 Wykrywacz metali Metalldetektor 지뢰탐지기 @@ -22,7 +22,7 @@ Détecteur de métaux Детектор металла Detektor kovů - 地雷探知機 + 金属探知機 Wykrywacz metali Metalldetektor 지뢰탐지기 @@ -69,7 +69,7 @@ Connect Headphones Подключить наушники Připojit sluchátka - ヘッドホンへつなぐ + ヘッドホンに接続 Podłącz słuchawki Kopfhörer verbinden 헤드폰에 연결 @@ -85,7 +85,7 @@ Disconnect Headphones Отключить наушники Odpojit sluchátka - ヘッドホンからはずす + ヘッドホンを切断 Odłącz słuchawki Kopfhörer trennen 헤드폰 연결 끊기 @@ -117,7 +117,7 @@ Headphones Disconnected Наушники отключены Sluchátka odpojena - ヘッドホンから外しました + ヘッドホンを切断しました Słuchawki odpięte Kopfhörer getrennt 헤드폰 연결 끊김 diff --git a/addons/missileguidance/CfgEventhandlers.hpp b/addons/missileguidance/CfgEventhandlers.hpp index 449681e8df..a288a93399 100644 --- a/addons/missileguidance/CfgEventhandlers.hpp +++ b/addons/missileguidance/CfgEventhandlers.hpp @@ -7,13 +7,13 @@ class Extended_PreStart_EventHandlers { class Extended_PreInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_SCRIPT(XEH_pre_init)); + init = QUOTE(call COMPILE_SCRIPT(XEH_preInit)); }; }; class Extended_PostInit_EventHandlers { class ADDON { - init = QUOTE(call COMPILE_SCRIPT(XEH_post_init)); + init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; diff --git a/addons/missileguidance/XEH_post_init.sqf b/addons/missileguidance/XEH_postInit.sqf similarity index 76% rename from addons/missileguidance/XEH_post_init.sqf rename to addons/missileguidance/XEH_postInit.sqf index cc09b1f0ac..eb0fb60abf 100644 --- a/addons/missileguidance/XEH_post_init.sqf +++ b/addons/missileguidance/XEH_postInit.sqf @@ -1,6 +1,6 @@ #include "script_component.hpp" -[QGVAR(handoff), {_this call FUNC(handleHandoff)}] call CBA_fnc_addEventHandler; +[QGVAR(handoff), LINKFUNC(handleHandoff)] call CBA_fnc_addEventHandler; ["ACE3 Weapons", QGVAR(cycleFireMode), localize LSTRING(CycleFireMode), { diff --git a/addons/missileguidance/XEH_pre_init.sqf b/addons/missileguidance/XEH_preInit.sqf similarity index 100% rename from addons/missileguidance/XEH_pre_init.sqf rename to addons/missileguidance/XEH_preInit.sqf diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf index 6ddb60d21b..b690ab2075 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_DIR.sqf @@ -39,7 +39,7 @@ private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; private _distanceToShooter = _projectilePos vectorDistance _shooterPos; private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; -TRACE_2("", _distanceToTarget, _distanceToShooter); +TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _returnTargetPos = _seekerTargetPos; @@ -69,5 +69,5 @@ switch (_attackProfileStateParams select 0) do { }; }; -TRACE_1("Adjusted target position", _returnTargetPos); +TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf index d7092a924d..f1f360e403 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_JAV_TOP.sqf @@ -39,7 +39,7 @@ private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; private _distanceToShooter = _projectilePos vectorDistance _shooterPos; private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; -TRACE_2("", _distanceToTarget, _distanceToShooter); +TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _returnTargetPos = _seekerTargetPos; @@ -58,7 +58,7 @@ switch( (_attackProfileStateParams select 0) ) do { private _cruisAlt = 140; if (_distanceShooterToTarget < 1250) then { _cruisAlt = 140 * (_distanceShooterToTarget/1250); - TRACE_1("_cruisAlt", _cruisAlt); + TRACE_1("_cruisAlt",_cruisAlt); }; if ( ((ASLToAGL _projectilePos) select 2) - ((ASLToAGL _seekerTargetPos) select 2) >= _cruisAlt) then { if (_cruisAlt < 140) then { @@ -72,7 +72,7 @@ switch( (_attackProfileStateParams select 0) ) do { }; case STAGE_COAST: { TRACE_1("STAGE_COAST",""); - TRACE_1("", ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) ); + TRACE_1("",((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2)); if (_distanceToTarget < ( ((ASLToAGL _projectilePos) select 2) - (( ASLToAGL _seekerTargetPos) select 2) ) * 2) then { _attackProfileStateParams set [0, STAGE_TERMINAL]; } else { @@ -86,5 +86,5 @@ switch( (_attackProfileStateParams select 0) ) do { }; }; -TRACE_1("Adjusted target position", _returnTargetPos); +TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf index 23476ec46c..e346b16eb6 100644 --- a/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf +++ b/addons/missileguidance/functions/fnc_attackProfile_LIN.sqf @@ -30,7 +30,7 @@ private _distanceToTarget = _projectilePos vectorDistance _seekerTargetPos; private _distanceToShooter = _projectilePos vectorDistance _shooterPos; private _distanceShooterToTarget = _shooterPos vectorDistance _seekerTargetPos; -TRACE_2("", _distanceToTarget, _distanceToShooter); +TRACE_2("",_distanceToTarget,_distanceToShooter); // Add height depending on distance for compensate private _addHeight = [0,0,0]; diff --git a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf index d25d2bc2b7..2263716724 100644 --- a/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf +++ b/addons/missileguidance/functions/fnc_cycleAttackProfileKeyDown.sqf @@ -18,7 +18,7 @@ TRACE_1("cycle fire mode",_this); if (!alive ACE_player) exitWith {}; -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {}; private _currentShooter = objNull; diff --git a/addons/missileguidance/functions/fnc_guidancePFH.sqf b/addons/missileguidance/functions/fnc_guidancePFH.sqf index 132af330c3..0620e9e3c0 100644 --- a/addons/missileguidance/functions/fnc_guidancePFH.sqf +++ b/addons/missileguidance/functions/fnc_guidancePFH.sqf @@ -37,7 +37,7 @@ private _adjustTime = 1; if (accTime > 0) then { _adjustTime = 1/accTime; _adjustTime = _adjustTime * (_runtimeDelta / TIMESTEP_FACTOR); - TRACE_4("Adjust timing", 1/accTime, _adjustTime, _runtimeDelta, (_runtimeDelta / TIMESTEP_FACTOR) ); + TRACE_4("Adjust timing",1/accTime,_adjustTime,_runtimeDelta,(_runtimeDelta / TIMESTEP_FACTOR)); } else { _adjustTime = 0; }; @@ -89,8 +89,8 @@ if ((_minDeflection != 0 || {_maxDeflection != 0}) && {_profileAdjustedTargetPos }; private _finalAdjustVector = [_yaw, _roll, _pitch]; - TRACE_3("", _pitch, _yaw, _roll); - TRACE_3("", _targetVector, _adjustVector, _finalAdjustVector); + TRACE_3("",_pitch,_yaw,_roll); + TRACE_3("",_targetVector,_adjustVector,_finalAdjustVector); if (accTime > 0) then { private _changeVector = (vectorDir _projectile) vectorAdd _finalAdjustVector; diff --git a/addons/missileguidance/functions/fnc_handleHandoff.sqf b/addons/missileguidance/functions/fnc_handleHandoff.sqf index 9c6e299d01..785071da01 100644 --- a/addons/missileguidance/functions/fnc_handleHandoff.sqf +++ b/addons/missileguidance/functions/fnc_handleHandoff.sqf @@ -19,4 +19,4 @@ params ["_target", "_args"]; if (isNil "_target" || {isNull _target} || {!local _target} ) exitWith { false }; -[FUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(guidancePFH), 0, _args] call CBA_fnc_addPerFrameHandler; diff --git a/addons/missileguidance/functions/fnc_onFired.sqf b/addons/missileguidance/functions/fnc_onFired.sqf index 1c964c5113..1d63d120a9 100644 --- a/addons/missileguidance/functions/fnc_onFired.sqf +++ b/addons/missileguidance/functions/fnc_onFired.sqf @@ -20,7 +20,7 @@ params ["_shooter","_weapon","","_mode","_ammo","","_projectile"]; // Bail on not missile -if (!(_ammo isKindOf "MissileBase")) exitWith {}; +if !(_ammo isKindOf "MissileBase") exitWith {}; // Bail if guidance is disabled for this ammo if ((getNumber (configFile >> "CfgAmmo" >> _ammo >> QUOTE(ADDON) >> "enabled")) != 1) exitWith {}; @@ -71,14 +71,14 @@ if (isNil "_target") then { if (!isPlayer _shooter) then { // This was an AI shot, lets still guide it on the AI target _target = _shooter getVariable [QGVAR(vanilla_target), nil]; - TRACE_1("Detected AI Shooter!", _target); + TRACE_1("Detected AI Shooter!",_target); } else { private _canUseLock = getNumber (_config >> "canVanillaLock"); // @TODO: Get vanilla target if (_canUseLock > 0 || difficulty < 1) then { private _vanillaTarget = cursorTarget; - TRACE_1("Using Vanilla Locking", _vanillaTarget); + TRACE_1("Using Vanilla Locking",_vanillaTarget); if (!isNil "_vanillaTarget") then { _target = _vanillaTarget; }; @@ -145,7 +145,7 @@ if (_onFiredFunc != "") then { // _stateParams params ["_lastRunTime", "_seekerStateParams", "_attackProfileStateParams", "_lastKnownPosState"]; // _seekerParams params ["_seekerAngle", "_seekerAccuracy", "_seekerMaxRange", "_seekerMinRange"]; -[FUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; +[LINKFUNC(guidancePFH), 0, _args ] call CBA_fnc_addPerFrameHandler; /* Clears locking settings diff --git a/addons/missileguidance/functions/fnc_seekerType_ARH.sqf b/addons/missileguidance/functions/fnc_seekerType_ARH.sqf index 20571e3d65..54e487a9a0 100644 --- a/addons/missileguidance/functions/fnc_seekerType_ARH.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_ARH.sqf @@ -72,7 +72,7 @@ if (_isActive || { CBA_missionTime >= _timeWhenActive }) then { }; _nearestObjects = _nearestObjects select { !isNull _x }; // Select closest object to the expected position to be the current radar target - if ((count _nearestObjects) <= 0) exitWith { + if (_nearestObjects isEqualTo []) exitWith { _projectile setMissileTarget objNull; _searchPos }; @@ -117,4 +117,3 @@ if !(isNull _target) then { _launchParams set [0, _target]; _expectedTargetPos - diff --git a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf index 7fc30fb30b..bac01d05b4 100644 --- a/addons/missileguidance/functions/fnc_seekerType_Optic.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_Optic.sqf @@ -34,12 +34,12 @@ private _losOkay = false; if (_angleOkay) then { _losOkay = [_projectile, _target] call FUNC(checkLos); }; -TRACE_2("", _angleOkay, _losOkay); +TRACE_2("",_angleOkay,_losOkay); // Can't see target, return [0,0,0] and let doSeekerSearch handle it if (!_angleOkay || !_losOkay) exitWith {[0,0,0]}; -TRACE_2("", _target, _foundTargetPos); +TRACE_2("",_target,_foundTargetPos); // @TODO: Configurable lead for seekers private _projectileSpeed = (vectorMagnitude velocity _projectile); private _distanceToTarget = (getPosASL _projectile) vectorDistance _foundTargetPos; diff --git a/addons/missileguidance/functions/fnc_seekerType_SALH.sqf b/addons/missileguidance/functions/fnc_seekerType_SALH.sqf index 4b74d0f7e3..a16c58ce5f 100644 --- a/addons/missileguidance/functions/fnc_seekerType_SALH.sqf +++ b/addons/missileguidance/functions/fnc_seekerType_SALH.sqf @@ -27,6 +27,6 @@ _laserParams params ["_code", "_wavelengthMin", "_wavelengthMax"]; private _laserResult = [(getPosASL _projectile), (velocity _projectile), _seekerAngle, _seekerMaxRange, [_wavelengthMin, _wavelengthMax], _code, _projectile] call EFUNC(laser,seekerFindLaserSpot); private _foundTargetPos = _laserResult select 0; -TRACE_1("Search", _laserResult); +TRACE_1("Search",_laserResult); _foundTargetPos; diff --git a/addons/missileguidance/stringtable.xml b/addons/missileguidance/stringtable.xml index dc050272b1..aacdd472d6 100644 --- a/addons/missileguidance/stringtable.xml +++ b/addons/missileguidance/stringtable.xml @@ -12,7 +12,7 @@ Orientação avançada de Míssil Fejlett rakétairányító Продвинутое наведение ракет - 高度なミサイルの誘導 + アドバンスドミサイル誘導 고급 미사일 유도 进阶导弹制导 進階飛彈制導 @@ -21,7 +21,7 @@ Advanced missile guidance, or AMG, provides multiple enhancements to missile locking and firing. It is also a framework required for missile weapon types. Zaawansowane namierzanie rakiet, lub ZNR, dostarcza wiele poprawek do systemu namierzania rakiet oraz dodaje nowe tryby strzału. Jest to wymagana opcja dla broni rakietowych. - Guida dei missili avanzata, o AMG, offre diversi miglioramenti alla teleguida di missili. E' anche un sistema necessario per i tipi di armi missile. + Guida dei missili avanzata, o GMA, offre diversi miglioramenti alla teleguida di missili. È anche un sistema necessario per la categoria d'arma dei missili. Продвинутое наведение ракет, или ПНР, обеспечивает множество усовершествований для наведения и стрельбы ракет. Также, это система, необходимая для всех ракетных типов оружия. El guiado avanzado de misiles, o AMG en sus siglas en inglés, ofrece múltiples mejoras en el fijado y disparo de misiles. Es también un sistema requerido para armas de tipo misil. Das Erweiterte Raketenlenksystem, auch ERls genannt, bietet viele Verbesserungen zum Aufschalten und Feuern mittels gelenkter Raketen. @@ -29,7 +29,7 @@ A fejlett rakétairányító (vagy AMG) többféle módosítást tartalmaz a rakéták célkövetéséhez és tüzeléséhez. Ez egy szükséges keresztrendszer a rakéta-alapú fegyverekhez. Orientação avançada de mísseis ou OAM, fornece vários aprimoramentos para travamento de mísseis e disparos. Também é um sistema requerido para disparar armas que utilizem mísseis. Pokočilé navádění raket (AMG) poskytuje několik vylepšení pro lepší zaměření a následnou střelbu. Je to prvek vyžadovaný u typu zbraní jako jsou rakety. - 高度なミサイルの誘導、または AMG はミサイルの捕捉と発射に複数の強化をあたえます。これはミサイルの種類によって、枠組みを必要とします。 + アドバンスドミサイル誘導 (AMG) は、ミサイルの捕捉と発射に複数の機能強化を提供します。 これは、ミサイル兵器の種類に必要なフレームワークでもあります。 고급 미사일 유도 혹은 AMG는 표적 획득 및 발사를 위한 여러 기능을 제공합니다. 미사일 종류에 따라 체계가 필요합니다. 进阶导弹制导增强了多种导弹锁定和射击的能力。此系统适用于所有导弹类型的武器。 進階飛彈制導增強了多種導彈鎖定和射擊的能力。此系統適用於所有飛彈類型的武器 @@ -76,11 +76,11 @@ Laserowo naprowadzana rakieta Hydra-70 DAGR Hydra-70 DAGR lasergelenkte Rakete Hydra-70 DAGR laserem naváděná střela - Hydra-70 DAGR Missile a Guida Laser + Hydra-70 DAGR Missile Laserguidato Míssil guiado a laser Hydra-70 DAGR Hydra-70 DAGR lézer-irányított rakéta Управляемая ракета лазерного наведения Hydra-70 DAGR - ハイドラ-70 DAGR レーザ誘導ミサイル + ハイドラ-70 DAGR レーザー誘導ミサイル 히드라-70 DAGR 레이저 유도 미사일 Hydra-70 激光制导直接攻击火箭(DAGR) 九頭蛇-70 直接攻擊雷射導引飛彈 @@ -93,7 +93,7 @@ Hellfire II AGM-114K Hellfire II AGM-114K Hellfire II AGM-114K - Missile Hellfire II AGM-114K + Missile AGM-114K Hellfire II Míssil Hellfire II AGM-114K Hellfire II AGM-114K rakéta Hellfire II AGM-114K @@ -127,11 +127,11 @@ Laserowo naprowadzana rakieta Hellfire II AGM-114K Hellfire II AGM-114K Lasergelenkte Rakete Hellfire II AGM-114K laserem naváděná střela - Missile a Guida Laser Hellfire II AGM-114K + Missile Laserguidato AGM-114K Hellfire II Míssil guiado a laser Hellfire II AGM-114K Hellfire II AGM-114K lézer-irányított rakéta Управляемая ракета лазерного наведения Hellfire II AGM-114K - ヘルファイア II AGM-114K レーザ誘導ミサイル + ヘルファイア II AGM-114K レーザー誘導ミサイル 헬파이어 II AGM-114K 레이저 유도 미사일 AGM-114K 地狱火二型激光制导导弹 地獄火II型 AGM-114K 雷射導引飛彈 @@ -196,10 +196,10 @@ Przełącz tryb ognia Guidage missiles - Changer le mode de tir Tüzelési mód váltása - Alterna le modalità di fuoco + Cambia modalità di fuoco Cambiar modo de disparo Alterar Modo de Disparo - 発射モード切り替え + 発射モードサイクル 발사 방식 순환 循环切换开火模式 循環切換開火模式 diff --git a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf index 63465a6588..88e2ba02d5 100644 --- a/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf +++ b/addons/missionmodules/functions/fnc_moduleAmbianceSound.sqf @@ -55,11 +55,9 @@ private _missionRoot = str missionConfigFile select [0, count str missionConfigF ERROR_1("Ambient Sounds: Sound ""%1"" not found.",_x); }; }; +} forEach _splittedList; - false -} count _splittedList; - -if (count _ambianceSounds == 0) exitWith {}; +if (_ambianceSounds isEqualTo []) exitWith {}; { if ((_x find ".") == -1) then { _ambianceSounds set [_forEachIndex, _x + ".wss"]; @@ -82,7 +80,7 @@ TRACE_1("",_ambianceSounds); private _allUnits = if (isMultiplayer) then {playableUnits} else {[ACE_player]}; // Check if there are enough players to even start playing this sound. - if (count _allUnits > 0) then { + if (_allUnits isNotEqualTo []) then { // find the position from which we are going to play this sound from. private _newPosASL = if (_followPlayers) then { // Select a target unit at random. diff --git a/addons/missionmodules/stringtable.xml b/addons/missionmodules/stringtable.xml index 0a33a92182..dfdcef97f3 100644 --- a/addons/missionmodules/stringtable.xml +++ b/addons/missionmodules/stringtable.xml @@ -11,7 +11,7 @@ ACE modules de mission ACE küldetési modulok ACE Модули миссий - Moduli Missione ACE + ACE Moduli Missione ACE ミッション モジュール ACE 미션 모듈 ACE 任务模块 @@ -78,7 +78,7 @@ Distance minimale Minimális távolság Мин. дистанция - Distanza Minimale + Distanza Minima 最低距離 최소 거리 最小距离 @@ -95,7 +95,7 @@ Valeur utilisée pour calculer une position aléatoire et définir la distance minimale entre les joueurs et les sons joués. Egy véletlenszerű pozíció számításához használt érték, amihez megadja a minimum távolságot a játékosok és a lejátszott hangfájl(ok) között Используется для расчета случайной позиции и указывает минимальное расстояние между игроками и источниками звука - Usati per calcolare una posizione casuale ed impostare la distanza minima tra i giocatori ed il file suono eseguito + Usati per calcolare una posizione casuale ed impostare la distanza minima tra i giocatori ed il file audio riprodotto 無作為な位置への計算や、プレイヤーと再生されるファイルの間へ最低距離を設定します 무작위 위치 계산에 사용되며 플레이어와 재생된 사운드 파일 간의 최소 거리를 설정합니다. 声音将随机产生在玩家附近,此选项定义该声音最近会距离玩家多少米 @@ -128,7 +128,7 @@ Valeur utilisée pour calculer une position aléatoire et définir la distance maximale entre les joueurs et les sons joués. Egy véletlenszerű pozíció számításához használt érték, amihez megadja a maximum távolságot a játékosok és a lejátszott hangfájl(ok) között Используется для расчета случайной позиции и указывает максимальное расстояние между игроками и источниками звука - Usato per calcolare una posizione casuale ed impostare la distanza massima tra giocatori e il file suono eseguito + Usato per calcolare una posizione casuale ed impostare la distanza massima tra giocatori e il file audio riprodotto 無作為な位置への計算や、プレイヤーと再生されるファイルの間へ最大距離を設定します 무작위 위치 계산에 사용되며 플레이어와 재생된 사운드 파일 간의 최대 거리를 설정합니다. 声音将随机产生在玩家附近,此选项定义该声音最远会距离玩家多少米 @@ -161,7 +161,7 @@ Délai minimal entre deux sons consécutifs. Minimum késleltetés a lejátszott hangok között Минимальная задержка между воспроизведением звуков - Pausa Minima tra suoni eseguiti + Pausa Minima tra suoni riprodotti 再生されるまでの最低遅延 재생된 소리간 최소 지연 시간 设定每个声音档案中间最少间隔多久再进行播放 @@ -195,7 +195,7 @@ Délai maximal entre deux sons consécutifs. Maximum késleltetés a lejátszott hangok között Максимальная задержка между воспроизведением звуков - Pausa Massima tra suoni eseguiti + Pausa Massima tra suoni riprodotti 再生されるまでの最大遅延 재생된 소리간 최대 지연 시간 设定每个声音档案中间最多间隔多久再进行播放 @@ -229,7 +229,7 @@ Suivre les joueurs. Si défini sur false, les sons ne seront joués qu'autour de la position du module. Játékosok követése. Ha le van tiltva, az ismétlés csak a legközelebbi logikai ponton játszik le hangokat. Следовать за игроками. Если установить в Ложь, звуки будут циклически проигрываться только около позиции Логики. - Segui Giocatori. Se impostato su falso, il ciclo eseguirà i suoni solo vicino ad una posizione logica. + Segui Giocatori. Se impostato su falso, il ciclo riprodurrà i suoni solo in prossimità del modulo. プレイヤーを追随します。False に設定するとロジックの近くで延々と再生します。 플레이어를 따라갑니다. False로 설정될 경우 오직 한 자리에서만 반복해서 소리를 재생합니다. 设定声音是否会在玩家的附近产生。假如关闭此功能,声音只会在模块的位置产生。 @@ -263,7 +263,7 @@ Définit le volume des sons. A lejátszott hangok hangereje Громкость воспроизводимых звуков - Il volume dei suoni eseguiti + Il volume dei suoni riprodotti 再生される音の大きさ 재생되는 소리의 볼륨 调整声音的音量 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/CfgWeapons.hpp b/addons/mk6mortar/CfgWeapons.hpp index c57c9aa2ea..b32cce1e41 100644 --- a/addons/mk6mortar/CfgWeapons.hpp +++ b/addons/mk6mortar/CfgWeapons.hpp @@ -10,7 +10,7 @@ class CfgWeapons { picture = QPATHTOF(UI\icon_rangeTable.paa); ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 0.5; + mass = 0.1; }; }; diff --git a/addons/mk6mortar/XEH_postInit.sqf b/addons/mk6mortar/XEH_postInit.sqf index 9f24a12a3b..280e16cf79 100644 --- a/addons/mk6mortar/XEH_postInit.sqf +++ b/addons/mk6mortar/XEH_postInit.sqf @@ -1,16 +1,17 @@ #include "script_component.hpp" if (hasInterface) then { - ["ace_infoDisplayChanged", FUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler; + #include "initKeybinds.inc.sqf" + ["ace_infoDisplayChanged", LINKFUNC(turretDisplayLoaded)] call CBA_fnc_addEventHandler; }; ["CBA_settingsInitialized", { TRACE_4("CBA_settingsInitialized",GVAR(airResistanceEnabled),GVAR(allowComputerRangefinder),GVAR(allowCompass),GVAR(useAmmoHandling)); - ["vehicle", FUNC(handlePlayerVehicleChanged), true] call CBA_fnc_addPlayerEventHandler; + ["vehicle", LINKFUNC(handlePlayerVehicleChanged), true] call CBA_fnc_addPlayerEventHandler; if (!GVAR(airResistanceEnabled)) exitWith {}; if (EGVAR(artillerytables,advancedCorrections)) exitWith { TRACE_1("defer firedEH to artillerytables",_this); }; - ["Mortar_01_base_F", "fired", {call FUNC(handleFired)}] call CBA_fnc_addClassEventHandler; + ["Mortar_01_base_F", "fired", LINKFUNC(handleFired)] call CBA_fnc_addClassEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/mk6mortar/XEH_preInit.sqf b/addons/mk6mortar/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/mk6mortar/XEH_preInit.sqf +++ b/addons/mk6mortar/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf index 3356e91c11..663afa2cc7 100644 --- a/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf +++ b/addons/mk6mortar/functions/fnc_csw_getProxyWeapon.sqf @@ -55,7 +55,7 @@ if (_proxyWeaponNeeded || GVAR(useAmmoHandling)) then { }; }; } else { - WARNING_1("unknown mag %1", _xMag); + WARNING_1("unknown mag %1",_xMag); }; }; } forEach (magazinesAllTurrets _mortar); diff --git a/addons/mk6mortar/functions/fnc_handleFired.sqf b/addons/mk6mortar/functions/fnc_handleFired.sqf index c09c96f777..8ea2984b79 100644 --- a/addons/mk6mortar/functions/fnc_handleFired.sqf +++ b/addons/mk6mortar/functions/fnc_handleFired.sqf @@ -24,11 +24,11 @@ params ["_vehicle", "", "", "", "", "", "_projectile"]; // Large enough distance to not simulate any wind deflection -if (_vehicle distance ACE_player > 8000) exitWith {false}; +if (_vehicle distance ACE_player > 8000) exitWith {}; //AI will have no clue how to use: private _shooterMan = gunner _vehicle; -if (!([_shooterMan] call EFUNC(common,isPlayer))) exitWith {false}; +if !([_shooterMan] call EFUNC(common,isPlayer)) exitWith {}; //Calculate air density: private _altitude = (getPosASL _vehicle) select 2; diff --git a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf index 216bab43bc..c3dcc2cfe4 100644 --- a/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf +++ b/addons/mk6mortar/functions/fnc_handlePlayerVehicleChanged.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: PabstMirror - * Handles player getting into new vehicle. Loads PFEG for mortar display if it is a mortar. + * Handles player getting into new vehicle. Loads PFEG for mortar display if it is a mortar. * * Arguments: * 0: Player @@ -11,7 +11,7 @@ * None * * Example: - * [bob, mortar] call ace_mk6mortar_fnc_handlePlayerVehicleChanged; + * [player, cursorObject] call ace_mk6mortar_fnc_handlePlayerVehicleChanged * * Public: No */ @@ -19,88 +19,83 @@ params ["_player", "_newVehicle"]; if (isNull _newVehicle) exitWith {}; -if (!(_newVehicle isKindOf "Mortar_01_base_F")) exitWith {}; +if !(_newVehicle isKindOf "Mortar_01_base_F") exitWith {}; private _tubeWeaponName = (weapons _newVehicle) select 0; private _fireModes = getArray (configFile >> "CfgWeapons" >> _tubeWeaponName >> "modes"); -//Restore last firemode: -private _lastFireMode = _newVehicle getVariable [QGVAR(lastFireMode), -1]; -if (_lastFireMode != -1) then { - _player action ["SwitchWeapon", _newVehicle, _player, _lastFireMode]; +// Restore last firemode +private _lastSavedWeaponsInfo = _newVehicle getVariable QGVAR(lastFireMode); + +if (!isNil "_lastSavedWeaponsInfo") then { + _newVehicle selectWeaponTurret [_lastSavedWeaponsInfo select 0, [0], _lastSavedWeaponsInfo select 1, _lastSavedWeaponsInfo select 2]; }; [{ - params ["_args", "_pfID"]; - _args params ["_mortarVeh", "_fireModes"]; + params ["_mortarVeh", "_pfhID"]; - if ((vehicle ACE_player) != _mortarVeh) then { - [_pfID] call CBA_fnc_removePerFrameHandler; + if ((vehicle ACE_player) != _mortarVeh) exitWith { + _pfhID call CBA_fnc_removePerFrameHandler; + }; + + // Save firemode ('charge' from weaponstate) on vehicle + _mortarVeh setVariable [QGVAR(lastFireMode), (weaponState [_mortarVeh, [0]]) select [0, 3]]; + + if (shownArtilleryComputer && {!GVAR(allowComputerRangefinder)}) then { + // Don't like this solution, but it works + closeDialog 0; + [parseText "Computer Disabled"] call EFUNC(common,displayTextStructured); + }; + + private _display = uiNamespace getVariable ["ACE_Mk6_RscWeaponRangeArtillery", displayNull]; + + if (isNull _display) exitWith {}; // It may be null for the first frame + + // Hud should hidden in 3rd person + private _notGunnerView = cameraView != "GUNNER"; + private _useMils = _mortarVeh getVariable [QGVAR(useMils), true]; + + // Get aiming values from ace_artillerytables + // Note: it also handles displaying the "charge" level + private _realAzimuth = missionNamespace getVariable [QEGVAR(artillerytables,predictedAzimuth), -1]; + private _realElevation = missionNamespace getVariable [QEGVAR(artillerytables,predictedElevation), -1]; + + // Update Heading Display + if (_notGunnerView || !GVAR(allowCompass)) then { + (_display displayCtrl 80156) ctrlSetText ""; } else { - - private _useMils = _mortarVeh getVariable [QGVAR(useMils), true]; - - //Compute: 'charge' from weaponstate - private _currentFireMode = (weaponState [_mortarVeh, [0]]) select 2; - private _currentChargeMode = _fireModes find _currentFireMode; - - //Save firemode on vehicle: - _mortarVeh setVariable [QGVAR(lastFireMode), _currentChargeMode]; - - if (shownArtilleryComputer && {!GVAR(allowComputerRangefinder)}) then { - //Don't like this solution, but it works - closeDialog 0; - [parseText "Computer Disabled"] call EFUNC(common,displayTextStructured); - }; - - private _display = uiNamespace getVariable ["ACE_Mk6_RscWeaponRangeArtillery", displayNull]; - if (isNull _display) exitWith {}; //It may be null for the first frame - - //Hud should hidden in 3rd person - private _notGunnerView = cameraView != "GUNNER"; - - // Get aiming values from ace_artillerytables - // Note: it also handles displaying the "charge" level - private _realAzimuth = missionNamespace getVariable [QEGVAR(artillerytables,predictedAzimuth), -1]; - private _realElevation = missionNamespace getVariable [QEGVAR(artillerytables,predictedElevation), -1]; - - //Update Heading Display: - if (_notGunnerView || (!GVAR(allowCompass))) then { - (_display displayCtrl 80156) ctrlSetText ""; + if (_useMils) then { + (_display displayCtrl 80156) ctrlSetText str (((round (_realAzimuth * 6400 / 360)) + 6400) % 6400); } else { + (_display displayCtrl 80156) ctrlSetText str ((round (_realAzimuth + 360)) % 360); + }; + }; + + // Update CurrentElevation Display + if (_notGunnerView) then { + (_display displayCtrl 80175) ctrlSetText ""; + } else { + if (_useMils) then { + (_display displayCtrl 80175) ctrlSetText str ((round (_realElevation * 6400 / 360)) % 6400); + } else { + (_display displayCtrl 80175) ctrlSetText str (((round (_realElevation * 100)) / 100) % 360); + }; + }; + + // Update ElevationNeeded Display + if (_notGunnerView || !GVAR(allowComputerRangefinder)) then { + (_display displayCtrl 80176) ctrlSetText ""; + } else { + private _elevDeg = parseNumber ctrlText (_display displayCtrl 176); + if (_elevDeg <= 0) then { // Bad data means "----" out of range + (_display displayCtrl 80176) ctrlSetText (ctrlText (_display displayCtrl 176)); + } else { + _elevDeg = _elevDeg + (_realElevation - (parseNumber ctrlText (_display displayCtrl 175))); if (_useMils) then { - (_display displayCtrl 80156) ctrlSetText str (((round (_realAzimuth * 6400 / 360)) + 6400) % 6400); + (_display displayCtrl 80176) ctrlSetText str round ((round (_elevDeg * 6400 / 360)) % 6400); } else { - (_display displayCtrl 80156) ctrlSetText str ((round (_realAzimuth + 360)) % 360); - }; - }; - - //Update CurrentElevation Display - if (_notGunnerView) then { - (_display displayCtrl 80175) ctrlSetText ""; - } else { - if (_useMils) then { - (_display displayCtrl 80175) ctrlSetText str ((round (_realElevation * 6400 / 360)) % 6400); - } else { - (_display displayCtrl 80175) ctrlSetText str (((round (_realElevation * 100)) / 100) % 360); - }; - }; - - //Update ElevationNeeded Display: - if (_notGunnerView || (!GVAR(allowComputerRangefinder))) then { - (_display displayCtrl 80176) ctrlSetText ""; - } else { - private _elevDeg = parseNumber ctrlText (_display displayCtrl 176); - if (_elevDeg <= 0) then { //Bad data means "----" out of range - (_display displayCtrl 80176) ctrlSetText (ctrlText (_display displayCtrl 176)); - } else { - _elevDeg = _elevDeg + (_realElevation - (parseNumber ctrlText (_display displayCtrl 175))); - if (_useMils) then { - (_display displayCtrl 80176) ctrlSetText str round ((round (_elevDeg * 6400 / 360)) % 6400); - } else { - (_display displayCtrl 80176) ctrlSetText str (((round (_elevDeg * 100)) / 100) % 360); - }; + (_display displayCtrl 80176) ctrlSetText str (((round (_elevDeg * 100)) / 100) % 360); }; }; }; -}, 0, [_newVehicle, _fireModes]] call CBA_fnc_addPerFrameHandler; +}, 0, _newVehicle] call CBA_fnc_addPerFrameHandler; 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/mk6mortar/initSettings.sqf b/addons/mk6mortar/initSettings.inc.sqf similarity index 100% rename from addons/mk6mortar/initSettings.sqf rename to addons/mk6mortar/initSettings.inc.sqf diff --git a/addons/mk6mortar/stringtable.xml b/addons/mk6mortar/stringtable.xml index 09f060ca00..c6f29a037d 100644 --- a/addons/mk6mortar/stringtable.xml +++ b/addons/mk6mortar/stringtable.xml @@ -12,7 +12,7 @@ Tabela de distâncias de para 82mm 82mm Rangetable Tavola di tiro 82mm - 82mm 射表 + 82mm用 射表 82mm 사거리표 82 mm 迫击炮射表 82毫米迫擊炮射表 @@ -28,8 +28,8 @@ Hatótáv-tábla a Mk6 82mm-es mozsárhoz Tabela de distâncias para morteiro Mk6 82mm Rangetable pro Mk6 82mm minomet - Tavola di tiro per il mortaio calibro 82mm Mk6 - Mk6 82mm 迫撃砲の射表 + Tavola di tiro per il mortaio Mk6 di calibro 82mm + Mk6 82mm迫撃砲専用の射撃表 Mk6 82mm 박격포 사격을 위한 사거리표 MK6 82 mm 迫击炮射表 MK6 82毫米迫擊炮射表 @@ -46,7 +46,7 @@ Abrir tabela de distâncias para 82mm Otevřít 82mm Rangetable Apri la tavola di tiro 82mm - 82mm 射表を開く + 82mm用 射表 を開く 82mm 사거리표 열기 开启82 mm 迫击炮射表 開啟82毫米迫擊炮射表 @@ -130,7 +130,7 @@ Játékos általi lövésekhez, legyen-e számított légellenállás és szélhatás Для выстрелов игрока. Моделирует сопротивление воздуха и эффект ветра Per Proiettili dei Giocatori, simula la Resistenza dell'Aria e gli Effetti del Vento - プレイヤが射撃すると、空気抵抗モデルと風による影響をあたえます。 + プレイヤーが射撃すると、空気抵抗モデルと風による影響をあたえます。 플레이어가 사격 시 공기저항과 바람에 영향을 받습니다 设定由玩家射击的迫击炮,将会受到空气阻力与风力的影响 設定由玩家射擊的迫擊砲,將會受到空氣阻力與風力的影響 @@ -146,7 +146,7 @@ Mk6 számítógép engedélyezése Разрешить компьютер Mk6 Consenti Computer Mk6 - Mk6 コンピュータを許可 + Mk6の砲撃コンピュータを許可 Mk6 탄도계산컴퓨터 허가 允许使用 MK6 弹道计算机 允許使用MK6射控電腦 @@ -162,8 +162,8 @@ Affiche l'ordinateur de tir et le télémètre. Cette option doit être DÉSACTIVÉE si la résistance de l'air est activée. A távmérő és számítógép megjelenítése (ezeket el KELL távolítani ha a légellenállás engedélyezve van) Показывает компьютер и дальномер (это НУЖНО отключить, если вы включаете сопротивление воздуха) - Mostra il Computer e Distaziometro (questi DEVONO essere rimossi se vuoi abilitare la resistenza dell'aria) - コンピュータと距離を表示します (空気抵抗を有効化している場合は必ず削除してください) + Consenti l'utilizzo del Computer Balistico e del Telemetro (questi DEVONO essere disabilitati se vuoi abilitare la resistenza dell'aria) + 砲撃コンピュータと距離計を表示します (空気抵抗を有効化する場合はこれらを取り除く必要があります) 탄도계산컴퓨터와 거리측정기를 보여줍니다(공기저항을 활성화했을 경우 이 항목은 비활성화 되어야 합니다) 显示弹道计算机和测距仪(如果有启用空气阻力功能时,须停用此项功能) 顯示射控電腦和測距儀 (如果有啟用空氣阻力功能時,須停用此項功能) @@ -179,7 +179,7 @@ Mk6 iránytű engedélyezése Разрешить компас Mk6 Consenti Bussola Mk6 - Mk6 への方位磁石を有効化 + Mk6の方位磁石を許可 Mk6 나침반 허용 允许使用 MK6 指南针 允許使用MK6指北針 @@ -195,8 +195,8 @@ Affiche la boussole numérique du Mk6. Az Mk6 digitális iránytű megjelenítése Показывает цифровой компас Mk6 - Mostra la Bussola Digitale Mk6 - Mk6 のデジタル方位磁石を表示 + Mostra la Bussola Digitale del Mk6 + Mk6迫撃砲のデジタル方位磁石を表示します Mk6 에서 전자 나침반을 보여줍니다 显示 MK6 的电子指南针 顯示MK6的數位指北針 @@ -210,9 +210,9 @@ Este módulo permite que você ajuste o morteiro Mk6. Модуль настройки миномета Mk6. Ce module permet de régler les options du mortier Mk6. - Questo modulo ti consente di impostare i parametri del mortaio Mk6. + Questo modulo ti consente di impostare le impostazioni del mortaio Mk6. Este módulo permite configurar los parámetros del mortero Mk6. - Mk6 迫撃砲への設定をできます。 + このモジュールでは、Mk6 迫撃砲の設定をセットアップできます。 이 모듈은 Mk6 설치 설정을 가능케 합니다. 这个模块允许你设定 MK6 迫击炮的相关功能 這個模塊允許你設定MK6迫擊砲的相關功能 @@ -238,10 +238,10 @@ Elimina los cargadores del mortero, requiriendo al artillero o cargador la carga manual de cada rondas. No afecta morteros controlados por IA. Usuwa magazynki moździerza, wymagając ładowania pojedynczych pocisków przez strzelca lub ładowniczego. Nie dotyczy moździerzy AI. Enlève les chargeurs de mortier, ce qui oblige le tireur ou le servant à charger les obus manuellement. N'affecte pas les mortiers IA. - Toglie i proiettili dal mortaio. I colpi singoli devono essere caricati dall'operatore. Non cambia quado l'IA spara. + Rimuove i caricatori di colpi dal mortaio. Un operatore dovrà caricare proiettili singoli prima di poter fare fuoco. Non viene applicato su operatori IA. Elimina os carregadores do morteiro, requerendo que o atirador ou carregador utilize de forma individual a munição. Não afeta os morteiros controlados pela IA. Удаляет артиллерийские магазины, требует загрузку отдельных снарядов стрелком или заряжающим. Не влияет на артиллерию ИИ. - 迫撃砲から弾薬を除去します。射手か装填手により予め装填されている必要があります。AI迫撃砲へ影響を与えません。 + 迫撃砲から弾倉を除去します。一発ずつ射手か装填手によって装填される必要があります。AIの迫撃砲には影響を与えません。 박격포 탄창을 제거합니다, 사수나 장전수가 개별적으로 탄환을 넣어줘야 합니다. 인공지능은 영향을 받지 않습니다. 开启此功能时。迫击炮的弹药需由炮手与装填手共同合作来进行装填。此功能并不影响由 AI 射击的迫击炮 開啟此功能時。迫擊砲的彈藥需由砲手與裝填手共同合作來進行裝填。此功能並不影響由AI射擊的迫擊砲 @@ -257,7 +257,7 @@ Odstranit náboj Remover munição Извлечь снаряд - 弾薬を除去 + 砲弾を取り除く 탄약 제거 卸除弹头 卸除彈頭 @@ -273,7 +273,7 @@ Nabít minomet Carregar morteiro Зарядить миномет - 弾薬を装填 + 砲弾を装填 탄약 장전 装载弹头 裝載彈頭 @@ -285,10 +285,10 @@ Descargando ronda Rozładowywanie moździerza Déchargement de l'obus - Scarica proiettile + Togliendo Proiettile Descarregar munição Извлечение снаряда - 弾薬を除去しています + 砲弾を取り除いています 탄약 제거 중 正在卸除弹头 卸除彈頭中 @@ -301,11 +301,11 @@ Preparando ronda Przygotowywanie pocisku Praparation de l'obus - Prepara il proiettile + Caricando Proiettile Připavuji náboj Preparar munição Подготовка снаряда - 砲弾を事前装填 + 砲弾を準備 탄약 준비 중 正在准备弹头 準備彈頭中 @@ -317,11 +317,11 @@ Cargar HE Załaduj pocisk wybuchowy Charger HE - Carica proiettile esplosivo ad alto potenziale (HE) + Carica Proiettile Esplosivo (HE) Nabít HE Carregar HE Зарядить фугасный - りゅう弾を装填 + 榴弾を装填 고폭탄 장전 装载高爆弹 裝載高爆彈 @@ -333,7 +333,7 @@ Cargar Humo Załaduj pocisk dymny Charger Fumigène - Carica fumogeno + Carica Proiettile Fumogeno Nabít Dýmovnici Carregar Fumaça Зарядить дымовой @@ -349,7 +349,7 @@ Cargar Iluminación Załaduj pocisk oświetlający Charger Éclairant - Carica illuminante + Carica Proiettile Illuminante Nabít Světlici Carregar Iluminação Зарядить осветительный @@ -365,11 +365,11 @@ Cagar HE Guiada Załaduj kierowany pocisk wybuchowy Charger HE guidé - Carica HE guidata + Carica Proiettile Esplosivo (HE) Guidato Nabít HE (Naváděné) Carregar HE Guiada Зарядить фугасный управляемый - 誘導りゅう弾を装填 + 誘導榴弾を装填 유도 고폭탄 장전 装载制导高爆弹 裝載導引高爆彈 @@ -381,11 +381,11 @@ Cargar HE Guiada por Laser Załaduj laserowo napr. pocisk wybuchowy Charger HE guidé au laser - Carica HE a guida laser + Carica Proiettile Esplosivo (HE) Laserguidato Nabít HE (Naváděné laserem) Carregar HE Guiada por Laser Зарядить фугасный управляемый по ЛЦУ - レーザ誘導りゅう弾を装填 + レーザー誘導榴弾を装填 레이저 유도 고폭탄 장전 装填激光制导高爆弹 裝載雷射導引高爆彈 @@ -401,7 +401,7 @@ [CSW] 82mm HE náboj [CSW] Munição 82mm HE [CSW] Фугасный снаряд 82мм - [CSW] 82mm りゅう弾 + [CSW] 82mm 榴弾 [CSW] 82mm 고폭탄 [班组] 82 mm 高爆弹 [CSW] 82毫米高爆彈 @@ -413,7 +413,7 @@ [CSW] Ronda 82mm Humo [CSW] Pocisk dymny kal. 82mm [CSW] Obus de 82 mm fumigène - [CSW] Proiettile Fumogeno da 82mm + [CSW] Proiettile da 82mm Fumogeno [CSW] 82mm Kouřový náboj [CSW] Munição 82mm Fumaça [CSW] Дымовой снаряд 82мм @@ -429,7 +429,7 @@ [CSW] Ronda 82mm Iluminación [CSW] Pocisk oświetlający kal. 82mm [CSW] Obus de 82 mm éclairant - [CSW] Proiettile illuminante da 82mm + [CSW] Proiettile da 82mm Illuminante [CSW] 82mm Osvětlovací náboj [CSW] Munição 82mm Iluminação [CSW] Осветительный снаряд 82мм @@ -445,11 +445,11 @@ [CSW] Ronda 82mm Guiada [CSW] Kierowany pocisk wybuchowy kal. 82mm [CSW] Obus de 82 mm HE guidé - [CSW] Proiettile HE guidato + [CSW] Proiettile da 82mm HE Guidato [CSW] 82mm HE náboj (naváděný) [CSW] Munição 82mm HE Guiada [CSW] Фугасный снаряд управляемый 82мм - [CSW] 82mm 誘導りゅう弾 + [CSW] 82mm 誘導榴弾 [CSW] 82mm 유도 고폭탄 [班组] 82 mm 制导高爆弹 [CSW] 82毫米導引高爆彈 @@ -461,11 +461,11 @@ [CSW] Ronda 82mm Guiada por Laser [CSW] Laserowo napr. pocisk wybuchowy kal. 82mm [CSW] Obus de 82 mm HE guidé au laser - [CSW] Proiettile HE a guida laser + [CSW] Proiettile da 82mm HE Laserguidato [CSW] 82mm HE náboj (naváděný laserem) [CSW] Munição 82mm HE Guiada por Laser [CSW] Фугасный снаряд управляемый по ЛЦУ 82мм - [CSW] 82mm レーザ誘導りゅう弾 + [CSW] 82mm レーザー誘導榴弾 [CSW] 82mm 레이저 유도 고폭탄 [班组] 82 mm 激光制导高爆弹 [CSW] 82毫米雷射導引高爆彈 @@ -481,7 +481,7 @@ Používá se u minometu Mk6 Usada no Morteiro MK6 Использовался в миномете Mk6 - Mk6 mortar で使います + Mk6 迫撃砲 で使用 Mk6 박격포에 사용됨 用于 Mk6 迫击炮 用於Mk6迫擊砲 @@ -492,11 +492,11 @@ [ACE] Caja de municiones 82mm HE [ACE] Skrzynka amunicji wybuchowej 82mm [ACE] Obus de 82 mm HE - [ACE] Scatola proiettili espolisvi ad alto potenziale (HE) da 82mm + [ACE] Scatola Proiettili Esplosivi (HE) da 82mm [ACE] Bedna s municí (82mm HE) [ACE] Caixa de Munição 82mm HE [ACE] Ящик фугасных снарядов 82мм - [ACE] 82mm りゅう弾入り弾薬箱 + [ACE] 82mm 榴弾入り弾薬箱 [ACE] 82mm 고폭탄 상자 [ACE] 82 mm 高爆弹药箱 [ACE] 82毫米高爆彈藥箱 @@ -508,7 +508,7 @@ [ACE] Caja de municiones 82mm Humo [ACE] Skrzynka amunicji dymnej 82mm [ACE] Obus de 82 mm fumigène - [ACE] Scatola fumogeni da 82mm + [ACE] Scatola Proiettili Fumogeni da 82mm [ACE] Bedna s municí (82mm Dýmovnice) [ACE] Caixa de Munição 82mm Fumaça [ACE] Ящик дымовых снарядов 82мм @@ -524,7 +524,7 @@ [ACE] Caja de municiones 82mm Iluminacion [ACE] Skrzynka amunicji oświetlającej 82mm [ACE] Obus de 82 mm éclairants - [ACE] Scatola illuminanti da 82mm + [ACE] Scatola Proiettili Illuminanti da 82mm [ACE] Bedna s municí (82mm Světlice) [ACE] Caixa de Munição 82mm Iluminação [ACE] Ящик осветительных снарядов 82мм @@ -540,11 +540,11 @@ [ACE] Caja de municiones 82mm por defecto [ACE] Skrzynka amunicji standardowej 82mm [ACE] Obus de 82 mm par défaut - [ACE] Scatola proiettili 82mm standard + [ACE] Scatola Proiettili 82mm Misti [ACE] Bedna se standardní 82mm municí [ACE] Caixa de Munição 82mm Padrão [ACE] Ящик снарядов 82мм (стандартный) - [ACE] 82mm 保管箱 + [ACE] 82mm 標準砲弾セット入り弾薬箱 [ACE] 82mm 기본 장비 상자 [ACE] 82 mm 预设弹药箱 [ACE] 82毫米預設彈藥箱 diff --git a/addons/modules/XEH_postInit.sqf b/addons/modules/XEH_postInit.sqf index bdc6a9cc40..c391916f19 100644 --- a/addons/modules/XEH_postInit.sqf +++ b/addons/modules/XEH_postInit.sqf @@ -26,7 +26,7 @@ _function = missionNamespace getVariable _function; }; if (_isSingular && {_logicType in _uniqueModulesHandled}) then { //ToDo: should this be an exit? - WARNING_1("Module [%1] - More than 1 singular module placed", _logicType); + WARNING_1("Module [%1] - More than 1 singular module placed",_logicType); }; if (_isSingular) then {_uniqueModulesHandled pushBack _logicType;}; diff --git a/addons/movement/CfgEventHandlers.hpp b/addons/movement/CfgEventHandlers.hpp index 2608d0260b..f6503c2479 100644 --- a/addons/movement/CfgEventHandlers.hpp +++ b/addons/movement/CfgEventHandlers.hpp @@ -15,9 +15,3 @@ class Extended_PostInit_EventHandlers { init = QUOTE(call COMPILE_SCRIPT(XEH_postInit)); }; }; - -class Extended_DisplayLoad_EventHandlers { - class RscDisplayInventory { - ADDON = QUOTE(_this call FUNC(inventoryDisplayLoad)); - }; -}; diff --git a/addons/movement/XEH_PREP.hpp b/addons/movement/XEH_PREP.hpp index ceafa7f5dc..36fe97880d 100644 --- a/addons/movement/XEH_PREP.hpp +++ b/addons/movement/XEH_PREP.hpp @@ -3,4 +3,3 @@ PREP(canClimb); PREP(climb); PREP(handleClimb); PREP(handleVirtualMass); -PREP(inventoryDisplayLoad); diff --git a/addons/movement/XEH_postInit.sqf b/addons/movement/XEH_postInit.sqf index f64b92603b..4d7cc5ba12 100644 --- a/addons/movement/XEH_postInit.sqf +++ b/addons/movement/XEH_postInit.sqf @@ -3,8 +3,8 @@ if (!hasInterface) exitWith {}; -["unit", FUNC(handleVirtualMass)] call CBA_fnc_addPlayerEventHandler; -["loadout", FUNC(handleVirtualMass)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handleVirtualMass)] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handleVirtualMass)] call CBA_fnc_addPlayerEventHandler; ["ACE3 Movement", QGVAR(climb), localize LSTRING(Climb), { // Conditions: canInteract diff --git a/addons/movement/stringtable.xml b/addons/movement/stringtable.xml index 544e7914a7..560d407f68 100644 --- a/addons/movement/stringtable.xml +++ b/addons/movement/stringtable.xml @@ -12,7 +12,7 @@ Mostrar peso em libras Súly megjelenítése fontban. Показывать вес в фунтах - ポンドで重量を表示する + ポンドで重量を表示 무게를 파운드(lb)로 보여줍니다 使用磅来显示重量 使用磅來顯示重量 @@ -29,7 +29,7 @@ Mászás Arrampicati Subir - 登る + よじ登る 오르기 攀爬 攀爬 diff --git a/addons/mx2a/stringtable.xml b/addons/mx2a/stringtable.xml index a16caf4075..fd7a76d6fa 100644 --- a/addons/mx2a/stringtable.xml +++ b/addons/mx2a/stringtable.xml @@ -29,7 +29,7 @@ Hőleképező készülék Тепловизионный прибор Dispositivo di visione termica - サーマル画像表示双眼鏡 + 熱画像表示装置 열화상 장치 热成像装置 熱成像裝置 diff --git a/addons/nametags/XEH_postInit.sqf b/addons/nametags/XEH_postInit.sqf index 85115690b4..a3fb7307f2 100644 --- a/addons/nametags/XEH_postInit.sqf +++ b/addons/nametags/XEH_postInit.sqf @@ -50,7 +50,7 @@ if (missionNamespace getVariable [QGVAR(useFactionIcons), true]) then { { if (isArray (_x >> QGVAR(rankIcons))) then { private _faction = configName _x; - if (!isNil {GVAR(factionRanks) getVariable _faction}) exitWith {}; // don't overwrite if already set + if (_faction in GVAR(factionRanks)) exitWith {}; // don't overwrite if already set private _icons = getArray (_x >> QGVAR(rankIcons)); [_faction, _icons] call FUNC(setFactionRankIcons); }; diff --git a/addons/nametags/XEH_preInit.sqf b/addons/nametags/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/nametags/XEH_preInit.sqf +++ b/addons/nametags/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/nametags/functions/fnc_drawNameTagIcon.sqf b/addons/nametags/functions/fnc_drawNameTagIcon.sqf index aa9c900390..efe0c6bf15 100644 --- a/addons/nametags/functions/fnc_drawNameTagIcon.sqf +++ b/addons/nametags/functions/fnc_drawNameTagIcon.sqf @@ -21,7 +21,7 @@ * Public: No */ -TRACE_1("drawName:", _this); +TRACE_1("drawName:",_this); params ["", "_target", "", "_heightOffset"]; @@ -42,7 +42,7 @@ _fnc_parameters = { default { private _targetFaction = _target getVariable [QGVAR(faction), faction _target]; - private _customRankIcons = GVAR(factionRanks) getVariable _targetFaction; + private _customRankIcons = GVAR(factionRanks) get _targetFaction; if (!isNil "_customRankIcons") then { _customRankIcons param [ALL_RANKS find rank _target, ""] // return diff --git a/addons/nametags/functions/fnc_initIsSpeaking.sqf b/addons/nametags/functions/fnc_initIsSpeaking.sqf index 5bae931e60..db2bf30ac3 100644 --- a/addons/nametags/functions/fnc_initIsSpeaking.sqf +++ b/addons/nametags/functions/fnc_initIsSpeaking.sqf @@ -41,14 +41,14 @@ switch (true) do { INFO("ACRE Detected."); DFUNC(isSpeaking) = { params ["_unit"]; - ([_unit] call acre_api_fnc_isSpeaking) && {!(_unit getVariable ["ACE_isUnconscious", false])} + ([_unit] call acre_api_fnc_isSpeaking) && {_unit call EFUNC(common,isAwake)} }; }; case (["task_force_radio"] call EFUNC(common,isModLoaded)): { INFO("TFAR Detected."); DFUNC(isSpeaking) = { params ["_unit"]; - (_unit getVariable ["tf_isSpeaking", false]) && {!(_unit getVariable ["ACE_isUnconscious", false])} + (_unit getVariable ["tf_isSpeaking", false]) && {_unit call EFUNC(common,isAwake)} }; }; default { @@ -65,7 +65,7 @@ switch (true) do { DFUNC(isSpeaking) = { params ["_unit"]; - (_unit getVariable [QGVAR(isSpeakingInGame), false]) && {!(_unit getVariable ["ACE_isUnconscious", false])} + (_unit getVariable [QGVAR(isSpeakingInGame), false]) && {_unit call EFUNC(common,isAwake)} }; }; }; diff --git a/addons/nametags/functions/fnc_onDraw3d.sqf b/addons/nametags/functions/fnc_onDraw3d.sqf index 7e9d156014..f831a3209f 100644 --- a/addons/nametags/functions/fnc_onDraw3d.sqf +++ b/addons/nametags/functions/fnc_onDraw3d.sqf @@ -138,8 +138,7 @@ if (_enabledTagsNearby) then { [ACE_player, _target, _alpha, _distance * 0.026, _drawName, _drawRank, _drawSoundwave] call FUNC(drawNameTagIcon); }; }; - nil - } count _targets; + } forEach _targets; }; END_COUNTER(GVAR(onDraw3d)); diff --git a/addons/nametags/functions/fnc_setFactionRankIcons.sqf b/addons/nametags/functions/fnc_setFactionRankIcons.sqf index 88fd880833..42d3ed40cb 100644 --- a/addons/nametags/functions/fnc_setFactionRankIcons.sqf +++ b/addons/nametags/functions/fnc_setFactionRankIcons.sqf @@ -25,7 +25,7 @@ */ if (isNil QGVAR(factionRanks)) then { - GVAR(factionRanks) = [] call CBA_fnc_createNamespace; + GVAR(factionRanks) = createHashMap; }; params [["_faction", "", [""]], ["_icons", [], [[]], [7]]]; @@ -33,6 +33,11 @@ TRACE_2("setFactionRankIcons",_faction,_icons); if !(_faction != "" && {_icons isEqualTypeAll ""}) exitWith {false}; -GVAR(factionRanks) setVariable [_faction, _icons]; +_faction = configName (configFile >> "CfgFactionClasses" >> _faction); + +// Faction doesn't exist +if (_faction == "") exitWith {false}; + +GVAR(factionRanks) set [_faction, _icons]; true diff --git a/addons/nametags/initSettings.sqf b/addons/nametags/initSettings.inc.sqf similarity index 100% rename from addons/nametags/initSettings.sqf rename to addons/nametags/initSettings.inc.sqf diff --git a/addons/nametags/stringtable.xml b/addons/nametags/stringtable.xml index 0e5f3cd522..9f410c6a75 100644 --- a/addons/nametags/stringtable.xml +++ b/addons/nametags/stringtable.xml @@ -12,7 +12,7 @@ Névcímkék Имена игроков Etichette Nomi - 名札 + ネーム タグ 이름표 玩家名称 玩家名稱 @@ -28,8 +28,8 @@ Ce module permet de configurer les options et la distance d'affichage du nom des unités. Ez a modul lehetővé teszi a névcímkék beállításainak testreszabását. Этот модуль позволяет настроить опции и дистанцию отображения имен игроков. - Questo modulo ti consente di personalizzare le impostazioni ed il raggio delle Etichette Nomi - これは名札の表示範囲と設定を変更できます。 + Questo modulo ti consente di personalizzare le impostazioni ed la distanza visibile delle Etichette Nomi + このモジュールを使用すると、ネーム タグの設定と範囲を調整できます。 이 모듈은 당신이 이름표의 범위를 임의로 수정할 수 있게 해줍니다. 这个模块允许您设定名字和显示范围等设定 這個模塊允許您設定名稱和顯示範圍等設定 @@ -63,7 +63,7 @@ Mostrar nomes de jogadores Mostra i nomi dei giocatori Показывать имена игроков (включить имена) - プレイヤ名を表示 + プレイヤー名を表示 플레이어 이름 표시 显示玩家名称 顯示玩家名稱 @@ -80,7 +80,7 @@ Mutassa a játékosok nevét és kezelje az aktivációjukat. Alapértelmezett: Engedélyezve Показывать имена игроков и установить их активацию. По умолчанию: Включено Mostra nomi giocatori ed imposta la loro attivazione. Default: Abilitato - プレイヤ名の表示と設定を有効化します。標準: 有効 + プレイヤー名の表示とそれを有効にする方法を設定します。 デフォルト: 有効 플레이어 이름의 표시와 설정을 활성화합니다. 기본설정: 활성화 显示玩家的名字并设置其启动方式。预设:启用 顯示玩家的名稱並設置其啟動方式。預設: 啟用 @@ -97,7 +97,7 @@ Csak kurzorra Только под курсором Solo su Cursore - カーソルでのみ + カーソルを合わせた時 커서만 해당 只有准心指到时 只有準心指到時 @@ -114,7 +114,7 @@ Csak gombnyomásra Только по нажатию клавиши Solo quando Premi Tasto - キー押下のみ + キーを押した時のみ 키를 누를 경우만 只有按按键时 只有按按鍵時 @@ -131,7 +131,7 @@ Csak kurzorra és gombnyomásra Под курсором или по нажатию клавиши Solo su Cursore e quando Premi Tasto - カーソルとキー押下のみ + カーソルを合わせてキーを押した時のみ 커서와 키를 누를 경우만 只有在准心指到和按按键时 只有在準心指到和按按鍵時 @@ -140,11 +140,11 @@ Fade on screen border Am Bildschirmrand ausblenden - 画面端では非表示 + 画面端でフェードアウト Ukryj na brzegach ekranu 화면 가장자리에서 사라짐 Estomper sur les bords de l'écran - Sfocatura nei bordi dello schermo + Sfoca ai bordi dello schermo 在屏幕边框旁淡出 在螢幕邊框旁淡出 Затухание на границе экрана @@ -164,7 +164,7 @@ Mostrar patente de jogadores (requer nome de jogadores) Játékosok rendfokozatának mutatása (a nevek mutatása szükséges) Показывать звания игроков (при вкл. именах) - プレイヤの階級を表示 (プレイヤ名が必要) + プレイヤーの階級を表示 (プレイヤー名を表示が必要) 플레이어 계급 표시 (플레이어 이름 필요) 显示玩家军阶(玩家必须有设定名字) 顯示玩家軍階 (玩家必須有設定名稱) @@ -198,7 +198,7 @@ A legénységi adatok mutatása, alapértelmezett esetben a játékos által kiválasztható. Alapértelmezett: Nincs felülbírálás Показывать информацию об экипаже техники, или по умолчанию, позволяет игрокам выбрать свою настройку. По умолчанию: Не обязывать Mostra informazioni sull'equipaggio del veicolo, oppure consenti di default di lasciare che siano i giocatori a scegliere. Default: Non Forzare - 車両の乗員を表示します。標準ではプレイヤ各々が選べられます。標準: 強制しない + 車両の乗組員情報を表示するか、デフォルトでのようにプレイヤーが自分で情報を選択できるようにします。 デフォルト: 強制しない 승무원 정보를 표시하거나 플레이어가 직접 고르게 놔둡니다. 기본설정: 강제하지 않음 显示载具成员信息。在预设的情况下,系统允许玩家自己决定开关此信息。预设:不显示 顯示載具成員訊息。在預設的情況下,系統允許玩家自己決定開關此訊息。預設: 不顯示 @@ -215,7 +215,7 @@ Névcímkék mutatása MI-egységeknél Mostra i nomi delle le unità AI Mostrar nomes para unidades de IA - AIユニットの名札を表示 + AIユニットのネーム タグを表示 인공지능 인원 이름 표시 显示 AI 单位名字 顯示AI單位名稱 @@ -232,7 +232,7 @@ Mutassa-e a szövetséges AI egységek nevét és rangját? Alapértelmezett: Nincs felülbírálás Показывать имена и звания дружественных ботов? По умолчанию: Не обязывать Mostra etichette nomi ed etichette gradi per unità IA alleate? Default: Non forzare - 友軍のAIにも名前と階級を表示しますか? 標準: 強制しない + 友軍のAIにも名前と階級を表示しますか? デフォルト: 強制しない 아군 인공지능의 계급을 표시합니까? 기본설정: 강제하지 않음 显示友军 AI 的名字和军阶? 预设:不显示 顯示友軍AI的名稱和軍階? 預設: 不顯示 @@ -265,7 +265,7 @@ Показывать имя командира техники (только если клиент включил отображение имен). По умолчанию: Нет Affiche les noms pour les commandants de véhicule (uniquement si le client a activé l'affichage des noms). Mostra il nome sul cursore per il comandante del veicolo (solo se il client ha le Etichette Nomi attive) Default: No - 車長の名札をカーソルを当てて表示します (クライアント側で名札を有効化する必要があります) 標準: 無効 + カーソルを当てた時、車長のネーム タグを表示します (クライアント側でネーム タグを有効化する必要があります) デフォルト: 無効 차장의 이름표를 표시합니다 (오직 클라이언트가 이름표를 활성화할 시에만 보입니다) 기본설정: 아니요 使载具指挥官能透过准心指到别的单位来显示其名字(仅当客户端的名字功能已启用)。预设:关闭 使載具指揮官能透過準心指到別的單位來顯示其名稱 (僅當客戶端的名稱功能已啟用)。預設: 關閉 @@ -282,7 +282,7 @@ "Hanghullámok" mutatása (a nevek mutatása szükséges) Mostra movimento audio (insieme ai nomi) Mostrar onda sonora (requer nome de jogadores) - 音波形を表示 (プレイヤ名が必要) + 音波形を表示 (プレイヤー名の表示が必要) 음파 표시 (플레이어 이름 필요) 当玩家讲话时,显示声波图案(玩家必须有设定名字) 當玩家講話時,顯示聲波圖案 (玩家必須有設定名稱) @@ -299,7 +299,7 @@ Hanghullám-effekt a beszélő játékosok feje felett a PTT-gomb lenyomásakor. Ez a beállítás TFAR és ACRE2 alatt működik. Эффект звуковой волны над головами говорящих игроков при удерживании кнопки push-to-talk. Эта опция работает также с рациями TFAR и ACRE2. Effetto delle onde sonore sopra la testa dei giocatori parlanti quando premono il tasto PTT. Questa opzione funziona con TFAR ed ACRE2 - プレイヤーが PTT キーを押している間は、音波形を表示します。このオプションは TFAR と ACRE2 で動作します。 + プレイヤーが PTT キーを押している間は、音波形を表示します。 このオプションは TFAR と ACRE2 で動作します。 플레이어가 눌러서 말할 시 머리위에 음파효과를 적용합니다. 이 옵션은 TFAR과 ACRE2가 있을 때만 적용됩니다. 当玩家使用按键发话时,其头上的角色名字旁会显示声波的图案。此功能可搭配 TFAR、ACRE2 等模组使用。 當玩家使用按鍵發話時,其頭上的角色名稱旁會顯示聲波的圖案。此功能可搭配TFAR、ACRE2等模組使用。 @@ -316,7 +316,7 @@ Névcímkék beállításának használata Так же, как имена Usa impostazioni Etichette Nomi - 名札の設定 + ネーム タグの設定 이름표 설정 사용 玩家名称设定 玩家名稱設定 @@ -333,7 +333,7 @@ Mindig minden mutatása Всегда показывать Mostra Sempre Tutto - 常に表示する + 常に全て表示する 항상 모두 표시 永远显示全部 永遠顯示全部 @@ -350,7 +350,7 @@ Játékosok nevének látótávja Дистанция отображения имен Distanza Visiva Etichette Nomi - プレイヤ名が見える範囲 + プレイヤー名の表示距離 플레이어 이름 표시 거리 玩家名称显示距离 玩家名稱顯示距離 @@ -366,8 +366,8 @@ Distance au delà de laquelle les noms des joueurs ne sont plus affichés. Valeur par défaut : 5 mètres. Méterben megadott érték a játékosok nevének mutatására. Alapértelmezett: 5 Дистанция в метрах, на которой отображаются имена игроков. По умолчанию: 5 - Distanza in metri a cui sono visibili i nomi giocatori. Default: 5 - プレイヤの周り何メートルまで名札を表示できます。標準: 5 + Distanza in metri entro la quale sono visibili i nomi dei giocatori. Predefinito: 5 + プレイヤー名が表示される距離 (メートル)。 デフォルト: 5 플레이어 이름이 표시되는 미터. 기본설정: 5 设定名字在多少距离以内显示。预设:5米 設定名稱在多少距離以內顯示。預設:5公尺 @@ -376,7 +376,7 @@ Player tags transparency Spielernamen Transparenz - プレイヤー名札の透明度 + プレイヤーのネーム タグの透明度 玩家名称标签透明度 玩家名稱透明度 Trasparenza Etichette Nome @@ -400,7 +400,7 @@ Névcímkék mérete Размер имен игроков Dimensione Etichette Nome - 名札の大きさ + ネーム タグの大きさ 이름표 크기 玩家名称标记大小 玩家名稱標記大小 @@ -416,7 +416,7 @@ Taille du texte et des icônes. Szöveg és ikon méretének skálázása Масштабирование размера текста и иконок - Proporzione Dimensioni Testo ed Icone + Proporzione e Dimensioni di Testo ed Icone 文字とアイコンの大きさ 글자와 아이콘 크기 비례합니다 文字和图示大小设定 @@ -434,7 +434,7 @@ Alap névcímke-szín (csoporton kívüli személyek) Colore dei nomi non appartenenti al gruppo Cor padrão do nome (unidades fora do grupo) - 標準の名札の色 (グループメンバー以外) + ネーム タグの標準色 (グループメンバー以外) 기본 이름표 색상 (비그룹 멤버) 预设名字颜色(非同小队队友) 預設名稱顏色 (非同小隊隊友) @@ -451,7 +451,7 @@ Erőltetett rejtett Обязательно: Скрывать Forza Nascosto - 強制で非表示 + 非表示を強制 강제로 숨기기 强制隐藏 強迫隱藏 @@ -467,8 +467,8 @@ /!\ Module obsolète /!\ - Forcer l'affichage Erőltetett látható Обязательно: Показывать - Forza Mostra - 強制で表示 + Forza Visibili + 表示を強制 강제로 표시 强制显示 強迫顯示 @@ -484,8 +484,8 @@ /!\ Module obsolète /!\ - Forcer l'affichage sous le curseur uniquement Erőltetett látható, csak kurzorra Обязательно: Только под курсором - Forza Mostra solo su Cursore - カーソルでのみに強制する + Forza Visibili solo su Cursore + カーソルを合わせた時のみ に強制する 커서만 강제로 해당 强制仅显示在准心指到时 強制僅顯示在準心指到時 @@ -501,8 +501,8 @@ /!\ Module obsolète /!\ - Forcer l'affichage par appui de touche uniquement Erőltetett látható, csak gombnyomásra Обязательно: Только по нажатию клавиши - Forza Mostra solo quando Premi Tasto - キー押下のみに強制する + Forza Visibili solo quando Premi Tasto + キーを押した時のみ に強制 키를 누를 경우만 강제로 해당 强制仅显示在按按键时 強制僅顯示在按按鍵時 @@ -519,7 +519,7 @@ Erőltetett látható, csak kurzorra és gombnyomásra Обязательно: Под курсором или по нажатию клавиши Forza Mostra solo su Cursore e quando Premi Tasto - カーソルとキー押下のみに強制する + カーソルを合わせてキーを押した時のみ に強制 커서와 키를 누를 경우만 강제로 해당 强制显示在准心指到和按按键时 強制顯示在準心指到和按按鍵時 @@ -528,7 +528,8 @@ Nametag Ambient Brightness Coefficient Коэф. освещения для меток игроков - 環境名札明るさ係数 + Coeff. di Luminosità Ambiente + ネーム タグ 環境明るさ係数 Coefficient de luminosité ambiante Spielernamen Umgebungshelligkeitskoeffizient Współczynnik jasności otoczenia @@ -539,7 +540,8 @@ Adjusts how strongly ambient brightness affects nametag view distance. Определяет как сильно окружающее освещение влияет на дальность отображения меток игроков. - 環境光の強さによって名札の描画距離を調整します。 + Definisce quanto fortemente la luminosità dell'ambiente influenza la visibilità delle etichette nomi. + 周囲の明るさがネーム タグの表示距離にどの程度強く影響するかを調整します。 Définit à quel point le manque de lumière ambiante abaisse la distance de visibilité du nom des joueurs. Stellt ein, wie stark sich die Umgebungshelligkeit auf die Sichtweite der Spielernamen auswirkt. Definiuje jak bardzo jasność otoczenia wpływa na zasięg wyświetlania imion postaci. 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_postInit.sqf b/addons/nightvision/XEH_postInit.sqf index 9bfee4d166..5a1aa19b82 100644 --- a/addons/nightvision/XEH_postInit.sqf +++ b/addons/nightvision/XEH_postInit.sqf @@ -61,7 +61,7 @@ if (!isNil QGVAR(serverPriorFog)) then {[] call FUNC(nonDedicatedFix);}; // If v if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((currentVisionMode ACE_player != 1)) exitWith {false}; - if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + if !(missionNamespace getVariable [QGVAR(allowBrightnessControl), true]) exitWith {false}; // just a mission setVar (not ace_setting) // Statement [ACE_player, 1] call FUNC(changeNVGBrightness); @@ -73,7 +73,7 @@ if (!isNil QGVAR(serverPriorFog)) then {[] call FUNC(nonDedicatedFix);}; // If v if !([ACE_player, objNull, ["isNotEscorting", "isNotInside", "isNotSitting", "isNotRefueling"]] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((currentVisionMode ACE_player != 1)) exitWith {false}; - if (!(missionNamespace getVariable [QGVAR(allowBrightnessControl), true])) exitWith {false}; // just a mission setVar (not ace_setting) + if !(missionNamespace getVariable [QGVAR(allowBrightnessControl), true]) exitWith {false}; // just a mission setVar (not ace_setting) // Statement [ACE_player, -1] call FUNC(changeNVGBrightness); diff --git a/addons/nightvision/XEH_preInit.sqf b/addons/nightvision/XEH_preInit.sqf index 9361d05015..8251bf8baf 100644 --- a/addons/nightvision/XEH_preInit.sqf +++ b/addons/nightvision/XEH_preInit.sqf @@ -6,6 +6,9 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" + +// #9781 - register effects layer ASAP +QGVAR(display) cutText ["", "PLAIN"]; ADDON = true; diff --git a/addons/nightvision/functions/fnc_onCameraViewChanged.sqf b/addons/nightvision/functions/fnc_onCameraViewChanged.sqf index 2cbec4d16e..6f03c2a3af 100644 --- a/addons/nightvision/functions/fnc_onCameraViewChanged.sqf +++ b/addons/nightvision/functions/fnc_onCameraViewChanged.sqf @@ -23,7 +23,7 @@ TRACE_2("onCameraViewChanged",_unit,_cameraView); call FUNC(refreshGoggleType); if (GVAR(disableNVGsWithSights) && {(hmd _unit) != ""}) then { - if ((vehicle _unit == _unit) + if ((isNull objectParent _unit) || {isTurnedOut _unit} || {!([_unit] call EFUNC(common,hasHatch)) && {[_unit] call EFUNC(common,getTurretIndex) in ([vehicle _unit] call EFUNC(common,getTurretsFFV))} diff --git a/addons/nightvision/functions/fnc_onFiredPlayer.sqf b/addons/nightvision/functions/fnc_onFiredPlayer.sqf index 0be73062d2..5bc7ff621e 100644 --- a/addons/nightvision/functions/fnc_onFiredPlayer.sqf +++ b/addons/nightvision/functions/fnc_onFiredPlayer.sqf @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile"]; -TRACE_7("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile); +TRACE_7("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile); if ((!GVAR(running)) || {!GVAR(shutterEffects)} @@ -55,7 +55,7 @@ _visibleFire = _visibleFireCoef * _visibleFire; if (_ammo isKindOf "BulletBase") then { _visibleFire = _visibleFire min 5; // Prevent every shot from triggering with HMG }; -TRACE_1("final", _visibleFire); +TRACE_1("final",_visibleFire); if (_visibleFire <= 1.5) exitWith {}; if ((random (linearConversion [1, 4, GVAR(nvgGeneration), 10, 20])) > _visibleFire) exitWith {}; diff --git a/addons/nightvision/functions/fnc_onVisionModeChanged.sqf b/addons/nightvision/functions/fnc_onVisionModeChanged.sqf index 1913454f3f..8086b2d1a0 100644 --- a/addons/nightvision/functions/fnc_onVisionModeChanged.sqf +++ b/addons/nightvision/functions/fnc_onVisionModeChanged.sqf @@ -21,7 +21,7 @@ TRACE_2("onVisionModeChanged",_unit,_visionMode); // Handle disableNVGsWithSights setting: if (GVAR(disableNVGsWithSights) && {(hmd _unit) != ""}) then { - if ((vehicle _unit == _unit) + if ((isNull objectParent _unit) || {isTurnedOut _unit} || {!([_unit] call EFUNC(common,hasHatch)) && {[_unit] call EFUNC(common,getTurretIndex) in ([vehicle _unit] call EFUNC(common,getTurretsFFV))} diff --git a/addons/nightvision/functions/fnc_pfeh.sqf b/addons/nightvision/functions/fnc_pfeh.sqf index 3300a7ae28..dbd101631c 100644 --- a/addons/nightvision/functions/fnc_pfeh.sqf +++ b/addons/nightvision/functions/fnc_pfeh.sqf @@ -25,8 +25,8 @@ if (currentVisionMode _unit != 1) exitWith { GVAR(PFID) = -1; (missionNamespace getVariable [QGVAR(firedEHs), []]) params [["_firedPlayerID", -1], ["_firedPlayerVehicleID", -1]]; TRACE_2("removing fired EHs",_firedPlayerID,_firedPlayerVehicleID); - ["ace_firedPlayer", _firedPlayerID] call CBA_fnc_removeEventHandler, - ["ace_firedPlayerVehicle", _firedPlayerVehicleID] call CBA_fnc_removeEventHandler, + ["ace_firedPlayer", _firedPlayerID] call CBA_fnc_removeEventHandler; + ["ace_firedPlayerVehicle", _firedPlayerVehicleID] call CBA_fnc_removeEventHandler; }; if (EGVAR(common,OldIsCamera)) exitWith { if (GVAR(running)) then { @@ -36,7 +36,7 @@ if (EGVAR(common,OldIsCamera)) exitWith { }; }; if (!GVAR(running)) then { - TRACE_1("Un-Pausing", GVAR(paused)); + TRACE_1("Un-Pausing",GVAR(paused)); GVAR(running) = true; [true] call FUNC(setupDisplayEffects); [] call FUNC(refreshGoggleType); diff --git a/addons/nightvision/functions/fnc_refreshGoggleType.sqf b/addons/nightvision/functions/fnc_refreshGoggleType.sqf index 7414e58d02..ccfbd017b6 100644 --- a/addons/nightvision/functions/fnc_refreshGoggleType.sqf +++ b/addons/nightvision/functions/fnc_refreshGoggleType.sqf @@ -51,7 +51,7 @@ if ((alive ACE_player) && {isNull (ACE_controlledUAV select 0)}) then { if (isArray (_config >> QGVAR(colorPreset))) then {_preset = getArray (_config >> QGVAR(colorPreset));}; }; - TRACE_1("source: hmd",GVAR(playerHMD)); // Source is player's HMD (or possibly a NVG scope, but no good way to detect that) + TRACE_1("source: hmd",GVAR(playerHMD)); // Source is player's HMD (or possibly a NVG scope,but no good way to detect that) private _config = configFile >> "CfgWeapons" >> GVAR(playerHMD); if (!isClass _config) exitWith {}; 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/initSettings.sqf b/addons/nightvision/initSettings.inc.sqf similarity index 98% rename from addons/nightvision/initSettings.sqf rename to addons/nightvision/initSettings.inc.sqf index afcc7250c9..9d11956a12 100644 --- a/addons/nightvision/initSettings.sqf +++ b/addons/nightvision/initSettings.inc.sqf @@ -19,8 +19,8 @@ GVAR(nextEffectsUpdate) = -1; (missionNamespace getVariable [QGVAR(firedEHs), []]) params [["_firedPlayerID", -1], ["_firedPlayerVehicleID", -1]]; TRACE_2("removing fired EHs",_firedPlayerID,_firedPlayerVehicleID); - ["ace_firedPlayer", _firedPlayerID] call CBA_fnc_removeEventHandler, - ["ace_firedPlayerVehicle", _firedPlayerVehicleID] call CBA_fnc_removeEventHandler, + ["ace_firedPlayer", _firedPlayerID] call CBA_fnc_removeEventHandler; + ["ace_firedPlayerVehicle", _firedPlayerVehicleID] call CBA_fnc_removeEventHandler; } else { // Start PFH if scaling was previously set to 0 if ((currentVisionMode ACE_player == 1) && {!GVAR(running)}) then { diff --git a/addons/nightvision/stringtable.xml b/addons/nightvision/stringtable.xml index 9bce5acc50..1c1cd61ba7 100644 --- a/addons/nightvision/stringtable.xml +++ b/addons/nightvision/stringtable.xml @@ -4,7 +4,7 @@ ACE Nightvision ACE 暗視装置 - ACE Visione notturna + ACE Visione Notturna ACE-Nachtsicht ACE夜視鏡 ACE 夜视仪 @@ -21,7 +21,8 @@ NV Goggles (Gen1, Brown) JVN (Gen1, marron) ПНВ (Gen1, Коричневый) - 暗視装置 (第1世代、ブラウン) + Visore Notturno (Gen1, Marrone) + NVゴーグル (第1世代、ブラウン) Gogle noktowizyjne (Gen 1, Brązowe) NS-Brille (1. Gen., braun) 夜视仪(一代,棕色) @@ -32,7 +33,8 @@ NV Goggles (Gen1, Black) JVN (Gen1, noires) ПНВ (Gen1, Чёрный) - 暗視装置 (第1世代、ブラック) + Visore Notturno (Gen1, Nero) + NVゴーグル (第1世代、ブラック) Gogle noktowizyjne (Gen 1, Czarne) NS-Brille (1. Gen., schwarz) 夜视仪(一代,黑色) @@ -43,7 +45,8 @@ NV Goggles (Gen1, Green) JVN (Gen1, vertes) ПНВ (Gen1, Зелёный) - 暗視装置 (第1世代、グリーン) + Visore Notturno (Gen1, Verde) + NVゴーグル (第1世代、グリーン) Gogle noktowizyjne (Gen 1, Zielone) NS-Brille (1. Gen., grün) 夜视仪(一代,绿色) @@ -54,7 +57,8 @@ NV Goggles (Gen2, Brown) JVN (Gen2, marron) ПНВ (Gen2, Коричневый) - 暗視装置 (第2世代、ブラウン) + Visore Notturno (Gen2, Marrone) + NVゴーグル (第2世代、ブラウン) Gogle noktowizyjne (Gen 2, Brązowe) NS-Brille (2. Gen., braun) 夜视仪(二代,棕色) @@ -65,7 +69,8 @@ NV Goggles (Gen2, Black) JVN (Gen2, noires) ПНВ (Gen2, Чёрный) - 暗視装置 (第2世代、ブラック) + Visore Notturno (Gen2, Nero) + NVゴーグル (第2世代、ブラック) Gogle noktowizyjne (Gen 2, Czarne) NS-Brille (2. Gen., schwarz) 夜视仪(二代,黑色) @@ -76,7 +81,8 @@ NV Goggles (Gen2, Green) NV Goggles (Gen2, vertes) ПНВ (Gen2, Зелёный) - 暗視装置 (第2世代、グリーン) + Visore Notturno (Gen2, Verde) + NVゴーグル (第2世代、グリーン) Gogle noktowizyjne (Gen 2, Zielone) NS-Brille (2. Gen., grün) 夜视仪(二代,绿色) @@ -88,13 +94,13 @@ Noktovizor (Gen3) JVN (Gen3) NS-Brille (3. Gen.) - Occhiali notturni (Gen3) + Visore Notturno (Gen3) Gogle noktowizyjne (Gen3) Óculos de visão noturna (Gen3) ПНВ (Gen3) Gafas de visión nocturna (Gen3) Éjjellátó szemüveg (3. Gen.) - 暗視装置 (第3世代) + NVゴーグル (第3世代) 야투경 (3세대) 夜视仪(三代) 夜視鏡 (三代) @@ -105,13 +111,13 @@ Noktovizor (Gen3, hnědý) JVN (Gen3, marron) NS-Brille (3. Gen., braun) - Occhiali notturni (Gen3, Marroni) + Visore Notturno (Gen3, Marrone) Gogle noktowizyjne (Gen3, Brązowe) Óculos de visão noturna (Gen3, marrons) ПНВ (Gen3, Коричневый) Gafas de visión nocturna (Gen3, Marrón) Éjjellátó szemüveg (3. Gen., barna) - 暗視装置 (第3世代、ブラウン) + NVゴーグル (第3世代、ブラウン) 야투경 (3세대, 갈색) 夜视仪(三代,棕色) 夜視鏡 (三代, 棕色) @@ -119,32 +125,38 @@ NV Goggles (Gen3, Brown, WP) - 暗視装置 (第3世代、ブラウン) + NVゴーグル (第3世代、ブラウン、白色蛍光) + Visore Notturno (Gen3, Marrone, FB) Gogle noktowizyjne (Gen3, Brązowe, WP) NS-Brille (3. Generation, Braun, WP) 야투경 (3세대, 갈색, 백색광) JVN (Gen3, marron, WP) + ПНВ (Gen3, Коричневый, БФ) + Gafas de visión nocturna (Gen3, Marrón, FB) Night Vision Goggles, White Phosphor - 暗視装置、白色蛍光体 + ナイトビジョン・ゴーグル、白色蛍光 + Visore Notturno, Fosforo Bianco Gogle noktowizyjne, Biały Fosfor Nachtsichtbrille, weißer Phosphor 백색광 야투경 Jumelles Vision Nocturne, Phosphore blanc + Очки ночного видения, белый фосфор + Gafas de Visión Nocturna, Fósforo Blanco NV Goggles (Gen3, Green) Noktovizor (Gen3, zelený) JVN (Gen3, vertes) NS-Brille (3. Gen., grün) - Occhiali notturni (Gen3, Verdi) + Visore Notturno (Gen3, Verde) Gogle noktowizyjne (Gen3, Zielone) Óculos de visão noturna (Gen3, verdes) ПНВ (Gen3, Зелёный) Gafas de visión nocturna (Gen3, Verde) Éjjellátó szemüveg (3. Gen., zöld) - 暗視装置 (第3世代、グリーン) + NVゴーグル (第3世代、グリーン) 야투경 (3세대, 녹색) 夜视仪(三代,绿色) 夜視鏡 (三代, 綠色) @@ -152,24 +164,27 @@ NV Goggles (Gen3, Green, WP) - 暗視装置 (第3世代、グリーン、白色蛍光) + Visore Notturno (Gen3, Verde, FB) + NVゴーグル (第3世代、グリーン、白色蛍光) Gogle noktowizyjne (Gen3, Zielone, WP) NS-Brille (3. Generation, Grün, WP) 야투경 (3세대, 녹색, 백색광) JVN (Gen3, vertes, WP) + ПНВ (Gen3, Зелёный, БФ) + Gafas de visión nocturna (Gen3, Verde, FB) NV Goggles (Gen3, Black) Noktovizor (Gen3, černý) JVN (Gen3, noires) NS-Brille (3. Gen., schwarz) - Occhiali notturni (Gen3, Neri) + Visore Notturno (Gen3, Nero) Gogle noktowizyjne (Gen3, Czarne) Óculos de visão noturna (Gen3, pretos) ПНВ (Gen3, Чёрный) Gafas de visión nocturna (Gen3, Negro) Éjjellátó szemüveg (3. Gen., fekete) - 暗視装置 (第3世代、ブラック) + NVゴーグル (第3世代、ブラック) 야투경 (3세대, 검정색) 夜视仪(三代,黑色) 夜視鏡 (三代, 黑色) @@ -177,17 +192,21 @@ NV Goggles (Gen3, Black, WP) - 暗視装置 (第3世代、ブラック、白色蛍光) + NVゴーグル (第3世代、ブラック、白色蛍光) + Visore Notturno (Gen3, Nero, FB) Gogle noktowizyjne (Gen3, Czarne, WP) NS-Brille (3. Generation, Schwarz, WP) 야투경 (3세대, 검정, 백색광) JVN (Gen3, noires, WP) + ПНВ (Gen3, Чёрный, БФ) + Gafas de visión nocturna (Gen3, Negro, FB) NV Goggles (Gen4, Brown) JVN (Gen4, marron) ПНВ (Gen4, Коричневый) - 暗視装置 (第4世代、ブラウン) + Visore Notturno (Gen4, Marrone) + NVゴーグル (第4世代、ブラウン) Gogle noktowizyjne (Gen 4, Brązowe) NS-Brille (4. Gen., braun) 夜视仪(四代,棕色) @@ -196,17 +215,21 @@ NV Goggles (Gen4, Brown, WP) - 暗視装置 (第4世代、ブラウン、白色蛍光) + NVゴーグル (第4世代、ブラウン、白色蛍光) + Visore Notturno (Gen4, Marrone, FB) Gogle noktowizyjne (Gen 4, Brązowe, WP) NS-Brille (4. Generation, Braun, WP) 야투경 (4세대, 갈색, 백색광) JVN (Gen4, marron, WP) + ПНВ (Gen4, Коричневый, БФ) + Gafas de visión nocturna (Gen4, Marrón, FB) NV Goggles (Gen4, Black) JVN (Gen4, noires) ПНВ (Gen4, Чёрный) - 暗視装置 (第3世代、ブラック) + Visore Notturno (Gen4, Nero) + NVゴーグル (第4世代、ブラック) Gogle noktowizyjne (Gen 4, Czarne) NS-Brille (4. Gen., schwarz) 夜视仪(四代,黑色) @@ -215,17 +238,21 @@ NV Goggles (Gen4, Black, WP) - 暗視装置 (第3世代、ブラック、白色蛍光) + NVゴーグル (第4世代、ブラック、白色蛍光) + Visore Notturno (Gen4, Nero, FB) Gogle noktowizyjne (Gen 4, Czarne, WP) NS-Brille (4. Generation, Schwarz, WP) 야투경 (4세대, 검정, 백색광) JVN (Gen4, noires, WP) + ПНВ (Gen4, Чёрный, БФ) + Gafas de visión nocturna (Gen4, Negro, FB) NV Goggles (Gen4, Green) JVN (Gen4, vertes) ПНВ (Gen4, Зелёный) - 暗視装置 (第3世代、グリーン) + Visore Notturno (Gen4, Verde) + NVゴーグル (第4世代、グリーン) Gogle noktowizyjne (Gen 4, Zielone) NS-Brille (4. Gen., grün) 夜视仪(四代,绿色) @@ -234,17 +261,21 @@ NV Goggles (Gen4, Green, WP) - 暗視装置 (第3世代、グリーン、白色蛍光) + NVゴーグル (第4世代、グリーン、白色蛍光) + Visore Notturno (Gen4, Verde, FB) Gogle noktowizyjne (Gen 4, Zielone, WP) NS-Brille (4. Generation, Grün, WP) 야투경 (4세대, 녹색, 백색광) JVN (Gen4, vertes, WP) + ПНВ (Gen4, Зелёный, БФ) + Gafas de visión nocturna (Gen4, Verde, FB) NV Goggles (Wide, Brown) JVN (Large, marron) ПНВ (Широкий, Коричневый) - 暗視装置 (ワイド、ブラウン) + Visore Notturno (Grandangolo, Marrone) + NVゴーグル (ワイド、ブラウン) Gogle noktowizyjne (Szerokie, Brązowe) NS-Brille (Weit, braun) 夜视仪(宽,棕色) @@ -253,17 +284,21 @@ NV Goggles (Wide, Brown, WP) - 暗視装置 (ワイド、ブラウン、白色蛍光) + NVゴーグル (ワイド、ブラウン、白色蛍光) + Visore Notturno (Grandangolo, Marrone, FB) Gogle noktowizyjne (Szerokie, Brązowe, WP) NS-Brille (Weit, Braun, WP) 야투경 (넓음, 갈색, 백색광) JVN (Large, marron, WP) + ПНВ (Широкий, Коричневый, БФ) + Gafas de visión nocturna (Panorámicas, Marrón, FB) NV Goggles (Wide, Black) JVN (Large, noires) ПНВ (Широкий, Чёрный) - 暗視装置 (ワイド、ブラック) + Visore Notturno (Grandangolo, Nero) + NVゴーグル (ワイド、ブラック) Gogle noktowizyjne (Szerokie, Czarne) NS-Brille (Weit, schwarz) 夜视仪(宽,黑色) @@ -272,17 +307,21 @@ NV Goggles (Wide, Black, WP) - 暗視装置 (ワイド、ブラック、白色蛍光) + NVゴーグル (ワイド、ブラック、白色蛍光) + Visore Notturno (Grandangolo, Nero, FB) Gogle noktowizyjne (Szerokie, Czarne, WP) NS-Brille (Weit, Schwarz, WP) 야투경 (넓음, 검정, 백색광) JVN (Large, noires, WP) + ПНВ (Широкий, Чёрный, БФ) + Gafas de visión nocturna (Panorámicas, Negro, FB) NV Goggles (Wide, Green) JVN (Large, vertes) ПНВ (Широкий, Зелёный) - 暗視装置 (ワイド、グリーン) + Visore Notturno (Grandangolo, Verde) + NVゴーグル (ワイド、グリーン) Gogle noktowizyjne (Szerokie, Zielone) NS-Brille (Weit, grün) 夜视仪(宽,绿色) @@ -291,11 +330,14 @@ NV Goggles (Wide, Green, WP) - 暗視装置 (ワイド、グリーン、白色蛍光) + NVゴーグル (ワイド、グリーン、白色蛍光) + Visore Notturno (Grandangolo, Verde, FB) Gogle noktowizyjne (Szerokie, Zielone, WP) NS-Brille (Weit, Grün, WP) 야투경 (넓음, 녹색, 백색광) JVN (Large, vertes, WP) + ПНВ (Широкий, Зелёный, БФ) + Gafas de visión nocturna (Panorámicas, Verde, FB) Brightness: %1 @@ -413,7 +455,7 @@ NVG Fog Scale - 暗視装置の霧の規模 + 暗視装置フォグ強度 Livello Nebbia NVG Nebel in Nachtsicht 夜視鏡霧氣程度 @@ -428,7 +470,7 @@ Fog is used to limit visibility. - 霧は視界制限のために使われます。 + 霧で視程を制限します。 La nebbia viene utilizzata per limitare la visibilità. Nebel wird genutzt, um die Sichtbarkeit einzuschränken. 透過霧氣來縮減夜視鏡的可視距離 @@ -443,8 +485,8 @@ NVG Effect Scale - 暗視装置の効果規模 - Effetto livello NVG + 暗視装置エフェクト強度 + Livello dell'Effetto ACE NVG Nachtsichteffekte 夜視鏡效果程度 夜视仪效果程度 @@ -459,7 +501,7 @@ Blur and brightness effects [Setting to 0 will disable ALL nightvision effects] ぼかしと粒子、明度効果 [0 に設定で全効果を無効化します] - Effetti di sfocatura e luminosità [Importare a 0 disabiliterà TUTTI gli effetti della visione notturna] + Effetti di sfocatura e luminosità [Importare a 0 disabiliterà TUTTI gli effetti ACE della visione notturna] Unschärfe und Helligkeitseffekte [Dies auf 0 zu setzen deaktiviert SÄMTLICHE Nachtsichteffekte] 調整模糊與亮度的效果。[設值為0會關閉所有夜視鏡的特殊效果] 调整模糊与亮度的效果。[设值为0会关闭所有夜视仪的特殊效果] @@ -478,7 +520,7 @@ 瞄準具模糊程度 瞄准具模糊程度 Flou de visée - Blur durante la mira + Sfoca la mira attraverso ottiche Rozmazanie podczas celowania z narządów celowniczych Размытие при опущеном прицеле Borrão ao mirar @@ -491,9 +533,9 @@ Intensität des Bildrauschens 夜視鏡雜訊程度 夜视仪噪声强度 - 暗視装置のノイズ度 + 暗視装置ノイズ強度 Intensité du bruit (JVN) - Fattore di Disturbo del NVG + Quantità di Disturbo del NVG Skala Szumu NVG Степень шума ПНВ Intensidade de Ruído/Efeito Granulado @@ -506,9 +548,9 @@ Intensität des Bildrauschens im Nachtsichtgerät 調整配戴夜視鏡時畫面雜訊的多寡。 调整配戴夜视仪时画面噪声的强度。 - 暗視装置を使用時に起きる画像ノイズの強度です + 暗視装置使用時の画像ノイズの強度 Intensité du bruit de l'image lorsque vous portez des JVN. - Intensità del disturbo dell'immagine quando i NVG sono equipaggiati + Intensità del disturbo nell'immagine degli NVG Intensywność efektu szumu podczas noszenia gogli noktowizyjnych Интенсивность шума при использовании ПНВ Intensidade de Ruído de Imagem ao utilizar Visão Noturna @@ -523,7 +565,7 @@ 快门效果 快門效果 Effets d'obturateur - Effetti lampeggianti + Effetti "Shutter" Efekt Shutter Эффекты затвора Efeito de Obturador @@ -534,11 +576,11 @@ Rolling shutter effect from muzzle flashes Rolling-Shutter-Effekt bei Müdungsfeuer - 発射炎が作るローリング シャッター効果です + 発射炎によるローリング シャッター効果 枪械开火时产生瞬间快门效果 槍開火時瞬間產生快門效果 Effet d'obturateur à rideau dû aux flashs du canon. - Effetto lampeggiante dato dal lampo dello sparo + Effetto "Shutter" dato dall'abbagliamento del visore in risposta al lampo dello sparo Efekt rolling shutter z błysków wylotowych Эффект затвора при вспышках выстрелов Efeito de rolamento de Obturador de flashes de focinho @@ -549,18 +591,24 @@ Night Vision Generation 暗視装置の世代 + Generazione del NVG Generacja gogli noktowizyjnych Nachtsicht-Generation 야투경 세대 Génération de jumelles de vision nocturne + Генерация ночного видения + Generación de Visión Nocturna Gen %1 第%1世代 Gen %1 + Gen %1 Gen %1 %1세대 Gen %1 + Генерация %1 + Gen %1 diff --git a/addons/nlaw/functions/fnc_attackProfile.sqf b/addons/nlaw/functions/fnc_attackProfile.sqf index ad7622eadd..9628974800 100644 --- a/addons/nlaw/functions/fnc_attackProfile.sqf +++ b/addons/nlaw/functions/fnc_attackProfile.sqf @@ -56,5 +56,5 @@ if ((count _test) > 0) then { }; #endif -// TRACE_1("Adjusted target position", _returnTargetPos); +// TRACE_1("Adjusted target position",_returnTargetPos); _returnTargetPos; diff --git a/addons/nlaw/functions/fnc_keyDown.sqf b/addons/nlaw/functions/fnc_keyDown.sqf index 60ac4bf3d8..5b75c72140 100644 --- a/addons/nlaw/functions/fnc_keyDown.sqf +++ b/addons/nlaw/functions/fnc_keyDown.sqf @@ -19,8 +19,8 @@ TRACE_1("lock key down",GVAR(isLockKeyDown)); if (!alive ACE_player) exitWith {}; -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith {}; -if (!(ACE_player call CBA_fnc_canUseWeapon)) exitWith {}; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {}; +if !(ACE_player call CBA_fnc_canUseWeapon) exitWith {}; if ((getNumber (configFile >> "CfgWeapons" >> (currentWeapon ACE_player) >> QGVAR(enabled))) == 0) exitWith {}; if (GVAR(isLockKeyDown)) exitWith {ERROR("already running?");}; diff --git a/addons/nlaw/stringtable.xml b/addons/nlaw/stringtable.xml index 93bd236237..0d2eaca93a 100644 --- a/addons/nlaw/stringtable.xml +++ b/addons/nlaw/stringtable.xml @@ -4,8 +4,8 @@ NLAW Track Target (Hold) NLAW Zielverfolgung - NLAW Traccia Bersaglio (Mantieni) - NALW 目標の追跡 (押しっぱ) + NLAW Traccia Bersaglio (Tieni Premuto) + NLAW 目標追跡 (ホールド) NLAW 追踪目标(按住) 次世代輕型反坦克導彈發射器追蹤目標 (按住) Śledzenie Celu NLAW (Przytrzymaj) @@ -25,7 +25,7 @@ 直射模式 直射模式 Bezpośredni atak - 직선 공격 + 직사 타격 Прямая атака Ataque Direto Attaque directe @@ -41,7 +41,7 @@ 飞越攻顶模式 攻頂模式 Atak z góry - 탑어택 + 상부 타격 Атака сверху Ataque por cima Attaque par le haut diff --git a/addons/noradio/XEH_preInit.sqf b/addons/noradio/XEH_preInit.sqf index 35b9e9ec47..75f7afa62e 100644 --- a/addons/noradio/XEH_preInit.sqf +++ b/addons/noradio/XEH_preInit.sqf @@ -27,4 +27,4 @@ if (hasInterface) then { }, true] call CBA_fnc_addPlayerEventHandler; }; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" diff --git a/addons/noradio/initSettings.sqf b/addons/noradio/initSettings.inc.sqf similarity index 100% rename from addons/noradio/initSettings.sqf rename to addons/noradio/initSettings.inc.sqf diff --git a/addons/noradio/stringtable.xml b/addons/noradio/stringtable.xml index 178a2661b4..d1cf51f0e6 100644 --- a/addons/noradio/stringtable.xml +++ b/addons/noradio/stringtable.xml @@ -5,9 +5,10 @@ No Radio 去无线电 Kein Funkgerät + Nessuna Radio 음소거 Brak Radia - 無線無し + 無線無効化 Нет рации No Radio Pas de radio @@ -34,7 +35,7 @@ Muta l'avatar del giocatore controllato. 靜音玩家所控制的角色 静音玩家所控制的角色。 - プレイヤーに操作されているこのキャラをミュートします。 + プレイヤーに操作されているキャラをミュートします。 Wycisza awatar kontrolowany przez gracza Заглушить контролируемого игрока Silencia o avatar do Jogador controlado diff --git a/addons/novehicleclanlogo/XEH_preInit.sqf b/addons/novehicleclanlogo/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/novehicleclanlogo/XEH_preInit.sqf +++ b/addons/novehicleclanlogo/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/novehicleclanlogo/initSettings.sqf b/addons/novehicleclanlogo/initSettings.inc.sqf similarity index 90% rename from addons/novehicleclanlogo/initSettings.sqf rename to addons/novehicleclanlogo/initSettings.inc.sqf index 471877ca5c..ddec0e1314 100644 --- a/addons/novehicleclanlogo/initSettings.sqf +++ b/addons/novehicleclanlogo/initSettings.inc.sqf @@ -1,4 +1,4 @@ -private _category = [ELSTRING(common,ACEKeybindCategoryVehicles), LSTRING(DisplayName)],; +private _category = [ELSTRING(common,ACEKeybindCategoryVehicles), LSTRING(DisplayName)]; [ QGVAR(enabled), "CHECKBOX", diff --git a/addons/novehicleclanlogo/stringtable.xml b/addons/novehicleclanlogo/stringtable.xml index c6be9efd9e..96d463f582 100644 --- a/addons/novehicleclanlogo/stringtable.xml +++ b/addons/novehicleclanlogo/stringtable.xml @@ -5,20 +5,22 @@ Remove clan logo from vehicles Usuń logo klanu z pojazdów 차량에서 클랜 로고 제거 - Убрать логотип кланов с техники + Убрать логотип отрядов с техники Suprimir logo del clan de los vehículos 乗り物から部隊ロゴを削除 Clan-Logo von Fahrzeugen entfernen + Rimuovi Icone Clan dai veicoli Retirer les logos de clan des véhicules 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. + Impedisce la visualizzazione di icone clan sui veicoli controllati da giocatori. Empêche les logos de clan d'être affichés sur les véhicules contrôlés par des joueurs. diff --git a/addons/optics/XEH_postInit.sqf b/addons/optics/XEH_postInit.sqf index abb97e5b5d..1641ee2174 100644 --- a/addons/optics/XEH_postInit.sqf +++ b/addons/optics/XEH_postInit.sqf @@ -28,4 +28,4 @@ GVAR(camera) = objNull; }] call CBA_fnc_addPlayerEventHandler; // Register fire event handler -["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; diff --git a/addons/optics/functions/fnc_handleFired.sqf b/addons/optics/functions/fnc_handleFired.sqf index 5a1ae0eca0..f36f04d881 100644 --- a/addons/optics/functions/fnc_handleFired.sqf +++ b/addons/optics/functions/fnc_handleFired.sqf @@ -18,7 +18,7 @@ */ // IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); disableSerialization; diff --git a/addons/optics/functions/fnc_onDrawScope2D.sqf b/addons/optics/functions/fnc_onDrawScope2D.sqf index df431407da..c7fb19c9c1 100644 --- a/addons/optics/functions/fnc_onDrawScope2D.sqf +++ b/addons/optics/functions/fnc_onDrawScope2D.sqf @@ -80,11 +80,11 @@ if (_isPIP) then { // Calculate lighting private _dayOpacity = call EFUNC(common,ambientBrightness); -private _nightOpacity = [1, 0] select (_dayOpacity == 1); +private _nightOpacity = parseNumber (_dayOpacity == 1); // Apply lighting and make layers visible (_display displayCtrl 1713001) ctrlSetTextColor [1, 1, 1, 1]; -(_display displayCtrl 1713002) ctrlSetTextColor [1, 1, 1, [0, 1] select (_dayOpacity < 0.5)]; +(_display displayCtrl 1713002) ctrlSetTextColor [1, 1, 1, parseNumber (_dayOpacity < 0.5)]; (_display displayCtrl 1713005) ctrlSetTextColor [1, 1, 1, _dayOpacity]; (_display displayCtrl 1713006) ctrlSetTextColor [1, 1, 1, _nightOpacity]; diff --git a/addons/optionsmenu/XEH_preInit.sqf b/addons/optionsmenu/XEH_preInit.sqf index d25516a277..aaa0b64a03 100644 --- a/addons/optionsmenu/XEH_preInit.sqf +++ b/addons/optionsmenu/XEH_preInit.sqf @@ -11,6 +11,6 @@ if (hasInterface) then { [[format ["ACE %1", localize LSTRING(headBugFix)], localize LSTRING(headBugFixTooltip)], QGVAR(MainMenuHelperHeadBugFix)] call CBA_fnc_addPauseMenuOption; }; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/optionsmenu/initSettings.sqf b/addons/optionsmenu/initSettings.inc.sqf similarity index 62% rename from addons/optionsmenu/initSettings.sqf rename to addons/optionsmenu/initSettings.inc.sqf index bf77a84fcc..e5bb44e512 100644 --- a/addons/optionsmenu/initSettings.sqf +++ b/addons/optionsmenu/initSettings.inc.sqf @@ -5,5 +5,9 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(aceNews)] LSTRING(showNewsOnMainMenu_name), _category, true, - 0 + 0, + { + if (!hasInterface) exitWith {}; + profileNamespace setVariable [QGVAR(showNewsOnMainMenu), _this]; + } ] call CBA_fnc_addSetting; diff --git a/addons/optionsmenu/stringtable.xml b/addons/optionsmenu/stringtable.xml index cdda474cdc..674ea3eb49 100644 --- a/addons/optionsmenu/stringtable.xml +++ b/addons/optionsmenu/stringtable.xml @@ -11,8 +11,8 @@ Debug vers le presse-papier Debug a vágólapra Отладка в буфер обмена - Debug su Blocco Note - クリップボードにデバッグ + Debug negli Appunti + デバッグ情報をコピー 클립보드를 디버그하기 复制调试信息至剪贴板 複製除錯訊息至剪貼簿 @@ -28,7 +28,7 @@ Envoie les informations de debug vers le RPT et le presse-papier. Debug információt küld az RPT-be és a vágólapra. Отправляет отладочную информацию в RPT и буфер обмена. - Invia informazioni di debug all'RPT e al Blocco Note + Invia informazioni di debug all'RPT e gli appunti di Windows. デバッグ情報を RPT とクリップボードに送ります。 디버그 정보를 보고하기 및 클립보드에 복사하기 위해 보냅니다. 复制调试信息至剪贴板与 RPT 报告档中。 @@ -79,7 +79,7 @@ Nouveautés ACE ACE hírek Новости ACE - Novità ACE + ACE Novità ACE ニュース ACE 새 소식 ACE 新闻 @@ -96,147 +96,12 @@ Hírek mutatása a főmenüben Показывать новости в главном меню Zobrazit zprávy v hlavním menu - Mostra News nel Menù Princinpale + Mostra novità nel Menù Principale メイン画面にニュースを表示します 메인메뉴에 새 소식을 표시합니다 显示新闻消息于主菜单 顯示新聞消息於主選單 Ana Menü de Haberleri Göster - - ACE Logistics - ACE Logistik - ACE Logistyka - ACE Logística - ACE Логистика - ACE Logistika - ACE Logística - ACE Logistica - ACE Logistique - ACE ロジスティクス - ACE 보급 - ACE 后勤设定 - ACE 後勤設定 - ACE Lojistik - - - Hide - Ukryj - Ocultar - Verstecken - Skrýt - Ocultar - Cacher - Elrejtés - Скрыть - Nascondi - 非表示 - 숨기기 - 隐藏 - 隱藏 - Gizle - - - Top right, downwards - Po prawej u góry, w dół - Arriba a la derecha, hacia abajo - Oben rechts, nach unten - Vpravo nahoře, dolů - Superior direito, para baixo - En haut à droite, vers le bas - Jobb felül, lefele - Справа — сверху вниз - In Alto a Destra, verso il Basso - 右上、下側 - 오른쪽 위에서 아래로 - 右上角,向下 - 右上角,向下 - Sağ üst, aşağı - - - Top right, to the left - Po prawej u góry, do lewej - Arriba a la derecha, hacia la izquierda - Von rechts nach links - Vpravo nahoře, do leva - Superior direito, à esquerda - En haut à droite, vers la gauche - Jobb felül, balra - Сверху — справа налево - In Alto a Destra, verso Sinistra - 右上、左詰 - 오른쪽 위에서 왼쪽으로 - 右上角,向左 - 右上角,向左 - Sağ üstte, solda - - - Top left, downwards - Po lewej u góry, w dół - Arriba a la izquierda, hacia abajo - Von links, nach unten - Vlevo nahoře, dolů - Superior esquerdo, para baixo - En haut à gauche, vers le bas - Bal felül, lefele - Слева - сверху вниз - In Alto a Sinistra, verso il Basso - 左上、下側 - 왼쪽 위에서 아래로 - 左上角,向下 - 左上角,向下 - Sol üst, aşağı - - - Top left, to the right - Po lewej u góry, do prawej - Arriba a la izquierda, hacia la derecha - Oben links nach rechts - Vlevo nahoře, do prava - Superior esquerdo, para a direita - En haut à gauche, vers la droite - Bal felül, jobbra - Сверху — слева направо - In Alto a Sinistra, verso Destra - 右上、右詰 - 왼쪽 위에서 오른쪽으로 - 左上角,向右 - 左上角,向右 - Sol üst, sağa - - - Top - Góra - Arriba - Oben - Nahoře - Acima - En haut - Fent - Сверху - Alto - 上側 - 상단 - 上方 - 上方 - Üst - - - Bottom - Dół - Abajo - Unten - Dole - Abaixo - En bas - Alul - Снизу - Basso - 下側 - 하단 - 下方 - 下方 - Alt - diff --git a/addons/overheating/ACE_Arsenal_Stats.hpp b/addons/overheating/ACE_Arsenal_Stats.hpp new file mode 100644 index 0000000000..ef1e497c55 --- /dev/null +++ b/addons/overheating/ACE_Arsenal_Stats.hpp @@ -0,0 +1,21 @@ +class EGVAR(arsenal,stats) { + class statBase; + class ACE_allowSwapBarrel: statBase { + scope = 2; + priority = -1; + stats[] = {QGVAR(allowSwapBarrel)}; + displayName = CSTRING(statBarrelType); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_allowSwapBarrel)); + tabs[] = {{0,1}, {}}; + }; + class ACE_boltType: statBase { + scope = 2; + priority = -1.1; + stats[] = {QGVAR(closedBolt)}; + displayName = CSTRING(statBoltType); + showText = 1; + textStatement = QUOTE(call FUNC(statTextStatement_boltType)); + tabs[] = {{0,1}, {}}; + }; +}; diff --git a/addons/overheating/CfgMagazines.hpp b/addons/overheating/CfgMagazines.hpp index 6819a26b53..2553428c91 100644 --- a/addons/overheating/CfgMagazines.hpp +++ b/addons/overheating/CfgMagazines.hpp @@ -7,7 +7,7 @@ class CfgMagazines { descriptionshort = CSTRING(SpareBarrelDescription); picture = QUOTE(PATHTOF(UI\spare_barrel_ca.paa)); count = 1; - mass = 60; + mass = 25; ACE_isUnique = 1; }; }; diff --git a/addons/overheating/CfgWeapons.hpp b/addons/overheating/CfgWeapons.hpp index cc0b768934..9232fa3249 100644 --- a/addons/overheating/CfgWeapons.hpp +++ b/addons/overheating/CfgWeapons.hpp @@ -109,7 +109,7 @@ class CfgWeapons { descriptionshort = CSTRING(SpareBarrelDescription); picture = QUOTE(PATHTOF(UI\spare_barrel_ca.paa)); class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 60; + mass = 25; }; }; }; diff --git a/addons/overheating/XEH_PREP.hpp b/addons/overheating/XEH_PREP.hpp index 865a049569..91d345914d 100644 --- a/addons/overheating/XEH_PREP.hpp +++ b/addons/overheating/XEH_PREP.hpp @@ -25,6 +25,8 @@ PREP(overheat); PREP(sendSpareBarrelsTemperaturesHint); PREP(setAmmoTemperature); PREP(setWeaponTemperature); +PREP(statTextStatement_boltType); +PREP(statTextStatement_allowSwapBarrel); PREP(swapBarrel); PREP(swapBarrelAssistant); PREP(swapBarrelCallback); diff --git a/addons/overheating/XEH_postInit.sqf b/addons/overheating/XEH_postInit.sqf index bbcd9da97f..a49030b1ad 100644 --- a/addons/overheating/XEH_postInit.sqf +++ b/addons/overheating/XEH_postInit.sqf @@ -20,7 +20,7 @@ if (hasInterface) then { }; ["CBA_settingsInitialized", { - TRACE_1("SettingsInitialized eh", GVAR(enabled)); + TRACE_1("SettingsInitialized eh",GVAR(enabled)); if (!GVAR(enabled)) exitWith {}; if (isServer) then { @@ -35,8 +35,8 @@ if (hasInterface) then { GVAR(storedSpareBarrels) = createHashMap; // Install event handlers for spare barrels - [QGVAR(sendSpareBarrelTemperatureHint), FUNC(sendSpareBarrelsTemperaturesHint)] call CBA_fnc_addEventHandler; - [QGVAR(loadCoolestSpareBarrel), FUNC(loadCoolestSpareBarrel)] call CBA_fnc_addEventHandler; + [QGVAR(sendSpareBarrelTemperatureHint), LINKFUNC(sendSpareBarrelsTemperaturesHint)] call CBA_fnc_addEventHandler; + [QGVAR(loadCoolestSpareBarrel), LINKFUNC(loadCoolestSpareBarrel)] call CBA_fnc_addEventHandler; // Schedule cool down calculation of stored spare barrels [] call FUNC(updateSpareBarrelsTemperaturesThread); @@ -50,14 +50,14 @@ if (hasInterface) then { //Add Take EH if required if (GVAR(unJamOnReload) || {GVAR(cookoffCoef) > 0}) then { - ["CAManBase", "Take", {_this call FUNC(handleTakeEH);}] call CBA_fnc_addClassEventHandler; + ["CAManBase", "Take", LINKFUNC(handleTakeEH)] call CBA_fnc_addClassEventHandler; }; // Register fire event handler - ["ace_firedPlayer", DFUNC(firedEH)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; // Only add eh to non local players if dispersion is enabled if (GVAR(overheatingDispersion) || {GVAR(showParticleEffectsForEveryone)}) then { - ["ace_firedPlayerNonLocal", DFUNC(firedEH)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; }; // Schedule cool down calculation of player weapons at (infrequent) regular intervals @@ -86,10 +86,10 @@ if (hasInterface) then { }] call CBA_fnc_addClassEventHandler; // Install event handler to display temp when a barrel was swapped - [QGVAR(showWeaponTemperature), DFUNC(displayTemperature)] call CBA_fnc_addEventHandler; + [QGVAR(showWeaponTemperature), LINKFUNC(displayTemperature)] call CBA_fnc_addEventHandler; // Install event handler to initiate an assisted barrel swap - [QGVAR(initiateSwapBarrelAssisted), DFUNC(swapBarrel)] call CBA_fnc_addEventHandler; + [QGVAR(initiateSwapBarrelAssisted), LINKFUNC(swapBarrel)] call CBA_fnc_addEventHandler; // Add an action to allow hot weapons to be cooled off in AceX Field Rations water sources if (["acex_field_rations"] call EFUNC(common,isModLoaded)) then { diff --git a/addons/overheating/XEH_preInit.sqf b/addons/overheating/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/overheating/XEH_preInit.sqf +++ b/addons/overheating/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/overheating/config.cpp b/addons/overheating/config.cpp index f04238fd10..4d8fb34cc3 100644 --- a/addons/overheating/config.cpp +++ b/addons/overheating/config.cpp @@ -26,6 +26,8 @@ class CfgPatches { #include "ACE_Settings.hpp" +#include "ACE_Arsenal_Stats.hpp" + class CfgMovesBasic { class ManActions { GVAR(GestureMountMuzzle) = QGVAR(GestureMountMuzzle); 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_firedEH.sqf b/addons/overheating/functions/fnc_firedEH.sqf index 9db3a73dd6..bdb7f864c9 100644 --- a/addons/overheating/functions/fnc_firedEH.sqf +++ b/addons/overheating/functions/fnc_firedEH.sqf @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); BEGIN_COUNTER(firedEH); diff --git a/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf b/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf index 29b7191471..a5fb95cf31 100644 --- a/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf +++ b/addons/overheating/functions/fnc_loadCoolestSpareBarrel.sqf @@ -31,7 +31,7 @@ if (_weaponBarrelClass == "") then { // Find all spare barrel the player has private _allBarrels = [_assistant, _weaponBarrelClass] call CBA_fnc_getMagazineIndex; TRACE_1("_allBarrels",_allBarrels); -if ((count _allBarrels) < 1) exitWith {}; +if (_allBarrels isEqualTo []) exitWith {}; // Determine which on is coolest private _coolestTemp = 10000; diff --git a/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf b/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf index 9204b58124..5f75423f2e 100644 --- a/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf +++ b/addons/overheating/functions/fnc_sendSpareBarrelsTemperaturesHint.sqf @@ -32,7 +32,7 @@ if (_weaponBarrelClass == "") then { }; private _allBarrels = [_unit, _weaponBarrelClass] call CBA_fnc_getMagazineIndex; TRACE_1("_allBarrels",_allBarrels); -if ((count _allBarrels) < 1) exitWith {}; +if (_allBarrels isEqualTo []) exitWith {}; // Determine the temp of each barrel private _temps = []; diff --git a/addons/overheating/functions/fnc_statTextStatement_allowSwapBarrel.sqf b/addons/overheating/functions/fnc_statTextStatement_allowSwapBarrel.sqf new file mode 100644 index 0000000000..9713023c17 --- /dev/null +++ b/addons/overheating/functions/fnc_statTextStatement_allowSwapBarrel.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Barrel Type statement. + * + * Arguments: + * 0: Not used + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Public: No +*/ + +params ["", "_config"]; +TRACE_1("statTextStatement_allowSwapBarrel",_config); + +if ((getNumber (_config >> QGVAR(allowSwapBarrel))) == 1) exitWith {LLSTRING(statBarrelType_removeable)}; + +LLSTRING(statBarrelType_nonRemoveable) diff --git a/addons/overheating/functions/fnc_statTextStatement_boltType.sqf b/addons/overheating/functions/fnc_statTextStatement_boltType.sqf new file mode 100644 index 0000000000..67967496c7 --- /dev/null +++ b/addons/overheating/functions/fnc_statTextStatement_boltType.sqf @@ -0,0 +1,21 @@ +#include "..\script_component.hpp" +/* + * Author: drofseh + * Bolt Type statement. + * + * Arguments: + * 0: Not used + * 1: Item config path + * + * Return Value: + * Stat Text + * + * Public: No +*/ + +params ["", "_config"]; +TRACE_1("statTextStatement_boltType",_config); + +if ((getNumber (_config >> QGVAR(closedBolt))) == 1) exitWith {LLSTRING(statBoltType_closedBolt)}; + +LLSTRING(statBoltType_openBolt) 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/initSettings.sqf b/addons/overheating/initSettings.inc.sqf similarity index 100% rename from addons/overheating/initSettings.sqf rename to addons/overheating/initSettings.inc.sqf 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 b48c4a31b1..d5e8ad7ca8 100644 --- a/addons/overheating/stringtable.xml +++ b/addons/overheating/stringtable.xml @@ -51,6 +51,7 @@ Heating Coefficient 過熱係数 Coefficient de surchauffe + Coefficiente di riscaldamento Коэф. нагрева Erhitzungs-Koeffizient Współczynnik nagrzewania @@ -62,6 +63,7 @@ Coefficient for the amount of heat a weapon generates per shot.\nHigher value increases heat. 射撃毎に武器が生み出す熱量の係数を設定します。\n高い値であるほど熱量が増加します。 Coefficient impactant la quantité de chaleur générée par l'arme à chaque tir. + Coefficiente che determina la quantità di calore generato da un'arma con ogni colpo sparato.\nValori alti accelerano il riscaldamento. Коэффициент количества тепла, выделяемого оружием за выстрел. \nБольшие значения увеличивают нагрев. Koeffizient für die Menge an Hitze, die eine Waffe pro Schuss erzeugt.\nHöhere Werte beschleunigen die Erhitzung. Współczynnik wpływający na ilość ciepła generowanego przez broń przy każdym strzale. @@ -74,6 +76,7 @@ 冷却系数 냉각 계수 Abkühlungskoeffizienten + Coefficiente di raffreddamento Współczynnik chłodzenia 冷却係数 Коэф. остывания @@ -85,6 +88,7 @@ 武器冷却速度系数。\n数值越高,冷却速度越快。 무기가 차가워지는 정도를 정합니다.\n높은 계수는 무기가 빨리 차가워지는데 관여합니다. Koeffizient, der angibt, wie schnell eine Waffe abkühlt.\nEin höherer Wert erhöht die Abkühlgeschwindigkeit. + Coefficiente che determina la velocità di raffreddamento di un'arma.\nValori alti aumentano la velocità di raffreddamento. Współczynnik szybkości chłodzenia broni.\nWiększa wartość zwiększa szybkość chłodzenia. 武器の冷却速度の係数。\n値を大きくすると冷却速度が速くなります。 Коэффициент скорости остывания орудия.\nЧем больше значение, тем быстрее остывает. @@ -96,6 +100,7 @@ 消音器系数 소음기 계수 Schalldämpfer-Koeffizient + Coefficiente di Silenziatore Współczynnik tłumika サプレッサー係数 Коэф. глушителя @@ -107,6 +112,7 @@ 附加了消音器后,产生的额外热量系数。\n数值越高,热量越高,0意味着消音器不产生额外热量。 소음기 장착 시 만들어 지는 열에 대한 계수를 적용합니다.\n높을 수록 온도가 높아집니다, 0으로 설정 시 추가적인 열을 얻지 않습니다. Koeffizient, der angibt, wie viel zusätzliche Wärme durch das Anbringen eines Schalldämpfers hinzugefügt wird. Ein höherer Wert erhöht die Menge an Wärme, 0 bedeutet, dass keine zusätzliche Wärme durch den Schalldämpfer hinzukommt. + Coefficiente che determina quanto calore viene aggiunto dalla presenza di un silenziatore.\nValori alti aumentano il calore, 0 significa che un silenziatore non fa differenza. Współczynnik określający, ile dodatkowego ciepła jest dodawane z założonego tłumika.\nWyższa wartość zwiększa ciepło, 0 oznacza brak dodatkowego ciepła z tłumika. サプレッサーを取り付けることで追加される熱量の係数。\n値が大きいほど熱が増加し、0はサプレッサーからの追加の熱がないことを意味します。 Коэффициент указывающий как много дополнительного тепла будет выделяться прикреплённым глушителем.\nБольшее значение увеличивает выделение тепла, 0 - отсутствие дополнительного тепла. @@ -124,7 +130,7 @@ Szöveges értesítés kijelzése a fegyver elakadásakor Mostrar texto quando trava acontecer Visualizza testo in caso di inceppamento - 弾詰りを文章で表示 + 弾詰まりを文章で表示 탄걸림의 경우 화면에 표시 在卡弹时显示提示信息 在卡彈時顯示提示訊息 @@ -139,8 +145,8 @@ Affiche une notification lorsque votre arme est enrayée. Egy szöveges értesítés jelenik meg, amikor a fegyver megakad Mostra uma notificação quando sua arma sofre um travamento. - Visualizza una notifica in caso la tua arma si inceppasse - 持っている武器が弾詰りをすると、通知を表示します + Visualizza una notifica quando tua arma si inceppa + 持っている武器が弾詰まりをすると、通知を表示します 총알이 무기에 걸릴 경우 화면에 알림을 띄웁니다 当武器卡弹时显示提示信息 當武器卡彈時顯示提示訊息 @@ -213,7 +219,7 @@ Overheating Dispersion Streuung bei Überhitzung Wpływ na rozrzut - Dispersione Surriscaldamento + Dispersione da Surriscaldamento Dispersión Dispersion Dispersão de superaquecimento @@ -229,13 +235,13 @@ Overheated weapons will be less accurate and have decreased muzzle velocity. Applys for all players. Überhitzte Waffen sind weniger genau und verfügen über eine geringere Mündungsgeschwindigkeit. Wird bei allen Spielern angewendet. Przegrzane bronie będą mniej celne oraz będą miały zmniejszoną prędkość pocisku. Wpływa na wszystkich graczy. - Armi surriscaldate saranno meno precise ed avranno una ridotta velocità alla volata. Applica per tutti i giocatori. + Armi surriscaldate saranno meno precise ed avranno una ridotta velocità alla volata. Applicato a tutti i giocatori. Las armas sobrecalentadas pierden precisión y tienen una velocidad de disparo reducida. Se aplica a todos los jugadores. Les armes surchauffées seront moins précises et auront une vitesse initiale moins élevée. S'applique à tous les joueurs. Armas superaquecidas irão ser menos precisas e ter velocidade de disparo reduzidas. Aplica a todos os jogadores. Перегретое оружие будет менее точным, а дульная скорость будет снижена. Применяется ко всем игрокам. Přehřátá zbraň bude méně přesná a bude mít menší úsťovou rychlost. Platí pro všechny hráče. - 過熱は精度を減少させたり、初速を低下させます。これは全プレイヤに適用します。 + 過熱は精度を減少させたり、初速を低下させます。これは全プレイヤーに適用します。 무기 과열 시 무기의 명중률이 저하되고 총구속도가 감소합니다. 이는 모든 플레이어에게 적용됩니다. 过热的武器将会有打不准和减少射击初速的情况。适用于所有玩家 過熱的武器將會有打不準和減少射擊初速的情況。適用於所有玩家 @@ -243,8 +249,9 @@ Distance for Effects and Dispersion - エフェクトと分散用距離 + エフェクトと分散の距離 Distance des effets et de la dispersion + Distanza per effetti e dispersione Дистанция для эффектов и разброса Abstand für Effekte und Dispersion Odległość efektów i rozproszenia @@ -254,8 +261,9 @@ The distance, in meters, from the player within which overheating particle effects and dispersion are visible. - プレイヤーが過熱パーティクル エフェクトと分散を見えるようになる距離 (m) を設定します。 + プレイヤーが過熱パーティクルのエフェクトと分散を見えるようになる距離 (m) を設定します。 Définit la distance en mètres, jusqu'à laquelle les effets de particules et la dispersion sont visibles. + La distanza in metri da cui sono visibili gli effetti particellari e la dispersione. Дистанция в метрах, с которой видны эффекты частиц и разброса при перегреве. Der Abstand in Metern vom Spieler, in dem Überhitzungspartikeleffekte und Dispersion sichtbar sind. Określa odległość w metrach, do której widoczne są efekty cząsteczkowe i rozproszenie. @@ -267,6 +275,7 @@ Heat Increases Fire Rate 熱による連射速度上昇 La chaleur augmente la cadence de tir + Calore aumenta la cadenza di tiro Нагрев увеличивает темп стрельбы Hitze erhöht die Feuerrate Ciepło zwiększa szybkostrzelność @@ -280,6 +289,7 @@ Lorsqu'une arme chauffe, sa cadence de tir peut augmenter jusqu'à 10%. При нареве орудия, его темп стрельбы увеличивается до 10%. Wenn sich Waffen erhitzen, erhöht sich ihre Feuerrate um bis zu 10%. + Quando le armi si surriscaldano, la loro cadenza di tiro può aumentare anche del 10%. Gdy broń się nagrzewa, jej szybkostrzelność może wzrosnąć nawet o 10%. 随着武器的过热,其射速最多增加10%。 과열될수록 발사속도가 최대 10%까지 올라갑니다. @@ -289,6 +299,7 @@ Jam Chance Coefficient 弾詰まり係数 Coefficient du risque d'enrayement + Coefficiente di inceppamento Шанс заклинивания оружия Koeffizient für Ladehemmung Szansa na zacięcie @@ -298,8 +309,9 @@ Coefficient for the chance that a weapon will jam from overheating.\nHigher value make jams more likely.\nSet to 0 to disable jamming. - 武器が過熱によって弾詰まりする確立係数を設定します。\n高い値では弾詰まりが起こりやすくなり、0 で弾詰まりが無効化されます。 + 武器が過熱によって弾詰まりする確率係数を設定します。\n高い値では弾詰まりが起こりやすくなり、0 で弾詰まりが無効化されます。 Coefficient modifiant les chances qu'une arme s'enraye à cause de la surchauffe.\nPlus la valeur est élevée, plus grand est le risque que l'arme s'enraye.\nDéfinir à 0 pour désactiver l'enrayement des armes. + Coefficiente della probabilità di inceppamento da surriscaldamento.\nValori alti aumentano la probabilità, 0 la disabilità. Шанс заклинивания оружия от перегрева.\nБольшие значения повышают шанс заклинивания.\nУстановите 0 для отключения заклинивания. Koeffizient für die Wahrscheinlichkeit, dass eine Waffe eine Ladehemmung hat.\Höhere Werte erhöhen die Wahrscheinlichkeit.\Auf 0 setzen, um Ladehemmungen zu deaktivieren. Współczynnik zmieniający szansę na zacięcie się broni z powodu przegrzania.\nIm wyższa wartość, tym większe ryzyko zacięcia się broni.\nUstaw na 0, aby wyłączyć zacinanie się broni. @@ -317,7 +329,7 @@ Uvolnit zbraň při přebití Desemperrar arma no recarregamento Исправлять клин при перезарядке - 再装填による弾詰りの解消 + 再装填による弾詰まり解消 재장전 시 기능고장 해결 重装弹匣以解决卡弹 重裝彈匣以解決卡彈 @@ -333,7 +345,7 @@ Přebití uvolní zaseknutou zbraň. Recarregar desemperra arma. Перезарядка устраняет заклинивание оружия. - 再装填により、弾詰りを除去します。 + 再装填により、弾詰まりを除去します。 기능고장이 재장전 시 해결됩니다. 利用重装弹匣来解决卡弹 利用重裝彈匣來解決卡彈 @@ -341,9 +353,10 @@ Unjam on Barrel Swap - 銃身交換で弾詰まり解消 + 銃身交換による弾詰まり解消 Désenrayer l'arme au changement de canon Замена ствола устраняет клин оружия + Disinceppa l'arma col cambio canna Usuń zacięcie przy wymianie lufy 更换枪管清除卡弹 총열 교환 시 기능고장 해결 @@ -356,6 +369,7 @@ Les armes se désenrayent lors d'un remplacement de canon. Определяет, устраняет ли замена ствола заклинивание оружия. Bestimmt, ob das Wechseln des Laufes eine Ladehemmung behebt. + Determina se la sostituzione della canna disinceppa l'arma. Określa, czy wymiana lufy usuwa zacięcie się broni. 通过更换枪管,以便清除卡弹。 총열을 교체하면서 기능고장을 해결합니다. @@ -371,7 +385,7 @@ Šance, že uvolnění zbraně selže Chance de falha de desemperramento Шанс неудачи при устранении клина - 弾詰りの除去を失敗する可能性 + 弾詰まりの除去を失敗する可能性 기능고장 해결 시도 실패확률 解决卡弹失败机率 解決卡彈失敗機率 @@ -383,11 +397,11 @@ Probabilidad de que el proceso de desencasquille falle, teniendo que repetirlo. Szansa na to, że przy przeładowaniu broni zacięcie nie zostanie usunięte, przez co czynność będzie musiała zostać powtórzona ponownie. Probabilité qu'une action de désenrayement échoue, nécessitant de recommencer. - Probabilità che si possa sbagliare a caso a disinceppare l'arma. Richiede di ripetere. + Probabilità casuale che si possa sbagliare a disinceppare l'arma. Richiedendo di ripetere il disinceppamento. Probabilidade que uma ação de desemperramento falhe, tendo que ser repetida Вертоятность того, что устранение заклинивания не сработает, и его придется повторить. Pravděpodobnost, že uvolnění zbraně selže, je proto nutné tuto akci opakovat. - 弾詰りの除去を失敗する可能性が生まれ、もう一度動作を行う必要があります。 + 弾詰まり解除アクションに失敗し、繰り返しが必要になる確率。 기능고장 해결 시도시 실패할 확률이 있습니다. 이는 다시 기능고장 해결을 시도해야함을 의미합니다. 清除卡弹时有可能会失败,需要反覆进行清枪。 清除卡彈時有可能會失敗,需要反覆進行清槍。 @@ -395,8 +409,9 @@ Overheating Cookoff Coefficient - 過熱誘爆係数 + 過熱暴発係数 Coefficient de l'auto-inflammation + Coefficiente di auto-combustione Коэф. возгорания при перегреве Selbstzündungskoeffizient bei Überhitzung Współczynnik samozapłonu @@ -406,8 +421,9 @@ Coefficient for the heat required for cookoffs to occur.\nHigher values require more heat to cookoff.\nSet to 0 to disable cookoff. - 過熱によって誘爆が起きる確立係数を設定します。\n高い値では誘爆までに必要な過熱量が増加し、0 で誘爆が無効化されます。 + 過熱によって暴発(コックオフ)が発生する確率の係数を設定します。\n高い値では暴発までに必要な過熱量が増加し、0 で暴発が無効化されます。 Coefficient modifiant la quantité de chaleur requise pour que les munitions s'auto-inflamment dans la chambre de l'arme.\nPlus la valeur est élevée, plus l'arme doit être chaude pour que les munitions s'auto-inflamment.\nDéfinir sur 0 pour désactiver l'auto-inflammation. + Coefficiente che determina il calore richiesto per auto-incendiare munizioni/carburante.\nImpostare su 0 per disabilitare l'auto-combustione. Коэффициент нагрева, при котором возникает возгорание. Koeffizient für die zum Selbstzünden erforderliche Hitze.\nHöhere Werte erfordern mehr Hitze zum Selbstzünden.\nAuf 0 setzen, um das Selbstzünden zu deaktivieren. Współczynnik modyfikujący ilość ciepła wymaganego do samozapłonu amunicji w komorze broni.\nIm wyższa wartość, tym gorętsza musi być broń, aby amunicja uległa samozapłonowi\nUstaw 0, aby wyłączyć samozapłon. @@ -441,8 +457,8 @@ Используется для смены ствола. Használd a cső kicseréléséhez. Use para trocar o cano. - Usata per cambiare la canna. - 予身の交換に使用します。 + Usata per sostituire una canna bollente. + 銃身の交換に使用します。 총열을 바꿀 때 사용합니다. 用来更换枪管 用來更換槍管 @@ -465,10 +481,11 @@ Weapon cooked off! - 武器が誘爆した! + 武器が暴発した! Auto-inflammation des munitions ! Оружие сдетонировало! Munition durchgezündet! + Munizione auto-incendiata! Samozapłon amunicji! 武器发生热诱发! 쿡오프가 일어납니다! @@ -479,6 +496,7 @@ 排莢に失敗しました。 Défaut d'éjection. Не удалось достать. + Mancata espulsione. Hülse wurde nicht ausgeworfen. Nie udało się wyrzucić łuski. 抛壳失败。 @@ -489,6 +507,7 @@ Failure to extract. 排出に失敗しました。 Défaut d'extraction. + Mancata estrazione. Не удалось извлечь. Hülse wurde nicht ausgezogen. Nie udało się wyjąć łuski. @@ -500,6 +519,7 @@ Failure to feed. 給弾に失敗しました。 Défaut d'alimentation. + Mancata alimentazione. Не удалось подать. Patrone wurde nicht zugeführt. Nie udało się załadować naboju. @@ -513,6 +533,7 @@ Défaut de tir. Не удалось выстрелить. Patrone wurde nicht gezündet! + Mancato innesco. Nie udało się strzelić. 未能开火。 발사가 되지 않음. @@ -528,8 +549,8 @@ Исправить клин оружия Akadás elhárítása Destravar arma - Ripulisci l'arma - 弾詰りを除去する + Disinceppa l'arma + 弾詰まりを解消する 기능고장 해결 清除卡弹 清除卡彈 @@ -545,7 +566,7 @@ Akadás elhárítva Arma destravada Arma pronta al fuoco - 弾詰りが除去されました + 弾詰まりが解消した 기능고장 해결됨 卡弹已清除 卡彈已清除 @@ -560,7 +581,7 @@ Zbraň se nepodařilo uvolnit Falha no desemperramento Не удалось исправить клин - 弾詰りの除去に失敗しました + 弾詰まりの解消に失敗した 기능고장 해결 실패 卡弹未能清除 卡彈未能清除 @@ -624,7 +645,7 @@ Conferir temperatura da arma Controlla la temperatura della canna Проверить температуру оружия - 武器の温度を測る + 武器の温度を確認 무기 온도 확인 检查枪管温度 檢查槍管溫度 @@ -640,7 +661,7 @@ Проверить температуру оружия Conferir temperatura Controlla la temperatura della canna - 武器の温度を測る + 武器の温度を確認 무기 온도 확인 检查枪管温度 檢查槍管溫度 @@ -668,7 +689,7 @@ Vérifier la température des canons de rechange Проверить температуру запасных стволов Zkontrolovat teplotu náhradní hlavně - 予備銃身の温度を測る + 予備銃身の温度を確認 Sprawdź temperaturę zapasowych luf Temperatur der Wechselläufe prüfen 총열 온도 확인 @@ -693,10 +714,11 @@ Cool weapon with... - 次で武器を冷ます・・・ + 武器をアイテムで冷却 Refroidir l'arme avec... Охладить оружие с... Waffe mit... kühlen + Raffredda arma con... Schłódź broń za pomocą... 冷却武器... 무기 온도 낮추기 @@ -708,6 +730,7 @@ Refroidissement du %1 avec %2... Охлаждение %1 с %2. Kühle %1 mit %2. + Raffredda %1 con %2 Chłodzenie %1 za pomocą %2. 冷却 %1 至 %2。 %1을 %2로 식히는 중. @@ -715,10 +738,11 @@ Cool weapon in water source. - 水源で武器を冷ます + 水源で武器を冷却 Refroidir l'arme dans la source d'eau. Охладить оружие в воде. Kühle Waffe aus Wasserquelle. + Raffredda arma in acqua. Schłódź broń wodą. 用水源冷却武器。 물로 무기 식히기 @@ -730,6 +754,7 @@ Refroidissement de l'arme dans la source d'eau... Охлаждение оружия в воде. Waffe wird aus Wasserquelle gekühlt. + Raffreddando arma con l'acqua. Chłodzenie broni wodą. 在水源中冷却武器。 물로 무기 식히는 중. @@ -741,6 +766,7 @@ Le récipient ne contient pas suffisamment d'eau. Воды недостаточно для охлаждения. Behälter beinhaltet nicht genug Wasser. + Contenitore non ha abbastanza acqua. Zbiornik nie ma wystarczającej ilości wody 容器里的水不够。 물이 충분치 않습니다. @@ -748,10 +774,11 @@ Weapon is cool enough the water has stopped boiling. - 武器が冷まりきり、水が沸騰していません。 + 武器が冷え切り、水は沸騰を止めた。 L'arme est suffisamment froide pour que l'eau ait cessé de bouillir. Оружие достаточно холодное для прекращения кипения воды. Waffe ist kalt genug, dass Wasser hat aufgehört zu kochen. + L'arma è abbastanza fredda, l'acqua ha smesso di bollire. Broń jest wystarczająco schłodzona. Woda przestała się gotować. 武器已经冷却,水已经停止沸腾了。 물이 끓지 않는 걸 보아 무기가 식은듯 하다. @@ -829,7 +856,7 @@ Bardzo gorące zapasowe lufy Sehr heiße Wechselläufe 매우 뜨거운 예비 총열 - Canna/e di Ricambio Estremamente Calda + Canna/e di Ricambio Bollente 备用枪管温度过热 備用槍管溫度過熱 @@ -848,5 +875,65 @@ 备用枪管温度非常热 備用槍管溫度超級熱 + + Bolt Type + Tipo di otturatore + 遊底(ボルト)形式 + 노리쇠 방식 + Тип болта + Type d'obturateur + Art des Verschlusses + Tipo de Cerrojo + + + Open Bolt + Otturatore Aperto + オープンボルト + 오픈 볼트 + Открыть болт + Obturateur ouvert + Offener Verschluss + Cerrojo Abierto + + + Closed Bolt + Otturatore Chiuso + クローズドボルト + 클로즈드 볼트 + Закрыть болт + Obturateur fermé + Geschlossener Verschluss + Cerrojo Cerrado + + + Barrel Type + Tipo di Canna + 銃身形式 + 총열 방식 + Тип ствола + Type de canon + Lauftyp + Tipo de Cañón + + + Non-Removeable + Non-Rimovibile + 取り外し不可 + 제거 불가 + Несъемный + Inamovible + Nicht entfernbar + No-Desmontable + + + Quick Change + Cambio Rapido + 即時交換可 + 신속 교체 + Быстросъемный + Changement rapide + Schnellwechsel + Cambiado Rápido + diff --git a/addons/overpressure/ACE_Settings.hpp b/addons/overpressure/ACE_Settings.hpp deleted file mode 100644 index d46cae7498..0000000000 --- a/addons/overpressure/ACE_Settings.hpp +++ /dev/null @@ -1,5 +0,0 @@ -class ACE_Settings { - class GVAR(distanceCoefficient) { - movedToSQF = 1; - }; -}; diff --git a/addons/overpressure/XEH_postInit.sqf b/addons/overpressure/XEH_postInit.sqf index 46fe460268..4b014e89e2 100644 --- a/addons/overpressure/XEH_postInit.sqf +++ b/addons/overpressure/XEH_postInit.sqf @@ -1,14 +1,17 @@ #include "script_component.hpp" ["CBA_settingsInitialized", { - TRACE_1("settingsInit eh",GVAR(distanceCoefficient)); - if (GVAR(distanceCoefficient) <= 0) exitWith {}; + TRACE_2("settingsInit eh",GVAR(backblastDistanceCoefficient),GVAR(overpressureDistanceCoefficient)); ["ace_overpressure", LINKFUNC(overpressureDamage)] call CBA_fnc_addEventHandler; - // Register fire event handler - ["ace_firedPlayer", LINKFUNC(firedEHBB)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicle", LINKFUNC(firedEHOP)] call CBA_fnc_addEventHandler; + // Register fire event handlers + if (GVAR(backblastDistanceCoefficient) > 0) then { + ["ace_firedPlayer", LINKFUNC(firedEHBB)] call CBA_fnc_addEventHandler; + }; + if (GVAR(overpressureDistanceCoefficient) > 0) then { + ["ace_firedPlayerVehicle", LINKFUNC(firedEHOP)] call CBA_fnc_addEventHandler; + }; GVAR(cacheHash) = createHashMap; }] call CBA_fnc_addEventHandler; diff --git a/addons/overpressure/XEH_preInit.sqf b/addons/overpressure/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/overpressure/XEH_preInit.sqf +++ b/addons/overpressure/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/overpressure/config.cpp b/addons/overpressure/config.cpp index 3815cc831f..7274cd5059 100644 --- a/addons/overpressure/config.cpp +++ b/addons/overpressure/config.cpp @@ -14,7 +14,6 @@ class CfgPatches { }; }; -#include "ACE_Settings.hpp" #include "CfgEventHandlers.hpp" #include "CfgWeapons.hpp" #include "ACE_Arsenal_Stats.hpp" diff --git a/addons/overpressure/functions/fnc_firedEHBB.sqf b/addons/overpressure/functions/fnc_firedEHBB.sqf index 53620da7b2..05a761bf06 100644 --- a/addons/overpressure/functions/fnc_firedEHBB.sqf +++ b/addons/overpressure/functions/fnc_firedEHBB.sqf @@ -16,12 +16,14 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); // Retrieve backblast values private _bbValues = [_weapon, _ammo, _magazine] call FUNC(getOverPressureValues); _bbValues params ["_backblastAngle", "_backblastRange", "_backblastDamage", "_offset"]; +_backblastRange = _backblastRange * GVAR(backblastDistanceCoefficient); + TRACE_4("cache",_backblastAngle,_backblastRange,_backblastDamage,_offset); if (_backblastDamage <= 0) exitWith {}; @@ -53,7 +55,7 @@ if (_distance < _backblastRange) then { [_damage * 100] call BIS_fnc_bloodEffect; - if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_unit, _damage, "body", "backblast", _unit] call EFUNC(medical,addDamageToUnit); } else { _unit setDamage (damage _unit + _damage); diff --git a/addons/overpressure/functions/fnc_firedEHOP.sqf b/addons/overpressure/functions/fnc_firedEHOP.sqf index 7a76f4b2be..e011098b59 100644 --- a/addons/overpressure/functions/fnc_firedEHOP.sqf +++ b/addons/overpressure/functions/fnc_firedEHOP.sqf @@ -16,12 +16,14 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); // Retrieve overpressure values private _opValues = [_weapon, _ammo, _magazine] call FUNC(getOverPressureValues); _opValues params ["_dangerZoneAngle", "_dangerZoneRange", "_dangerZoneDamage"]; +_dangerZoneRange = _dangerZoneRange * GVAR(overpressureDistanceCoefficient); + TRACE_3("cache",_dangerZoneAngle,_dangerZoneRange,_dangerZoneDamage); if (_dangerZoneDamage <= 0) exitWith {}; diff --git a/addons/overpressure/functions/fnc_getDistance.sqf b/addons/overpressure/functions/fnc_getDistance.sqf index 891178cb52..64ee563974 100644 --- a/addons/overpressure/functions/fnc_getDistance.sqf +++ b/addons/overpressure/functions/fnc_getDistance.sqf @@ -19,7 +19,7 @@ */ params ["_posASL", "_direction", "_maxDistance", "_shooter"]; -TRACE_4("params",_posASL,_direction,_maxDistance, _shooter); +TRACE_4("params",_posASL,_direction,_maxDistance,_shooter); private _intersections = lineIntersectsSurfaces [_posASL, _posASL vectorAdd (_direction vectorMultiply _maxDistance), _shooter, objNull, true, 99]; diff --git a/addons/overpressure/functions/fnc_getOverPressureValues.sqf b/addons/overpressure/functions/fnc_getOverPressureValues.sqf index 4372d4c8e6..374e9de9d6 100644 --- a/addons/overpressure/functions/fnc_getOverPressureValues.sqf +++ b/addons/overpressure/functions/fnc_getOverPressureValues.sqf @@ -54,7 +54,7 @@ TRACE_1("ConfigPath",_config); // get the Variables out of the Configs and populate return array with them _return = [ (getNumber (_config >> QGVAR(angle))), - (getNumber (_config >> QGVAR(range))) * GVAR(distanceCoefficient), + (getNumber (_config >> QGVAR(range))), (getNumber (_config >> QGVAR(damage))), (getNumber (_config >> QGVAR(offset))) ]; diff --git a/addons/overpressure/functions/fnc_overpressureDamage.sqf b/addons/overpressure/functions/fnc_overpressureDamage.sqf index 2fd0c0f7e5..12b7a820ca 100644 --- a/addons/overpressure/functions/fnc_overpressureDamage.sqf +++ b/addons/overpressure/functions/fnc_overpressureDamage.sqf @@ -57,7 +57,7 @@ TRACE_3("cache",_overpressureAngle,_overpressureRange,_overpressureDamage); [_damage * 100] call BIS_fnc_bloodEffect; }; - if (["ACE_Medical"] call EFUNC(common,isModLoaded)) then { + if (GETEGVAR(medical,enabled,false)) then { [_x, _damage, "body", "backblast", _firer] call EFUNC(medical,addDamageToUnit); } else { _x setDamage (damage _x + _damage); diff --git a/addons/overpressure/initSettings.inc.sqf b/addons/overpressure/initSettings.inc.sqf new file mode 100644 index 0000000000..ece1230dcc --- /dev/null +++ b/addons/overpressure/initSettings.inc.sqf @@ -0,0 +1,23 @@ +private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(DisplayName)]; + +[ + QGVAR(overpressureDistanceCoefficient), + "SLIDER", + [LSTRING(distanceCoefficient_displayName), LSTRING(distanceCoefficient_toolTip)], + _category, + [0, 10, 1, 1], + 1, + {[QGVAR(overpressureDistanceCoefficient), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + +[ + QGVAR(backblastDistanceCoefficient), + "SLIDER", + [LSTRING(backblastDistanceCoefficient_displayName), LSTRING(backblastDistanceCoefficient_toolTip)], + _category, + [0, 10, 1, 1], + 1, + {[QGVAR(backblastDistanceCoefficient), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; diff --git a/addons/overpressure/initSettings.sqf b/addons/overpressure/initSettings.sqf deleted file mode 100644 index 7fe6401131..0000000000 --- a/addons/overpressure/initSettings.sqf +++ /dev/null @@ -1,9 +0,0 @@ -private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(DisplayName)]; - -[ - QGVAR(distanceCoefficient), "SLIDER", - [LSTRING(distanceCoefficient_displayName), LSTRING(distanceCoefficient_toolTip)], - _category, - [-1, 10, 1, 1], - 1 -] call CBA_fnc_addSetting; diff --git a/addons/overpressure/stringtable.xml b/addons/overpressure/stringtable.xml index fff44a9a0a..2ce7615ad4 100644 --- a/addons/overpressure/stringtable.xml +++ b/addons/overpressure/stringtable.xml @@ -5,9 +5,10 @@ Overpressure 超压 Überdruck + Sovrapressione 과중압력 Nadciśnienie - 過圧 + 超過圧力 Перегрузка Sobrepresiòn Surpression @@ -15,11 +16,11 @@ Overpressure Distance Coefficient Überdruckentfernungskoeffizient - 過圧の距離係数 + 超過圧力の距離係数 과중압력 거리 계수 Mnożnik dystansu nadciśnienia Coefficient de distance pour la surpression - Coefficente Distanza Sovrapressione + Coefficiente Distanza Sovrapressione 超压影响距离系数 高壓影響距離係數 Коэф. избыточного давления @@ -29,25 +30,41 @@ Coeficiente de distancia de sobrepresión - Scales the overpressure effect [Default: 1] - Stellt den Koeffizient für die Überdruckentfernung ein [Standard: 1] - 過圧効果の範囲 [標準: 1] - 과중압력의 효과 크기 [기본설정: 1] - Skaluje efekt nadciśnienia [Domyślne: 1] - Ajuste l'effet de surpression. Valeur par défaut : 1. - Scala l'effetto di sovrapressione [Predefinito: 1] - 超压影响的范围 [预设:1] - 高壓影響的範圍 [預設: 1] - Степень зависимости избыточного давления от расстояния [По умолчанию: 1] - Escala o efeito de sobrepressão [Padrão: 1] - Állítja a túlnyomás hatását [Alapértelmezett: 1] - Nastavuje jak velký je efekt přetlaku [Standard: 1] - Escala el efecto de sobrepresión [Predeterminado: 1] + Scales the overpressure effect + Stellt den Koeffizient für die Überdruckentfernung ein + 火砲による超過圧力の影響範囲の大きさ + 과중압력의 효과 크기 + Skaluje efekt nadciśnienia + Ajuste l'effet de surpression + Scala l'effetto di sovrapressione + 超压影响的范围 + 高壓影響的範圍 + Степень зависимости избыточного давления от расстояния + Escala o efeito de sobrepressão + Állítja a túlnyomás hatását + Nastavuje jak velký je efekt přetlaku + Escala el efecto de sobrepresión + + + Backblast Distance Coefficient + Коэффициент расстояния рекативной струи + Rückstrahl-Entfernung Multiplikator + Coefficiente distanza di svampata + 後方噴射の距離係数 + 후폭풍 거리 계수 + + + Scales the backblast effect + Масштабирует эффект реактивной струи + Skaliert den Rückstrahl-Effekt + Scala l'effetto delle svampate dei lanciarazzi + 無反動砲による後方噴射の影響範囲の大きさ + 후폭풍 효과의 스케일을 조정합니다 Backblast range Rückstrahlzone - 後方噴射の範囲 + 後方噴射範囲 向后喷射的范围 後方尾焰的範圍 Raggio della fiammata [lanciarazzi] @@ -63,7 +80,7 @@ Backblast angle Rückstrahlwinkel - 後方噴射の角度 + 後方噴射角度 向后喷射的角度 後方尾焰的角度 Angolo della fiammata [lanciarazzi] diff --git a/addons/parachute/CfgVehicles.hpp b/addons/parachute/CfgVehicles.hpp index f764494224..545d9a3705 100644 --- a/addons/parachute/CfgVehicles.hpp +++ b/addons/parachute/CfgVehicles.hpp @@ -101,4 +101,36 @@ class CfgVehicles { class B_Soldier_05_f; class B_Pilot_F: B_Soldier_05_f {backpack = "ACE_NonSteerableParachute";}; class I_Soldier_04_F; class I_pilot_F: I_Soldier_04_F {backpack = "ACE_NonSteerableParachute";}; class O_helipilot_F; class O_Pilot_F: O_helipilot_F {backpack = "ACE_NonSteerableParachute";}; + + class Plane_Base_F; + class Plane_CAS_01_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_CAS_02_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_01_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_02_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_03_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; + class Plane_Fighter_04_base_F: Plane_Base_F { + class EjectionSystem { + EjectionParachute = "NonSteerable_Parachute_F"; + }; + }; }; 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/XEH_postInit.sqf b/addons/parachute/XEH_postInit.sqf index 1217fa3cab..f10748b0cf 100644 --- a/addons/parachute/XEH_postInit.sqf +++ b/addons/parachute/XEH_postInit.sqf @@ -34,9 +34,9 @@ if (!hasInterface) exitWith {}; }, {false}, [24, [false, false, false]], false] call CBA_fnc_addKeybind; // Handle reserve chute based on current backpack (fires when parachute opens too) -["loadout", FUNC(handleReserve), true] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handleReserve), true] call CBA_fnc_addPlayerEventHandler; // Don't show vanilla speed and height when in expert mode -["ace_infoDisplayChanged", {_this call FUNC(handleInfoDisplayChanged)}] call CBA_fnc_addEventHandler; +["ace_infoDisplayChanged", LINKFUNC(handleInfoDisplayChanged)] call CBA_fnc_addEventHandler; -["vehicle", {_this call FUNC(handleFailureChance)}] call CBA_fnc_addPlayerEventHandler; +["vehicle", LINKFUNC(handleFailureChance)] call CBA_fnc_addPlayerEventHandler; diff --git a/addons/parachute/XEH_preInit.sqf b/addons/parachute/XEH_preInit.sqf index cb77025b4d..d3aa4bd2d5 100644 --- a/addons/parachute/XEH_preInit.sqf +++ b/addons/parachute/XEH_preInit.sqf @@ -8,6 +8,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/parachute/functions/fnc_cutParachute.sqf b/addons/parachute/functions/fnc_cutParachute.sqf index 564a9e09cd..c66d9ff050 100644 --- a/addons/parachute/functions/fnc_cutParachute.sqf +++ b/addons/parachute/functions/fnc_cutParachute.sqf @@ -16,7 +16,7 @@ * Public: No */ params ["_unit", "_parachute"]; -TRACE_2("cutParachute", _unit, _parachute); +TRACE_2("cutParachute",_unit,_parachute); playSound3d ["A3\Sounds_F\characters\parachute\parachute_landing.wss", _unit]; _unit action ["GetOut", _parachute]; diff --git a/addons/parachute/functions/fnc_showAltimeter.sqf b/addons/parachute/functions/fnc_showAltimeter.sqf index 47b014f4ab..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,9 +54,9 @@ private _TimeText = _display displayCtrl 1001; 0 }; - _TimeText ctrlSetText (format ["%1:%2", [_hour, 2] call CBA_fnc_formatNumber, [_minute, 2] call CBA_fnc_formatNumber]); - _HeightText ctrlSetText (format ["%1", floor _height]); - _DecendRate ctrlSetText (format ["%1", _descentRate max 0]); + _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); (_this select 0) set [1, _height]; (_this select 0) set [2, _curTime]; diff --git a/addons/parachute/initSettings.sqf b/addons/parachute/initSettings.inc.sqf similarity index 77% rename from addons/parachute/initSettings.sqf rename to addons/parachute/initSettings.inc.sqf index 0cfc3f8ca0..0c6804cff7 100644 --- a/addons/parachute/initSettings.sqf +++ b/addons/parachute/initSettings.inc.sqf @@ -5,9 +5,7 @@ private _category = [LELSTRING(common,categoryUncategorized), localize "str_dn_p "CHECKBOX", [LSTRING(HideAltimeter), LSTRING(HideAltimeter_tooltip)], _category, - true, - false, - {[QGVAR(hideAltimeter), _this, false] call EFUNC(common,cbaSettings_settingChanged)} + true ] call CBA_fnc_addSetting; [ diff --git a/addons/parachute/stringtable.xml b/addons/parachute/stringtable.xml index 0e3a7a5ac4..db48a6109c 100644 --- a/addons/parachute/stringtable.xml +++ b/addons/parachute/stringtable.xml @@ -142,6 +142,7 @@ 開傘失敗率 Szansa na nieotwarcie się spadochronu Wahrscheinlichkeit, dass ein Fallschirm sich nicht öffnet + Probabilità che l'apertura del paracadute fallisca 开伞失败率 낙하산 펼치기 실패 확률 Probabilidad de fallo de paracaidas diff --git a/addons/pylons/XEH_preInit.sqf b/addons/pylons/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/pylons/XEH_preInit.sqf +++ b/addons/pylons/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/pylons/functions/fnc_showDialog.sqf b/addons/pylons/functions/fnc_showDialog.sqf index a06cb6f114..9c0faab52d 100644 --- a/addons/pylons/functions/fnc_showDialog.sqf +++ b/addons/pylons/functions/fnc_showDialog.sqf @@ -107,7 +107,7 @@ GVAR(comboBoxes) = []; private _mirroredIndex = getNumber (_x >> "mirroredMissilePos"); private _button = controlNull; - if (count allTurrets [_aircraft, false] > 0) then { + if ((allTurrets [_aircraft, false]) isNotEqualTo []) then { _button = _display ctrlCreate ["ctrlButtonPictureKeepAspect", -1]; private _turret = [_aircraft, _forEachIndex] call EFUNC(common,getPylonTurret); [_button, false, _turret] call FUNC(onButtonTurret); diff --git a/addons/pylons/initSettings.sqf b/addons/pylons/initSettings.inc.sqf similarity index 100% rename from addons/pylons/initSettings.sqf rename to addons/pylons/initSettings.inc.sqf diff --git a/addons/pylons/stringtable.xml b/addons/pylons/stringtable.xml index 8805ad3704..1021a2fc15 100644 --- a/addons/pylons/stringtable.xml +++ b/addons/pylons/stringtable.xml @@ -94,7 +94,7 @@ %1 is already configuring this aircraft! - %1 はすでにこの機体へ設定されています! + %1 は すでにこの機体へ設定されています! % sta già configurando questo aereo! %1已經正在定義此飛機的武裝配置! %1已经正在定义此飞机的武器配置! @@ -109,7 +109,7 @@ Replacing pylon %1 out of %2... - %2 中 %1 のパイロンを交換しています・・・ + %2 個中 %1 番目のパイロンを交換しています・・・ Sostituendo pilone %1 al posto di %2... 共有%2個派龍架,正在整補%1號派龍架中... 共有%2个发射架,正在整装%1号挂架... @@ -124,7 +124,7 @@ Stopped at pylon %1! - パイロン %1 で中断しました! + %1 番目のパイロンで中断しました! Fermato al pilone %1! 已停止在%1號派龍架! 已在整装%1号挂架时停止! @@ -157,7 +157,7 @@ 启用宙斯导弹挂架菜单 啟用派龍架選單給宙斯 Abilita Menù Piloni da Zeus - Zeus でパイロン メニューを有効化 + Zeusでパイロン メニューを有効化 Aktiviert Außenlaststationsmenü im Zeus Activer le menu des pylônes (Zeus) Aktywuj Menu Pylonów dla Zeus'a @@ -171,8 +171,8 @@ Enables use of the zeus module. 允许启用宙斯模组 允啟使用宙斯模塊 - Abilita l'uso dal modulo di Zeus - Zeus モジュールでパイロン メニューを利用できます。 + Abilita l'uso del modulo Zeus + Zeusモジュールでパイロン メニューを利用できるようにします。 Aktiviert die Nutzung im Zeus Permet l'utilisation des modules Zeus. Aktywuj wykorzystanie modułu zeus'a. @@ -186,7 +186,7 @@ Enable Pylons Menu from Ammo Trucks 启用弹药车导弹挂架菜单 啟用從彈藥卡車使用派龍架選單 - Abilita Menù Piloni da mezzi rifornimento munizioni + Abilita Menù Piloni da mezzi di rifornimento munizioni 弾薬トラックからパイロン メニューを有効化 Aktiviert Außenlaststationsmenü von Munitionstransportern Activer le menu des pylônes (camions de munitions) @@ -201,7 +201,7 @@ Enables use of pylons menu from ammo trucks. 允许在弹药车上启用导弹挂架菜单 允許從彈藥卡車使用派龍架選單 - Abilita l'uso del Menù Piloni da mezzi rifornimento munizioni + Abilita l'uso del Menù Piloni da mezzi di rifornimento munizioni 弾薬給弾トラックからパイロン メニューを利用できます。 Aktiviert die Nutzung von Außenlaststationsmenü von Munitionstransportern. Permet l'utilisation du menu des pylônes à partir des camions de ravitaillement de munitions. @@ -217,7 +217,7 @@ 这架飞机没有导弹挂架 這架飛機沒有派龍架 Questo aereo non ha piloni - 航空機にパイロンがありません + この航空機にはパイロンがありません Dieses Flugzeug hat keine Außenlaststationen Cet aéronef n'a pas de pylônes. Ten pojazd nie posiada pylonów @@ -231,8 +231,8 @@ Configure pylons module is disabled for zeus 宙斯模组的导弹挂架已禁用 宙斯模塊的派龍架設定已被禁用 - Il modulo per configurare i piloni da Zeus è disabilitato - Zeus のパイロン モジュールを無効化 + Il modulo Zeus per configurare i piloni è disabilitato + Zeusのパイロン編集を無効化 Die Konfiguration für das Außenlaststationen ist im Zeus deaktiviert Le module de configuration des pylônes est désactivé pour Zeus. Konfiguracja modułu pylonów jest wyłączona dla zeus'a @@ -274,7 +274,7 @@ Time Per Pylon - パイロンへの時間 + パイロンあたりの所要時間 Tempo Per Pilone 派龍架整補所需時間(個別) 导弹挂架整装所需时间(个别) @@ -289,7 +289,7 @@ The time it takes to replace each pylon (in seconds). - 各パイロンの置き換えにかかる時間を設定します。(秒) + 各パイロンの置き換えに掛かる時間。 (秒単位) Il tempo che impiega ogni pilone ad essere sostituito (in secondi). 每個派龍架需花多久時間進行整補(單位為秒) 每个挂架需花多久时间进行整装(单位为秒)。 @@ -335,7 +335,7 @@ Require Engineer 工兵の必須化 - Necessita Ingegnere + Necessita Geniere 需要工兵 必须是工兵 정비병 요구 @@ -350,7 +350,7 @@ Require an engineer. 工兵を必須とします。 - Necessita un ingegnere. + Necessita un Geniere. 需要工兵才能進行彈藥整補 必须是工兵才能进行弹药整装。 정비병이 필요합니다. @@ -365,7 +365,7 @@ Require Toolkit ツールキットの必須化 - Necessita Kit Riparazione + Necessita Kit Utensili 需要工具包 需要工具包 도구모음 요구 @@ -380,7 +380,7 @@ Require a toolkit in inventory. インベントリ内にツールキットの存在を必須とします。 - Necessita un kit di riparazione nell'inventario + Necessita un kit utensili nell'inventario 需要工具包才能進行彈藥整補 需要工具包才能进行弹药整装。 도구모음이 필요합니다. diff --git a/addons/quickmount/XEH_postInitClient.sqf b/addons/quickmount/XEH_postInitClient.sqf index 23c225f583..6dbd38742b 100644 --- a/addons/quickmount/XEH_postInitClient.sqf +++ b/addons/quickmount/XEH_postInitClient.sqf @@ -2,9 +2,8 @@ if (!hasInterface) exitWith {}; -["ACE3 Movement", QGVAR(mount), [localize LSTRING(KeybindName), localize LSTRING(KeybindDescription)], "", { +["ACE3 Movement", QGVAR(mount), [LLSTRING(KeybindName), LLSTRING(KeybindDescription)], "", { if (!dialog) then { - [] call FUNC(getInNearest); + call FUNC(getInNearest); }; - false }] call CBA_fnc_addKeybind; diff --git a/addons/quickmount/XEH_preInit.sqf b/addons/quickmount/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/quickmount/XEH_preInit.sqf +++ b/addons/quickmount/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; 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..52bc8cd220 100644 --- a/addons/quickmount/functions/fnc_getInNearest.sqf +++ b/addons/quickmount/functions/fnc_getInNearest.sqf @@ -1,131 +1,125 @@ #include "..\script_component.hpp" /* * Author: Kingsley - * Mount the player in the vehicle they are directly looking at based on their distance. + * Mounts the player in the vehicle they are directly looking at based on their distance. * * Arguments: - * 0: Target (Optional) + * 0: Target (default: objNull) * * Return Value: * None * * Example: - * [] call ace_quickmount_fnc_getInNearest; + * call ace_quickmount_fnc_getInNearest * * Public: No */ -if (!GVAR(enabled) || +if ( + !GVAR(enabled) || {isNull ACE_player} || - {vehicle ACE_player != ACE_player} || - {!alive ACE_player} || - {ACE_player getVariable ["ace_unconscious", false]} + {!isNull objectParent ACE_player} || + {!(ACE_player call EFUNC(common,isAwake))} ) exitWith {}; -params [["_interactionTarget", objNull, [objNull]]]; -TRACE_1("getInNearest",_interactionTarget); +params [["_target", objNull, [objNull]]]; +TRACE_1("getInNearest",_target); -private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot"); -private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); -private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; -private _target = (_objects param [0, []]) param [2, objNull]; - -if ((isNull _target) && {alive _interactionTarget}) then { - _end = _start vectorAdd ((_start vectorFromTo (aimPos _interactionTarget)) vectorMultiply GVAR(distance)); - _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; - TRACE_1("2nd ray attempt at interaction target aim pos",_objects); +// If target is not defined (e.g. keybind was used), search for valid target +if (isNull _target) then { + private _start = ACE_player modelToWorldVisualWorld (ACE_player selectionPosition "pilot"); + private _end = (_start vectorAdd (getCameraViewDirection ACE_player vectorMultiply GVAR(distance))); + private _objects = lineIntersectsSurfaces [_start, _end, ACE_player]; _target = (_objects param [0, []]) param [2, objNull]; }; -if (locked _target in [2,3] || {!simulationEnabled _target}) exitWith { - [localize LSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); - true +if (!alive _target) exitWith {}; + +if (locked _target >= 2 || {!simulationEnabled _target}) exitWith { + [LLSTRING(VehicleLocked)] call EFUNC(common,displayTextStructured); }; TRACE_2("",_target,typeOf _target); -if (!isNull _target && - {alive _target} && - {{_target isKindOf _x} count ["Air","LandVehicle","Ship","StaticMortar"] > 0} && - {([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} && - {speed _target <= GVAR(speed)} - ) then { +if ( + (speed _target > GVAR(speed)) || + {["Air", "LandVehicle", "Ship", "StaticMortar"] findIf {_target isKindOf _x} == -1} || + {!([ACE_player, _target, ["isNotSwimming"]] call EFUNC(common,canInteractWith))} +) exitWith {}; +private _seats = ["driver", "gunner", "commander", "cargo"]; +private _sortedSeats = [_seats select GVAR(priority)]; +_seats deleteAt GVAR(priority); +_sortedSeats append _seats; - if (GVAR(priority) > 3 || GVAR(priority) < 0) then { - GVAR(priority) = 0; - }; +private _fullCrew = fullCrew [_target, "", true]; - private _seats = ["Driver", "Gunner", "Commander", "Cargo"]; - private _sortedSeats = [_seats select GVAR(priority)]; - _seats deleteAt GVAR(priority); - _sortedSeats append _seats; +private _hasAction = false; +scopeName "SearchForSeat"; +{ + private _desiredRole = _x; - private _hasAction = false; - scopeName "SearchForSeat"; { - private _desiredRole = _x; - { - _x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; - if ((isNull _unit) || {!alive _unit}) then { - private _effectiveRole = toLower _role; + _x params ["_unit", "_role", "_cargoIndex", "_turretPath"]; - 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) + if (!alive _unit) then { + private _effectiveRole = _role; - // Seats can be locked independently of the main vehicle - if ((_role == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);}; - if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);}; - if ((_turretPath isNotEqualTo []) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; + 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) - if (_effectiveRole == "turret") then { - private _turretConfig = [_target, _turretPath] call CBA_fnc_getTurret; - if (getNumber (_turretConfig >> "isCopilot") == 1) exitWith { - _effectiveRole = "driver"; - }; - if ( - _cargoIndex >= 0 // FFV - || {"" isEqualTo getText (_turretConfig >> "gun")} // turret without weapon - ) exitWith { - _effectiveRole = "cargo"; - }; - _effectiveRole = "gunner"; // door gunners / 2nd turret - }; - TRACE_2("",_effectiveRole,_x); - if (_effectiveRole != _desiredRole) exitWith {}; + // Seats can be locked independently of the main vehicle + if ((_effectiveRole == "driver") && {lockedDriver _target}) exitWith {TRACE_1("lockedDriver",_x);}; + if ((_cargoIndex >= 0) && {_target lockedCargo _cargoIndex}) exitWith {TRACE_1("lockedCargo",_x);}; + if ((_turretPath isNotEqualTo []) && {_target lockedTurret _turretPath}) exitWith {TRACE_1("lockedTurret",_x);}; - if (_turretPath isNotEqualTo []) then { - // Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander - ACE_player action ["GetInTurret", _target, _turretPath]; - TRACE_3("Geting In Turret",_x,_role,_turretPath); - } else { - if (_cargoIndex > -1) then { - // GetInCargo expects the index of the seat in the "cargo" array from fullCrew - // See description: https://community.bistudio.com/wiki/fullCrew - private _cargoActionIndex = -1; - { - if ((_x select 2) == _cargoIndex) exitWith {_cargoActionIndex = _forEachIndex}; - } forEach (fullCrew [_target, "cargo", true]); + if (_effectiveRole == "turret") then { + private _turretConfig = [_target, _turretPath] call CBA_fnc_getTurret; - ACE_player action ["GetInCargo", _target, _cargoActionIndex]; - TRACE_4("Geting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex); - } else { - ACE_player action ["GetIn" + _role, _target]; - TRACE_2("Geting In",_x,_role); - }; + if (getNumber (_turretConfig >> "isCopilot") == 1) exitWith { + _effectiveRole = "driver"; }; - _hasAction = true; - breakTo "SearchForSeat"; + if ( + _cargoIndex >= 0 || // FFV + {getText (_turretConfig >> "gun") == ""} // Turret without weapon + ) exitWith { + _effectiveRole = "cargo"; + }; + + _effectiveRole = "gunner"; // Door gunners / 2nd turret }; - } forEach (fullCrew [_target, "", true]); - } forEach _sortedSeats; - if (!_hasAction) then { - TRACE_1("no empty seats",_hasAction); - [localize LSTRING(VehicleFull)] call EFUNC(common,displayTextStructured); - }; + TRACE_2("",_effectiveRole,_x); + + if (_effectiveRole != _desiredRole) exitWith {}; + + if (_turretPath isNotEqualTo []) then { + // Using GetInTurret seems to solve problems with incorrect GetInEH params when gunner/commander + ACE_player action ["GetInTurret", _target, _turretPath]; + TRACE_3("Getting In Turret",_x,_role,_turretPath); + } else { + if (_cargoIndex > -1) then { + // GetInCargo expects the index of the seat in the "cargo" array from fullCrew + // See description: https://community.bistudio.com/wiki/fullCrew + private _cargoActionIndex = (fullCrew [_target, "cargo", true]) findIf {(_x select 2) == _cargoIndex}; + + ACE_player action ["GetInCargo", _target, _cargoActionIndex]; + TRACE_4("Getting In Cargo",_x,_role,_cargoActionIndex,_cargoIndex); + } else { + ACE_player action ["GetIn" + _role, _target]; + TRACE_2("Getting In",_x,_role); + }; + }; + + _hasAction = true; + breakTo "SearchForSeat"; + }; + } forEach _fullCrew; +} forEach _sortedSeats; + +if (!_hasAction) then { + TRACE_1("no empty seats",_hasAction); + [LLSTRING(VehicleFull)] call EFUNC(common,displayTextStructured); }; - -true diff --git a/addons/quickmount/initSettings.sqf b/addons/quickmount/initSettings.inc.sqf similarity index 100% rename from addons/quickmount/initSettings.sqf rename to addons/quickmount/initSettings.inc.sqf diff --git a/addons/quickmount/stringtable.xml b/addons/quickmount/stringtable.xml index 2f1b19bd1f..3ebff2f7d2 100644 --- a/addons/quickmount/stringtable.xml +++ b/addons/quickmount/stringtable.xml @@ -98,7 +98,7 @@ Maximum distance to check for vehicles. Maximale Entfernung zu Fahrzeugen - Distanza massima per controllare i veicoli. + Distanza massima da controllare per presenza di veicoli. 車両を検知できる最大距離を設定します。 最大可检查载具的距离。 最大可檢查載具的距離 diff --git a/addons/rangecard/CfgWeapons.hpp b/addons/rangecard/CfgWeapons.hpp index 851e324346..cb55b0dcac 100644 --- a/addons/rangecard/CfgWeapons.hpp +++ b/addons/rangecard/CfgWeapons.hpp @@ -14,7 +14,7 @@ class CfgWeapons { ACE_isTool = 1; class ItemInfo: CBA_MiscItem_ItemInfo { - mass = 1; + mass = 0.1; }; }; }; diff --git a/addons/rangecard/XEH_postInit.sqf b/addons/rangecard/XEH_postInit.sqf index 9e60821fc1..af4dfa923c 100644 --- a/addons/rangecard/XEH_postInit.sqf +++ b/addons/rangecard/XEH_postInit.sqf @@ -1,7 +1,5 @@ #include "script_component.hpp" -#include "initKeybinds.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/rangecard/functions/fnc_calculateRangeCard.sqf b/addons/rangecard/functions/fnc_calculateRangeCard.sqf index 179437eb58..d2347b8494 100644 --- a/addons/rangecard/functions/fnc_calculateRangeCard.sqf +++ b/addons/rangecard/functions/fnc_calculateRangeCard.sqf @@ -49,7 +49,8 @@ private _bulletSpeed = 0; private _gravity = [0, sin(_scopeBaseAngle) * -GRAVITY, cos(_scopeBaseAngle) * -GRAVITY]; private _deltaT = 1 / _simSteps; private _speedOfSound = 0; -if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { +private _isABenabled = missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]; +if (_isABenabled) then { _speedOfSound = _temperature call EFUNC(weather,calculateSpeedOfSound); }; @@ -68,7 +69,7 @@ if (_useABConfig) then { }; private _airFrictionCoef = 1; -if (!_useABConfig && (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) then { +if (!_useABConfig && _isABenabled) then { private _airDensity = [_temperature, _barometricPressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity); _airFrictionCoef = _airDensity / 1.22498; }; diff --git a/addons/rangecard/functions/fnc_updateRangeCard.sqf b/addons/rangecard/functions/fnc_updateRangeCard.sqf index d7acd46486..c2c8673844 100644 --- a/addons/rangecard/functions/fnc_updateRangeCard.sqf +++ b/addons/rangecard/functions/fnc_updateRangeCard.sqf @@ -33,7 +33,7 @@ if (_ammoClass == "" || _magazineClass == "" || _weaponClass == "") exitWith {}; GVAR(controls) = []; for "_row" from 0 to 49 do { - private _offset = if (_row < 5) then {0} else {0.003}; + private _offset = [0.003, 0] select (_row < 5); private _control = (__dsp ctrlCreate ["RangeCard_RscText", 790000 + _row]); _control ctrlSetPosition [safeZoneX + 0.183, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.062, 0.025]; if (_row in [0, 8, 18, 28, 38, 48]) then { @@ -47,7 +47,7 @@ for "_row" from 0 to 49 do { }; for "_column" from 0 to 8 do { for "_row" from 0 to 49 do { - private _offset = if (_row < 5) then {0} else {0.003}; + private _offset = [0.003, 0] select (_row < 5); private _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + _column * 100 + _row]); _control ctrlSetPosition [safeZoneX + 0.249 + _column * 0.055, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.052, 0.025]; _control ctrlCommit 0; @@ -57,7 +57,7 @@ for "_column" from 0 to 8 do { }; for "_column" from 0 to 2 do { for "_row" from 0 to 49 do { - private _offset = if (_row < 5) then {0} else {0.003}; + private _offset = [0.003, 0] select (_row < 5); private _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + (9 +_column) * 100 + _row]); _control ctrlSetPosition [safeZoneX + 0.743 + _column * 0.049, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.047, 0.025]; _control ctrlCommit 0; @@ -67,7 +67,7 @@ for "_column" from 0 to 2 do { }; for "_column" from 0 to 2 do { for "_row" from 0 to 49 do { - private _offset = if (_row < 5) then {0} else {0.003}; + private _offset = [0.003, 0] select (_row < 5); private _control = (__dsp ctrlCreate ["RangeCard_RscText", 90000 + (12 +_column) * 100 + _row]); _control ctrlSetPosition [safeZoneX + 0.892 + _column * 0.049, safeZoneY + 0.374 + 0.027 * _row + _offset, 0.047, 0.025]; _control ctrlCommit 0; @@ -100,19 +100,24 @@ private _barrelLength = _weaponConfig select 2; private _muzzleVelocity = 0; private _bc = 0; -if (count (_ammoConfig select 6) > 0) then { +if ((_ammoConfig select 6) isNotEqualTo []) then { _bc = (_ammoConfig select 6) select 0; }; private _transonicStabilityCoef = _ammoConfig select 4; private _dragModel = _ammoConfig select 5; private _atmosphereModel = _ammoConfig select 8; -private _useABConfig = (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]); -if (_bc == 0) then { - _useABConfig = false; -}; +private _isABenabled = (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) && (_bc != 0); +private _useBarrelLengthInfluence = ( + _isABenabled && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} +); +private _useAmmoTemperatureInfluence = ( + _isABenabled && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]} +); -if (_barrelLength > 0 && _useABConfig) then { +if (_barrelLength > 0 && _useBarrelLengthInfluence) then { _muzzleVelocity = [_barrelLength, _ammoConfig select 10, _ammoConfig select 11, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift); } else { private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "initSpeed"); @@ -128,7 +133,7 @@ if (_barrelLength > 0 && _useABConfig) then { ctrlSetText [770000, format["%1'' - %2 gr (%3)", round((_ammoConfig select 1) * 39.3700787) / 1000, round((_ammoConfig select 3) * 15.4323584), _ammoClass]]; if (_barrelLength > 0) then { - if (_useABConfig && _barrelTwist > 0) then { + if (_useBarrelLengthInfluence && _barrelTwist > 0) then { ctrlSetText [770002, format["Barrel: %1'' 1:%2'' twist", round(2 * _barrelLength * 0.0393700787) / 2, round(_barrelTwist * 0.0393700787)]]; } else { ctrlSetText [770002, format["Barrel: %1''", round(2 * _barrelLength * 0.0393700787) / 2]]; @@ -136,7 +141,7 @@ if (_barrelLength > 0) then { }; lnbAddRow [770100, ["4mps Wind(MRADs)", "1mps LEAD(MRADs)"]]; -if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { +if (_isABenabled) then { lnbAddRow [770100, ["Air/Ammo Temp", "Air/Ammo Temp"]]; lnbAddRow [770200, ["-15°C", " -5°C", " 5°C", " 10°C", " 15°C", " 20°C", " 25°C", " 30°C", " 35°C"]]; @@ -145,7 +150,7 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t ctrlSetText [77003, format["%1m ZERO", round(_zeroRange)]]; -if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { +if (_isABenabled) then { ctrlSetText [770001, format["Drop Tables for B.P.: %1mb; Corrected for MVV at Air/Ammo Temperatures -15-35 °C", round(EGVAR(scopes,zeroReferenceBarometricPressure) * 100) / 100]]; ctrlSetText [77004 , format["B.P.: %1mb", round(EGVAR(scopes,zeroReferenceBarometricPressure) * 100) / 100]]; } else { @@ -153,30 +158,30 @@ if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) t ctrlSetText [77004 , ""]; }; -private _cacheEntry = missionNamespace getVariable format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]]; -if (isNil {_cacheEntry}) then { - private _scopeBaseAngle = if (!_useABConfig) then { +private _cacheEntry = missionNamespace getVariable format [QGVAR(%1_%2_%3_%4_%5_%6_%7), _zeroRange, _boreHeight, _ammoClass, _weaponClass, _isABenabled, _useBarrelLengthInfluence, _useAmmoTemperatureInfluence]; +if (isNil "_cacheEntry") then { + private _scopeBaseAngle = if (!_isABenabled) then { private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZero:%1:%2:%3:%4", _zeroRange, _muzzleVelocity, _airFriction, _boreHeight]; (parseNumber _zeroAngle) } else { private _zeroAngle = "ace_advanced_ballistics" callExtension format ["calcZeroAB:%1:%2:%3:%4:%5:%6:%7:%8:%9", _zeroRange, _muzzleVelocity, _boreHeight, EGVAR(scopes,zeroReferenceTemperature), EGVAR(scopes,zeroReferenceBarometricPressure), EGVAR(scopes,zeroReferenceHumidity), _bc, _dragModel, _atmosphereModel]; (parseNumber _zeroAngle) }; - if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && missionNamespace getVariable [QEGVAR(advanced_ballistics,ammoTemperatureEnabled), false]) then { + if (_useAmmoTemperatureInfluence) then { { private _mvShift = [_ammoConfig select 9, _x] call EFUNC(advanced_ballistics,calculateAmmoTemperatureVelocityShift); private _mv = _muzzleVelocity + _mvShift; - [_scopeBaseAngle,_boreHeight,_airFriction,_mv,_x,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,_forEachIndex,_useABConfig] call FUNC(calculateRangeCard); + [_scopeBaseAngle,_boreHeight,_airFriction,_mv,_x,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,_forEachIndex,_isABenabled] call FUNC(calculateRangeCard); } forEach [-15, -5, 5, 10, 15, 20, 25, 30, 35]; } else { - [_scopeBaseAngle,_boreHeight,_airFriction,_muzzleVelocity,15,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,3,_useABConfig] call FUNC(calculateRangeCard); + [_scopeBaseAngle,_boreHeight,_airFriction,_muzzleVelocity,15,EGVAR(scopes,zeroReferenceBarometricPressure),EGVAR(scopes,zeroReferenceHumidity),200,4,1,GVAR(rangeCardEndRange),_bc,_dragModel,_atmosphereModel,_transonicStabilityCoef,3,_isABenabled] call FUNC(calculateRangeCard); }; for "_i" from 0 to 9 do { GVAR(lastValidRow) pushBack count (GVAR(rangeCardDataElevation) select _i); while {count (GVAR(rangeCardDataElevation) select _i) < 50} do { - if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { + if (_isABenabled) then { (GVAR(rangeCardDataElevation) select _i) pushBack "###"; (GVAR(rangeCardDataWindage) select _i) pushBack "##"; (GVAR(rangeCardDataLead) select _i) pushBack "##"; @@ -188,7 +193,7 @@ if (isNil {_cacheEntry}) then { }; }; - missionNamespace setVariable [format[QGVAR(%1_%2_%3_%4_%5), _zeroRange, _boreHeight, _ammoClass, _weaponClass, missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]], [GVAR(rangeCardDataElevation), GVAR(rangeCardDataWindage), GVAR(rangeCardDataLead), GVAR(rangeCardDataMVs), GVAR(lastValidRow)]]; + missionNamespace setVariable [format [QGVAR(%1_%2_%3_%4_%5_%6_%7), _zeroRange, _boreHeight, _ammoClass, _weaponClass, _isABenabled, _useBarrelLengthInfluence, _useAmmoTemperatureInfluence], [GVAR(rangeCardDataElevation), GVAR(rangeCardDataWindage), GVAR(rangeCardDataLead), GVAR(rangeCardDataMVs), GVAR(lastValidRow)]]; } else { GVAR(rangeCardDataElevation) = _cacheEntry select 0; GVAR(rangeCardDataWindage) = _cacheEntry select 1; diff --git a/addons/rangecard/initKeybinds.sqf b/addons/rangecard/initKeybinds.inc.sqf similarity index 100% rename from addons/rangecard/initKeybinds.sqf rename to addons/rangecard/initKeybinds.inc.sqf diff --git a/addons/rangecard/stringtable.xml b/addons/rangecard/stringtable.xml index 55238c8c3d..3e79eac985 100644 --- a/addons/rangecard/stringtable.xml +++ b/addons/rangecard/stringtable.xml @@ -12,7 +12,7 @@ Távolsági kártya Таблица поправок Tavola Balistica - 射表 + レンジカード (弾道射表) 사거리표 射表 彈道射表 @@ -29,7 +29,7 @@ 50 MÉTERES lépések - MRAD/MRAD (célzó/lövegek) Шаг 50 МЕТРОВ - MRAD/MRAD (сетка/маховички) Incrementi per 50 METRI - MRAD/MRAD (reticolo/torrette) - 50 メートル増やす -- MRAD/MRAD (照準線/砲塔) + 50 メートル単位 -- MRAD/MRAD (レチクル/タレット) 50 미터 늘리기 -- MRAD/MRAD (조준선/포탑) 50米增量 -- 毫弧度/毫弧度(瞄镜分划线/调整纽) 50公尺增量 -- 毫弧度/毫弧度 (瞄鏡分劃線/調整紐) @@ -46,7 +46,7 @@ Távolsági kártya kinyitása Открыть таблицу поправок Apri Tavola Balistica - 射表を開く + レンジカードを開く 사거리표 열기 开启射表 開啟彈道射表 @@ -63,7 +63,7 @@ Távolsági kártya-másolat kinyitása Открыть копию таблицы поправок Apri Copia Tavola Balistica - 複製された射表を開く + レンジカードの複製を開く 복제 사거리표 열기 开启射表副本 開啟彈道射表副本 @@ -80,7 +80,7 @@ Távolsági kártya kinyitása Открыть таблицу поправок Apri Tavola Balistica - 射表を開く + レンジカードを開く 사거리표 열기 开启射表 開啟彈道射表 @@ -97,7 +97,7 @@ Távolsági kártya-másolat kinyitása Открыть копию таблицы поправок Apri Copia Tavola Balistica - 複製された射表を開く + レンジカードの複製を開く 복제 사거리표 열기 开启射表副本 開啟彈道射表副本 @@ -114,7 +114,7 @@ Távolsági kártya másolása Скопировать таблицу поправок Copia Tavola Balistica - 射表を複製する + レンジカードを複製 사거리표 복제 复制射表 複製彈道射表 diff --git a/addons/realisticnames/Attachments.hpp b/addons/realisticnames/Attachments.hpp new file mode 100644 index 0000000000..a861bb4a04 --- /dev/null +++ b/addons/realisticnames/Attachments.hpp @@ -0,0 +1,174 @@ +//attachments + +class ItemCore; + +class acc_flashlight: ItemCore { + displayName = CSTRING(flashlight_Name); +}; + +class optic_MRD: ItemCore { + displayName = CSTRING(optic_mrd_Name); +}; +class optic_MRD_black: optic_MRD { + displayName = CSTRING(optic_mrd_black_Name); +}; + +class optic_Hamr: ItemCore { + displayName = CSTRING(optic_hamr); +}; +class optic_Hamr_khk_F: optic_Hamr { + displayName = CSTRING(optic_hamr_khk); +}; +class ACE_optic_Hamr_2D: optic_Hamr { + displayName = CSTRING(optic_hamr_2d); +}; +class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D { + displayName = CSTRING(optic_hamr_pip); +}; + +class optic_Arco: ItemCore { + displayName = CSTRING(optic_arco); +}; +class optic_Arco_blk_F: optic_Arco { + displayName = CSTRING(optic_arco_blk); +}; +class optic_Arco_ghex_F: optic_Arco { + displayName = CSTRING(optic_arco_ghex); +}; +class ACE_optic_Arco_2D: optic_Arco { + displayName = CSTRING(optic_arco_2d); +}; +class ACE_optic_Arco_PIP: ACE_optic_Arco_2D { + displayName = CSTRING(optic_arco_pip); +}; +class optic_Arco_lush_F: optic_Arco { + displayName = CSTRING(optic_arco_lush); +}; +class optic_Arco_arid_F: optic_Arco { + displayName = CSTRING(optic_arco_arid); +}; +class optic_Arco_AK_blk_F: optic_Arco_blk_F { + displayName = CSTRING(optic_arco_ak_blk); +}; +class optic_Arco_AK_lush_F: optic_Arco_lush_F { + displayName = CSTRING(optic_arco_ak_lush); +}; +class optic_Arco_AK_arid_F: optic_Arco_arid_F { + displayName = CSTRING(optic_arco_ak_arid); +}; + +class optic_ERCO_blk_f: optic_Arco { + displayName = CSTRING(optic_erco_blk); +}; +class optic_ERCO_khk_f: optic_ERCO_blk_f { + displayName = CSTRING(optic_erco_khk); +}; +class optic_ERCO_snd_f: optic_ERCO_blk_f { + displayName = CSTRING(optic_erco_snd); +}; + +class optic_LRPS: ItemCore { + displayName = CSTRING(optic_lrps); +}; +class optic_LRPS_ghex_F: optic_LRPS { + displayName = CSTRING(optic_lrps_ghex); +}; +class optic_LRPS_tna_F: optic_LRPS { + displayName = CSTRING(optic_lrps_tna); +}; +class ACE_optic_LRPS_2D: optic_LRPS { + displayName = CSTRING(optic_lrps_2d); +}; +class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D { + displayName = CSTRING(optic_lrps_pip); +}; + +class optic_AMS_base; +class optic_AMS: optic_AMS_base { + displayName = CSTRING(optic_ams); +}; +class optic_AMS_khk: optic_AMS { + displayName = CSTRING(optic_ams_khk); +}; +class optic_AMS_snd: optic_AMS { + displayName = CSTRING(optic_ams_snd); +}; + +class optic_KHS_base; +class optic_KHS_blk: optic_KHS_base { + displayName = CSTRING(optic_khs_blk); +}; +class optic_KHS_hex: optic_KHS_blk { + displayName = CSTRING(optic_khs_hex); +}; +class optic_KHS_old: ItemCore { + displayName = CSTRING(optic_khs_old); +}; +class optic_KHS_tan: optic_KHS_blk { + displayName = CSTRING(optic_khs_tan); +}; + +class optic_DMS: ItemCore { + displayName = CSTRING(optic_dms); +}; +class optic_DMS_ghex_F: optic_DMS { + displayName = CSTRING(optic_dms_ghex); +}; +class optic_DMS_weathered_F: optic_DMS { + displayName = CSTRING(optic_dms_weathered); +}; +class optic_DMS_weathered_Kir_F: optic_DMS_weathered_F { + displayName = CSTRING(optic_dms_weathered_kir); +}; + +class optic_holosight: ItemCore { + displayName = CSTRING(optic_holosight); +}; +class optic_Holosight_blk_F: optic_holosight { + displayName = CSTRING(optic_holosight_blk); +}; +class optic_Holosight_khk_F: optic_holosight { + displayName = CSTRING(optic_holosight_khk); +}; +class optic_Holosight_lush_F: optic_holosight { + displayName = CSTRING(optic_holosight_lush); +}; +class optic_Holosight_arid_F: optic_holosight { + displayName = CSTRING(optic_holosight_arid); +}; +class optic_Holosight_smg: ItemCore { + displayName = CSTRING(optic_holosight_smg); +}; +class optic_Holosight_smg_blk_F: optic_Holosight_smg { + displayName = CSTRING(optic_holosight_smg_blk); +}; +class optic_Holosight_smg_khk_F: optic_Holosight_smg { + displayName = CSTRING(optic_holosight_smg_khk); +}; + +class optic_MRCO: ItemCore { + displayName = CSTRING(optic_MRCO); +}; +class ACE_optic_MRCO_2D: optic_MRCO { + displayName = CSTRING(optic_MRCO_2d); +}; +class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D { + displayName = CSTRING(optic_MRCO_pip); +}; + +class optic_Yorris: ItemCore { + displayName = CSTRING(optic_Yorris); +}; + +class optic_ACO: ItemCore { + displayName = CSTRING(optic_ACO); +}; +class optic_ACO_grn: ItemCore { + displayName = CSTRING(optic_ACO_grn); +}; +class optic_ACO_smg: ItemCore { + displayName = CSTRING(optic_ACO_smg); +}; +class optic_ACO_grn_smg: ItemCore { + displayName = CSTRING(optic_ACO_grn_smg); +}; diff --git a/addons/realisticnames/CfgVehicles.hpp b/addons/realisticnames/CfgVehicles.hpp index 8d4d0c2f4a..29ac412957 100644 --- a/addons/realisticnames/CfgVehicles.hpp +++ b/addons/realisticnames/CfgVehicles.hpp @@ -249,6 +249,10 @@ class CfgVehicles { class O_Truck_02_medical_F: Truck_02_medical_base_F { displayName = CSTRING(Truck_02_medical_Name); }; + class Truck_02_water_base_F; + class C_IDAP_Truck_02_water_F: Truck_02_water_base_F { + displayName = CSTRING(Truck_02_water_Name); + }; class I_Truck_02_transport_F: Truck_02_transport_base_F { displayName = CSTRING(Truck_02_transport_Name); }; @@ -283,6 +287,12 @@ class CfgVehicles { class C_Truck_02_box_F: Truck_02_box_base_F { displayName = CSTRING(Truck_02_box_Name); }; + class C_IDAP_Truck_02_transport_F: Truck_02_transport_base_F { + displayName = CSTRING(Truck_02_transport_Name); + }; + class C_IDAP_Truck_02_F: Truck_02_base_F { + displayName = CSTRING(Truck_02_covered_Name); + }; class Truck_03_base_F; class O_Truck_03_transport_F: Truck_03_base_F { @@ -384,6 +394,9 @@ class CfgVehicles { class I_Heli_Transport_02_F: Heli_Transport_02_base_F { displayName = CSTRING(Heli_Transport_02_Name); }; + class C_IDAP_Heli_Transport_02_F: Heli_Transport_02_base_F { + displayName = CSTRING(Heli_Transport_02_Name); + }; // planes class Plane_CAS_01_base_F; diff --git a/addons/realisticnames/CfgWeapons.hpp b/addons/realisticnames/CfgWeapons.hpp index 953f981051..5b0e33e98c 100644 --- a/addons/realisticnames/CfgWeapons.hpp +++ b/addons/realisticnames/CfgWeapons.hpp @@ -2,6 +2,7 @@ class Mode_SemiAuto; class Mode_FullAuto; class CfgWeapons { + #include "Attachments.hpp" // assault rifles // MX @@ -707,176 +708,20 @@ class CfgWeapons { }; }; - //attachments - - class ItemCore; - - class acc_flashlight: ItemCore { - displayName = "UTG Defender 126"; - }; - - class optic_Hamr: ItemCore { - displayName = CSTRING(optic_hamr); - }; - class optic_Hamr_khk_F: optic_Hamr { - displayName = CSTRING(optic_hamr_khk); - }; - class ACE_optic_Hamr_2D: optic_Hamr { - displayName = CSTRING(optic_hamr_2d); - }; - class ACE_optic_Hamr_PIP: ACE_optic_Hamr_2D { - displayName = CSTRING(optic_hamr_pip); - }; - - class optic_Arco: ItemCore { - displayName = CSTRING(optic_arco); - }; - class optic_Arco_blk_F: optic_Arco { - displayName = CSTRING(optic_arco_blk); - }; - class optic_Arco_ghex_F: optic_Arco { - displayName = CSTRING(optic_arco_ghex); - }; - class ACE_optic_Arco_2D: optic_Arco { - displayName = CSTRING(optic_arco_2d); - }; - class ACE_optic_Arco_PIP: ACE_optic_Arco_2D { - displayName = CSTRING(optic_arco_pip); - }; - class optic_Arco_lush_F: optic_Arco { - displayName = CSTRING(optic_arco_lush); - }; - class optic_Arco_arid_F: optic_Arco { - displayName = CSTRING(optic_arco_arid); - }; - class optic_Arco_AK_blk_F: optic_Arco_blk_F { - displayName = CSTRING(optic_arco_ak_blk); - }; - class optic_Arco_AK_lush_F: optic_Arco_lush_F { - displayName = CSTRING(optic_arco_ak_lush); - }; - class optic_Arco_AK_arid_F: optic_Arco_arid_F { - displayName = CSTRING(optic_arco_ak_arid); - }; - - class optic_ERCO_blk_f: optic_Arco { - displayName = CSTRING(optic_erco_blk); - }; - class optic_ERCO_khk_f: optic_ERCO_blk_f { - displayName = CSTRING(optic_erco_khk); - }; - class optic_ERCO_snd_f: optic_ERCO_blk_f { - displayName = CSTRING(optic_erco_snd); - }; - - class optic_LRPS: ItemCore { - displayName = CSTRING(optic_lrps); - }; - class optic_LRPS_ghex_F: optic_LRPS { - displayName = CSTRING(optic_lrps_ghex); - }; - class optic_LRPS_tna_F: optic_LRPS { - displayName = CSTRING(optic_lrps_tna); - }; - class ACE_optic_LRPS_2D: optic_LRPS { - displayName = CSTRING(optic_lrps_2d); - }; - class ACE_optic_LRPS_PIP: ACE_optic_LRPS_2D { - displayName = CSTRING(optic_lrps_pip); - }; - - class optic_AMS_base; - class optic_AMS: optic_AMS_base { - displayName = CSTRING(optic_ams); - }; - class optic_AMS_khk: optic_AMS { - displayName = CSTRING(optic_ams_khk); - }; - class optic_AMS_snd: optic_AMS { - displayName = CSTRING(optic_ams_snd); - }; - - class optic_KHS_base; - class optic_KHS_blk: optic_KHS_base { - displayName = CSTRING(optic_khs_blk); - }; - class optic_KHS_hex: optic_KHS_blk { - displayName = CSTRING(optic_khs_hex); - }; - class optic_KHS_old: ItemCore { - displayName = CSTRING(optic_khs_old); - }; - class optic_KHS_tan: optic_KHS_blk { - displayName = CSTRING(optic_khs_tan); - }; - - class optic_DMS: ItemCore { - displayName = CSTRING(optic_dms); - }; - class optic_DMS_ghex_F: optic_DMS { - displayName = CSTRING(optic_dms_ghex); - }; - class optic_DMS_weathered_F: optic_DMS { - displayName = CSTRING(optic_dms_weathered); - }; - class optic_DMS_weathered_Kir_F: optic_DMS_weathered_F { - displayName = CSTRING(optic_dms_weathered_kir); - }; - - class optic_holosight: ItemCore { - displayName = CSTRING(optic_holosight); - }; - class optic_Holosight_blk_F: optic_holosight { - displayName = CSTRING(optic_holosight_blk); - }; - class optic_Holosight_khk_F: optic_holosight { - displayName = CSTRING(optic_holosight_khk); - }; - class optic_Holosight_lush_F: optic_holosight { - displayName = CSTRING(optic_holosight_lush); - }; - class optic_Holosight_arid_F: optic_holosight { - displayName = CSTRING(optic_holosight_arid); - }; - class optic_Holosight_smg: ItemCore { - displayName = CSTRING(optic_holosight_smg); - }; - class optic_Holosight_smg_blk_F: optic_Holosight_smg { - displayName = CSTRING(optic_holosight_smg_blk); - }; - class optic_Holosight_smg_khk_F: optic_Holosight_smg { - displayName = CSTRING(optic_holosight_smg_khk); - }; - - class optic_MRCO: ItemCore { - displayName = CSTRING(optic_MRCO); - }; - class ACE_optic_MRCO_2D: optic_MRCO { - displayName = CSTRING(optic_MRCO_2d); - }; - class ACE_optic_MRCO_PIP: ACE_optic_MRCO_2D { - displayName = CSTRING(optic_MRCO_pip); - }; - - class optic_Yorris: ItemCore { - displayName = CSTRING(optic_Yorris); - }; - - class optic_ACO: ItemCore { - displayName = CSTRING(optic_ACO); - }; - class optic_ACO_grn: ItemCore { - displayName = CSTRING(optic_ACO_grn); - }; - class optic_ACO_smg: ItemCore { - displayName = CSTRING(optic_ACO_smg); - }; - class optic_ACO_grn_smg: ItemCore { - displayName = CSTRING(optic_ACO_grn_smg); - }; - // APEX/Tanoa + // Type 115 + class arifle_ARX_base_F; + class arifle_ARX_blk_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_blk_Name); + }; + class arifle_ARX_ghex_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_ghex_Name); + }; + class arifle_ARX_hex_F: arifle_ARX_base_F { + displayName = CSTRING(arifle_arx_hex_Name); + }; + // QBZ-95 and variants class arifle_CTAR_base_F; class arifle_CTAR_blk_F: arifle_CTAR_base_F { @@ -1018,6 +863,16 @@ class CfgWeapons { // Contact/Livonia + // CZ 581 Shotgun + class sgun_HunterShotgun_01_base_F; + class sgun_HunterShotgun_01_F: sgun_HunterShotgun_01_base_F { + displayName = CSTRING(sgun_huntershotgun_01_Name); + }; + class sgun_HunterShotgun_01_sawedoff_base_F; + class sgun_HunterShotgun_01_sawedoff_F: sgun_HunterShotgun_01_sawedoff_base_F { + displayName = CSTRING(sgun_huntershotgun_sawedoff_01_Name); + }; + // FNX-45 (Green) class hgun_Pistol_heavy_01_green_F: hgun_Pistol_heavy_01_F { displayName = CSTRING(hgun_Pistol_heavy_01_green_Name); diff --git a/addons/realisticnames/stringtable.xml b/addons/realisticnames/stringtable.xml index d624fae683..af864f64df 100644 --- a/addons/realisticnames/stringtable.xml +++ b/addons/realisticnames/stringtable.xml @@ -13,7 +13,7 @@ XM312 XM312 XM312 - XM312 + XM312 중기관총 XM312重機槍 XM312 XM312 @@ -30,7 +30,7 @@ XM312A XM312A XM312A - XM312A + XM312A 무인중기관총 XM312A重機槍 XM312A XM312A @@ -45,9 +45,9 @@ XM312 (Высокий) XM312 (Alta) XM312 (Magasított) - XM312 (Alta) - XM312 (高) - XM312 (높음) + XM312 (Alto) + XM312 (ハイマウント) + XM312 중기관총 (높음) XM312重機槍 (高射腳架) XM312(高) XM312 (Yüksek) @@ -64,7 +64,7 @@ XM307 XM307 XM307 - XM307 + XM307 유탄기관총 XM307榴彈機槍 XM307 XM307 @@ -81,7 +81,7 @@ XM307A XM307A XM307A - XM307A + XM307A 무인유탄기관총 XM307A榴彈機槍 XM307A XM307A @@ -96,9 +96,9 @@ XM307 (Высокий) XM307 (Alta) XM307 (Magasított) - XM307 (Alta) - XM307 (高) - XM307 (높음) + XM307 (Alto) + XM307 (ハイマウント) + XM307 유탄기관총 (높음) XM307榴彈機槍 (高射腳架) XM307(高) XM307 (Yüksek) @@ -149,7 +149,7 @@ YABHON-R3 YABHON-R3 YABHON-R3 - YABHON-R3 + YABHON-R3 무인기 "亞伯罕-R3型"空中無人載具 "联合"-R3 YABHON-R3 @@ -166,7 +166,7 @@ YABHON-R3 (CAS) YABHON-R3 (CAS) YABHON-R3 (CAS) - YABHON-R3 (근접지원) + YABHON-R3 무인기 (근접지원) "亞伯罕-R3型"空中無人載具 (近空支援) "联合"-R3(近空支援) YABHON-R3 (CAS) @@ -453,7 +453,7 @@ HEMTT (боеприпасы) HEMTT Munições HEMTT (lőszerszállító) - HEMTT di rifornimento munizioni + HEMTT Munizioni HEMTT 弾薬 HEMTT 탄약 重型增程機動戰術卡車 (彈藥) @@ -470,7 +470,7 @@ HEMTT (топливозаправщик) HEMTT Combustível HEMTT (üzemanyag-szállító) - HEMTT di rifornimento carburante + HEMTT Carburante HEMTT 燃料 HEMTT 연료 重型增程機動戰術卡車 (燃油) @@ -487,7 +487,7 @@ HEMTT (ремонтный) HEMTT Reparador HEMTT (szerelő-jármű) - HEMTT Riparatore + HEMTT Riparazioni HEMTT 修理 HEMTT 수리 重型增程機動戰術卡車 (維修) @@ -556,7 +556,7 @@ Leopard 2SG Leopard 2SG Leopard 2SG - レオパルト 2SG + レオパルト2SG 레오파르트 2SG "豹2型新加坡版"主戰坦克 "豹"2 新加坡版 @@ -573,7 +573,7 @@ FV510 Warrior FV510 Warrior FV510 Warrior - FV510 ウォーリアー + FV510 ウォーリア FV510 워리어 보병전투차 FV510 "戰士"步兵戰車 FV510 "战士" @@ -640,7 +640,7 @@ КамАЗ (боеприпасы) KamAZ Munições KamAZ (lőszerszállító) - KamAZ di rifornimento munizioni + KamAZ Munizioni KamAZ 弾薬 카마즈 탄약 "卡瑪斯"卡車 (彈藥) @@ -657,7 +657,7 @@ КамАЗ (топливозаправщик) KamAZ Combustível KamAZ (üzemanyag-szállító) - KamAZ di rifornimento carburante + KamAZ Carburante KamAZ 燃料 카마즈 연료 "卡瑪斯"卡車 (燃油) @@ -674,7 +674,7 @@ КамАЗ (ремонтный) KamAZ Reparador KamAZ (szerelő-jármű) - KamAZ riparatore + KamAZ Riparazioni KamAZ 修理 카마즈 수리 "卡瑪斯"卡車 (維修) @@ -698,6 +698,15 @@ "卡玛兹"(医疗) KamAZ Medikal + + KamAZ Water + KamAZ Água + KamAZ 給水 + КамАЗ (водоноситель) + 카마즈 급수 + KamAS Wasser + KamAZ Acqua + KamAZ MRL KamAS MRL @@ -894,7 +903,7 @@ Тайфун (устройство) Typhoon Dispositivo Typhoon (eszköz) - Typhoon per dispositivo + Typhoon con Dispositivo タイフーン デバイス 타이푼 장치 "颱風"卡車 (精密設備) @@ -911,7 +920,7 @@ Тайфун (боеприпасы) Typhoon Munições Typhoon (lőszerszállító) - Typhoon di rifornimento munizioni + Typhoon Munizioni タイフーン 弾薬 타이푼 탄약 "颱風"卡車 (彈藥) @@ -928,7 +937,7 @@ Тайфун (топливозаправщик) Typhoon Combustível Typhoon (üzemanyag-szállító) - Typhoon di rifornimento carburante + Typhoon Carburante タイフーン 燃料 타이푼 연료 "颱風"卡車 (燃油) @@ -945,7 +954,7 @@ Тайфун (ремонтный) Typhoon Reparador Typhoon (szerelő-jármű) - Typhoon riparatore + Typhoon Riparazioni タイフーン 修理 타이푼 수리 "颱風"卡車 (維修) @@ -962,7 +971,7 @@ Тайфун (медицинский) Typhoon Médico Typhoon (egészségügyi) - Typhoon medico + Typhoon Medico タイフーン 衛生 타이푼 의료 "颱風"卡車 (醫療) @@ -1216,7 +1225,7 @@ Ka-60 Kasatka (preto e branco) Ka-60 Касатка (чёрно-белый) Ka-60 Kasatka (blanco y negro) - Ka-60 カサートカ (黒 & 白) + Ka-60 カサートカ (ブラック & ホワイト) Ka-60 카사트카 (검정 및 하양) Ka-60 "逆戟鯨"直升機 (黑&白) Ka-60 "虎鲸"(黑白) @@ -1300,7 +1309,7 @@ M18A1 Клеймор M18A1 Claymore M18A1 Claymore akna - M18A1 Claymore Mina antiuomo + M18A1 Claymore Mina Antiuomo M18A1 クレイモア M18A1 클레이모어 M18A1 "闊刀"地雷 @@ -1317,7 +1326,7 @@ M183 комплектный подрывной заряд M183 Sacola de Demolição M183 romboló töltet - M183 Demolition Charge Assembly + M183 Carica da Demolizioni M183 梱包爆薬 M183 폭파 장약 조립 M183炸藥包 @@ -1327,7 +1336,8 @@ M183 Demolition Charge (Throwable) M183 Charge de démolition (lançable) - M183 梱包爆薬 (投てき仕様) + M183 Carica da Demolizioni (Lanciabile) + M183 梱包爆薬 (投擲仕様) M183 Demolition Charge (Throwable) Carga de demolición M183 (Lanzable) M183 комплектный подрывной заряд (бросаемый) @@ -1346,7 +1356,7 @@ M112 подрывной заряд M112 Carga de Demolição M112 romboló tömb - M112 da Demolizione + M112 Blocco da Demolizione M112 爆薬ブロック M112 폭파 블럭 M112塑性炸藥 @@ -1356,7 +1366,8 @@ M112 Demolition Charge (Throwable) M112 Bloc de démolition (lançable) - M112 爆薬ブロック (投てき仕様) + M112 Blocco da Demolizione (Lanciabile) + M112 爆薬ブロック (投擲仕様) M112 Demolition Charge (Throwable) Bloque de demolición M112 (Lanzable) M112 подрывной заряд (бросаемый) @@ -1443,7 +1454,7 @@ M18 Granada de fumaça (Verde) M18 füstgránát (Zöld) M18 Granata fumogena (Verde) - M18 煙幕手榴弾 (緑) + M18 発煙手榴弾 (緑) M18 연막탄 (초록) M18煙霧彈 (綠色) M18 烟雾弹(绿色) @@ -1494,7 +1505,7 @@ M18 Granada de fumaça (Vermelha) M18 füstgránát (Piros) M18 Granata fumogena (Rosso) - M18 煙幕手榴弾 (赤) + M18 発煙手榴弾 (赤) M18 연막탄 (빨강) M18煙霧彈 (紅色) M18 烟雾弹(红色) @@ -1527,7 +1538,7 @@ M15 противотанковая мина M15 Mina anticarro M15 harckocsiakna - M15 Mine anticarro + M15 Mina Anticarro M15 対戦車地雷 M15 대전차지뢰 M15反坦克地雷 @@ -1544,7 +1555,7 @@ VS-50 противопехотная мина VS-50 Mina antipessoal VS-50 gyalogsági taposóakna - VS-50 Mine antiuomo + VS-50 Mina Antiuomo VS-50 対人地雷 VS-50 대인지뢰 VS-50反人員地雷 @@ -1561,7 +1572,7 @@ M26 противопехотная мина M26 Mina saltadora antipessoal M26 gyalogsági ugróakna - M26 Mine saltanti antiuomo + M26 Mina Antiuomo Saltante M26 対人跳躍地雷 M26 대인도약지뢰 M26反人員彈跳雷 @@ -1578,8 +1589,8 @@ PMR-3 противопехотная мина PMR-3 Mina antipessoal (armadilha) PMR-3 botlódrótos gyalogsági akna - PMR-3 Mine antiuomo - PMR-3 仕掛け型対人地雷 + PMR-3 Mina Antiuomo + PMR-3 仕掛け線対人地雷 PMR-3 대인인계철선지뢰 PMR-3反人員絆線雷 PMR-3 反人员绊雷 @@ -1629,7 +1640,7 @@ Custom Covert II Custom Covert II Custom Covert II - ACP-C2 + Custom Covert II カスタム コバートⅡ 커스텀 커버트 II 特裝隱蔽Ⅱ型手槍 @@ -1653,6 +1664,24 @@ FNX-45戰術型手槍 FNX-45 战术型 + + CZ 581 + CZ 581 + CZ 581 + CZ 581 + CZ 581 + CZ 581 + CZ 581 + + + CZ 581 (Sawed-Off) + CZ 581 (Cano serrado) + CZ 581 (ソードオフ) + CZ 581 (Sawed-Off) + CZ 581 (소드오프) + CZ 581 (Abgesägt) + CZ 581 (Canne mozze) + FNX-45 Tactical (Green) FNX-45 Tactical (Grün) @@ -1782,7 +1811,7 @@ Mini-Spike (AT) Mini-Spike (ПТРК) Mini-Spike (AT) - Mini-Spike (AT) + Mini-Spike (AC) ミニスパイク (対戦車) 스파이크 미사일 (대전차) "迷你長釘"導彈發射器 (反坦克) @@ -1877,7 +1906,7 @@ MX(卡其) MX (Kaki) MX (Caqui) - MX (Kaki) + MX (Cachi) MX (Khaki) MX (хаки) MX (Khaki) @@ -1927,7 +1956,7 @@ MXC(卡其) MXC (Kaki) MXC (Caqui) - MXC (Kaki) + MXC (Cachi) MXC (Khaki) MXC (хаки) MXC (Khaki) @@ -1977,7 +2006,7 @@ MX 3GL(卡其) MX 3GL (Kaki) MX 3GL (Caqui) - MX 3GL (Kaki) + MX 3GL (Cachi) MX 3GL (Khaki) MX 3GL (хаки) MX 3GL (Khaki) @@ -2027,7 +2056,7 @@ MX LSW(卡其) MX LSW (Kaki) MX LSW (Caqui) - MX LSW (Kaki) + MX LSW (Cachi) MX LSW (Khaki) MX LSW (хаки) MX LSW (Khaki) @@ -2077,7 +2106,7 @@ MXM(卡其) MXM (Kaki) MXM (Caqui) - MXM (Kaki) + MXM (Cachi) MXM (Khaki) MXM (хаки) MXM (Khaki) @@ -2097,7 +2126,7 @@ KH2002 Sama KH2002 Сама KT2002 Sama - KT2002 Katiba + KH2002 Sama KH2002 サマ KH2002 사마 KH2002 "海白爾"突擊步槍 @@ -2114,7 +2143,7 @@ KH2002C Sama KH2002C Сама KT2002C Sama - KT2002C Katiba + KH2002C Sama KH2002C サマ KH2002C 사마 KH2002C"海白爾"卡賓步槍 @@ -2131,7 +2160,7 @@ KH2002 Sama KGL KH2002 Сама KGL KT2002 Sama KGL - KT2002 Katiba KGL + KH2002 Sama KGL KH2002 サマ KGL KH2002 사마 KGL KH2002 "海白爾"突擊步槍 (榴彈) @@ -2148,8 +2177,8 @@ F2000 (Camuflaje) F2000 (камуфляжный) F2000 (Camo) - F2000 (Camo) - F2000 (カモフラージュ) + F2000 (Mimetica) + F2000 (AAF迷彩) F2000 (위장) F2000突擊步槍 (迷彩) F2000(迷彩) @@ -2182,8 +2211,8 @@ F2000 Tactical (Camuflaje) F2000 Tactical (камуфляжный) F2000 Tactical (Camo) - F2000 Tactical (Camo) - F2000 タクティカル (カモフラージュ) + F2000 Tactical (Mimetica) + F2000 タクティカル (AAF迷彩) F2000 택티컬 (위장) F2000戰術型突擊步槍 (迷彩) F2000 战术型(迷彩) @@ -2216,8 +2245,8 @@ F2000 EGLM (Camuflaje) F2000 EGLM (камуфляжный) F2000 EGLM (Camo) - F2000 EGLM (Camo) - F2000 EGLM (カモフラージュ) + F2000 EGLM (Mimetica) + F2000 EGLM (AAF迷彩) F2000 EGLM (위장) F2000突擊步槍 (榴彈—迷彩) F2000 ELGM(迷彩) @@ -2319,7 +2348,7 @@ Scorpion Evo 3 A1 Scorpion Evo 3 A1 Scorpion Evo 3 A1 - スコーピオン エボ 3 A1 + スコーピオン Evo 3 A1 스콜피온 에보 3 A1 "蠍式"Evo 3 A1衝鋒槍 Evo 3 A1 "蝎" @@ -2370,7 +2399,7 @@ Stoner 99 LMG Stoner 99 LMG Stoner 99 LMG - ストーナー 99 LMG + ストーナー99 LMG 스토너 99 LMG 斯通納99輕機槍 斯通纳 99 @@ -2437,8 +2466,8 @@ GM6 Lynx (Camuflaje) GM6 Lynx (камуфляжный) GM6 Lynx (Camo) - GM6 Lynx (Camo) - GM6 リンクス (カモフラージュ) + GM6 Lynx (Mimetica) + GM6 リンクス (六角形迷彩) GM6 링스 (위장) GM6 "天貓"反器材狙擊步槍 (迷彩) GM6 "猞猁"(迷彩) @@ -2471,8 +2500,8 @@ M200 Intervention (Camuflaje) M200 Intervention (камуфляжный) M200 Intervention (Camo) - M200 Intervention (Camo) - M200 インターベンション (カモフラージュ) + M200 Intervention (Mimetica) + M200 インターベンション (迷彩) M200 인터벤션 (위장) M200干預型狙擊步槍 (迷彩) M200 "干预"(迷彩) @@ -2537,10 +2566,10 @@ Noreen "Bad News" ULR (камуфляжный) Noreen "Bad News" ULR (Tarnmuster) Noreen "Bad News" ULR (kamuflaż) - Noreen "Bad News" ULR (Camo) + Noreen "Bad News" ULR (Mimetica) Noreen "Bad News"ULR (Terepmintás) Noreen "Bad News" ULR (Camuflagem) - ノレーン "バッド ニュース" ULR (カモフラージュ) + ノレーン "バッド ニュース" ULR (CTRG迷彩) 노린 "배드뉴스" ULR (위장) 諾琳"壞消息"極距狙擊步槍 (迷彩) 诺琳 "坏消息" 极距狙击步枪(迷彩) @@ -2557,7 +2586,7 @@ Noreen "Bad News" ULR (Sabbia) Noreen "Bad News"ULR (Homok) Noreen "Bad News" ULR (Deserto) - ノレーン "バッド ニュース" ULR (砂地) + ノレーン "バッド ニュース" ULR (サンド) 노린 "배드뉴스" ULR (모래) 諾琳"壞消息"極距狙擊步槍 (沙色) 诺琳 "坏消息" 极距狙击步枪(沙色) @@ -2605,7 +2634,7 @@ SIG 556 (хаки) SIG 556 (Khaki) SIG 556 (Khaki) - SIG 556 (Khaki) + SIG 556 (Cachi) SIG 556 (Khaki) SIG 556 (Caqui) SIG 556 (カーキ) @@ -2639,10 +2668,10 @@ SIG 556 (камуфляжный) SIG 556 (kamuflaż) SIG 556 (Tarnmuster) - SIG 556 (Camo) + SIG 556 (Mimetica) SIG 556 (Terepmintás) SIG 556 (Camuflagem) - SIG 556 (カモフラージュ) + SIG 556 (MTP迷彩) 시그 556 (위장) SIG 556精準步槍 (迷彩) SIG 556(迷彩) @@ -2656,10 +2685,10 @@ SIG 556 (Woodland) SIG 556 (leśny) SIG 556 (Grünes Tarnmuster) - SIG 556 (Woodland) + SIG 556 (Boschivo) SIG 556 (Erdőmintás) SIG 556 (Floresta) - SIG 556 (森林) + SIG 556 (森林迷彩) 시그 556 (수풀) SIG 556精準步槍 (森林迷彩) SIG 556(森林迷彩) @@ -2707,7 +2736,7 @@ ASP-1 Kir (пустынный) ASP-1 Kir (Hellbraun) ASP-1 Kir (Tan) - ASP-1 Kir (Tan) + ASP-1 Kir (Marroncino) ASP-1 Kir (Cserszín) ASP-1 Kir (Deserto) ASP-1 キール (タン) @@ -2761,7 +2790,7 @@ Cyrus (Hex) Cyrus (Hex) Cyrus (Hex) - サイラス (ヘックス) + サイラス (六角形迷彩) 사이러스 (육각) "居鲁士"狙擊步槍 (數位蜂巢迷彩) "居鲁士"(蜂巢迷彩) @@ -2775,7 +2804,7 @@ Cyrus (пустынный) Cyrus (Hellbraun) Cyrus (podpalany) - Cyrus (Tan) + Cyrus (Marroncino) Cyrus (Cserszín) Cyrus (Deserto) サイラス (タン) @@ -2809,10 +2838,10 @@ M14 (камуфляжный) M14 (kamuflaż) M14 (Tarnmuster) - M14 (Camo) + M14 (Mimetica) M14 (Terepmintás) M14 (Camuflagem) - M14 (カモフラージュ) + M14 (迷彩) M14 (위장) M14精準步槍 (迷彩) M14(迷彩) @@ -2826,10 +2855,10 @@ M14 (олива) M14 (oliwkowy) M14 (Olivgrün) - M14 (Olive) + M14 (Oliva) M14 (Olíva) M14 (Oliva) - M14 (オリーブド ラブ) + M14 (オリーブ) M14 (올리브) M14精準步槍 (橄欖色) M14(橄榄色) @@ -2863,7 +2892,7 @@ HK121 (Hex) HK121 (Hex) HK121 (Hex) - HK 121 (ヘックス) + HK 121 (六角形迷彩) HK121 (육각) HK121中型機槍 (數位蜂巢迷彩) HK121(蜂巢迷彩) @@ -2877,7 +2906,7 @@ HK121 (пустынный) HK121 (Hellbraun) HK121 (podpalany) - HK121 (Tan) + HK121 (Marroncino) HK121 (Cserszín) HK121 (Deserto) HK 121 (タン) @@ -2914,7 +2943,7 @@ LWMMG (MTP) LWMMG (MTP) LWMMG (MTP) - LWMMG (マルチカモ) + LWMMG (MTP迷彩) LWMMG (MTP) 輕量化中型機槍 (多地形迷彩) LWMMG(多地形迷彩) @@ -3054,6 +3083,33 @@ "柏拉格" 战斗无人机 Burraq UCAV + + Type 115 (Black) + Type 115 (Preto) + Type 115 (ブラック) + Type 115 (чёрный) + 115식 보총 (검정) + Type 115 (Schwarz) + Type 115 (Nero) + + + Type 115 (Green Hex) + Type 115 (Verde Hex) + Type 115 (緑六角形迷彩) + Type 115 (зелёный гекс) + 115식 보총 (초록육각) + Type 115 (Hex Grün) + Type 115 (Hex Verde) + + + Type 115 (Hex) + Type 115 (Hex) + Type 115 (六角形迷彩) + Type 115 (гекс) + 115식 보총 (육각) + Type 115 (Hex) + Type 115 (Hex) + QBZ-95-1 (Black) QBZ-95-1 (Černá) @@ -3075,14 +3131,14 @@ QBZ-95-1 (Green Hex) QBZ-95-1 (Hex Grün) QBZ-95-1 (Hex Verde) - QBZ-95-1 (zielony hex) + QBZ-95-1 (Zielony hex) QBZ-95-1 (Zelený Hex) QBZ-95-1 (Hex Vert) QBZ-95-1 (зелёный гекс) QBZ-95-1 (Verde Hex) QBZ-95-1 (Zöld Hex) QBZ-95-1 (Hex Verde) - QBZ-95-1 (緑ヘックス) + QBZ-95-1 (緑六角形迷彩) QBZ-95-1 (초록육각) QBZ-95-1式自動步槍 (綠色數位蜂巢迷彩) 95-1式自动步枪(绿色蜂巢迷彩) @@ -3099,7 +3155,7 @@ QBZ-95-1 (Hex) QBZ-95-1 (Hex) QBZ-95-1 (Hex) - QBZ-95-1 (ヘックス) + QBZ-95-1 (六角形迷彩) QBZ-95-1 (육각) QBZ-95-1式自動步槍 (數位蜂巢迷彩) 95-1式自动步枪(蜂巢迷彩) @@ -3126,14 +3182,14 @@ QBZ-95-1 GL (Green Hex) QBZ-95-1 GL (Hex Grün) QBZ-95-1 GL (Hex Verde) - QBZ-95-1 GL (zielony hex) + QBZ-95-1 GL (Zielony hex) QBZ-95-1 GL (Zelený Hex) QBZ-95-1 GL (Hex Vert) QBZ-95-1 GL (зелёный гекс) QBZ-95-1 GL (Verde Hex) QBZ-95-1 GL (Zöld Hex) QBZ-95-1 GL (Hex Verde) - QBZ-95-1 GL (緑ヘックス) + QBZ-95-1 GL (緑六角形迷彩) QBZ-95-1 GL (초록육각) QBZ-95-1式自動步槍 (榴彈—綠色數位蜂巢迷彩) 95-1式自动步枪 10A式榴弹(绿色蜂巢迷彩) @@ -3150,7 +3206,7 @@ QBZ-95-1 GL (Hex) QBZ-95-1 GL (Hex) QBZ-95-1 GL (Hex) - QBZ-95-1 GL (ヘックス) + QBZ-95-1 GL (六角形迷彩) QBZ-95-1 GL (육각) QBZ-95-1式自動步槍 (榴彈—數位蜂巢迷彩) 95-1式自动步枪 10A式榴弹(蜂巢迷彩) @@ -3177,14 +3233,14 @@ QBZ-95-1 LSW (Green Hex) QBZ-95-1 LSW (Hex Grün) QBZ-95-1 LSW (Hex Verde) - QBZ-95-1 LSW (zielony hex) + QBZ-95-1 LSW (Zielony hex) QBZ-95-1 LSW (Zelený Hex) QBZ-95-1 LSW (Hex Vert) QBZ-95-1 LSW (зелёный гекс) QBZ-95-1 LSW (Verde Hex) QBZ-95-1 LSW (Zöld Hex) QBZ-95-1 LSW (Hex Verde) - QBZ-95-1 LSW (緑ヘックス) + QBZ-95-1 LSW (緑六角形迷彩) QBZ-95-1 LSW (초록육각) QBZ-95-1式輕機槍 (綠色數位蜂巢迷彩) 95-1式班用机枪(绿色蜂巢迷彩) @@ -3201,7 +3257,7 @@ QBZ-95-1 LSW (Hex) QBZ-95-1 LSW (Hex) QBZ-95-1 LSW (Hex) - QBZ-95-1 LSW (ヘックス) + QBZ-95-1 LSW (六角形迷彩) QBZ-95-1 LSW (육각) QBZ-95-1式輕機槍 (數位蜂巢迷彩) 95-1式班用机枪(蜂巢迷彩) @@ -3228,14 +3284,14 @@ QBU-88 (Green Hex) QBU-88 (Hex Grün) QBU-88 (Hex Verde) - QBU-88 (zielony hex) + QBU-88 (Zielony hex) QBU-88 (Zelený Hex) QBU-88 (Hex Vert) QBU-88 (зелёный гекс) QBU-88 (Verde Hex) QBU-88 (Zöld Hex) QBU-88 (Hex Verde) - QBU-88 (緑ヘックス) + QBU-88 (緑六角形迷彩) QBU-88 (초록육각) QBU-88式狙擊步槍 (綠色數位蜂巢迷彩) 88式狙击步枪(绿色蜂巢迷彩) @@ -3252,7 +3308,7 @@ QBU-88 (Hex) QBU-88 (Hex) QBU-88 (Hex) - QBU-88 (ヘックス) + QBU-88 (六角形迷彩) QBU-88 (육각) QBU-88式狙擊步槍 (數位蜂巢迷彩) 88式狙击步枪(蜂巢迷彩) @@ -3269,7 +3325,7 @@ GM6 Lynx (Verde Hex) GM6 Lynx (Zöld Hex) GM6 Lynx (Hex Verde) - GM6 リンクス (緑ヘックス) + GM6 リンクス (緑六角形迷彩) GM6 링스 (초록육각) GM6 "天貓"反器材狙擊步槍 (綠色數位蜂巢迷彩) GM6 "猞猁"(绿色蜂巢迷彩) @@ -3303,7 +3359,7 @@ M200 Intervention (тропик) M200 Intervention (Trópico) M200 Intervention (Tropico) - M200 インターベンション (熱帯) + M200 インターベンション (熱帯ジャングル迷彩) M200 인터벤션 (열대) M200干預型狙擊步槍 (熱帶迷彩) M200 "干预"(热带迷彩) @@ -3351,7 +3407,7 @@ HK416A5 11 " (хаки) HK416A5 11 " (Khaki) HK416A5 11 " (Khaki) - HK416A5 11 " (Khaki) + HK416A5 11 " (Cachi) HK416A5 11 " (Khaki) HK416A5 11 " (Caqui) HK416A5 11 " (カーキ) @@ -3402,7 +3458,7 @@ HK416A5 11 " GL (хаки) HK416A5 11 " GL (Khaki) HK416A5 11 " GL (Khaki) - HK416A5 11 " GL (Khaki) + HK416A5 11 " GL (Cachi) HK416A5 11 " GL (Khaki) HK416A5 11 " GL (Caqui) HK416A5 11 " GL (カーキ) @@ -3453,7 +3509,7 @@ HK416A5 14.5 " (хаки) HK416A5 14.5 " (Khaki) HK416A5 14.5 " (Khaki) - HK416A5 14.5 " (Khaki) + HK416A5 14.5 " (Cachi) HK416A5 14.5 " (Khaki) HK416A5 14.5 " (Caqui) HK416A5 14.5 " (カーキ) @@ -3504,7 +3560,7 @@ HK417A2 20 " (хаки) HK417A2 20 " (Khaki) HK417A2 20 " (Khaki) - HK417A2 20 " (Khaki) + HK417A2 20 " (Cachi) HK417A2 20 " (Khaki) HK417A2 20 " (Caqui) HK417A2 20 " (カーキ) @@ -3534,14 +3590,14 @@ RPG-32 (Green Hex) RPG-32 (Hex Grün) RPG-32 (Hex Verde) - RPG-32 (zielony hex) + RPG-32 (Zielony hex) RPG-32 (Zelený Hex) RPG-32 (Hex Vert) RPG-32 (зелёный гекс) RPG-32 (Verde Hex) RPG-32 (Zöld Hex) RPG-32 (Hex Verde) - RPG-32 (緑ヘックス) + RPG-32 (緑六角形迷彩) RPG-32 (초록육각) RPG-32火箭發射器 (綠色數位蜂巢迷彩) RPG-32(绿色蜂巢迷彩) @@ -3555,7 +3611,7 @@ P99 (хаки) P99 (Khaki) P99 (Khaki) - P99 (Khaki) + P99 (Cachi) P99 (Khaki) P99 (Caqui) P99 (カーキ) @@ -3612,7 +3668,7 @@ Polaris DAGOR (XM312) Polaris DAGOR (XM312) Polaris DAGOR (XM312) - 폴라리스 DAGOR (XM312) + 폴라리스 DAGOR (XM312 중기관총) Polaris DAGOR (Mini-Spike AT) @@ -3628,7 +3684,7 @@ Polaris DAGOR (Mini-Spike AT) Polaris DAGOR (Mini-Spike AT) Polaris DAGOR (Mini-Spike AT) - 폴라리스 DAGOR (스파이크 미사일 대전차) + 폴라리스 DAGOR (스파이크 대전차미사일) Polaris DAGOR @@ -3649,7 +3705,7 @@ Polaris DAGOR (light) Polaris DAGOR (leicht) - ポラリス DAGOR (軽) + ポラリス DAGOR (軽装) "北極星"先進佈署越野車 (輕型) "北极星"(轻型) Polaris DAGOR (leggero) @@ -3676,7 +3732,7 @@ LSV Mk. II (M134) LSV Mk. II (M134) LSV Mk. II (M134) - LSV Mk.II (M134) + LSV Mk.II (M134 미니건) LSV Mk. II (Metis-M) @@ -3788,7 +3844,7 @@ Wiesel 2 Ozelot (AA) Wiesel 2 Ozelot (AA) Wiesel 2 Ozelot (AA) - 비젤 2 오셀롯 (대공) + 비젤 2 오젤롯 (대공) Wiesel 2 (ATGM) @@ -3804,7 +3860,7 @@ Wiesel 2 (ATGM) Wiesel 2 (ATGM) Wiesel 2 (ATGM) - 비젤 2 (대전차유도) + 비젤 2 (대전차미사일) Wiesel 2 (MK20) @@ -3838,6 +3894,33 @@ Wiesel 2 RFCV (Radar) 비젤 2 RFCV (레이더) + + UTG Defender 126 + UTG Defender 126 + UTG ディフェンダー 126 + UTG Defender 126 + UTG 디펜더 126 + UTG Defender 126 + UTG Defender 126 + + + EOTech MRDS + EOTech MRDS + EOTech MRDS + EOTech MRDS + 이오텍 MRDS + EOTech MRDS + EOTech MRDS + + + EOTech MRDS (Black) + EOTech MRDS (Preto) + EOTech MRDS (ブラック) + EOTech MRDS (чёрный) + 이오텍 MRDS (검정) + EOTech MRDS (Schwarz) + EOTech MRDS (Nero) + Leupold Mark 4 HAMR Leupold Mark 4 HAMR @@ -3860,7 +3943,7 @@ Leupold Mark 4 HAMR (卡其色) Leupold Mark 4 HAMR(卡其色) Leupold Mark 4 HAMR (カーキ) - Leupold Mark 4 HAMR (Khaki) + Leupold Mark 4 HAMR (Cachi) Leupold Mark 4 HAMR (Khaki) Leupold Mark 4 HAMR (хаки) Leupold Mark 4 HAMR (Khaki) @@ -3908,7 +3991,7 @@ ELCAN SpecterOS (黃褐色) ELCAN SpecterOS(沙色) ELCAN SpecterOS (タン) - ELCAN SpecterOS (Tan) + ELCAN SpecterOS (Marroncino) ELCAN SpecterOS (Tan) ELCAN SpecterOS (пустынный) ELCAN SpecterOS (Bege) @@ -3938,8 +4021,8 @@ ELCAN SpecterOS (Green Hex) ELCAN SpecterOS (綠色數位蜂巢迷彩) ELCAN SpecterOS(绿色蜂巢迷彩) - ELCAN SpecterOS (緑ヘックス) - ELCAN SpecterOS (Verde Hex) + ELCAN SpecterOS (緑六角形迷彩) + ELCAN SpecterOS (Hex Verde) ELCAN SpecterOS (Zielony Hex) ELCAN SpecterOS (зелёный гекс) ELCAN SpecterOS (Verde Hex) @@ -3986,7 +4069,8 @@ ELCAN SpecterOS (Lush) ELCAN SpecterOS (Leśny) ELCAN SpecterOS (Forêt) - ELCAN SpecterOS (緑地) + ELCAN SpecterOS (Verdeggiante) + ELCAN SpecterOS (緑地迷彩) ELCAN SpecterOS (Grün) ELCAN SpecterOS(繁茂) 엘칸 스펙터OS (초목) @@ -3997,7 +4081,8 @@ ELCAN SpecterOS (Arid) ELCAN SpecterOS (Jałowy) ELCAN SpecterOS (Désert) - ELCAN SpecterOS (乾燥地帯) + ELCAN SpecterOS (Arido) + ELCAN SpecterOS (乾燥地帯迷彩) ELCAN SpecterOS (Trocken) ELCAN SpecterOS(干旱) 엘칸 스펙터OS (건조) @@ -4008,6 +4093,7 @@ ELCAN SpecterOS 7.62 (Black) ELCAN SpecterOS 7.62 (Czarny) ELCAN SpecterOS 7.62 (Noire) + ELCAN SpecterOS 7.62 (Nero) ELCAN SpecterOS 7.62 (ブラック) ELCAN SpecterOS 7.62 (Schwarz) ELCAN SpecterOS 7.62(黑色) @@ -4019,7 +4105,8 @@ ELCAN SpecterOS 7.62 (Lush) ELCAN SpecterOS 7.62 (Leśny) ELCAN SpecterOS 7.62 (Forêt) - ELCAN SpecterOS 7.62 (緑地) + ELCAN SpecterOS 7.62 (Verdeggiante) + ELCAN SpecterOS 7.62 (緑地迷彩) ELCAN SpecterOS 7.62 (Grün) ELCAN SpecterOS 7.62(繁茂) 엘칸 스펙터OS 7.62 (초목) @@ -4030,7 +4117,8 @@ ELCAN SpecterOS 7.62 (Arid) ELCAN SpecterOS 7.62 (Jałowy) ELCAN SpecterOS 7.62 (Désert) - ELCAN SpecterOS 7.62 (乾燥地帯) + ELCAN SpecterOS 7.62 (Arido) + ELCAN SpecterOS 7.62 (乾燥地帯迷彩) ELCAN SpecterOS 7.62 (Trocken) ELCAN SpecterOS 7.62(干旱) 엘칸 스펙터OS 7.62 (건조) @@ -4059,7 +4147,7 @@ SIG BRAVO4 / ROMEO3 (卡其色) SIG BRAVO4 / ROMEO3(卡其色) SIG BRAVO4 / ROMEO3 (カーキ) - SIG BRAVO4 / ROMEO3 (Khaki) + SIG BRAVO4 / ROMEO3 (Cachi) SIG BRAVO4 / ROMEO3 (Khaki) SIG BRAVO4 / ROMEO3 (хаки) SIG BRAVO4 / ROMEO3 (Khaki) @@ -4105,8 +4193,8 @@ Nightforce NXS (Green Hex) Nightforce NXS (綠色數位蜂巢迷彩) Nightforce NXS(绿色蜂巢迷彩) - Nightforce NXS (緑ヘックス) - Nightforce NXS (Verde Hex) + Nightforce NXS (緑六角形迷彩) + Nightforce NXS (Hex Verde) Nightforce NXS (Zielony Hex) Nightforce NXS (зелёный гекс) Nightforce NXS (Verde Hex) @@ -4122,7 +4210,7 @@ Nightforce NXS (Dschungel) Nightforce NXS (叢林色) Nightforce NXS(丛林色) - Nightforce NXS (ジャングル) + Nightforce NXS (熱帯ジャングル迷彩) Nightforce NXS (Giungla) Nightforce NXS (Dżungla) Nightforce NXS (джунгли) @@ -4171,7 +4259,7 @@ US Optics MR-10(黑色) US Optics MR-10 (ブラック) US Optics MR-10 (Czarny) - Ottica US MR-10 (nera) + Ottica US MR-10 (Nera) US Optics MR-10 (чёрный) US Optics MR-10 (Preto) US Optics MR-10 (Noire) @@ -4187,7 +4275,7 @@ US Optics MR-10(卡其色) US Optics MR-10 (カーキ) US Optics MR-10 (Khaki) - Ottica US MR-10 (cachi) + Ottica US MR-10 (Cachi) US Optics MR-10 (хаки) US Optics MR-10 (Khaki) US Optics MR-10 (Kaki) @@ -4203,7 +4291,7 @@ US Optics MR-10(沙色) US Optics MR-10 (サンド) US Optics MR-10 (Piasek) - Ottica US MR-10 (sabbia) + Ottica US MR-10 (Sabbia) US Optics MR-10 (песочный) US Optics MR-10 (Areia) US Optics MR-10 (Beige) @@ -4219,7 +4307,7 @@ KAHLES Helia(黑色) KAHLES ヘリア (ブラック) KAHLES Helia (Czarny) - KAHLES Helia (nero) + KAHLES Helia (Nero) KAHLES Helia (чёрный) KAHLES Helia (Preto) KAHLES Helia (Noire) @@ -4233,9 +4321,9 @@ KAHLES Helia (Hex) KAHLES Helia (Hex) KAHLES Helia(蜂巢迷彩) - KAHLES ヘリア (ヘックス) + KAHLES ヘリア (六角形迷彩) KAHLES Helia (Hex) - KAHLES Helia (esagonale) + KAHLES Helia (Hex) KAHLES Helia (гекс) KAHLES Helia (Hex) KAHLES Helia (Hex) @@ -4251,7 +4339,7 @@ KAHLES Helia(旧) KAHLES ヘリア (使い古し) KAHLES Helia (Stary) - KAHLES Helia (vecchio) + KAHLES Helia (Vecchio) KAHLES Helia (старый) KAHLES Helia (Velho) KAHLES Helia (Usée) @@ -4265,9 +4353,9 @@ KAHLES Helia (Tan) KAHLES Helia (Tan) KAHLES Helia(沙色) - KAHLES Helia (タン) + KAHLES ヘリア (タン) KAHLES Helia (Tan) - KAHLES Helia (marroncino) + KAHLES Helia (Marroncino) KAHLES Helia (пустынный) KAHLES Helia (Bege) KAHLES Helia (Tan) @@ -4297,8 +4385,8 @@ Burris XTR II (Green Hex) Burris XTR II (綠色數位蜂巢迷彩) Burris XTR II(绿色蜂巢迷彩) - Burris XTR II (緑ヘックス) - Burris XTR II (Green Hex) + Burris XTR II (緑六角形迷彩) + Burris XTR II (Hex Verde) Burris XTR II (Zielony Hex) Burris XTR II (зелёный гекс) Burris XTR II (Verde Hex) @@ -4313,6 +4401,7 @@ Burris XTR II (Old) Burris XTR II (Stary) Burris XTR II (Usée) + Burris XTR II (Vecchio) Burris XTR II (使い古し) Burris XTR II (Alt) Burris XTR II(陈旧) @@ -4324,7 +4413,8 @@ Burris XTR II (ASP-1 Kir) Burris XTR II (ASP-1 Kir) Burris XTR II (ASP-1 Kir) - Burris XTR II (ASP-1 Kir) + Burris XTR II (APS-1 Kir) + Burris XTR II (ASP-1 キール用) Burris XTR II (ASP-1 Kir) Burris XTR II(ASP-1 Kir) 버리스 XTR II (ASP-1 키르용) @@ -4337,7 +4427,7 @@ EOTech XPS3 (黃褐色) EOTech XPS3(沙色) EOTech XPS3 (タン) - EOTech XPS3 (Tan) + EOTech XPS3 (Marroncino) EOTech XPS3 (Tan) EOTech XPS3 (пустынный) EOTech XPS3 (Bege) @@ -4353,7 +4443,7 @@ EOTech XPS3 (黑色) EOTech XPS3(黑色) EOTech XPS3 (ブラック) - EOTech XPS3 (Black) + EOTech XPS3 (Nero) EOTech XPS3 (Czarny) EOTech XPS3 (чёрный) EOTech XPS3 (Preto) @@ -4369,7 +4459,7 @@ EOTech XPS3 (卡其色) EOTech XPS3(卡其色) EOTech XPS3 (カーキ) - EOTech XPS3 (Khaki) + EOTech XPS3 (Cachi) EOTech XPS3 (Khaki) EOTech XPS3 (хаки) EOTech XPS3 (Khaki) @@ -4383,7 +4473,8 @@ EOTech XPS3 (Lush) EOTech XPS3 (Leśny) EOTech XPS3 (Forêt) - EOTech XPS3 (緑地) + EOTech XPS3 (Verdeggiante) + EOTech XPS3 (緑地迷彩) EOTech XPS3 (Grün) EOTech XPS3(繁茂) 이오텍 XPS3 (초목) @@ -4394,7 +4485,8 @@ EOTech XPS3 (Arid) EOTech XPS3 (Jałowy) EOTech XPS3 (Désert) - EOTech XPS3 (乾燥地帯) + EOTech XPS3 (Arido) + EOTech XPS3 (乾燥地帯迷彩) EOTech XPS3 (Trocken) EOTech XPS3(干旱) 이오텍 XPS3 (건조) @@ -4407,7 +4499,7 @@ EOTech XPS3 SMG (黃褐色) EOTech XPS3(冲锋枪用,沙色) EOTech XPS3 SMG (タン) - EOTech XPS3 SMG (Tan) + EOTech XPS3 SMG (Marroncino) EOTech XPS3 SMG (Tan) EOTech XPS3 SMG (пустынный) EOTech XPS3 SMG (Bege) @@ -4439,7 +4531,7 @@ EOTech XPS3 SMG (卡其色) EOTech XPS3(冲锋枪用,卡其色) EOTech XPS3 SMG (カーキ) - EOTech XPS3 SMG (Khaki) + EOTech XPS3 SMG (Cachi) EOTech XPS3 SMG (Khaki) EOTech XPS3 SMG (хаки) EOTech XPS3 SMG (Khaki) @@ -4602,7 +4694,7 @@ P90 TR (хаки) P90 TR (Khaki) P90 TR (Khaki) - P90 TR (Khaki) + P90 TR (Cachi) P90 TR (Khaki) P90 TR (Caqui) P90 TR (カーキ) @@ -4619,10 +4711,10 @@ P90 TR (камуфляжный) P90 TR (kamuflaż) P90 TR (Camo) - P90 TR (Camo) + P90 TR (Mimetica) P90 TR (Terepmintás) P90 TR (Camuflagem) - P90 TR (カモフラージュ) + P90 TR (AAF迷彩) P90 TR (迷彩) P90 TR(迷彩) P90 TR (위장) @@ -4639,7 +4731,7 @@ P90 TR (Hex) P90 TR (Hex) P90 TR (Hex) - P90 TR (ヘックス) + P90 TR (六角形迷彩) P90 TR (數位蜂巢迷彩) P90 TR(蜂巢迷彩) P90 TR (육각) @@ -4670,7 +4762,7 @@ P90 (хаки) P90 (Khaki) P90 (Khaki) - P90 (Khaki) + P90 (Cachi) P90 (Khaki) P90 (Caqui) P90 (カーキ) @@ -4687,10 +4779,10 @@ P90 (камуфляжный) P90 (kamuflaż) P90 (Camo) - P90 (Camo) + P90 (Mimetica) P90 (Terepmintás) P90 (Camuflagem) - P90 (カモフラージュ) + P90 (AAF迷彩) P90 (迷彩) P90(迷彩) P90 (위장) @@ -4707,7 +4799,7 @@ P90 (Hex) P90 (Hex) P90 (Hex) - P90 (ヘックス) + P90 (六角形迷彩) P90 (數位蜂巢迷彩) P90(蜂巢迷彩) P90 (육각) @@ -4738,7 +4830,7 @@ PS90 TR (хаки) PS90 TR (Khaki) PS90 TR (Khaki) - PS90 TR (Khaki) + PS90 TR (Cachi) PS90 TR (Khaki) PS90 TR (Caqui) PS90 TR (カーキ) @@ -4755,10 +4847,10 @@ PS90 TR (камуфляжный) PS90 TR (kamuflaż) PS90 TR (Camo) - PS90 TR (Camo) + PS90 TR (Mimetica) PS90 TR (Terepmintás) PS90 TR (Camuflagem) - PS90 TR (カモフラージュ) + PS90 TR (AAF迷彩) PS90 TR (迷彩) PS90 TR(迷彩) PS90 TR (위장) @@ -4775,7 +4867,7 @@ PS90 TR (Hex) PS90 TR (Hex) PS90 TR (Hex) - PS90 TR (ヘックス) + PS90 TR (六角形迷彩) PS90 TR (數位蜂巢迷彩) PS90 TR(蜂巢迷彩) PS90 TR (육각) @@ -4806,7 +4898,7 @@ PS90 (хаки) PS90 (Khaki) PS90 (Khaki) - PS90 (Khaki) + PS90 (Cachi) PS90 (Khaki) PS90 (Caqui) PS90 (カーキ) @@ -4823,10 +4915,10 @@ PS90 (камуфляжный) PS90 (kamuflaż) PS90 (Camo) - PS90 (Camo) + PS90 (Mimetica) PS90 (Terepmintás) PS90 (Camuflagem) - PS90 (カモフラージュ) + PS90 (AAF迷彩) PS90 (迷彩) PS90(迷彩) PS90 (위장) @@ -4843,7 +4935,7 @@ PS90 (Hex) PS90 (Hex) PS90 (Hex) - PS90 (ヘックス) + PS90 (六角形迷彩) PS90 (數位蜂巢迷彩) PS90(蜂巢迷彩) PS90 (육각) @@ -4860,7 +4952,7 @@ Carregador de 50 projéteis de 5.7mm Caricatore 5.7mm 50Rnd Магазин из 50-ти 5,7 мм - 5.7mm 50 発入り弾倉 + 5.7mm 50Rnd マガジン 5.7mm 50發 彈匣 5.7 mm 50发 弹匣 5.7mm 50발 들이 탄창 @@ -4939,7 +5031,7 @@ AK-15 (草木茂盛) AK-15 (Forêt) AK-15 (exuberante) - AK-15 (verdeggiante) + AK-15 (Verdeggiante) AK-15 (region z bujną roślinnością) AK-15 (обильная растительность) AK-15 (Grün) @@ -4947,7 +5039,7 @@ AK-15 (Exuberante) AK-15 (초목) AK-15(繁茂) - AK-15 (緑地) + AK-15 (緑地迷彩) AK-15 (Gür) AK-15 (esőerdő) @@ -4956,7 +5048,7 @@ AK-15 (乾燥氣候) AK-15 (Désert) AK-15 (árido) - AK-15 (arido) + AK-15 (Arido) AK-15 (region suchy) AK-15 (сухая местность) AK-15 (Trocken) @@ -4964,7 +5056,7 @@ AK-15 (Árido) AK-15 (건조) AK-15(干旱) - AK-15 (乾燥地帯) + AK-15 (乾燥地帯迷彩) AK-15 (Kurak) AK-15 (sivatag) @@ -4990,7 +5082,7 @@ AK-15 GL (草木茂盛) AK-15 GL (Forêt) AK-15 GL (exuberante) - AK-15 GL (verdeggiante) + AK-15 GL (Verdeggiante) AK-15 GL (region z bujną roślinnością) AK-15 GL (обильная растительность) AK-15 GL (Grün) @@ -4998,7 +5090,7 @@ AK-15 GL (Exuberante) AK-15 GL (초목) AK-15 GP-34(繁茂) - AK-15 GL (緑地) + AK-15 GL (緑地迷彩) AK-15 GL (Gür) AK-15 GL (esőerdő) @@ -5007,7 +5099,7 @@ AK-15 GL (乾燥氣候) AK-15 GL (Désert) AK-15 GL (árido) - AK-15 GL (arido) + AK-15 GL (Arido) AK-15 GL (region suchy) AK-15 GL (сухая местность) AK-15 GL (Trocken) @@ -5015,7 +5107,7 @@ AK-15 GL (Árido) AK-15 GL (건조) AK-15 GP-34(干旱) - AK-15 GL (乾燥地帯) + AK-15 GL (乾燥地帯迷彩) AK-15AK-15 GL (Kurak) AK-15 GL (sivatag) @@ -5041,7 +5133,7 @@ AK-15K (草木茂盛) AK-15K (Forêt) AK-15K (exuberante) - AK-15K (verdeggiante) + AK-15K (Verdeggiante) AK-15K (region z bujną roślinnością) AK-15K (обильная растительность) AK-15K (Grün) @@ -5049,7 +5141,7 @@ AK-15K (Exuberante) AK-15K (초목) AK-15K(繁茂) - AK-15K (緑地) + AK-15K (緑地迷彩) AK-15K (Gür) AK-15K (esőerdő) @@ -5058,7 +5150,7 @@ AK-15K (乾燥氣候) AK-15K (Désert) AK-15K (árido) - AK-15K (arido) + AK-15K (Arido) AK-15K (region suchy) AK-15K (сухая местность) AK-15K (Trocken) @@ -5066,7 +5158,7 @@ AK-15K (Árido) AK-15K (건조) AK-15K(干旱) - AK-15K (乾燥地帯) + AK-15K (乾燥地帯迷彩) AK-15K (Kurak) AK-15K (sivatag) @@ -5092,7 +5184,7 @@ RPK (草木茂盛) RPK (Forêt) RPK (exuberante) - RPK (verdeggiante) + RPK (Verdeggiante) RPK (region z bujną roślinnością) RPK (обильная растительность) RPK (Grün) @@ -5100,7 +5192,7 @@ RPK (Exuberante) RPK (초목) RPK(繁茂) - RPK (緑地) + RPK (緑地迷彩) RPK (Gür) RPK (esőerdő) @@ -5109,7 +5201,7 @@ RPK (乾燥氣候) RPK (Désert) RPK (árido) - RPK (arido) + RPK (Arido) RPK (region suchy) RPK (сухая местность) RPK (Trocken) @@ -5117,7 +5209,7 @@ RPK (Árido) RPK (건조) RPK(干旱) - RPK (乾燥地帯) + RPK (乾燥地帯迷彩) RPK (Kurak) RPK (sivatag) @@ -5126,7 +5218,7 @@ M14 (经典) M14 (classique) M14 (clásico) - M14 (classico) + M14 (Classico) M14 (klasyczny) M14 (классический) M14 (klassisch) @@ -5151,7 +5243,7 @@ Stoner 99 LMG (Preto) 스토너 99 LMG (검정) 斯通纳 99(黑色) - ストーナー 99 LMG(ブラック) + ストーナー 99 LMG (ブラック) Stoner 99 LMG (Siyah) Stoner 99 Könnyűgéppuska (Fekete) @@ -5194,7 +5286,7 @@ MSBS Grot(迷彩) MSBS Grot (Camo) MSBS Grot (Camuflaje) - MSBS Grot (Camo) + MSBS Grot (Mimetica) MSBS Grot (Kamuflaż) MSBS Grot (камуфляжный) MSBS Grot (Tarnmuster) @@ -5202,7 +5294,7 @@ MSBS Grot (Camo) MSBS 그롯 (위장) MSBS Grot(迷彩) - MSBS グロート (カモフラージュ) + MSBS グロート (LDF迷彩) MSBS Grot (Kamuflaj) MSBS Grot (Terepmintás) @@ -5262,7 +5354,7 @@ MSBS Grot GL(迷彩) MSBS Grot GL (Camo) MSBS Grot GL (Camuflaje) - MSBS Grot GL (Camo) + MSBS Grot GL (Mimetica) MSBS Grot GL (Kamuflaż) MSBS Grot GL (камуфляжный) MSBS Grot GL (Tarnmuster) @@ -5270,7 +5362,7 @@ MSBS Grot GL (Camo) MSBS 그롯 GL (위장) MSBS Grot GPBO-40(迷彩) - MSBS グロート GL (カモフラージュ) + MSBS グロート GL (LDF迷彩) MSBS Grot GL (Kamuflaj) MSBS Grot GL (Terepmintás) @@ -5330,7 +5422,7 @@ MSBS Grot MR(迷彩) MSBS Grot MR (Camo) MSBS Grot MR (Camuflaje) - MSBS Grot MR (Camo) + MSBS Grot MR (Mimetica) MSBS Grot MR (Kamuflaż) MSBS Grot MR (камуфляжный) MSBS Grot MR (Tarnmuster) @@ -5338,7 +5430,7 @@ MSBS Grot MR (Camo) MSBS 그롯 MR (위장) MSBS Grot MR(迷彩) - MSBS グロート MR (カモフラージュ) + MSBS グロート MR (LDF迷彩) MSBS Grot MR (Kamuflaj) MSBS Grot MR (Terepmintás) @@ -5398,7 +5490,7 @@ MSBS Grot SG(迷彩) MSBS Grot SG (Camo) MSBS Grot SG (Camuflaje) - MSBS Grot SG (Camo) + MSBS Grot SG (Mimetica) MSBS Grot SG (Kamuflaż) MSBS Grot SG (камуфляжный) MSBS Grot SG (Tarnmuster) @@ -5406,7 +5498,7 @@ MSBS Grot SG (Camo) MSBS 그롯 SG (위장) MSBS Grot SG(迷彩) - MSBS グロート SG (カモフラージュ) + MSBS グロート SG (LDF迷彩) MSBS Grot SG (Kamuflaj) MSBS Grot SG (Terepmintás) diff --git a/addons/rearm/XEH_postInit.sqf b/addons/rearm/XEH_postInit.sqf index f156fb71d6..61ec35b8de 100644 --- a/addons/rearm/XEH_postInit.sqf +++ b/addons/rearm/XEH_postInit.sqf @@ -1,9 +1,8 @@ #include "script_component.hpp" -GVAR(hardpointGroupsCache) = [] call CBA_fnc_createNamespace; GVAR(configTypesAdded) = []; -GVAR(magazineNameCache) = [] call CBA_fnc_createNamespace; -GVAR(originalMagazineNames) = []; +GVAR(magazineNameCache) = createHashMap; +GVAR(usedMagazineNames) = createHashMap; [QGVAR(initSupplyVehicle), { TRACE_1("initSupplyVehicle EH",_this); // Warning: this can run before settings are init diff --git a/addons/rearm/XEH_preInit.sqf b/addons/rearm/XEH_preInit.sqf index 10156a7d1c..4aa8cb80ad 100644 --- a/addons/rearm/XEH_preInit.sqf +++ b/addons/rearm/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" DFUNC(rearm_statement) = { // moved from config because of build problems TRACE_1("rearm_statement",_this); diff --git a/addons/rearm/XEH_preStart.sqf b/addons/rearm/XEH_preStart.sqf index b092699f9b..b013b04b86 100644 --- a/addons/rearm/XEH_preStart.sqf +++ b/addons/rearm/XEH_preStart.sqf @@ -4,6 +4,6 @@ // Test binarization one time at startup - ref https://github.com/acemod/ACE3/pull/8093 private _test = getText (configFile >> "Cfg3DEN" >> "Object" >> "AttributeCategories" >> "ace_attributes" >> "Attributes" >> "ace_rearm_rearmCargo" >> "defaultValue"); -if (!("else {" in _test)) then { +if !("else {" in _test) then { ERROR("3den attribute has ERROR [check binarization]"); }; 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_getMagazineName.sqf b/addons/rearm/functions/fnc_getMagazineName.sqf index 2ee4a988ed..e961831c8c 100644 --- a/addons/rearm/functions/fnc_getMagazineName.sqf +++ b/addons/rearm/functions/fnc_getMagazineName.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* - * Author: PabstMirror - * Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE) + * Author: PabstMirror, johnb43 + * Gets a non-ambigious display name for a magazine using displayNameShort (AP/HE). * * Arguments: * 0: Magazine Classname @@ -10,7 +10,7 @@ * Display Name * * Example: - * ["B_20mm_AP"] call ace_rearm_fnc_getMagazineName + * "60Rnd_20mm_AP_shells" call ace_rearm_fnc_getMagazineName * * Public: No */ @@ -18,31 +18,31 @@ params ["_className"]; TRACE_1("getMagazineName",_className); -private _magName = GVAR(magazineNameCache) getVariable _className; -if (isNil "_magName") then { - private _displayName = getText(configFile >> "CfgMagazines" >> _className >> "displayName"); +GVAR(magazineNameCache) getOrDefaultCall [_className, { + private _cfgMagazines = configFile >> "CfgMagazines"; + private _displayName = getText (_cfgMagazines >> _className >> "displayName"); + if (_displayName == "") then { _displayName = _className; WARNING_1("Magazine is missing display name [%1]",_className); }; - if ((_displayName select [0,6]) == "[CSW] ") then { _displayName = _displayName select [6]; }; + // [CSW] prefix is localised + if (["ace_csw"] call EFUNC(common,isModLoaded)) then { + _displayName = trim (_displayName regexReplace [LELSTRING(csw,regex), ""]); + }; - GVAR(magazineNameCache) setVariable [_className, _displayName]; - GVAR(originalMagazineNames) pushBack _displayName; + // If the display name exists already, add displayNameShort to the existing entry + private _existingClassname = GVAR(usedMagazineNames) get _displayName; + + if (!isNil "_existingClassname") then { + GVAR(magazineNameCache) set [_existingClassname, format ["%1: %2", _displayName, getText (_cfgMagazines >> _existingClassname >> "displayNameShort")]]; + + _displayName = format ["%1: %2", _displayName, getText (_cfgMagazines >> _className >> "displayNameShort")]; + }; + + GVAR(usedMagazineNames) set [_displayName, _className]; TRACE_2("Adding to cache",_className,_displayName); - // go through all existing cache entries and update if there now are duplicates - { - private _xMagName = GVAR(magazineNameCache) getVariable _x; - if ((_xMagName == _displayName) && {({_xMagName == _x} count GVAR(originalMagazineNames)) > 1}) then { - private _xMagName = format ["%1: %2", _displayName, getText(configFile >> "CfgMagazines" >> _x >> "displayNameShort")]; - GVAR(magazineNameCache) setVariable [_x, _xMagName]; - TRACE_2("Using unique name",_x,_xMagName); - }; - } forEach (allVariables GVAR(magazineNameCache)); - - _magName = GVAR(magazineNameCache) getVariable _className; -}; - -_magName + _displayName +}, true] // return diff --git a/addons/rearm/functions/fnc_hasEnoughSupply.sqf b/addons/rearm/functions/fnc_hasEnoughSupply.sqf index c7efb7eca6..8b606bdf6f 100644 --- a/addons/rearm/functions/fnc_hasEnoughSupply.sqf +++ b/addons/rearm/functions/fnc_hasEnoughSupply.sqf @@ -44,7 +44,6 @@ if (GVAR(supply) == 2) exitWith { { _x params ["_magazine", "_rounds"]; if ((_magazine isEqualTo _magazineClass) && (_rounds > 0)) exitWith {_magazinePresent = true; }; - false - } count _magazineSupply; + } forEach _magazineSupply; _magazinePresent }; 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/rearm/functions/fnc_readSupplyCounter.sqf b/addons/rearm/functions/fnc_readSupplyCounter.sqf index 7526fd013a..f298579705 100644 --- a/addons/rearm/functions/fnc_readSupplyCounter.sqf +++ b/addons/rearm/functions/fnc_readSupplyCounter.sqf @@ -58,8 +58,7 @@ if (GVAR(supply) == 1) then { _numChars = _numChars max (count _line); _text = format ["%1
%2", _text, _line]; _supply = _supply + 0.5; - false - } count _magazines; + } forEach _magazines; }; if (_supply > 1.5) then { [[LSTRING(Hint_RemainingAmmo), _text], _supply, _unit, (_numChars/2.9)] call EFUNC(common,displayTextStructured); diff --git a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf index d014e9d58d..396b501dab 100644 --- a/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf +++ b/addons/rearm/functions/fnc_rearmEntireVehicleSuccess.sqf @@ -28,8 +28,7 @@ if (isServer) then { } else { [QGVAR(rearmEntireVehicleSuccessLocalEH), [_truck, _vehicle, _x], _turretOwnerID] call CBA_fnc_ownerEvent; }; - false - } count _turrets; + } forEach _turrets; } else { [QGVAR(rearmEntireVehicleSuccessEH), _this] call CBA_fnc_serverEvent; }; diff --git a/addons/rearm/functions/fnc_rearmSuccessLocal.sqf b/addons/rearm/functions/fnc_rearmSuccessLocal.sqf index 71802451b7..f41dff6ea9 100644 --- a/addons/rearm/functions/fnc_rearmSuccessLocal.sqf +++ b/addons/rearm/functions/fnc_rearmSuccessLocal.sqf @@ -54,7 +54,7 @@ private _maxMagazines = [_vehicle, _turretPath, _magazineClass] call FUNC(getMax private _ammoCounts = [_vehicle, _turretPath, _magazineClass] call FUNC(getTurretMagazineAmmo); TRACE_3("start",_magazineClass,_maxMagazines,_ammoCounts); -private _ammoToAdd = if (GVAR(level) == 2) then {_numRounds} else {_rounds}; +private _ammoToAdd = [_rounds, _numRounds] select (GVAR(level) == 2); private _ammoAdded = 0; private _arrayModified = false; // skip needing to remove and re-add mags, if we are only adding new ones diff --git a/addons/rearm/initSettings.sqf b/addons/rearm/initSettings.inc.sqf similarity index 72% rename from addons/rearm/initSettings.sqf rename to addons/rearm/initSettings.inc.sqf index d83ac3c760..6489bd9326 100644 --- a/addons/rearm/initSettings.sqf +++ b/addons/rearm/initSettings.inc.sqf @@ -1,4 +1,4 @@ -private _category = [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(DisplayName)]; +private _category = [ELSTRING(main,Category_Logistics), LLSTRING(DisplayName)]; [ QGVAR(enabled), "CHECKBOX", @@ -7,7 +7,7 @@ private _category = [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(DisplayN true, true, {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -15,8 +15,7 @@ private _category = [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(DisplayN [LSTRING(RearmSettings_level_DisplayName), LSTRING(RearmSettings_level_Description)], _category, [[0,1,2],[LSTRING(RearmSettings_vehicle), LSTRING(RearmSettings_magazine), LSTRING(RearmSettings_caliber)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(level), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -24,8 +23,7 @@ private _category = [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(DisplayN [LSTRING(RearmSettings_supply_DisplayName), LSTRING(RearmSettings_supply_Description)], _category, [[0,1,2],[LSTRING(RearmSettings_unlimited), LSTRING(RearmSettings_limited), LSTRING(RearmSettings_magazineSupply)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -33,6 +31,5 @@ private _category = [LELSTRING(OptionsMenu,CategoryLogistics), LLSTRING(DisplayN [LLSTRING(RearmSettings_distance_DisplayName), LLSTRING(RearmSettings_distance_Description)], _category, [10, 50, 20, 0], - true, // isGlobal - {[QGVAR(supply), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/rearm/script_component.hpp b/addons/rearm/script_component.hpp index 83d495bc38..1cc6379ff7 100644 --- a/addons/rearm/script_component.hpp +++ b/addons/rearm/script_component.hpp @@ -28,7 +28,9 @@ #define REARM_HOLSTER_WEAPON \ - _unit setVariable [QGVAR(selectedWeaponOnRearm), currentWeapon _unit]; \ + if (currentWeapon _unit != "") then { \ + _unit setVariable [QGVAR(selectedWeaponOnRearm), (weaponState _unit) select [0, 3]]; \ + }; \ TRACE_2("REARM_HOLSTER_WEAPON",_unit,currentWeapon _unit); \ _unit action ["SwitchWeapon", _unit, _unit, 299]; diff --git a/addons/rearm/stringtable.xml b/addons/rearm/stringtable.xml index 88be22aae3..b8dfd37f77 100644 --- a/addons/rearm/stringtable.xml +++ b/addons/rearm/stringtable.xml @@ -53,10 +53,10 @@ Степень перевооружения Quantidade de rearme Rychlost přezbrojení - Ammontare Riarmo + Velocità Riarmo Velocidad de rearme Quantité à réarmer - 再武装が可能な量 + 再武装の所要時間 재보급 양 整装所需时间 整裝所需時間 @@ -71,7 +71,7 @@ Quanto velocemente dovrebbe essere riarmato un veicolo? Cuán rápido es el proceso de rearme? Définit la vitesse à laquelle s'effectue le réarmement. - 車両を再武装する早さを設定します。 + 車両がどれくらいの早さで再武装されるか? 차량을 얼마나 빨리 재보급 시킵니까? 载具多快会整装完毕? 載具多快會整裝完畢? @@ -113,10 +113,10 @@ В зависимости от калибра Quantidade baseada no calibre Rychlost závisí na ráži - Ammontare basato sul calibro + Quantità basata sul calibro Cantidad basada en el calibre En fonction du calibre - 口径に基づいた量 + 口径に基づいて 구경에 따라 수량 설정 基于口径决定所耗时间 基於口徑決定所耗時間 @@ -229,7 +229,7 @@ There is ammunition worth %1 points left. Es ist noch Munition für %1 Punkte übrig. - E' presente una penalità delle munizioni %1 punti rimanenti. + Sono presenti ancora munizioni del valore di %1 punti. 弾薬は %1 残っています。 还剩下%1多的弹药。 還剩下%1多的彈藥. @@ -244,8 +244,8 @@ The following ammunition is left:%1 Folgende Munition ist übrig:%1 - Mancano le seguenti:%1 - この弾薬の残りは: %1 + Rimangono le seguenti munizioni:%1 + この弾薬は残り: %1 以下剩余的弹药:%1 以下剩餘的彈藥:%1 Pozostała amunicja: %1 @@ -327,7 +327,7 @@ Sto prendendo %1 per %2... Tomando %1 para %2... Prise de %1 pour %2... - %1 を %2 用として取得中・・・ + %1 を %2 用に取得中・・・ %2를 위해 %1 가져오는 중... 正在拿取%1给%2... 拿取%1給%2中... @@ -419,7 +419,7 @@ Riarmati %1 colpi di %2 su %3 Rearmadas %1 rondas de %2 en %3 %1 balles réarmées de %2 dans %3. - %1発の%2を%3に装填しました + %1 発の %2 を %3 に装填しました %3에 2%의 %1 탄약 재보급 整装了%1发%2到%3上 整裝了%1發%2到%3上 @@ -445,7 +445,7 @@ Světlice Fusées Leuchtkörper - Razzi luminosi + Illuminanti Flary Sinalizadores ЛТЦ @@ -651,9 +651,9 @@ Rearm Cargo Munitionsvorrat - 再武装用カーゴ + 再武装用資源積載量 Ładunek Dozbrajający - Rifornimento Munizioni + Munizioni Caricate Боеприпасы для перевооружения Carga de Rearme 整裝用貨物 @@ -666,9 +666,9 @@ The cargo for rearming (-1 disable) Der Munitionsvorrat, zum Aufmunitionieren von Fahrzeugen (-1 deaktiviert) - カーゴからの再武装 (-1 で無効化) + 再武装に使用する資源の積載量 (-1 で補給無効) Ładunek do dozbrajania (-1 wyłączy) - Il rifornimento delle munizioni (-1 per disabilitarlo) + Il carico di munizioni per poter riarmare (-1 per disabilitarlo) Объем боеприпасов для перевооружения (-1 для отмены) A Carga para Rearmamento (-1 para desativar) 貨物可以提高多少次整裝(-1為停用) @@ -698,10 +698,10 @@ Distance maximale à laquelle un véhicule peut être réarmé. Die maximale Distanz, über die ein Fahrzeug Aufmunitioniert werden kann A distância máxima que um veículo pode ser rearmado/municiado. - 車両から再武装できる範囲を決定します。 + 車両から再武装できる最大距離 與載具之最大可整裝距離 车辆可重新整装的最大距离 - La distanza massima a cui un veicolo può essere riarmato + La distanza massima da cui un veicolo può essere riarmato Maximální vzdálenost na jakou může být vozidlo přezbrojeno Maksymalna odległość na jakiej pojazd może zostać przezbrojony Максимальная дистанция для перевооружения diff --git a/addons/recoil/XEH_postInit.sqf b/addons/recoil/XEH_postInit.sqf index 29e5464612..639b22d6f9 100644 --- a/addons/recoil/XEH_postInit.sqf +++ b/addons/recoil/XEH_postInit.sqf @@ -1,4 +1,4 @@ #include "script_component.hpp" // Register fire event handler -["ace_firedPlayer", DFUNC(camShake)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(camShake)] call CBA_fnc_addEventHandler; diff --git a/addons/recoil/functions/fnc_camshake.sqf b/addons/recoil/functions/fnc_camshake.sqf index 8ffa0eb755..d68da81db7 100644 --- a/addons/recoil/functions/fnc_camshake.sqf +++ b/addons/recoil/functions/fnc_camshake.sqf @@ -17,14 +17,14 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); #define BASE_POWER 0.40 #define BASE_TIME 0.19 #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/ACE_Refuel_Positions.hpp b/addons/refuel/ACE_Refuel_Positions.hpp new file mode 100644 index 0000000000..78af5b6d48 --- /dev/null +++ b/addons/refuel/ACE_Refuel_Positions.hpp @@ -0,0 +1,96 @@ +class GVAR(positions) { + Altis[] = { /* Altis */ {"Land_fs_feed_F", {{3757,13478,0},{4001,12592,0},{5023,14430,0},{5769,20086,0},{6199,15081,0},{6798,15561,0},{8482,18261,0},{9026,15729,0},{9206,12112,0},{11832,14156,0},{12025,15830,0},{14173,16542,0},{14221,18303,0},{15297,17566,0},{15781,17453,0},{16751,12513,0},{16875,15469,0},{17417,13937,0},{19961,11454,0},{20785,16666,0},{21231,7117,0},{23379,19799,0},{25701,21373,0}}}}; + Stratis[] = { /* Stratis */ {"Land_FuelStation_Feed_F", {{2708,5788,0}}}}; + VR[] = {}; + Malden[] = { /* Malden 2035 */ + {"Land_fs_feed_F", {{3227,6291,0},{5111,9062,0},{5504,3500,0},{6633,8807,0},{7047,7052,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{7224,7772,0},{8047,4023,0}}}, + {"Land_FuelStation_Feed_F", {{10063,3988,0},{11600,4477,0}}} + }; + Tanoa[] = { /* Tanoa */ + {"Land_fs_feed_F", {{2132,3360,0},{2452,7435,0},{3030,11316,0},{5174,8806,0},{5380,4093,0},{5594,12508,0},{7978,7419,0},{8319,9709,0},{8494,12432,0},{8954,13678,0},{8970,10332,0},{10827,6490,0},{10941,9855,0},{11146,5152,0},{11631,2999,0},{14261,11513,0},{14365,8743,0}}}, + {"Land_FuelStation_01_pump_F", {{1865,12128,0},{5409,9905,0},{5682,10165,0},{5776,4222,0},{5793,10825,0},{6592,13080,0},{6887,7491,0},{7359,7998,0},{9954,13467,0},{11635,13047,0},{11694,2271,0},{12613,7583,0}}} + }; + Enoch[] = { /* Livonia */ + {"Land_FuelStation_03_pump_F", {{2008,7365,0},{6259,3949,0}}}, + {"Land_FuelStation_Feed_F", {{10208,2173,0}}} + }; + + Bootcamp_ACR[] = { /* CUP Bukovina */ {"Land_A_FuelStation_Feed", {{652,473,0},{2849,1612,0}}}}; + Woodland_ACR[] = { /* CUP Bystrica */ {"Land_A_FuelStation_Feed", {{447,1381,0},{1302,2185,0},{1855,6852,0},{4102,1195,0},{4755,4499,0}}}}; + chernarus[] = { /* CUP Chernarus (Autumn) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2692,5602,0},{2997,7471,0},{3648,8968,0},{4733,6381,0},{5847,2191,0},{5849,10112,0},{6705,2996,0},{7255,7662,0},{9502,2005,0},{10154,5300,0},{10446,8866,0},{10726,10786,0},{12988,10076,0},{13385,6603,0}}}}; + chernarus_summer[] = { /* CUP Chernarus (Summer) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2685,5606,0},{2998,7473,0},{3652,8973,0},{4733,6381,0},{5854,2193,0},{5849,10112,0},{6702,2995,0},{7255,7662,0},{9502,2005,0},{10154,5300,0},{10452,8869,0},{10726,10786,0},{13001,10074,0},{13398,6606,0}}}}; + Chernarus_Winter[] = { /* CUP Chernarus (Winter) */ {"Land_A_FuelStation_Feed", {{2021,2242,0},{2685,5604,0},{2997,7471,0},{3657,8979,0},{4733,6381,0},{5854,2193,0},{5849,10112,0},{6702,2995,0},{7255,7662,0},{9503,2019,0},{10155,5309,0},{10452,8869,0},{10726,10786,0},{12994,10075,0},{13385,6603,0}}}}; + cup_chernarus_A3[] = { /* CUP Chernarus 2020 */ + {"Land_fs_feed_F", {{2511,5279,0}}}, + {"Land_FuelStation_03_pump_F", {{313,9385,0},{1129,2400,0},{2021,2242,0},{2692,5602,0},{2991,7471,1},{3007,12654,0},{3648,8968,0},{4328,13081,0},{4733,6381,0},{5847,2191,0},{5849,10112,0},{6699,3001,0},{7255,7662,0},{7494,12662,0},{9502,2005,0},{10155,5309,0},{10452,8869,0},{10726,10786,0},{13001,10074,0},{13398,6606,0},{13569,13329,0}}} + }; + Desert_E[] = { /* CUP Desert */ }; + porto[] = { /* CUP Porto */ }; + ProvingGrounds_PMC[] = { /* CUP Proving Grounds */ {"Land_FuelStation_Feed_PMC", {{698,1208,0}}}}; + intro[] = { /* CUP Rahmadi */ }; + sara[] = { /* CUP Sahrani */ + {"Land_Benzina_schnell", {{8473,9423,0},{9227,5840,0},{9433,5187,0},{10168,6423,0},{10932,9475,0},{11233,6114,0},{11756,10227,0},{12289,6833,0}}}, + {"Land_Fuelstation_army", {{9568,9819,0},{19294,13879,0}}} + }; + sara_dbe1[] = { /* CUP United Sahrani */ + {"Land_Benzina_schnell", {{8473,9423,0},{9227,5840,0},{9433,5187,0},{10168,6423,0},{10932,9475,0},{11233,6114,0},{11756,10227,0},{12289,6833,0}}}, + {"Land_Fuelstation_army", {{9568,9819,0},{19294,13879,0}}} + }; + saralite[] = { /* CUP Southern Sahrani */ + {"Land_Benzina_schnell", {{3593,6663,0},{4347,3080,0},{4553,2427,0},{5288,3663,0},{6052,6715,0},{6353,3354,0},{6876,7467,0},{7409,4073,0}}}, + {"Land_Fuelstation_army", {{4688,7059,0}}} + }; + Shapur_BAF[] = { /* CUP Shapur */ {"Land_Ind_FuelStation_Feed_EP1", {{1512,1298,0}}}}; + takistan[] = { /* CUP Takistan */ {"Land_Ind_FuelStation_Feed_EP1", {{2004,11720,0},{3081,9848,0},{3549,4197,0},{5538,9284,0},{5836,5771,0},{7497,1818,0},{8248,7800,0},{10422,6328,0},{10647,11021,0}}}}; + Mountains_ACR[] = { /* CUP Takistan Mountains */ {"Land_Ind_FuelStation_Feed_EP1", {{2962,4197,0},{5249,5771,0}}}}; + utes[] = { /* CUP Utes */ }; + zargabad[] = { /* CUP Zargabad */ {"Land_Ind_FuelStation_Feed_EP1", {{3736,2784,0},{3867,4208,0},{3871,5980,0},{5027,1906,0}}}}; + + pja310[] = { /* G.O.S Al Rayak */ {"Land_Ind_FuelStation_Feed_EP1", {{887,18588,0},{964,18356,0},{1196,18463,0},{1872,8754,0},{2051,8437,0},{2125,8238,0},{2240,8584,0},{2310,8566,0},{2366,3901,0},{2879,13142,0},{3880,10361,0},{4056,13261,0},{4122,13487,0},{4302,13628,0},{4475,13377,0},{4556,13742,0},{6461,3372,0},{7216,6059,0},{7228,6344,0},{7416,6099,0},{7472,6838,0},{7591,6081,0},{11650,3536,0},{14863,7292,0},{16466,18897,0},{16476,19116,0},{16642,18994,0},{16676,19199,0},{16858,10558,0},{16908,9959,0},{17120,3706,0},{17100,4375,0},{18056,4133,0},{18229,4066,0},{18235,4571,0},{18814,5010,0}}}}; + australia[] = { /* Aussie Australia v5.09 */ + {"Land_fs_feed_F", {{4614,16978,0},{5509,19273,0},{5487,19276,0},{5508,19330,0},{5540,19357,0},{5564,19377,0},{5623,19376,0},{5643,19352,0},{6355,17860,0},{12811,27772,0},{15837,33438,0},{16335,33436,0},{16367,33436,0},{17127,33902,0},{20754,12737,0},{20874,12793,0},{20901,12793,1},{22127,25635,0},{22127,25666,0},{22162,25712,0},{22194,25712,0},{22213,25630,0},{22315,19235,0},{22595,24757,0},{24909,13855,0},{25050,12786,0},{25071,12786,0},{26085,11260,1},{26212,11174,0},{26824,28005,0},{27719,17108,0},{27757,12033,0},{28473,35132,0},{30707,11879,0},{31091,5370,0},{31096,10918,0},{31096,10945,0},{31165,10914,0},{31165,10958,0},{31313,16763,0},{31515,9673,0},{31515,9652,0},{31758,4861,0},{32224,2736,0},{33919,13364,0},{33936,13350,0},{34789,26383,0},{35274,26021,2},{35786,12148,0},{35765,12170,0},{35835,12145,0},{35833,12188,0},{35812,12210,0},{36199,16479,0},{36399,13140,0},{36593,12065,0},{36574,13089,0},{36595,13089,0},{36597,13282,0},{38153,14544,0},{38520,18891,0},{38515,20173,0},{38535,20198,0},{38565,20198,0}}}, + {"Land_FuelStation_01_pump_F", {{5495,18693,0},{32067,29608,0},{32087,29611,0},{33215,4147,0},{37293,13172,0},{37293,13193,0}}}, + {"Land_FuelStation_Feed_F", {{19303,16449,0},{31064,20116,0}}} + }; + Farabad[] = { /* Farabad */ + {"Land_Benzina_schnell", {{592,7505,0},{804,1445,0},{3132,3129,0}}}, + {"Land_fs_feed_F", {{1920,4960,0},{5052,4703,1},{9456,9277,0}}}, + {"Land_FuelStation_01_pump_F", {{2378,6248,0},{7092,534,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{4788,5525,0}}} + }; + IslaPera[] = { /* Isla Pera */ + {"Land_fs_feed_F", {{1855,2866,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{3981,2065,0},{5306,8796,0},{9236,4287,0}}} + }; + VTF_Lybor[] = { /* Lybor */ + {"Land_FuelStation_03_pump_F", {{3879,3823,0}}}, + {"Land_FuelStation_Feed_F", {{1831,2694,0},{2175,3323,0},{3304,2981,0},{4271,3024,0}}} + }; + rof_mok[] = { /* Mull of Kintyre, Scotland */ + {"Land_A_FuelStation_Feed", {{12837,5124,1},{15271,17533,0},{19453,21896,0}}}, + {"Land_fs_feed_F", {{7492,17369,0}}}, + {"Land_Fuelstation", {{10284,18679,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{9762,16325,0}}} + }; + pulau[] = { /* Pulau */ + {"Land_fs_feed_F", {{2368,3128,0},{4891,7168,0},{7358,7368,0}}}, + {"Land_FuelStation_Feed_F", {{5994,5789,0}}} + }; + WL_Rosche[] = { /* Rosche, Germany (2.0) */ + {"Land_fs_feed_F", {{693,4803,0},{12059,6700,0},{13320,14822,0}}}, + {"Land_FuelStation_01_pump_F", {{447,6859,0}}}, + {"Land_Ind_FuelStation_Feed_EP1", {{1437,5455,0}}} + }; + Kapaulio[] = { /* Saint Kapaulio */ + {"Land_fs_feed_F", {{931,7647,0},{958,6796,0},{2034,9426,0},{2563,9427,0},{3500,8110,0},{3602,6082,0},{4222,6308,0},{4561,693,0},{8077,5906,0},{8434,13145,0},{8525,17299,0},{9265,7155,0},{10527,18267,0},{12078,1846,0},{12833,6464,0},{13433,6327,0},{14084,6308,0},{14172,7786,0},{14831,4649,0},{16080,14743,0},{17356,2312,0},{18047,5254,0},{18318,5042,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{18039,18139,0}}}, + {"Land_FuelStation_Feed_F", {{756,12133,0},{1239,7346,0},{1726,17469,0},{3113,10070,0},{3828,8362,0},{5668,16967,0},{7435,14185,0},{7543,12107,0},{8366,6086,0},{9672,9586,0},{11749,12255,0},{12802,10022,0},{13989,3591,0},{15198,10900,0},{19063,1654,0},{19378,18517,0}}} + }; + pabst_yellowstone[] = { /* Yellowstone */ + {"Land_fs_feed_F", {{3075,7426,0},{7060,3626,0},{7950,4060,0},{7974,4072,0}}}, + {"Land_FuelStation_01_pump_F", {{4565,1953,0}}}, + {"Land_FuelStation_01_pump_malevil_F", {{7072,3676,0}}}, + {"Land_FuelStation_Feed_F", {{4678,3971,0},{6391,5174,0}}} + }; +}; diff --git a/addons/refuel/Cfg3DEN.hpp b/addons/refuel/Cfg3DEN.hpp index 3383107995..00d5453d95 100644 --- a/addons/refuel/Cfg3DEN.hpp +++ b/addons/refuel/Cfg3DEN.hpp @@ -1,7 +1,4 @@ -#define GET_NUMBER(config,default) (if (isNumber (config)) then {getNumber (config)} else {default}) #define GET_1ST_ARRAY(config) (if (isArray (config)) then {getArray (config) select 0} else {[ARR_3(0,0,0)]}) - -#define DEFAULT_FUELCARGO GET_NUMBER(configOf _this >> QQGVAR(fuelCargo),REFUEL_DISABLED_FUEL) #define DEFAULT_HOOKS GET_1ST_ARRAY(configOf _this >> QQGVAR(hooks)) class Cfg3DEN { @@ -14,8 +11,8 @@ class Cfg3DEN { tooltip = CSTRING(fuelCargo_edenDesc); property = QGVAR(fuelCargo); control = "EditShort"; - expression = QUOTE(if (_value != DEFAULT_FUELCARGO) then {[ARR_2(_this,_value)] call DFUNC(makeSource)}); - defaultValue = QUOTE(DEFAULT_FUELCARGO); + expression = QUOTE(if (_value != (_this call FUNC(getFuelCargo))) then {[ARR_2(_this,_value)] call FUNC(makeSource)}); + defaultValue = QUOTE(_this call FUNC(getFuelCargo)); validate = "number"; condition = "(1-objectBrain)*(1-objectAgent)"; typeName = "NUMBER"; diff --git a/addons/refuel/CfgVehicles.hpp b/addons/refuel/CfgVehicles.hpp index 5fba336943..44575a141d 100644 --- a/addons/refuel/CfgVehicles.hpp +++ b/addons/refuel/CfgVehicles.hpp @@ -1,3 +1,5 @@ +#define XEH_INHERITED class EventHandlers {class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {};} + class CBA_Extended_EventHandlers; class CfgNonAIVehicles { @@ -45,9 +47,7 @@ class CfgVehicles { class ThingX; class GVAR(fuelNozzle): ThingX { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; + XEH_INHERITED; displayName = QGVAR(fuelNozzle); scope = 1; @@ -275,12 +275,6 @@ class CfgVehicles { GVAR(hooks)[] = {{0.38,-3.17,-0.7},{-0.41,-3.17,-0.7}}; GVAR(fuelCargo) = 2000; }; - class C_Van_01_fuel_F: Van_01_fuel_base_F { - transportFuel = 0; //1k - }; - class I_G_Van_01_fuel_F: Van_01_fuel_base_F { - transportFuel = 0; //1k - }; class Tank_F: Tank { GVAR(fuelCapacity) = 1200; @@ -295,7 +289,6 @@ class CfgVehicles { class B_APC_Tracked_01_base_F: APC_Tracked_01_base_F {}; class B_APC_Tracked_01_CRV_F: B_APC_Tracked_01_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.08,-4.81,-0.8}}; GVAR(fuelCargo) = 1000; }; @@ -407,7 +400,6 @@ class CfgVehicles { // Vanilla fuel vehicles class Truck_02_fuel_base_F: Truck_02_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.99,-3.47,-0.67},{-1.04,-3.47,-0.67}}; GVAR(fuelCargo) = 10000; }; @@ -416,13 +408,11 @@ class CfgVehicles { }; class B_Truck_01_fuel_F: B_Truck_01_mover_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.28,-4.99,-0.3},{-0.25,-4.99,-0.3}}; GVAR(fuelCargo) = 10000; }; class O_Truck_03_fuel_F: Truck_03_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{1.3,-1.59,-0.62},{-1.16,-1.59,-0.62}}; GVAR(fuelCargo) = 10000; }; @@ -436,20 +426,17 @@ class CfgVehicles { class Pod_Heli_Transport_04_base_F: Slingload_base_F {}; class Land_Pod_Heli_Transport_04_fuel_F: Pod_Heli_Transport_04_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.49,1.41,-0.3}}; GVAR(fuelCargo) = 10000; }; class Slingload_01_Base_F: Slingload_base_F {}; class B_Slingload_01_Fuel_F: Slingload_01_Base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{0.55,3.02,-0.5},{-0.52,3.02,-0.5}}; GVAR(fuelCargo) = 10000; }; class O_Heli_Transport_04_fuel_F: Heli_Transport_04_base_F { - transportFuel = 0; //3k GVAR(hooks)[] = {{-1.52,1.14,-1.18}}; GVAR(fuelCargo) = 10000; }; @@ -466,11 +453,7 @@ class CfgVehicles { }; }; class Land_StorageBladder_01_F: StorageBladder_base_F { - class EventHandlers { - class CBA_Extended_EventHandlers: CBA_Extended_EventHandlers {}; - }; - - transportFuel = 0; //60k + XEH_INHERITED; GVAR(hooks)[] = {{-3.35,2.45,0.17}}; GVAR(fuelCargo) = 60000; }; @@ -486,36 +469,35 @@ class CfgVehicles { }; }; class Land_FlexibleTank_01_F: FlexibleTank_base_F { - transportFuel = 0; //300 GVAR(hooks)[] = {{0, 0, 0.5}}; GVAR(fuelCargo) = 300; }; // Vanilla buildings class Land_Fuelstation_Feed_F: House_Small_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0,0,-0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_fs_feed_F: House_Small_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{-0.4,0.022,-0.23}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_F: House_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_01_pump_malevil_F: House_F { - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; class Land_FuelStation_03_pump_F: House_F { // Enoch - transportFuel = 0; //50k + XEH_INHERITED; GVAR(hooks)[] = {{0, 0.4, -0.5}, {0, -0.4, -0.5}}; GVAR(fuelCargo) = REFUEL_INFINITE_FUEL; }; diff --git a/addons/refuel/XEH_PREP.hpp b/addons/refuel/XEH_PREP.hpp index 077c8f1aed..cb9279500b 100644 --- a/addons/refuel/XEH_PREP.hpp +++ b/addons/refuel/XEH_PREP.hpp @@ -11,6 +11,7 @@ PREP(disconnect); PREP(dropNozzle); PREP(getCapacity); PREP(getFuel); +PREP(getFuelCargo); PREP(handleDisconnect); PREP(handleRespawn); PREP(initSource); diff --git a/addons/refuel/XEH_postInit.sqf b/addons/refuel/XEH_postInit.sqf index c826efd3d4..d007266e5f 100644 --- a/addons/refuel/XEH_postInit.sqf +++ b/addons/refuel/XEH_postInit.sqf @@ -1,95 +1,150 @@ #include "script_component.hpp" -if (isServer) then { - addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; -}; +["CBA_settingsInitialized", { + if (!GVAR(enabled)) exitWith {}; -[QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; + ["All", "InitPost", { + params ["_vehicle"]; + if (getFuelCargo _vehicle <= 0) exitWith {}; + TRACE_1("initPost",_vehicle); -if (!hasInterface) exitWith {}; + if (local _vehicle) then { + _vehicle setFuelCargo 0; + LOG("initPost setFuelCargo"); + }; + }, true, ["Man"], true] call CBA_fnc_addClassEventHandler; -["isNotRefueling", {!((_this select 0) getVariable [QGVAR(isRefueling), false])}] call EFUNC(common,addCanInteractWithCondition); + if (isServer) then { + addMissionEventHandler ["HandleDisconnect", {call FUNC(handleDisconnect)}]; + }; -["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + private _cfgPositions = configFile >> QGVAR(positions) >> worldName; + if (isArray _cfgPositions) then { + { + _x params ["_class", "_positions"]; + { + private _objects = _x nearObjects [_class, 30]; + if (_objects isEqualTo []) then { + WARNING_3("no pumps %1 found near %2 %3",_class,worldName,_x); + } else { + { + // terrain fuel pumps don't trigger init and must setFuelCargo on each client + _x setFuelCargo 0; + } forEach _objects; + }; + } forEach _positions; + } forEach getArray _cfgPositions; -GVAR(mainAction) = [ - QGVAR(Refuel), - localize LSTRING(Refuel), - QPATHTOF(ui\icon_refuel_interact.paa), - {}, - { - alive _target - && {[_player, _target, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith)} - && {REFUEL_DISABLED_FUEL != ([_target] call FUNC(getCapacity))} - }, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE -] call EFUNC(interact_menu,createAction); + // placed in editor static objects don't trigger init but synchronize fuel cargo + // placed in editor vehicles both trigger init and synchronize fuel cargo + { + if (getFuelCargo _x > 0 && {local _x}) then { + TRACE_1("allMissionObjects",_x); + _x setFuelCargo 0; + }; + } forEach allMissionObjects ""; + } else { + // here are both terrain and editor static objects + WARNING_2("World %1: %2 is not configured; can load slower",worldName,QGVAR(positions)); + private _halfWorldSize = worldSize / 2; + private _worldCenter = [_halfWorldSize, _halfWorldSize]; + _halfWorldSize = _halfWorldSize * sqrt 2; + private _baseStaticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseStatic)); -GVAR(actions) = [ - [QGVAR(TakeNozzle), - localize LSTRING(TakeNozzle), + { + { + _x setFuelCargo 0; + } forEach (_worldCenter nearObjects [_x, _halfWorldSize]); + } forEach _baseStaticClasses; + }; + + [QGVAR(initSource), LINKFUNC(initSource)] call CBA_fnc_addEventHandler; + + if (!hasInterface) exitWith {}; + + ["isNotRefueling", {!((_this select 0) getVariable [QGVAR(isRefueling), false])}] call EFUNC(common,addCanInteractWithCondition); + + ["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + + GVAR(mainAction) = [ + QGVAR(Refuel), + localize LSTRING(Refuel), QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(TakeNozzle)}, - {[_player, _target] call FUNC(canTakeNozzle)}, + {}, + { + alive _target + && {[_player, _target, [INTERACT_EXCEPTIONS]] call EFUNC(common,canInteractWith)} + && {REFUEL_DISABLED_FUEL != ([_target] call FUNC(getCapacity))} + }, {}, [], [0,0,0], REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(CheckFuelCounter), - localize LSTRING(CheckFuelCounter), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(readFuelCounter)}, - {true}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(CheckFuel), - localize LSTRING(CheckFuel), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(checkFuel)}, - {[_player, _target] call FUNC(canCheckFuel)}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction), - [QGVAR(Return), - localize LSTRING(Return), - QPATHTOF(ui\icon_refuel_interact.paa), - {[_player, _target] call FUNC(returnNozzle)}, - {[_player, _target] call FUNC(canReturnNozzle)}, - {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE - ] call EFUNC(interact_menu,createAction) -]; + ] call EFUNC(interact_menu,createAction); -// init menu for config refuel vehicles -private _cacheRefuelClasses = call (uiNamespace getVariable [QGVAR(cacheRefuelClasses), {[[],[]]}]); -_cacheRefuelClasses params [["_staticClasses", [], [[]]], ["_dynamicClasses", [], [[]]]]; + GVAR(actions) = [ + [QGVAR(TakeNozzle), + localize LSTRING(TakeNozzle), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(TakeNozzle)}, + {[_player, _target] call FUNC(canTakeNozzle)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(CheckFuelCounter), + localize LSTRING(CheckFuelCounter), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(readFuelCounter)}, + {true}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(CheckFuel), + localize LSTRING(CheckFuel), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(checkFuel)}, + {[_player, _target] call FUNC(canCheckFuel)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction), + [QGVAR(Return), + localize LSTRING(Return), + QPATHTOF(ui\icon_refuel_interact.paa), + {[_player, _target] call FUNC(returnNozzle)}, + {[_player, _target] call FUNC(canReturnNozzle)}, + {}, [], [0,0,0], + REFUEL_ACTION_DISTANCE + ] call EFUNC(interact_menu,createAction) + ]; -{ - private _className = _x; - [_className, 0, ["ACE_MainActions"], GVAR(mainAction)] call EFUNC(interact_menu,addActionToClass); + private _staticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesStatic)); + private _baseDynamicClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseDynamic)); + + // init menu for config refuel vehicles { - [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x] call EFUNC(interact_menu,addActionToClass); - } forEach GVAR(actions); - TRACE_1("add menu to static",_x); -} forEach _staticClasses; + private _className = _x; + [_className, 0, ["ACE_MainActions"], GVAR(mainAction)] call EFUNC(interact_menu,addActionToClass); + { + [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to static",_x); + } forEach _staticClasses; -{ - private _className = _x; - [_className, 0, ["ACE_MainActions"], GVAR(mainAction), true] call EFUNC(interact_menu,addActionToClass); { - [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x, true] call EFUNC(interact_menu,addActionToClass); - } forEach GVAR(actions); - TRACE_1("add menu to dynamic",_x); -} forEach _dynamicClasses; + private _className = _x; + [_className, 0, ["ACE_MainActions"], GVAR(mainAction), true] call EFUNC(interact_menu,addActionToClass); + { + [_className, 0, ["ACE_MainActions", QGVAR(Refuel)], _x, true] call EFUNC(interact_menu,addActionToClass); + } forEach GVAR(actions); + TRACE_1("add menu to dynamic",_x); + } forEach _baseDynamicClasses; -#ifdef DRAW_HOOKS_POS -addMissionEventHandler ["Draw3D", { - private _source = cursorObject; - private _cfgPos = getArray (configOf _source >> QGVAR(hooks)); - private _dynPos = _source getVariable [QGVAR(hooks), []]; - { - drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,1,1,1], _source modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; - } forEach ([_dynPos, _cfgPos] select (_dynPos isEqualTo [])); -}]; -#endif + #ifdef DRAW_HOOKS_POS + addMissionEventHandler ["Draw3D", { + private _source = cursorObject; + private _cfgPos = getArray (configOf _source >> QGVAR(hooks)); + private _dynPos = _source getVariable [QGVAR(hooks), _cfgPos]; + { + drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\icon_text\group_1_ca.paa", [1,1,1,1], _source modelToWorldVisual _x, 1, 1, 0, format ["Hook %1", _forEachIndex]]; + } forEach _dynPos; + }]; + #endif +}] call CBA_fnc_addEventHandler; diff --git a/addons/refuel/XEH_preInit.sqf b/addons/refuel/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/refuel/XEH_preInit.sqf +++ b/addons/refuel/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/refuel/XEH_preStart.sqf b/addons/refuel/XEH_preStart.sqf index fa5fe4acda..308ca30a9b 100644 --- a/addons/refuel/XEH_preStart.sqf +++ b/addons/refuel/XEH_preStart.sqf @@ -4,27 +4,44 @@ // cache refuel vehicles, see XEH_postInit.sqf private _staticClasses = []; -private _dynamicClasses = []; +private _baseStaticClasses = []; +private _baseDynamicClasses = []; +private _cacheRefuelCargo = createHashMap; { - private _fuelCargo = getNumber (_x >> QGVAR(fuelCargo)); + private _transportFuel = getNumber (_x >> "transportFuel"); + private _fuelCargo = [_x >> QGVAR(fuelCargo), "NUMBER", _transportFuel] call CBA_fnc_getConfigEntry; if (_fuelCargo > 0 || {_fuelCargo == REFUEL_INFINITE_FUEL}) then { private _sourceClass = configName _x; + private _noXEH = !isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init"); + private _isPublic = getNumber (_x >> "scope") == 2; // check if we can use actions with inheritance if ( - !isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init") // addActionToClass relies on XEH init - || {configName _x isKindOf "Static"} // CBA_fnc_addClassEventHandler doesn't support "Static" class + _noXEH // addActionToClass relies on XEH init + || {_sourceClass isKindOf "Static"} // CBA_fnc_addClassEventHandler doesn't support "Static" class ) then { - if (2 == getNumber (_x >> "scope")) then { - _staticClasses pushBackUnique _sourceClass; + if (_isPublic) then { + if (_noXEH) then { + WARNING_3("Class %1: %2 [%3] needs XEH",_sourceClass,configName inheritsFrom _x,configSourceMod _x); + }; + _staticClasses pushBack _sourceClass; + if (_baseStaticClasses findIf {_sourceClass isKindOf _x} == -1) then { + _baseStaticClasses pushBack _sourceClass; + }; }; } else { - if (-1 == _dynamicClasses findIf {_sourceClass isKindOf _x}) then { - _dynamicClasses pushBackUnique _sourceClass; + if (_baseDynamicClasses findIf {_sourceClass isKindOf _x} == -1) then { + _baseDynamicClasses pushBack _sourceClass; }; }; + if (_isPublic) then { + _cacheRefuelCargo set [_sourceClass, _fuelCargo]; + }; }; -} forEach ('true' configClasses (configFile >> "CfgVehicles")); +} forEach ("true" configClasses (configFile >> "CfgVehicles")); -TRACE_2("compiled",count _staticClasses,count _dynamicClasses); -uiNamespace setVariable [QGVAR(cacheRefuelClasses), compileFinal str [_staticClasses, _dynamicClasses]]; +TRACE_3("found",count _staticClasses,count _baseStaticClasses,count _baseDynamicClasses); +uiNamespace setVariable [QGVAR(cacheRefuelClassesStatic), compileFinal (_staticClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelClassesBaseStatic), compileFinal (_baseStaticClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelClassesBaseDynamic), compileFinal (_baseDynamicClasses createHashMapFromArray [])]; +uiNamespace setVariable [QGVAR(cacheRefuelCargo), compileFinal _cacheRefuelCargo]; diff --git a/addons/refuel/config.cpp b/addons/refuel/config.cpp index b39b665059..79b97994f1 100644 --- a/addons/refuel/config.cpp +++ b/addons/refuel/config.cpp @@ -14,6 +14,7 @@ class CfgPatches { }; }; +#include "ACE_Refuel_Positions.hpp" #include "ACE_Settings.hpp" #include "Cfg3DEN.hpp" #include "CfgEventHandlers.hpp" diff --git a/addons/refuel/dev/exportTerrainRefuelPositions.sqf b/addons/refuel/dev/exportTerrainRefuelPositions.sqf new file mode 100644 index 0000000000..c7f9abfb2f --- /dev/null +++ b/addons/refuel/dev/exportTerrainRefuelPositions.sqf @@ -0,0 +1,95 @@ +// call compileScript ["z\ace\addons\refuel\dev\exportTerrainRefuelPositions.sqf"] +// can be run in Eden Editor console + +#include "\z\ace\addons\refuel\script_component.hpp" + +{ + if (!isArray (configFile >> QGVAR(positions) >> configName _x)) then { + WARNING_1("need configs on [%1]",configName _x); + }; +} forEach ("true" configClasses (configFile >> "CfgWorldList")); + + + +private _basePumps = []; +private _totalCount = 0; +private _posCount = 0; +private _message = ""; +private _halfWorldSize = worldSize / 2; +private _worldCenter = [_halfWorldSize, _halfWorldSize]; +_halfWorldSize = _halfWorldSize * sqrt 2; + +private _baseStaticClasses = keys (uiNamespace getVariable QGVAR(cacheRefuelClassesBaseStatic)); +private _class = ""; +private _objects = []; +private _positions = []; +private _object = objNull; +private _pos = []; + +{ + _class = _x; + _objects = _worldCenter nearObjects [_class, _halfWorldSize]; + if (_objects isEqualTo []) then { + continue; + }; + ADD(_totalCount,count _objects); + _positions = []; + { + _object = _x; + _pos = ASLToAGL getPosASL _object; + if (-1 < _positions findIf {60 > _x distance _pos && {20 < _x distance _pos}}) then { + _message = "INCREASE DISTANCE " + str _pos; + }; + if (-1 == _positions findIf {20 > _x distance _pos}) then { + _positions pushBack (_pos apply {round _x}); + INC(_posCount); + }; + } forEach _objects; + _positions sort true; // sort positions by smallest first + _basePumps pushBack [_class, _positions]; +} forEach _baseStaticClasses; + +_basePumps sort true; // sort pump classes alphabetically + +// check final array as it's calculated in postInit +private _checkCount = 0; +{ + _x params ["_class", "_positions"]; + private _pumps = []; + { + _pumps append (_x nearObjects [_class, 30]); + } forEach _positions; + _pumps = _pumps arrayIntersect _pumps; + _checkCount = _checkCount + count _pumps; +} forEach _basePumps; +if (_checkCount != _totalCount) then { + _message = "WRONG COUNT " + str _checkCount; +}; + +// export text +private _nl = toString [10]; +private _multipleBasePumps = 1 < count _basePumps; +private _output = [format [" %1[] = { /* %2 */", worldName, getText (configfile >> "CfgWorlds" >> worldName >> "description")]]; +{ + if (_forEachIndex > 0) then {_output pushBack ","}; + _x params ["_class", "_positions"]; + if (_multipleBasePumps) then { + _output pushBack (_nl + " "); + } else { + _output pushBack " "; + }; + _output pushBack format ["{""%1"", {", _class]; + { + if (_forEachIndex > 0) then {_output pushBack ","}; + _output pushBack format ["{%1,%2,%3}", _x#0, _x#1, _x#2]; + } forEach _positions; + _output pushBack "}}"; +} forEach _basePumps; +if (_multipleBasePumps) then {_output pushBack (_nl + " ")}; +if (_basePumps isEqualTo []) then {_output pushBack " "}; +_output pushBack ("};" + _nl); + +_output = _output joinString ""; + +copyToClipboard _output; +[_totalCount, _posCount, _message, _output] diff --git a/addons/refuel/dev/test_debugConfigs.sqf b/addons/refuel/dev/test_debugConfigs.sqf index f427f07d28..52ff8a962a 100644 --- a/addons/refuel/dev/test_debugConfigs.sqf +++ b/addons/refuel/dev/test_debugConfigs.sqf @@ -5,14 +5,14 @@ private _testPass = true; -diag_log text format ["[ACE-refuel] Showing CfgVehicles with vanilla transportFuel"]; -private _fuelTrucks = configProperties [configFile >> "CfgVehicles", "(isClass _x) && {(getNumber (_x >> 'transportFuel')) > 0}", true]; +INFO("Showing CfgVehicles with transportFuel and without XEH"); +private _badCfgVehicles = ' + 2 == getNumber (_x >> "scope") + && {0 < getNumber (_x >> "transportFuel")} + && {!isText (_x >> "EventHandlers" >> "CBA_Extended_EventHandlers" >> "init")} +' configClasses (configFile >> "CfgVehicles"); { - if ((configName _x) isKindOf "Car") then { - diag_log text format ["Car [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - } else { - diag_log text format ["Non-car? [%1] needs config [transportFuel: %2]", configName _x, getNumber (_x >> 'transportFuel')]; - }; -} forEach _fuelTrucks; + diag_log text format ["Class %1: %2 [%3] needs XEH", configName _x, configName inheritsFrom _x, configSourceMod _x]; +} forEach _badCfgVehicles; _testPass 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_getCapacity.sqf b/addons/refuel/functions/fnc_getCapacity.sqf index 94681480ae..c6218831da 100644 --- a/addons/refuel/functions/fnc_getCapacity.sqf +++ b/addons/refuel/functions/fnc_getCapacity.sqf @@ -30,7 +30,7 @@ if (isNil "_capacity") then { // Set capacity even if this isn't a fuel source to save on config lookup time in the event this function is used in a loop _source setVariable [QGVAR(capacity), _capacity, true]; // handle weird edge case when trying to run on "camera"/CfgNonAIVehicles which won't support setVariable and will inf-loop - if (isNil {_source getVariable QGVAR(capacity)}) exitWith { WARNING_1("trying to getCapacity from non-CfgVehicle %1", _this); }; + if (isNil {_source getVariable QGVAR(capacity)}) exitWith { WARNING_1("trying to getCapacity from non-CfgVehicle %1",_this); }; [_source, _capacity] call FUNC(setFuel); }; diff --git a/addons/refuel/functions/fnc_getFuelCargo.sqf b/addons/refuel/functions/fnc_getFuelCargo.sqf new file mode 100644 index 0000000000..360679013e --- /dev/null +++ b/addons/refuel/functions/fnc_getFuelCargo.sqf @@ -0,0 +1,20 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Returns vehicle fuel amount from config (cached). + * + * Arguments: + * 0: Fuel Source + * + * Return Value: + * Fuel amount from config + * + * Example: + * cursorObject call ace_refuel_fnc_getFuelCargo + * + * Public: No + */ + +params ["_source"]; + +(uiNamespace getVariable QGVAR(cacheRefuelCargo)) getOrDefault [typeOf _source, REFUEL_DISABLED_FUEL] diff --git a/addons/refuel/functions/fnc_makeJerryCan.sqf b/addons/refuel/functions/fnc_makeJerryCan.sqf index 2a1bc75280..31a91a30d7 100644 --- a/addons/refuel/functions/fnc_makeJerryCan.sqf +++ b/addons/refuel/functions/fnc_makeJerryCan.sqf @@ -16,6 +16,13 @@ * Public: Yes */ +// Only run this after the settings are initialized +if !(EGVAR(common,settingsInitFinished)) exitWith { + EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeJerryCan), _this]; +}; + +if (!GVAR(enabled)) exitWith {}; + params [["_target", objNull, [objNull]], ["_fuelAmount", 20, [0]]]; if (isNull _target || @@ -40,7 +47,8 @@ private _action = [QGVAR(Refuel), {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions"], _action] call EFUNC(interact_menu,addActionToObject); // Add pickup @@ -52,7 +60,8 @@ _action = [QGVAR(PickUpNozzle), {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add turnOn @@ -64,7 +73,8 @@ _action = [QGVAR(TurnOn), {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add turnOn container @@ -76,7 +86,8 @@ _action = [QGVAR(TurnOn_Container), {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add check fuel @@ -88,7 +99,8 @@ _action = [QGVAR(CheckFuel), {}, [], [0,0,0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction), + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add turnOff @@ -100,7 +112,8 @@ _action = [QGVAR(TurnOff), {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); // Add disconnect @@ -112,5 +125,6 @@ _action = [QGVAR(Disconnect), {}, [], [0, 0, 0], - REFUEL_ACTION_DISTANCE] call EFUNC(interact_menu,createAction); + REFUEL_ACTION_DISTANCE +] call EFUNC(interact_menu,createAction); [_target, 0, ["ACE_MainActions", QGVAR(Refuel)], _action] call EFUNC(interact_menu,addActionToObject); diff --git a/addons/refuel/functions/fnc_makeSource.sqf b/addons/refuel/functions/fnc_makeSource.sqf index 38b2d8a261..9d76635849 100644 --- a/addons/refuel/functions/fnc_makeSource.sqf +++ b/addons/refuel/functions/fnc_makeSource.sqf @@ -25,21 +25,39 @@ if !(EGVAR(common,settingsInitFinished)) exitWith { EGVAR(common,runAtSettingsInitialized) pushBack [FUNC(makeSource), _this]; }; +if (!GVAR(enabled)) exitWith {}; + params [ ["_source", objNull, [objNull]], ["_fuelCargo", 0, [0]], ["_hooks", nil, [[]]] ]; -TRACE_3("makeSource",_source,_fuelCargo,_hooks); -private _fuelCargoConfig = getNumber (configOf _source >> QGVAR(fuelCargo)); +private _fuelCargoConfig = _source call FUNC(getFuelCargo); + +TRACE_4("makeSource",_source,_fuelCargo,_hooks,_fuelCargoConfig); if ( isNull _source || {_fuelCargo < 0 && {!(_fuelCargo in [REFUEL_INFINITE_FUEL, REFUEL_DISABLED_FUEL])}} - || {_fuelCargo != 0 && {_fuelCargo == _fuelCargoConfig}} ) exitWith {}; +// We might be removing fuel from an object that in config doesn't have fuel, but was given fuel via this function prior +if (_fuelCargo == REFUEL_DISABLED_FUEL && {_fuelCargoConfig == REFUEL_DISABLED_FUEL}) exitWith { + if (isNil {_source getVariable QGVAR(currentFuelCargo)}) exitWith {}; + + _source setVariable [QGVAR(currentFuelCargo), nil, true]; + _source setVariable [QGVAR(capacity), REFUEL_DISABLED_FUEL, true]; + + private _jipID = _source getVariable QGVAR(initSource_jipID); + + if (isNil "_jipID") exitWith {}; + + _jipID call CBA_fnc_removeGlobalEventJIP; + + _source setVariable [QGVAR(initSource_jipID), nil]; +}; + private _capacity = if (_fuelCargo < 0) then {_fuelCargo} else {_fuelCargoConfig max _fuelCargo}; _source setVariable [QGVAR(capacity), _capacity, true]; @@ -57,10 +75,10 @@ if ( }; // only add if menu doesn't already exist -if (!(_fuelCargoConfig != 0 && {!isNil {_source getVariable QGVAR(initSource_jipID)}})) then { - private _jipID = [QGVAR(initSource), [_source]] call CBA_fnc_globalEventJIP; - [_jipID, _source] call CBA_fnc_removeGlobalEventJIP; - _source setVariable [QGVAR(initSource_jipID), _jipID]; -}; +if (_fuelCargoConfig != REFUEL_DISABLED_FUEL || {!isNil {_source getVariable QGVAR(initSource_jipID)}}) exitWith {}; + +private _jipID = [QGVAR(initSource), [_source]] call CBA_fnc_globalEventJIP; +[_jipID, _source] call CBA_fnc_removeGlobalEventJIP; +_source setVariable [QGVAR(initSource_jipID), _jipID]; [QGVAR(sourceInitialized), [_source]] call CBA_fnc_globalEvent; 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/initSettings.sqf b/addons/refuel/initSettings.inc.sqf similarity index 55% rename from addons/refuel/initSettings.sqf rename to addons/refuel/initSettings.inc.sqf index 087e253dc4..2888ad190c 100644 --- a/addons/refuel/initSettings.sqf +++ b/addons/refuel/initSettings.inc.sqf @@ -1,35 +1,43 @@ +private _category = [ELSTRING(main,Category_Logistics), "str_state_refuel"]; + +[ + QGVAR(enabled), "CHECKBOX", + ELSTRING(common,Enabled), + _category, + true, + 1, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart +] call CBA_fnc_addSetting; + [ QGVAR(rate), "SLIDER", [LSTRING(RefuelSettings_speed_DisplayName), LSTRING(RefuelSettings_speed_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_refuel"], + _category, [0,25,1,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(rate), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ QGVAR(cargoRate), "SLIDER", [LSTRING(RefuelSettings_speedCargo_DisplayName), LSTRING(RefuelSettings_speedCargo_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_refuel"], + _category, [0,250,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(cargoRate), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ QGVAR(hoseLength), "SLIDER", [LSTRING(RefuelSettings_hoseLength_DisplayName)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_refuel"], + _category, [0,50,12,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(hoseLength), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ QGVAR(progressDuration), "TIME", [LSTRING(RefuelSettings_progressDuration_DisplayName), LSTRING(RefuelSettings_progressDuration_Description)], - [localize ELSTRING(OptionsMenu,CategoryLogistics), localize "str_state_refuel"], + _category, [0, 10, 2], // [min, max, default value] - true, // isGlobal - {[QGVAR(progressDuration), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; diff --git a/addons/refuel/stringtable.xml b/addons/refuel/stringtable.xml index f8e0d431c7..648ee38c6d 100644 --- a/addons/refuel/stringtable.xml +++ b/addons/refuel/stringtable.xml @@ -24,7 +24,7 @@ Скорость заправки Velocidade da vazão Rychlost tankování - Portata Flusso + Portata di Flusso Caudal de llenado Débit de la pompe 流量 @@ -40,7 +40,7 @@ Как быстро техника должна быть заправлена? Quão rápido deve ser o veículo reabastecido? Jak rychle bude vozidlo natankováno? - Quanto velocemente dovrebbe essere rifornito un veicolo? + Quanto velocemente si può rifornire un veicolo? Cuán rápido se reabastecen los vehículos? Définit la vitesse de ravitaillement en carburant des véhicules. どのくらいの速さで車両へ給油しますか? @@ -54,18 +54,22 @@ 화물 주유량 Caudal de llenado de la carga 貨物流量 + Portata di Flusso al Carico Prędkość Tankowania Ładunku Frachtflussrate Vitesse de ravitaillement + Скорость заполнения груза How fast should a fuel source's tank be filled? 연료 공급처의 저장 탱크를 얼마나 빨리 채웁니까? Cómo de rápido puede llenarse una fuente de combustible. どのくらいの速さで給油源へ給油しますか? + Quanto velocemente si può rifornire il carico di carburante di un veicolo? 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 @@ -90,7 +94,7 @@ Взять топливный шланг Pegar o bocal de combustível Vzít výdejní pistoli - Prendi manica benzina + Prendi Pistola Erogatrice Tomar surtidor Prendre le pistolet 給油ノズルを取る @@ -106,7 +110,7 @@ Берем топливный шланг... Pegando o bocal de combustível... Beru výdejní pistoli... - Prendendo manicotto benzina... + Prendendo Pistola Erogatrice... Tomando surtidor... Prise du pistolet... 給油ノズルを取っています・・・ @@ -122,7 +126,7 @@ Присоединить топливный шланг Conectar o bocal de combustível Připojit výdejní pistoli - Collega manica benzina + Collega Pistola Erogatrice Conectar surtidor Introduire le pistolet 給油ノズルを接続する @@ -138,7 +142,7 @@ Присоединяем топливный шланг... Conectando o bocal de combustível... Připojuji výdejní pistoli... - Collegando manicotto benzina... + Collegando Pistola Erogatrice... Conectando surtidor... Introduction du pistolet... 給油ノズルを接続しています・・・ @@ -154,7 +158,7 @@ Отсоединить топливный шланг Desconectar o bocal de combustível Odpojit výdejní pistoli - Scollega manicotto benzina + Scollega Pistola Erogatrice Desconectar surtidor Retirer le pistolet 給油ノズルを外す @@ -186,7 +190,7 @@ Проверить остаток топлива Verificar combustível restante Zkontrolovat zůstatek paliva - Controlla benzina rimanente + Controlla carburante rimanente Verificar combustible remanente Vérifier le carburant restant 残燃料を見る @@ -202,7 +206,7 @@ Проверяем остаток топлива... Verificando combustível restante... Kontroluji zůstatek paliva... - Controllando la benzina rimanente... + Controllando carburante rimanente... Verificando combustible remanente,,, Vérification du carburant restant... 残燃料を見ています・・・ @@ -221,7 +225,7 @@ Sono rimasti %1 litri. Quedan %1 litros. Il reste %1 litres. - 後 %1 リットル残っています。 + あと %1 リットル残っています。 %1 리터 남음 剩下%1升的燃料。 剩下%1公升的燃料。 @@ -234,7 +238,7 @@ Топлива нет. Não há combustível Bez paliva. - Non è rimasta più benzina. + Non c'è alcun carburante rimanente. No queda combustible. Il n'y a plus de carburant. もう燃料は残っていません。 @@ -282,7 +286,7 @@ Остановить заправку Parar reabastecimento Zastavit tankování - Ferma rifornimento + Interrompi rifornimento Detener reabastecimiento Arrêter le ravitaillement 給油を止める @@ -311,10 +315,12 @@ Start fueling (container) Betankung beginnen (Container) 연료 재급유 시작 (컨테이너) + Inizia rifornimento (Contenitore) Iniciando repostado (contenedor) 給油を始める (コンテナ) Rozpocznij tankowanie (zbiornik) Commencer le ravitaillement (container) + Начать заправку топливом (контейнер) Couldn't turn on fuel nozzle @@ -342,7 +348,7 @@ %1 litri riforniti %1 lt reabastecido %1 litres pompés. - %1 リッターを給油しました + %1 リットル給油した %1 리터 재급유됨 已加入%1升的燃料 已加入%1公升的燃料 @@ -355,7 +361,7 @@ Источник топлива пустой. A fonte de combustível está vazia. Zdroj paliva je prázdný. - La fonte di benzina è vuota. + La fonte di carburante è vuota. La fuente de combustible está vacía. La source de carburant est vide. 給油元は空です。 @@ -371,7 +377,7 @@ Достигнута максимальная длина шланга. Distância máxima da mangueira de combustível alcançada. Dosažena maximální délka hadice - Distanza massima della pompa raggiunta. + Raggiunta lunghezza massima della tubazione. Máxima longitud de manguera alcanzada. Tuyau tendu au maximum. 給油ホースはもうこれ以上届きません。 @@ -403,7 +409,7 @@ Заправка остановлена Reabastecimento parado Tankování zastaveno - Rifornimento fermato + Rifornimento interrotto Reabastecimiento detenido Ravitaillement arrêté. 給油を止めました @@ -435,7 +441,7 @@ Вернуть топливный шланг Retornar bocal de combustível Vrátit výdejní pistoli - Riponi manicotto benzina + Riponi Pistola Erogatrice Devolver surtidor Ranger le pistolet 給油ノズルを戻す @@ -451,7 +457,7 @@ Возвращаем топливный шланг... Retornando bocal de combustível... Vracím výdejní pistoli... - Riponendo la manica della benzina... + Riponendo la Pistola Erogatrice... Devolviendo el surtidor... Rangement du pistolet... 給油ノズルを戻しています・・・ @@ -467,7 +473,7 @@ Проверить счетчик топлива Verificar contador de combustível Zkonrolovat palivoměr - Controlla indicatore livello benzina + Controlla livello carburante Verificar el contador de combustible Vérifier le compteur 燃料計を見る @@ -486,7 +492,7 @@ %1 litri sono stati riforniti. Se reabastecieron %1 lt %1 litres ont été pompés. - %1 リッターが給油されました。 + %1 リットル給油されました。 %1 리터가 재급유되었습니다. 已加入%1升 已加入%1公升 @@ -494,24 +500,59 @@ Pick up fuel canister + Treibstoffkanister aufheben + Raccogli contenitore di carburante + 燃料キャニスターを持つ + 연료통 집어들기 + Взять канистру с топливом + Ramasser le réservoir de carburant + Coger garrafa de combustible Picking fuel canister up... + Hebe Treibstoffkanister auf... + Raccogliendo contenitore di carburante... + 燃料キャニスターを持ち上げています・・・ + 연료통 집어드는 중... + Поднимаю канистру с топливом... + Ramasser les bidons de carburant... + Cogiendo garrafa de combustible... Connect fuel canister + Treibstoffkanister anschließen + Collega contenitore di carburante + 燃料キャニスターを接続する + 연료통 꽂기 + Подсоединить канистру с топливом + Raccorder le réservoir de carburant + Conectar garrafa de combustible Connecting fuel canister... + Schließe Treibstoffkanister an... + Collegando contenitore di carburante... + 燃料キャニスターを接続しています・・・ + 연료통 꽂는 중... + Подсоединение топливной канистры... + Raccorder le réservoir de carburant... + Conectando garrafa de combustible... Disconnect fuel canister + Treibstoffkanister lösen + Scollega contenitore di carburante + 燃料キャニスターを外します + 연료통 빼기 + Отсоединить канистру с топливом + Débrancher le réservoir de carburant + Desconectar garrafa de combustible Refuel hose length Betankung Schlauchlänge Reabastecer longitud de manguera - Rifiuta lungezza tubo + Lunghezza tubazione di rifornimento 給油ホースの長さ 加油软管长度 加油軟管長度 @@ -529,7 +570,8 @@ 펌프/호스 상호작용 시간 Время взаимодействия со шлангом Tiempo de interacción con la Bomba/Manguera - ポンプとホースのインタラクション時間 + Tempo di interazione Pompa/Pistola + ポンプ/ホースのインタラクション所要時間 Czas Interakcji z Pompą/Wężem Interaktionszeit zwischen Pumpe und Schlauch Temps d'interaction pompe/tuyau @@ -540,7 +582,8 @@ 연료 재보급 상호작용에 걸리는 시간(초)입니다. Время в секундах, которое занимает взаимодействие со шлангом. Cuanto tiempo en segundos tardan las interacciones de repostado. - 燃料補給にかかる時間 (秒) + Durata delle interazioni in secondi. + 燃料補給に掛かる時間。 (秒単位) Jak długo powinna trwać interakcja tankowania w sekundach. Wie lange Auftank-Interaktionen in Sekunden dauern. Durée des interactions de ravitaillement en secondes. @@ -549,8 +592,8 @@ Fuel Cargo Volume Tankvolumen Объем топлива для заправки - 貯油量 - Capacità Carburante Cargo + 給油用燃料積載量 + Capacità di Carico Carburante 儲油量 储油量 연료통 크기 @@ -566,8 +609,8 @@ The fuel volume available for refueling (-1 disable, -10 if infinite) Das Tankvolumen, welches zum Nachtanken verfügbar ist (-1 deaktiviert, -10 unendlich) Объем топлива, доступный для заправки других машин (-1 отключить, -10 если неограничен) - 給油用の貯油量を設定できます (-1で無効、-10で無限) - La capacità del carburante disponibile per il rifornimento (-1 disabilita, -10 se infinito) + 給油に使用する燃料の積載量 (-1で補給無効、-10で無限補給) + La capacità di carburante disponibile al rifornimento altrui (-1 disabilita, -10 se infinito) 設定有多少油料可供載具進行加油(-1時關閉,-10為無限油量) 设定有多少油料可供载具进行加油(-1时关闭,-10为无限油量) 재급유에 사용할 수 있는 연료량 (-1=비활성, -10=무한) @@ -582,7 +625,7 @@ Befestigungskoordinaten der Zapfpistole Координаты крепления шланга 給油ノズルの取り付け座標 - Coordinate del tubo di rifornimento + Coordinate di attacco tubazione 加油軟管安裝位置 加油软管安装位置 재급유기 부착 좌표 @@ -597,7 +640,7 @@ Modelkoordinaten zum Anheften der Zapfpistole Координаты модели, куда крепится заправочный шланг 給油ノズルの取り付けにモデル座標を使用します - Coordinate del modello utilizzate per il fissaggio del tubo + Coordinate del modello utilizzate per l'attacco della tubazione di rifornimento 設定加油軟管會安裝到模型的哪個位置上 设定加油软管会安装到模型的哪个位置上 재급유기 부착에 쓰이는 모델 좌표 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 65ce1d0b4b..a219efed0a 100644 --- a/addons/reload/XEH_postInit.sqf +++ b/addons/reload/XEH_postInit.sqf @@ -52,4 +52,19 @@ if (!hasInterface) exitWith {}; -#include "initKeybinds.sqf" +#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/XEH_preInit.sqf b/addons/reload/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/reload/XEH_preInit.sqf +++ b/addons/reload/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; 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_canCheckAmmoSelf.sqf b/addons/reload/functions/fnc_canCheckAmmoSelf.sqf index b554833fb0..0427fb33e1 100644 --- a/addons/reload/functions/fnc_canCheckAmmoSelf.sqf +++ b/addons/reload/functions/fnc_canCheckAmmoSelf.sqf @@ -17,4 +17,4 @@ params ["_player"]; -_player call CBA_fnc_canUseWeapon && {!((vehicle _player) isKindOf "StaticWeapon")} +_player call CBA_fnc_canUseWeapon && {currentWeapon _player != ""} && {!((vehicle _player) isKindOf "StaticWeapon")} 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/initKeybinds.sqf b/addons/reload/initKeybinds.inc.sqf similarity index 100% rename from addons/reload/initKeybinds.sqf rename to addons/reload/initKeybinds.inc.sqf diff --git a/addons/reload/initSettings.sqf b/addons/reload/initSettings.inc.sqf similarity index 100% rename from addons/reload/initSettings.sqf rename to addons/reload/initSettings.inc.sqf diff --git a/addons/reload/stringtable.xml b/addons/reload/stringtable.xml index 9aa239a2f9..2f0c6c60c1 100644 --- a/addons/reload/stringtable.xml +++ b/addons/reload/stringtable.xml @@ -36,9 +36,9 @@ Always show check ammo self interaction Zawsze pokazuj interakcję od sprawdzania amunicji - Mostra sempre l'interazione di autocontrollo delle munizioni + Mostra sempre l'autointerazione di controllo delle munizioni Vždy zobrazit kontrolu munice v menu vlastní interakce - セルフ インタラクションへ弾薬確認を常に表示 + 弾薬確認アクションを常に表示 總是在自我互動中顯示檢查彈藥動作 总是在自我互动中显示检查弹药动作 Toujours afficher l'action de vérification des munitions @@ -51,9 +51,9 @@ Shows check ammo self interaction even when not in static weapons. Pokazuje interakcję od sprawdzania amunicji poza bronią statyczną. - Mostra il controllo dell'interazione tra le munizioni anche quando non sono in armi statiche. + Mostra l'autointerazione di controllo delle munizioni anche quando non si è in un'arma statica. Zobrazuje kontrolu munice v menu vlastní interakce i pokud hráč nepoužívá statickou zbraň. - 設置型火器を使っていなくても、セルフ インタラクションへ弾薬確認を常に表示します。 + 設置型火器以外でも常にセルフ・インタラクションに弾薬確認アクションを表示します。 即使不是固定式支援武器也依然在自我互動中顯示檢查彈藥動作 即使不是固定式支援武器也依然在自我互动中显示检查弹药动作 Permet d'afficher l'action de vérification des munitions du menu d'interaction personnel, même si le joueur n'utilise pas d'arme statique. @@ -106,7 +106,7 @@ Podłącz taśmę Gurt anhängen Töltényheveder összekötése - Attacca la tracolla + Combina nastro Ligar cintos de munição ベルトを繋げる 탄띠 연결 @@ -122,7 +122,7 @@ Podłączanie taśmy... Gurt anhängen... Töltényheveder összekötése folyamatban... - Attaccando la tracolla... + Combinando nastro... Ligando cintos... ベルトを繋げています・・・ 탄띠 연결 중... @@ -133,17 +133,23 @@ Belt was linked Bande a été attachée Gurt wurde angehängt + Nastro combinato ベルトがリンクされた Taśma została połączona 탄띠가 연결되었습니다 + Ремень был пристегнут + Cinta enganchada Belt could not be linked Bande n'a pas pu être attachée Gurt konnte nicht angehängt werden + Non è stato possibile combinare il nastro ベルトはリンクされなかった Taśma nie mogła być połączona 탄띠를 연결할 수 없습니다 + Ремень не удалось пристегнуть + La cinta no ha podido ser enganchada diff --git a/addons/reloadlaunchers/XEH_preInit.sqf b/addons/reloadlaunchers/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/reloadlaunchers/XEH_preInit.sqf +++ b/addons/reloadlaunchers/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/reloadlaunchers/initSettings.sqf b/addons/reloadlaunchers/initSettings.inc.sqf similarity index 100% rename from addons/reloadlaunchers/initSettings.sqf rename to addons/reloadlaunchers/initSettings.inc.sqf diff --git a/addons/reloadlaunchers/stringtable.xml b/addons/reloadlaunchers/stringtable.xml index 188b977800..b55ccde170 100644 --- a/addons/reloadlaunchers/stringtable.xml +++ b/addons/reloadlaunchers/stringtable.xml @@ -3,19 +3,25 @@ Display notifications for buddy loading - バディ装填時の通知表示 + バディローディング時の通知表示 Wyświetlanie powiadomień o ładowaniu przez asystenta Buddy Nachlade Nachricht anzeigen + Mostra avviso di ricarica da parte del coppio 동료의 장전에 대한 알림 표시 Affichage de notifications lors d'une rechargement par un ami + Отображает уведомления о загрузке помощника + Mostrar notificaciones para recarga de compañero Displays notifications when an assistant loads a gunner's launcher. 助手が射手のランチャーを装填した際に通知を表示します。 Wyświetla powiadomienie, gdy asystent ładuje wyrzutnię. Zeigt Benachrichtigungen an, wenn ein Assistent den Werfer eines Richtschützen lädt. + Mostra un avviso quando un assistente sta ricaricando il proprio lanciatore. 부사수가 사수의 발사기를 장전할 때 알림을 표시합니다. Affiche une notofication lorsqu'un assistant recharge l'arme du tireur. + Отображает уведомления, когда помощник загружает пусковую установку стрелка. + Mostrar notificaciones cuando un asistente recarga el lanzador del tirador. Load launcher @@ -26,7 +32,7 @@ Załaduj wyrzutnię Charger lanceur Kilövö betöltése - Carica lanciamissili + Carica lanciatore Recarregar lançador ランチャーを装填 무기 재장전 @@ -38,17 +44,23 @@ %1 is loading your launcher %1 lädt deine Panzerabwehr %1 charge ton lanceur + %1 sta caricando il tuo lanciatore %1 がランチャーを装填しています %1 ładuje twoją wyrzutnię %1이(가) 당신의 발사기를 장전했습니다. + %1 загружает Вашу установку + %1 está cargando tu lanzador %1 stopped loading your launcher %1 hat aufgehört, deine Panzerabwehr zu laden %1 a arrêté de charger ton lanceur + %1 ha smesso di caricare il tuo lanciatore %1 がランチャーの装填を中断しました %1 przestał ładować twoją wyrzutnię %1이(가) 당신의 발사기 장전을 멈췄습니다. + %1 прекратил загружать Вашу установку + %1 paró de cargar tu lanzador Loading launcher... @@ -59,7 +71,7 @@ Nabíjím odpalovač... Ładowanie wyrzutni... Kilövő betöltés alatt... - Caricando il lanciamissili... + Caricando il lanciatore... Recarregando lançador... ランチャーを装填中・・・ 무기 재장전 중... @@ -76,7 +88,7 @@ Odpalovač nabit Wyrzutnia załadowana Kilövő betöltve - Lanciamissili caricato + Lanciatore caricato Lançador Carregado ランチャーの装填完了 무기 재장전됨 @@ -93,7 +105,7 @@ Nabít %1 Załadowano %1 %1 betöltése - Caricato %1 + Carica %1 Recarregar %1 %1 を装填します %1 장전 @@ -104,17 +116,24 @@ Launcher could not be loaded Panzerabwehr konnte nicht geladen werden + Impossibile caricare il lanciatore Le lanceur n'a pas pu être chargé ランチャーを装填できませんでした Wyrzutnia nie mogła być załadowana 발사기를 장전할 수 없습니다. + Не удалось загрузить пусковую установку + El lanzador no ha podido ser cargado Buddy Loading Ładowanie przez Asystenta 부사수 장전 중 + Caricamento da coppio Chargement par un ami Nachladen durch Kamerad + バディローディング + Перезарядка помощником + Cargado de Compañero diff --git a/addons/repair/XEH_PREP.hpp b/addons/repair/XEH_PREP.hpp index 0bb3ccbff2..c3ed4632e5 100644 --- a/addons/repair/XEH_PREP.hpp +++ b/addons/repair/XEH_PREP.hpp @@ -26,7 +26,6 @@ PREP(getSelectionsToIgnore); PREP(getPatchWheelTime); PREP(getPostRepairDamage); PREP(getRepairItems); -PREP(getWheelHitPointsWithSelections); PREP(hasItems); PREP(isEngineer); PREP(isInRepairFacility); diff --git a/addons/repair/XEH_postInit.sqf b/addons/repair/XEH_postInit.sqf index 58bb1be6e5..2e9a9178ff 100644 --- a/addons/repair/XEH_postInit.sqf +++ b/addons/repair/XEH_postInit.sqf @@ -2,10 +2,10 @@ ["CBA_settingsInitialized", { - if !GVAR(enabled) exitWith {}; + if (!GVAR(enabled)) exitWith {}; - [QGVAR(setVehicleDamage), {_this call FUNC(setDamage)}] call CBA_fnc_addEventHandler; - [QGVAR(setVehicleHitPointDamage), {_this call FUNC(setHitPointDamage)}] call CBA_fnc_addEventHandler; + [QGVAR(setVehicleDamage), LINKFUNC(setDamage)] call CBA_fnc_addEventHandler; + [QGVAR(setVehicleHitPointDamage), LINKFUNC(setHitPointDamage)] call CBA_fnc_addEventHandler; [QGVAR(setWheelHitPointDamage), { params ["_object", "_hitPoint", "_damage"]; private _damageDisabled = !isDamageAllowed _object; diff --git a/addons/repair/XEH_preInit.sqf b/addons/repair/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/repair/XEH_preInit.sqf +++ b/addons/repair/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/repair/dev/draw_showRepairInfo.sqf b/addons/repair/dev/draw_showRepairInfo.sqf index f516e14ef9..182b2f7a08 100644 --- a/addons/repair/dev/draw_showRepairInfo.sqf +++ b/addons/repair/dev/draw_showRepairInfo.sqf @@ -4,6 +4,7 @@ #include "..\script_component.hpp" addMissionEventHandler ["Draw3D", { + if (isGamePaused) exitWith {}; if !((cursorObject isKindOf "Car") || (cursorObject isKindOf "Tank") || (cursorObject isKindOf "Air")) exitWith {}; private _config = configOf cursorObject; @@ -11,7 +12,7 @@ addMissionEventHandler ["Draw3D", { private _hitpointGroups = getArray (_config >> QGVAR(hitpointGroups)); (getAllHitPointsDamage cursorObject) params [["_hitPoints", []], ["_hitSelections", []]]; - ([cursorObject] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; + ([cursorObject] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _output = []; @@ -20,7 +21,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]; @@ -28,7 +29,7 @@ addMissionEventHandler ["Draw3D", { _info = _info + "[Wheel]"; _color = [0,1,0,1]; }; - if (!((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"])) then { + if !((getText (_config>> "HitPoints" >> _hitpoint >> "depends")) in ["", "0"]) then { _info = _info + format ["[depends: %1]", getText (_config>> "HitPoints" >> _hitpoint >> "depends")]; _color = [0,0,1,1] }; diff --git a/addons/repair/functions/fnc_addRepairActions.sqf b/addons/repair/functions/fnc_addRepairActions.sqf index 30481cdb50..3d89d8ffe1 100644 --- a/addons/repair/functions/fnc_addRepairActions.sqf +++ b/addons/repair/functions/fnc_addRepairActions.sqf @@ -37,7 +37,7 @@ if (_type == "") exitWith {}; (getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // Since 1.82 these are all lower case // get hitpoints of wheels with their selections -([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; +([_vehicle] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _hitPointsAddedNames = []; private _hitPointsAddedStrings = []; @@ -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 _indexesToIgnore) then { @@ -122,7 +122,7 @@ private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehi if ("rotor" in _hitPoint || "hull" in _hitPoint || "engine" in _hitPoint) then { _position = compile format ["_target selectionPosition ['%1', 'HitPoints', 'AveragePoint'];", _selection]; }; - + { _x params ["_hit", "_pos"]; if (_hitPoint == _hit) exitWith { diff --git a/addons/repair/functions/fnc_canRepair.sqf b/addons/repair/functions/fnc_canRepair.sqf index d8e7f3b8ee..300f46dffb 100644 --- a/addons/repair/functions/fnc_canRepair.sqf +++ b/addons/repair/functions/fnc_canRepair.sqf @@ -38,7 +38,7 @@ private _engineerRequired = if (isNumber (_config >> "requiredEngineer")) then { if !([_unit, _engineerRequired] call FUNC(isEngineer)) exitWith {false}; private _items = _config call FUNC(getRepairItems); -if (count _items > 0 && {!([_unit, _items] call FUNC(hasItems))}) exitWith {false}; +if (_items isNotEqualTo [] && {!([_unit, _items] call FUNC(hasItems))}) exitWith {false}; private _return = true; if (getText (_config >> "condition") != "") then { @@ -65,7 +65,7 @@ if (!_return) exitWith {false}; // if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; private _repairLocations = getArray (_config >> "repairLocations"); -if (!("All" in _repairLocations)) then { +if !("All" in _repairLocations) then { private _repairFacility = {([_unit] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; private _repairVeh = {([_unit] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; { diff --git a/addons/repair/functions/fnc_doRepairTrack.sqf b/addons/repair/functions/fnc_doRepairTrack.sqf index a970488268..519a3f78d6 100644 --- a/addons/repair/functions/fnc_doRepairTrack.sqf +++ b/addons/repair/functions/fnc_doRepairTrack.sqf @@ -26,7 +26,7 @@ TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_track", objNull]]; if ((isNull _track) || {!([_unit, _track, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - ERROR_1("Bad Track", _claimedObjects); + ERROR_1("Bad Track",_claimedObjects); }; // can't use a destroyed track diff --git a/addons/repair/functions/fnc_doReplaceTrack.sqf b/addons/repair/functions/fnc_doReplaceTrack.sqf index d52072b647..a512089c89 100644 --- a/addons/repair/functions/fnc_doReplaceTrack.sqf +++ b/addons/repair/functions/fnc_doReplaceTrack.sqf @@ -26,7 +26,7 @@ TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_track", objNull]]; if ((isNull _track) || {!([_unit, _track, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - ERROR_1("Bad Track", _claimedObjects); + ERROR_1("Bad Track",_claimedObjects); }; // get current hitpoint damage diff --git a/addons/repair/functions/fnc_doReplaceWheel.sqf b/addons/repair/functions/fnc_doReplaceWheel.sqf index 98c3d95cf9..7ec617127c 100644 --- a/addons/repair/functions/fnc_doReplaceWheel.sqf +++ b/addons/repair/functions/fnc_doReplaceWheel.sqf @@ -26,7 +26,7 @@ TRACE_4("params",_unit,_vehicle,_hitPoint,_claimedObjects); _claimedObjects params [["_wheel", objNull]]; if ((isNull _wheel) || {!([_unit, _wheel, ["isNotDragging", "isNotCarrying", "isNotOnLadder"]] call EFUNC(common,canInteractWith))}) exitWith { - WARNING_1("Bad Claimed Wheel", _claimedObjects); + WARNING_1("Bad Claimed Wheel",_claimedObjects); }; // get current hitpoint damage diff --git a/addons/repair/functions/fnc_getClaimObjects.sqf b/addons/repair/functions/fnc_getClaimObjects.sqf index be294d89db..ca02ef14c1 100644 --- a/addons/repair/functions/fnc_getClaimObjects.sqf +++ b/addons/repair/functions/fnc_getClaimObjects.sqf @@ -7,6 +7,7 @@ * 0: Unit that does the repairing * 1: Max range to seach from unit (meters) * 2: Array of arrays of classnames + * 3: Sort objects by damage (default: false) * * Return Value: * Array of objects, or [] if not all available @@ -17,8 +18,8 @@ * Public: Yes */ -params ["_unit", "_maxRange", "_objectsToClaim"]; -TRACE_3("params",_unit,_maxRange,_objectsToClaim); +params ["_unit", "_maxRange", "_objectsToClaim", ["_sortByDamage", false]]; +TRACE_4("params",_unit,_maxRange,_objectsToClaim,_sortByDamage); private _return = []; @@ -27,6 +28,11 @@ private _return = []; private _ableToAquire = []; //will be array of objects { private _nearObjects = _unit nearEntities [_x, _maxRange]; + if (_sortByDamage && {count _nearObjects > 1}) then { + _nearObjects = _nearObjects apply {[damage _x, _x]}; + _nearObjects sort true; + _nearObjects = _nearObjects apply {_x select 1}; + }; { if (!(_x in _ableToAquire) && {(_x getVariable [QEGVAR(common,owner), objNull]) in [objNull, _unit]}) exitWith { // skip claimed objects _ableToAquire pushBack _x diff --git a/addons/repair/functions/fnc_getHitPointString.sqf b/addons/repair/functions/fnc_getHitPointString.sqf index ec71c1840e..509a3c73a2 100644 --- a/addons/repair/functions/fnc_getHitPointString.sqf +++ b/addons/repair/functions/fnc_getHitPointString.sqf @@ -20,17 +20,9 @@ */ params ["_hitPoint", "_textLocalized", "_textDefault", ["_trackArray", []]]; +_trackArray params [["_trackNames", []], ["_trackStrings", []], ["_trackAmount", []]]; -private _track = (count _trackArray > 0); -private _trackNames = []; -private _trackStrings = []; -private _trackAmount = []; - -if (_track) then { - _trackNames = _trackArray select 0; - _trackStrings = _trackArray select 1; - _trackAmount = _trackArray select 2; -}; +private _track = _trackArray isNotEqualTo []; // Prepare first part of the string from stringtable //IGNORE_STRING_WARNING(str_ace_repair_hit); @@ -40,7 +32,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 @@ -86,7 +78,7 @@ for "_i" from 0 to (count _hitPoint) do { // Don't display part name if no string is found in stringtable if (_text == LSTRING(Hit)) then { - if (_hitPoint != "") then { LOG_1("Hitpoint [%1] - could not be localized", _hitPoint); }; + if (_hitPoint != "") then { LOG_1("Hitpoint [%1] - could not be localized",_hitPoint); }; _text = _textDefault; }; diff --git a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf index 8258798b39..f87691843e 100644 --- a/addons/repair/functions/fnc_getSelectionsToIgnore.sqf +++ b/addons/repair/functions/fnc_getSelectionsToIgnore.sqf @@ -39,7 +39,7 @@ private _turretPaths = ((fullCrew [_vehicle, "gunner", true]) + (fullCrew [_vehi (getAllHitPointsDamage _vehicle) params [["_hitPoints", []], ["_hitSelections", []]]; // get hitpoints of wheels with their selections -([_vehicle] call FUNC(getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; +([_vehicle] call EFUNC(common,getWheelHitPointsWithSelections)) params ["_wheelHitPoints", "_wheelHitSelections"]; private _indexesToIgnore = []; private _processedSelections = []; @@ -48,7 +48,7 @@ private _complexDependsMap = createHashMap; { 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 @@ -56,7 +56,7 @@ private _complexDependsMap = createHashMap; continue }; - if (_isWheelOrTrack && {_selection in _processedSelections || {_selection isEqualTo ""}}) then { + if (_isWheelOrTrack && {_selection in _processedSelections || {_selection isEqualTo ""}}) then { TRACE_3("Skipping duplicate Wheel/Track or empty selection",_hitPoint,_forEachIndex,_selection); _indexesToIgnore pushBack _forEachIndex; _processedSelections pushBack _selection; @@ -121,7 +121,7 @@ private _complexDependsMap = createHashMap; continue }; - if (!(getText (_vehCfg >> "HitPoints" >> _hitPoint >> "depends") in ["", "0"])) then { + if !(getText (_vehCfg >> "HitPoints" >> _hitPoint >> "depends") in ["", "0"]) then { // Caches depends hitpoints and their parents private _parentHitPoint = getText (_vehCfg >> "HitPoints" >> _hitPoint >> "depends"); private _parentHitPointIndex = _hitPoints findIf {_x == _parentHitPoint}; @@ -129,7 +129,7 @@ private _complexDependsMap = createHashMap; if (_parentHitPointIndex != -1) then { _dependsIndexMap set [_forEachIndex, _parentHitPointIndex]; TRACE_3("Depends hitpoint and parent index",_hitPoint,_forEachIndex,_parentHitPoint); - } else { + } else { // Multiple/Complex parents or broken parents _indexesToIgnore pushBack _forEachIndex; private _parentHitPoints = _parentHitPoint splitString "+*() "; @@ -162,7 +162,7 @@ private _complexDependsMap = createHashMap; continue }; - if (ANY_OF(_hitPointGroups, ANY_OF(_x select 1, _x == _hitPoint))) then { + if (ANY_OF(_hitpointGroups,ANY_OF(_x select 1,_x == _hitpoint))) then { TRACE_3("Skipping child hitpoint",_hitPoint,_forEachIndex,_selection); _indexesToIgnore pushBack _forEachIndex; _processedSelections pushBack _selection; diff --git a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf b/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf deleted file mode 100644 index 347c3878d7..0000000000 --- a/addons/repair/functions/fnc_getWheelHitPointsWithSelections.sqf +++ /dev/null @@ -1,97 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: commy2 - * Returns the wheel hitpoints and their selections. - * - * Arguments: - * 0: Vehicle - * - * Return Value: - * 0: Wheel hitpoints - * 1: Wheel hitpoint selections in model coordinates - * - * Example: - * [car1] call ace_repair_fnc_getWheelHitPointsWithSelections - * - * Public: No - */ - -params ["_vehicle"]; -TRACE_1("params",_vehicle); - -// get the vehicles wheel config -private _wheels = configOf _vehicle >> "Wheels"; - -// exit with nothing if the vehicle has no wheels class -if !(isClass _wheels) exitWith {TRACE_1("No Wheels",_wheels); [[],[]]}; - -// get all hitpoints and selections -(getAllHitPointsDamage _vehicle) params ["_hitPoints", "_hitPointSelections"]; - -// get all wheels and read selections from config -_wheels = "true" configClasses _wheels; - -private _wheelHitPoints = []; -private _wheelHitPointSelections = []; - -{ - private _wheelName = configName _x; - private _wheelCenter = getText (_x >> "center"); - private _wheelBone = getText (_x >> "boneName"); - private _wheelBoneNameResized = _wheelBone select [0, 9]; //ount "wheel_X_Y"; // this is a requirement for physx. Should work for all addon vehicles. - - TRACE_4("",_wheelName,_wheelCenter,_wheelBone,_wheelBoneNameResized); - - private _wheelHitPoint = ""; - private _wheelHitPointSelection = ""; - - //Commy's orginal method - { - if ((_wheelBoneNameResized != "") && {_x find _wheelBoneNameResized == 0}) exitWith { // same as above. Requirement for physx. - _wheelHitPoint = _hitPoints select _forEachIndex; - _wheelHitPointSelection = _hitPointSelections select _forEachIndex; - TRACE_2("wheel found [Orginal]",_wheelName,_wheelHitPoint); - }; - } forEach _hitPointSelections; - - - if (_vehicle isKindOf "Car") then { - //Backup method, search for the closest hitpoint to the wheel's center selection pos. - //Ref #2742 - RHS's HMMWV - if (_wheelHitPoint == "") then { - private _wheelCenterPos = _vehicle selectionPosition _wheelCenter; - if (_wheelCenterPos isEqualTo [0,0,0]) exitWith {TRACE_1("no center?",_wheelCenter);}; - - - private _bestDist = 99; - private _bestIndex = -1; - { - if (_x != "") then { - //Filter out things that definitly aren't wheeels (#3759) - if ((toLower (_hitPoints select _forEachIndex)) in ["hitengine", "hitfuel", "hitbody"]) exitWith {TRACE_1("filter",_x)}; - private _xPos = _vehicle selectionPosition _x; - if (_xPos isEqualTo [0,0,0]) exitWith {}; - private _xDist = _wheelCenterPos distance _xPos; - if (_xDist < _bestDist) then { - _bestIndex = _forEachIndex; - _bestDist = _xDist; - }; - }; - } forEach _hitPointSelections; - - TRACE_2("closestPoint",_bestDist,_bestIndex); - if (_bestIndex != -1) then { - _wheelHitPoint = _hitPoints select _bestIndex; - _wheelHitPointSelection = _hitPointSelections select _bestIndex; - TRACE_2("wheel found [Backup]",_wheelName,_wheelHitPoint); - }; - }; - }; - - if ((_wheelHitPoint != "") && {_wheelHitPointSelection != ""}) then { - _wheelHitPoints pushBack _wheelHitPoint; - _wheelHitPointSelections pushBack _wheelHitPointSelection; - }; -} forEach _wheels; - -[_wheelHitPoints, _wheelHitPointSelections] diff --git a/addons/repair/functions/fnc_isEngineer.sqf b/addons/repair/functions/fnc_isEngineer.sqf index 2a013bccda..2962e4f8ad 100644 --- a/addons/repair/functions/fnc_isEngineer.sqf +++ b/addons/repair/functions/fnc_isEngineer.sqf @@ -22,7 +22,7 @@ private _class = _unit getVariable ["ACE_IsEngineer", _unit getUnitTrait "engine // This if statement is here for copmatability with the common variant of isEngineer, which requires a bool. // We cannot move this function to common because we require the GVAR(engineerSetting_Repair), which only makes sense to include in the repair module. -if (_class isEqualType false) then {_class = [0, 1] select _class}; +if (_class isEqualType false) then {_class = parseNumber _class}; TRACE_3("isEngineer",_unit,_engineerN,_class); if (_class >= _engineerN) exitWith {true}; diff --git a/addons/repair/functions/fnc_isInRepairFacility.sqf b/addons/repair/functions/fnc_isInRepairFacility.sqf index 7ea8ace60f..51cc5424bb 100644 --- a/addons/repair/functions/fnc_isInRepairFacility.sqf +++ b/addons/repair/functions/fnc_isInRepairFacility.sqf @@ -34,7 +34,7 @@ private _checkObject = { private _fnc_check = { private _position = _unit modelToWorldVisual [0, 0, eyePos _unit select 2]; - CHECK_OBJECTS(lineIntersectsWith [ARR_3(_position, _position vectorAdd [ARR_3(0, 0, 10)], _unit)]) + CHECK_OBJECTS(lineIntersectsWith [ARR_3(_position,_position vectorAdd [ARR_3(0,0,10)],_unit)]) || {CHECK_OBJECTS(_unit nearObjects 7.5)} }; diff --git a/addons/repair/functions/fnc_moduleAddSpareParts.sqf b/addons/repair/functions/fnc_moduleAddSpareParts.sqf index bccccdcc22..cb6da371d7 100644 --- a/addons/repair/functions/fnc_moduleAddSpareParts.sqf +++ b/addons/repair/functions/fnc_moduleAddSpareParts.sqf @@ -30,8 +30,7 @@ if (!isNull _logic) then { // Add synchronized objects to list { _list pushBack _x; - nil - } count (synchronizedObjects _logic); + } forEach (synchronizedObjects _logic); if (_list isEqualTo []) exitWith {}; @@ -40,6 +39,5 @@ if (!isNull _logic) then { // Add spare parts { [_x, _amount, _part, true] call FUNC(addSpareParts); - false - } count _list; + } forEach _list; }; diff --git a/addons/repair/functions/fnc_normalizeHitPoints.sqf b/addons/repair/functions/fnc_normalizeHitPoints.sqf index 360b46697d..b6bb67a1ba 100644 --- a/addons/repair/functions/fnc_normalizeHitPoints.sqf +++ b/addons/repair/functions/fnc_normalizeHitPoints.sqf @@ -19,7 +19,7 @@ params ["_vehicle"]; TRACE_2("params",_vehicle,typeOf _vehicle); // Can't execute all commands if the vehicle isn't local, exit if that's so -if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1", _vehicle);}; +if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1",_vehicle);}; ([_vehicle] call FUNC(getSelectionsToIgnore)) params ["", "_dependsIndexMap", "_complexDependsMap"]; diff --git a/addons/repair/functions/fnc_repair.sqf b/addons/repair/functions/fnc_repair.sqf index e4d3bfa0ac..6d1da338a0 100644 --- a/addons/repair/functions/fnc_repair.sqf +++ b/addons/repair/functions/fnc_repair.sqf @@ -44,7 +44,7 @@ if ((isEngineOn _target) && {!GVAR(autoShutOffEngineWhenStartingRepair)}) exitWi }; private _items = _config call FUNC(getRepairItems); -if (count _items > 0 && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; +if (_items isNotEqualTo [] && {!([_caller, _items] call FUNC(hasItems))}) exitWith {false}; private _return = true; if (getText (_config >> "condition") != "") then { @@ -70,7 +70,7 @@ if (!_return) exitWith {false}; // if (_vehicleStateCondition == 1 && {!([_target] call FUNC(isInStableCondition))}) exitWith {false}; private _repairLocations = getArray (_config >> "repairLocations"); -if (!("All" in _repairLocations)) then { +if !("All" in _repairLocations) then { private _repairFacility = {([_caller] call FUNC(isInRepairFacility)) || ([_target] call FUNC(isInRepairFacility))}; private _repairVeh = {([_caller] call FUNC(isNearRepairVehicle)) || ([_target] call FUNC(isNearRepairVehicle))}; { @@ -95,7 +95,7 @@ if (!("All" in _repairLocations)) then { private _requiredObjects = getArray (_config >> "claimObjects"); private _claimObjectsAvailable = []; if (_requiredObjects isNotEqualTo []) then { - _claimObjectsAvailable = [_caller, 5, _requiredObjects] call FUNC(getClaimObjects); + _claimObjectsAvailable = [_caller, 5, _requiredObjects, true] call FUNC(getClaimObjects); if (_claimObjectsAvailable isEqualTo []) then { TRACE_2("Missing Required Objects",_requiredObjects,_claimObjectsAvailable); _return = false @@ -149,10 +149,15 @@ if (_callbackProgress == "") then { // Player Animation private _callerAnim = [getText (_config >> "animationCaller"), getText (_config >> "animationCallerProne")] select (stance _caller == "PRONE"); private _loopAnim = (getNumber (_config >> "loopAnimation")) isEqualTo 1; -_caller setVariable [QGVAR(selectedWeaponOnrepair), currentWeapon _caller]; + +private _currentWeapon = currentWeapon _caller; + +if (_currentWeapon != "") then { + _caller setVariable [QGVAR(selectedWeaponOnrepair), (weaponState _caller) select [0, 3]]; +}; // Cannot use secondairy weapon for animation -if (currentWeapon _caller == secondaryWeapon _caller) then { +if (_currentWeapon == secondaryWeapon _caller) then { _caller selectWeapon (primaryWeapon _caller); }; @@ -172,7 +177,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_repair_failure.sqf b/addons/repair/functions/fnc_repair_failure.sqf index d6ef515b28..f2ae9d742d 100644 --- a/addons/repair/functions/fnc_repair_failure.sqf +++ b/addons/repair/functions/fnc_repair_failure.sqf @@ -38,9 +38,11 @@ if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) th _caller setVariable [QGVAR(repairCurrentAnimCaller), nil]; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; -private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); -if (_weaponSelect != "") then { +private _weaponSelect = _caller getVariable QGVAR(selectedWeaponOnrepair); + +if (!isNil "_weaponSelect") then { _caller selectWeapon _weaponSelect; + _caller setVariable [QGVAR(selectedWeaponOnrepair), nil]; } else { _caller action ["SwitchWeapon", _caller, _caller, 299]; }; @@ -65,7 +67,7 @@ if (isNil _callback) then { } else { _callback = missionNamespace getVariable _callback; }; -if (!(_callback isEqualType {})) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; +if !(_callback isEqualType {}) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; _args call _callback; diff --git a/addons/repair/functions/fnc_repair_success.sqf b/addons/repair/functions/fnc_repair_success.sqf index 182845d1b6..d893fe4739 100644 --- a/addons/repair/functions/fnc_repair_success.sqf +++ b/addons/repair/functions/fnc_repair_success.sqf @@ -38,9 +38,11 @@ if (vehicle _caller == _caller && {!(_caller call EFUNC(common,isSwimming))}) th _caller setVariable [QGVAR(repairCurrentAnimCaller), nil]; _caller setVariable [QGVAR(repairPrevAnimCaller), nil]; -private _weaponSelect = (_caller getVariable [QGVAR(selectedWeaponOnrepair), ""]); -if (_weaponSelect != "") then { +private _weaponSelect = _caller getVariable QGVAR(selectedWeaponOnrepair); + +if (!isNil "_weaponSelect") then { _caller selectWeapon _weaponSelect; + _caller setVariable [QGVAR(selectedWeaponOnrepair), nil]; } else { _caller action ["SwitchWeapon", _caller, _caller, 299]; }; @@ -60,7 +62,7 @@ if (isNil _callback) then { } else { _callback = missionNamespace getVariable _callback; }; -if (!(_callback isEqualType {})) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; +if !(_callback isEqualType {}) then {_callback = {TRACE_1("callback was NOT code",_callback)};}; _args call _callback; diff --git a/addons/repair/functions/fnc_setHitPointDamage.sqf b/addons/repair/functions/fnc_setHitPointDamage.sqf index 04bc6f14ff..bd1c2d7775 100644 --- a/addons/repair/functions/fnc_setHitPointDamage.sqf +++ b/addons/repair/functions/fnc_setHitPointDamage.sqf @@ -23,7 +23,7 @@ params ["_vehicle", "_hitPointIndex", "_hitPointDamage", ["_useEffects", false]] TRACE_4("params",_vehicle,typeOf _vehicle,_hitPointIndex,_hitPointDamage); // can't execute all commands if the vehicle isn't local. exit here. -if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1", _vehicle);}; +if !(local _vehicle) exitWith {ERROR_1("Vehicle Not Local %1",_vehicle);}; // get all hitpoints and selections and damages (getAllHitPointsDamage _vehicle) params ["", ["_hitSelections", []], ["_damageValues", []]]; diff --git a/addons/repair/initSettings.sqf b/addons/repair/initSettings.inc.sqf similarity index 85% rename from addons/repair/initSettings.sqf rename to addons/repair/initSettings.inc.sqf index 26d502e757..e39bb93a76 100644 --- a/addons/repair/initSettings.sqf +++ b/addons/repair/initSettings.inc.sqf @@ -8,16 +8,14 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; true, true, {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ QGVAR(displayTextOnRepair), "CHECKBOX", [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], _category, - true, // default value - false, // isGlobal - {[QGVAR(displayTextOnRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // default value ] call CBA_fnc_addSetting; [ @@ -25,8 +23,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_Repair_name), LSTRING(engineerSetting_Repair_description)], _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],1], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_repair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -34,8 +31,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_Wheel_name), LSTRING(engineerSetting_Wheel_description)], _category, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_wheel), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -69,8 +65,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(repairDamageThreshold_name), LSTRING(repairDamageThreshold_description)], _category, [0, 1, 0.6, 1, true], - true, // isGlobal - {[QGVAR(repairDamageThreshold), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -78,8 +73,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(repairDamageThreshold_Engineer_name), LSTRING(repairDamageThreshold_Engineer_description)], _category, [0, 1, 0.4, 1, true], - true, // isGlobal - {[QGVAR(repairDamageThreshold_engineer), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -87,8 +81,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(consumeItem_ToolKit_name), LSTRING(consumeItem_ToolKit_description)], _category, [[0,1],[ELSTRING(common,No), ELSTRING(common,Yes)],0], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(consumeItem_toolKit), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -105,8 +98,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(fullRepairLocation), LSTRING(fullRepairLocation_description)], _catFullRepair, [[0,1,2,3,4],[LSTRING(useAnywhere), LSTRING(repairVehicleOnly), LSTRING(repairFacilityOnly), LSTRING(vehicleAndFacility), ELSTRING(common,Disabled)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(fullRepairLocation), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -114,8 +106,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(engineerSetting_fullRepair_name), LSTRING(engineerSetting_fullRepair_description)], _catFullRepair, [[0,1,2],[LSTRING(engineerSetting_anyone), LSTRING(engineerSetting_EngineerOnly), LSTRING(engineerSetting_AdvancedOnly)],2], // [values, titles, defaultIndex] - true, // isGlobal - {[QGVAR(engineerSetting_fullRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ @@ -168,8 +159,7 @@ private _catFullRepair = [_category, LLSTRING(fullRepair)]; [LSTRING(autoShutOffEngineWhenStartingRepair_name), LSTRING(autoShutOffEngineWhenStartingRepair_description)], _category, false, // default value - true, // isGlobal - {[QGVAR(autoShutOffEngineWhenStartingRepair), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/repair/stringtable.xml b/addons/repair/stringtable.xml index 44e01ddc1e..6f16e91e09 100644 --- a/addons/repair/stringtable.xml +++ b/addons/repair/stringtable.xml @@ -41,8 +41,10 @@ Rueda タイヤ Koło + Ruota 바퀴 Roue + Колесо Change Wheel @@ -272,24 +274,31 @@ Full Repair Time Coefficient - 完全修理時間係数 + 完全修理所要時間係数 Współczynnik Czasu Pełnej Naprawy Vollständiger Reparaturzeitkoeffizient + Coefficiente di riparazione completa 전체 수리 시간 계수 Coefficient du temps de réparation complète + Коэф. времени полного ремонта + Coeficiente de Tiempo de Reparación Completa 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. - 完全修復にかかる時間を変更します。\n修理時間は、通常アクセスできない部品も含め、各部品に必要な修理量に基づいて決定されます。 + 完全修復に掛かる時間を変更します。\n修理所要時間は、通常アクセスできない部品も含め、各部品に必要な修理量に基づいて決定されます。 + Determina la durata di una riparazione completa.\nIl tempo richiesto si basa sul numero di riparazioni necessarie, include quelle su componenti normalmente inaccessibili. Modyfikuje czas potrzebny do wykonania Pełnej Naprawy. Czas naprawy jest oparty na ilości napraw potrzebnych dla każdej części, w tym tych normalnie niedostępnych. Ä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Время ремонта зависит от объема ремонтных работ, необходимых для каждой детали, включая те, которые обычно недоступны. + Modifica cuánto tiempo lleva realizar una Reparación Completa.\nEl tiempo de reparación está basado en la cantidad de reparaciones necesarias para cada parte, incluyendo aquellas que normalmente no son accesibles. Boost engineer training when in repair vehicles or facilities. Untrained becomes engineer, engineer becomes advanced engineer. Améliore les compétences en ingénierie des unités en fonction du lieu où elles se trouvent ; notamment dans les véhicules de réparation ou les ateliers.\nUn soldat non formé devient ingénieur, un ingénieur devient ingénieur avancé. 修理車両か施設内では工兵能力を上昇させます。兵士は工兵になり、工兵は上級工兵になります。 + Aumenta la formazione di Geniere se in veicoli o strutture di riparazioni. Se non addestrato diventa Geniere, se ingegnere diventa Geniere avanzato. Повысьте подготовку инженеров при ремонте транспортных средств или объектов. Нетренированный становится инженером, инженер становится продвинутым инженером. Steigert die Ausbildung von Pionieren, wenn Sie sich in Reparaturfahrzeugen oder -einrichtungen befinden. Aus Ungelerntem wird Pionier, aus Pionier wird ein fortgeschrittener Pionier. Zwiększ wyszkolenie inżynierów w pojazdach i budynkach naprawczych. Niewyszkoleni zostają inżynierami, inżynierowie zostają zaawansowanymi inżynierami. @@ -307,7 +316,7 @@ Lugares de reparación completa Luoghi Riparazione Completa Endroits pour réparation complète - 完全修理できる場所 + 完全修理可能な場所 완전수리 구역 完整维修地点 完整維修地點 @@ -384,9 +393,9 @@ ¿Añadir repuestos para vehículos (requiere componente de carga)? Добавлять запасные части в технику (требуется модуль Грузоперевозок)? Přidat náhradní díly do vozidla (vyžaduje úložný prostor)? - Aggiungi parti di ricambio ai veicoli (richiede componente Cargo)? + Aggiungi parti di ricambio ai veicoli (richiede spazio nel carico)? Ajoute des pièces de rechange aux véhicules (nécessite le système de cargaison). - 車両へ予備部品を追加しますか? (カーゴ コンポーネントが必要) + 車両へ予備部品を追加しますか? (貨物室が必要) 차량에 예비 부품을 더합니까?(짐칸 요소 필요) 添加载具备件(需相关货物组件)? 添加載具備件 (需相關貨物組件)? @@ -512,7 +521,7 @@ Частично отремонтировано часть Parcialmente reparada parte Díl částečně opraveno - Parte parzialmente riparato + Parte parzialmente riparata Pièce partiellement réparé(e). 部品 を部分的に修理しました 부품 부분적으로 수리됨 @@ -577,7 +586,7 @@ Scafo Test Корпус - 機体 + 構造体 선체 车壳 車殼 @@ -588,15 +597,15 @@ Léger Claro - Chiaro + Luci Light Светлый Hell Světlá Claro - 밝은 + 조명 轻型 - + 照明 Işık @@ -626,7 +635,7 @@ Stabilizzatore Orizzontale Sinistro Stabilisateur horizontal gauche Linkes Höhenleitwerk - 左側の水平安定機 + 左側水平安定装置 왼쪽 수평안정판 左侧悬挂稳定 左側懸掛穩定 @@ -642,7 +651,7 @@ Stabilizzatore Orizzontale Destro Stabilisateur horizontal droit Rechtes Höhenleitwerk - 右側の水平安定機 + 右側水平安定装置 오른쪽 수평안정판 右侧悬挂稳定 右側懸掛穩定 @@ -658,7 +667,7 @@ Stabilizzatore Verticale Stabilisateur vertical Seitenleitwerk - 車両スタビライザ + 垂直安定装置 수직 안정판 垂直稳定 垂直穩定 @@ -705,7 +714,7 @@ Engrenagem Rueda Podvozek - Motore + Carrello Trains d'atterrissage ギア 기어 @@ -771,7 +780,7 @@ Statický port Porta Statica Système pitot-statique - スタティック ポート + 静圧管 정압공 静态端口 靜態端口 @@ -834,10 +843,10 @@ Dowódca Wieżyczka Velitel Věž Comandante Torre - Comandante Torretta + Torretta Comandante Parancsnok Lövegtorony Башня командира - 車長の砲塔 + 車長砲塔 지휘관 포탑 指挥官 炮塔 指揮官 砲塔 @@ -851,10 +860,10 @@ Dowódca Działo Velitel Kanón Comandante Canhão - Comandante Cannone + Cannone Comandante Parancsnok Ágyú Пушка командира - 車長の砲 + 車長砲 지휘관 포 指挥官 枪 指揮官 槍 @@ -887,7 +896,7 @@ Cingolo sinistro Bal lánctalp Левую гусеницу - 左の履帯 + 左履帯 왼쪽 궤도 左履带 左履帶 @@ -903,7 +912,7 @@ Cingolo destro Jobb lánctalp Правую гусеницу - 右の履帯 + 右履帯 오른쪽 궤도 右履带 右履帶 @@ -919,7 +928,7 @@ Ruota frontale sinistra Bal első kerék Левое переднее колесо - 左の前輪 + 左前輪 왼쪽 앞바퀴 左前轮 左前輪 @@ -935,7 +944,7 @@ Ruota frontale destra Jobb első kerék Правое переднее колесо - 右の前輪 + 右前輪 오른쪽 앞바퀴 右前轮 右前輪 @@ -951,7 +960,7 @@ Seconda ruota frontale sinistra Második bal első kerék Второе переднее левое колесо - 左の 2 つめの前輪 + 左第二前輪 왼쪽 두번째 바퀴 第二左前轮 第二左前輪 @@ -967,7 +976,7 @@ Seconda ruota frontale destra Második jobb hátsó kerék Второе правое переднее колесо - 右の 2 つめの前輪 + 右第二前輪 오른쪽 두번째 바퀴 第二右前轮 第二右前輪 @@ -983,7 +992,7 @@ Ruota centrale sinistra Bal középső kerék Левое среднее колесо - 左の中央の前輪 + 左中央輪 왼쪽 가운데 바퀴 左中轮 左中輪 @@ -999,7 +1008,7 @@ Ruota centrale destra Jobb középső kerék Правое среднее колесо - 右の中央の前輪 + 右中央輪 오른족 가운데 바퀴 右中轮 右中輪 @@ -1015,7 +1024,7 @@ Ruota posteriore sinistra Bal hátsó kerék Левое заднее колесо - 左の後輪 + 左後輪 왼쪽 뒤쪽 바퀴 左后轮 左後輪 @@ -1031,7 +1040,7 @@ Ruota posteriore destra Jobb hátsó kerék Правое заднее колесо - 右の後輪 + 右後輪 오른쪽 뒤쪽 바퀴 右后轮 右後輪 @@ -1063,7 +1072,7 @@ Rotore principale Főrotor Несущий винт - 主翼 + メインローター 주 로터 主旋翼 主旋翼 @@ -1080,7 +1089,7 @@ Rotore di coda Farokrotor Рулевой винт - テイル ローター + テールローター 꼬리 로터 尾桨 尾槳 @@ -1157,7 +1166,7 @@ ERA ERA ERA - ERA + Corrazza Reattiva Reaktivpanzerung ERA Blindage réactif @@ -1176,7 +1185,7 @@ Ремонт Ajustes de reparación Nastavení oprav - Impostazioni Riparazioni + Impostazioni di Riparazione Paramètres des réparations 修理設定 수리 설정 @@ -1193,7 +1202,7 @@ Poskytuje rozsáhlý systém oprav pro všechny typy vozidel. Fornisce un sistema di riparazione per tutti i tipi di veicoli. Fournit un système de réparation pour tous les types de véhicules. - 全種類の車両に修理システムを適用しますか? + あらゆる車種に対応した修理システムを提供します。 모든 차량에 대해 수리 시스템을 제공합니다. 提供修复系统给所有载具 提供修復系統給所有載具 @@ -1249,11 +1258,13 @@ Allow Wheel Replacement Erlaube Radwechsel + Permetti sostituzione ruote Wymiana kół Разрешить замену колес タイヤ交換の許可 바퀴 교체 허용 Autoriser le remplacement des roues + Permitir Recambio de Rueda Who can remove and replace wheels? @@ -1273,18 +1284,24 @@ Allow Wheel Patching Erlaube Radflicken + Permetti di toppare le ruote タイヤ補修を許可 Zezwól na Łatanie Kół 바퀴 수리 허용 Autoriser le rafistolage des roues + Разрешить починить колесо + Permitir Parcheo de Rueda Who can patch wheels? Wer kann Radflicken durchführen? + Chi può rattoppare ruote 誰がタイヤの補修を出来るようにしますか? Kto może łatać koła? 누가 바퀴를 수리할 수 있습니까? Qui peut rafistoler les roues ? + Кто может починить колеса? + Quién puede parchear ruedas? Allow Repair @@ -1339,9 +1356,9 @@ Какой максимальный урон можно починить с помощью ремкомплекта? ¿Cuál es el daño máximo que puede ser reparado con una caja de herramientas? Jaké maximální poškození může být opraveno pomocí opravárenské sady? - Qual'è il danno massimo che può essere riparato con il Toolkit? + Qual'è il danno massimo che può essere riparato con il Kit Utensili?\n0% significa che tutti i danni possono essere riparati. Définit la quantité maximale de dégâts pouvant être réparés avec une trousse à outils. - ツールキットで修理できる、最大の損傷許容範囲を設定しますか? + ツールキットを使用して修復できるパーツの最大ダメージ。\n0% はすべてのダメージを修復できることを意味します。 어느정도의 피해까지 도구모음으로 수리가 가능합니까? 工具包可以修复的最大损坏值? 工具包可以修復的最大損壞值? @@ -1369,9 +1386,9 @@ Какой максимальный урон может починить инженер? ¿Cuál es el daño máximo que puede ser reparado por un ingeniero? Jaké maximální poškození může být opraveno pomoci inženýra? - Qual'è il danno massimo che può essere riparato da un Geniere? + Qual'è il danno massimo che può essere riparato da un Geniere?\n0% significa che tutti i danni possono essere riparati. Définit la quantité maximale de dégâts qu'un ingénieur peut réparer. - 工兵が修理できる、最大の損傷許容範囲を設定しますか? + 修理に必要な最小レベルを超える工兵が修復できるパーツの最大ダメージ。\n0% は、すべてのダメージを修復できることを意味します。 정비공은 어느정도의 피해까지 수리할 수 있습니까? 工兵可以修复的最大损坏值? 工兵可以修復的最大損壞值? @@ -1384,9 +1401,9 @@ Удалять ремкомплект после использования Eliminar conjunto de herramientas al usarlo Odstranit sadu nástrojů po použití - Rimuovi Toolkit dopo l'uso + Consuma Kit Utensili dopo l'uso Retirer la trousse à outils après usage - ツールキットを使うと削除 + ツールキットを使用後に削除 도구모음 사용 후 제거 使用后删除工具包 使用後刪除工具包 @@ -1399,9 +1416,9 @@ Следует ли удалять ремкомплект после использования? ¿Deben retirarse las herramientas al usarlas? Má být odstraněna sada nástroju po použití? - Il Toolkit dev'essere rimosso dopo l'uso? + Il Kit Utensili viene consumato e rimosso dopo l'uso? Définit si la trousse à outils doit être retirée après usage. - ツールキットを使うと削除しますか? + ツールキットを使用時に消費しますか? 도구모음을 사용하면 제거를 합니까? 要在使用后删除工具包吗? 要在使用後刪除工具包嗎? @@ -1459,7 +1476,7 @@ Только у ремонтного транспорта или ремонтных сооружений Reparar en instalación o vehículo Opravárenské zařízení nebo vozidlo - Strutture Riparazioni o Veicoli + Strutture o Veicoli di Riparazioni Ateliers ou véhicules de réparation 修理施設または車両のみ 수리 시설혹은 차량 @@ -1504,9 +1521,9 @@ Список имен юнитов, которые будут классифицированы как инженеры, разделенный запятыми. Lista de los nombres de las unidades que serán clasificados como ingeniero, separados por comas. Seznam jmen jednotek, které budou klasifikovány jako inženýr, oddělit čárkami. - Lista di unità che verranno classificate come genieri, separate da virgole. + Lista di nomi di unità che verranno classificate come genieri, separate da virgole. Liste d'unités qui seront classées comme ingénieurs, séparées par des virgules. - 一覧に記載されたユニット名を、工兵として指定します。コンマで複数を指定できます。 + 工兵に指定されるユニットのリスト。カンマで区切ります。 목록 내 보직이름은 정비공으로 분류됩니다. 쉼표로 구분합니다. 工兵名单,把单位名称输入在这边即可定义其为工兵。每个单位使用逗号以做区隔。 工兵名單,把單位名稱輸入在這邊即可定義其為工兵。每個單位使用逗號以做區隔。 @@ -1519,9 +1536,9 @@ Это инженер Es un ingeniero Inženýr - E' Geniere + È Geniere Qualification technique - 工兵とする + 工兵にする 은 정비공이다 是工兵 是工兵 @@ -1534,9 +1551,9 @@ Укажите уровень инженерного мастерства для юнита Selecciona el nivel de conocimientos de ingeniería de la unidad Vyberte úroveň dovednosti inženýra pro jednotku - Seleziona il livello di abilità geniere dell'unità + Seleziona il livello di formazione da geniere dell'unità Choix du niveau de compétence technique de l'unité. - ユニットへの工兵スキルを選択 + ユニットの工兵スキルのレベルを定義します。 선택한 인원의 정비 실력을 고르십시요 选择工兵的技术水平 選擇工兵的技術水平 @@ -1577,7 +1594,7 @@ Adv. Engineer Instandsetzer - Adv. Geniere + Geniere Av. 上級工兵 高级工兵 專精 @@ -1600,7 +1617,7 @@ Přiřaďte jednu nebo více osob jako inženýra Assegna una o più unità come genieri Assigne une ou plusieurs unités en tant qu'ingénieur. - 修理車両として指定 + 単体、または複数のユニットを工兵として割り当てます 하나 혹은 여러 인원을 정비공으로 등록합니다 指定一个或多个单位为工兵 指定一個或多個單位為工兵 @@ -1615,7 +1632,7 @@ Přiřaďte opraváresnké vozidlo Assegna Veicolo Riparazioni Affecter véhicule(s) de réparation - 修理車両として指定 + 修理車両に割り当て 정비 차량 등록 指定维修载具 指定維修載具 @@ -1645,7 +1662,7 @@ Seznam vozidel, která budou klasifikována jako opravárenská, oddělit čárkami. Lista di Veicoli che verranno considerati veicoli riparazioni, separati da virgole. Liste de véhicules qui seront classés comme véhicules de réparation, séparés par des virgules. - 一覧に記載されたユニット名を、修理車両として指定します。コンマで複数を指定できます。 + 修理車両に割り当てる車両のリスト。カンマで区切ります。 목록내 차량은 정비 차량으로 분류됩니다. 쉼표로 구분합니다. 载具名单,把载具名称输入在这边即可定义其为维修载具。每个载具使用逗号以做区隔。 載具名單,把載具名稱輸入在這邊即可定義其為維修載具。每個載具使用逗號以做區隔。 @@ -1658,7 +1675,7 @@ Это ремонтный транспорт Es un vehículo de reparación Opravárenské vozidlo - E' Veicolo Riparazioni + È Veicolo Riparazioni Est un véhicule de réparation 修理車両とする 은 정비 차량이다 @@ -1675,7 +1692,7 @@ Je vozidlo klasifikováno jako opravárenské? Il veicolo è classificato dome veicolo riparazioni? Définit s'il s'agit d'un véhicule de réparation. - 車両を修理車両と指定しますか? + 車両を修理車両として割り当てます 이 차량을 정비 차량으로 분류합니까? 此载具是维修载具吗? 此載具是維修載具嗎? @@ -1690,7 +1707,7 @@ Přiřaďte jedno nebo více vozidel jako opravárenské vozidlo Assegna uno o più veicoli come veicoli riparazioni Affecte un ou plusieurs véhicules en tant que véhicule de réparation - 単体、または複数の車両を修理車両とします + 単体、または複数の車両を修理車両として割り当てます 하나 혹은 여러 차량을 정비 차량으로 등록합니다 指定一个或多个载具作为维修载具 指定一個或多個載具作為維修載具 @@ -1705,7 +1722,7 @@ Přiřaďte opravárenské zařízení Assegna Struttura Riparazioni Affecter atelier(s) de réparation - 修理施設とする + 修理施設に割り当て 정비 시설 등록 指定维修设施 指定維修設施 @@ -1733,9 +1750,9 @@ Список объектов, которые будут классифицированы как ремонтные, разделенный запятыми. Lista de los objetos que se clasifican como instalaciones para la reparación, separados por comas. Seznam objektů, které budou klasifikovány jako opravárenské zařízení, oddělit čárkami. - Lista di oggetti che verranno classificati come strutture riparazioni, separate da virgole. + Lista di oggetti che verranno classificati come strutture riparazioni, separati da virgole. Liste d'objets qui seront classés comme ateliers de réparation, séparés par des virgules. - 一覧に記載されたユニット名を、修理施設として指定します。コンマで複数を指定できます。 + 修理施設に割り当てるオブジェクトのリスト。カンマで区切ります。 목록내 시설은 정비 시설으로 분류됩니다. 쉼표로 구분합니다. 设施名单,把设施名称输入在这边即可定义其为维修设施。每个设施使用逗号以做区隔。 設施名單,把設施名稱輸入在這邊即可定義其為維修設施。每個設施使用逗號以做區隔。 @@ -1748,7 +1765,7 @@ Это ремонтное сооружение Es una instalación de reparación Opravárenské zařízení - E' Struttura Riparazioni + È Struttura Riparazioni Est un atelier de réparation 修理施設とする 은 정비 시설이다 @@ -1765,7 +1782,7 @@ Je objekt klasifikován jako opravárenské zařízení? L'oggetto è classificato come struttura riparazioni? Définit l'objet comme étant un atelier de réparation. - オブジェクトを修理施設として指定しますか? + オブジェクトを修理施設として割り当てます 이 시설을 정비 시설로 분류합니까? 此设施是维修设施吗? 此設施是維修設施嗎? @@ -1780,7 +1797,7 @@ Přiřaďte jeden nebo více objektů jako opravárenské zařízení Assegna uno o più oggetti come strutture riparazioni Assigne un ou plusieurs objets en tant qu'atelier de réparation. - ひとつ、または複数オブジェクトに予備部品を追加 + 単体、または複数のオブジェクトを修理施設として割り当てます 하나 혹은 여러 시설을 정비 시설로 등록합니다 指定一个或多个物体作为维修设施 指定一個或多個對象作為維修設施 @@ -1810,7 +1827,7 @@ Přidat náhradní díly do jednoho nebo více objektů Aggiungi parti di ricambio ad uno o più oggetti Ajoute des pièces de rechange à un ou plusieurs objets. - 一覧に追加されたオブジェクトへ予備部品を与えます。コンマで複数を指定できます。 + 単体、または複数のオブジェクトに予備部品の追加を割り当てます 하나 혹은 여러 물체가 예비 부품을 더합니다 添加备件到一个或多个物体上 添加備件到一個或多個對象上 @@ -1839,9 +1856,9 @@ Lista de los objetos que tendrán repuestos añadidos, separados por comas. Список транспортных средств, в которые будут добавляться запчасти, разделенный запятыми. Seznam objektů, které dostanou náhradní díly, oddělit čárkami. - Lista di oggetti a cui verranno aggiunte parti di ricambio, separate da virgole. + Lista di oggetti a cui verranno aggiunte parti di ricambio, separati da virgole. Liste d'objets dans lesquels des pièces de rechange seront ajoutées, séparés par des virgules. - 一覧に追加されたオブジェクトへ予備部品を与えます。コンマで複数を指定できます。 + 予備部品が追加されるオブジェクトのリスト。カンマで区切ります。 목록내 물체는 예비 부품을 받습니다, 쉼표로 구분합니다. 添加备件到名单的载具上。每个载具使用逗号以做区隔。 添加備件到名單的載具上。每個載具使用逗號以做區隔。 @@ -1886,7 +1903,7 @@ Množství Quantità Quantité - + 数量 수량 数量 數量 @@ -1901,7 +1918,7 @@ Počet vybraných náhradních dílů. Numero di parti di ricambio selezionate. Nombre de pièces de rechange séléctionnées. - 選択された予備部品の数を選択します。 + 選択された予備部品の数量を選択します。 선택한 부품의 수 选择的备件数量 選擇的備件數量 @@ -1914,7 +1931,7 @@ Для ремонта колес требуется Requerimentos para reparo de rodas Vyžaduje opravu kol - Requisiti riparazione ruote + Requisiti sostituzione ruote Exigences pour réparation des roues タイヤ修理の要求 바퀴 교체 요구사항 @@ -1929,9 +1946,9 @@ Предметы, которые требуются для снятия/замены колес Itens requeridos para remover/trocar rodas Položka vyžaduje odstraněná/vyměněná kola - Oggetti richiesti per riparare/rimuovere ruote + Oggetti richiesti per rimuovere/sostituire ruote Outils nécessaires pour le démontage ou le remplacement des roues. - タイヤの除去と交換にアイテムを必要としますか? + タイヤの除去と交換にアイテムを必要とします。 바퀴를 제거/교체하는데 필요한 물건을 정합니다. 需要特定物品来移除/更换车轮 需要特定物品來移除/更換車輪 @@ -1939,23 +1956,29 @@ Wheel Patch Requirements Bedingungen für die Radflicken + Requisiti per rattoppare ruote タイヤ補修の要求 Wymagania do Łatania Koła 바퀴 수리 아이템 필요 Exigences pour rafistoler une roue + Требования для починки колеса + Requerimientos de Parcheo de Ruedas Items required to patch a wheel. Gegenstänge, die zum Reifenflicken benötigt werden. - タイヤ補修にアイテムを必要としますか? + Oggetti richiesti per rattoppare ruote. + タイヤ補修にアイテムを必要とします。 Przedmioty wymagane do załatania koła 바퀴를 수리하기 위해 아이템이 필요합니다. Equipements requis pour rafistoler une roue. + Предметы, необходимые для починки колеса. + Objetos requeridos para parchear una rueda. Misc Repair Requirements Sonstige Reparaturbedingungen - 部分修理条件 + 部分修理の条件 額外修理條件 部分全面维修条件 Exigences pour réparations diverses @@ -1970,7 +1993,7 @@ Items required to repair a specific vehicle component or remove/replace tracks. Gegenstände die benötigt werden, um eine spezifische Fahrzeugkomponente oder eine Kette zu entfernen/auszutauschen. - 車両の特定コンポーネントか履帯の除去/交換にアイテムを必要とします。 + 車両の特定コンポーネントの修理や履帯の除去/交換にアイテムを必要とします。 是否需要物品來修復一些特別載具部位或者移除/替換履帶 维修特定车辆部件或拆除/更换轨道所需的物品。 Outils nécessaires pour la réparation d'un équipement spécifique du véhicule, et pour le démontage ou le remplacement des chenilles. @@ -1978,14 +2001,14 @@ Przedmioty wymagane do naprawy określonego elementu pojazdu lub usunięcia/wymiany gąsienicy. Items necessários para reparar uma peça específica ou remover/substituir lagarta. Objetos necesarios para reparar un componente específico del vehículo o quitar/reemplazar las orugas. - Elementi necessari per riparare un componente specifico del veicolo o per rimuovere/sostituire i cingoli + Oggetti necessari per riparare un componente specifico del veicolo o per rimuovere/sostituire i cingoli Предметы, необходимые для ремонта отдельных компонентов или снятия/замены гусеницы. 차량의 궤도나 부품을 제거/교체할 때 필요한 아이템을 정합니다. Full Repair Requirements Bedingungen für vollständige Reparatur - 完全修理条件 + 完全修理の条件 完整修復條件 全面维修条件 Exigences pour réparations complètes @@ -2008,7 +2031,7 @@ Przedmioty wymagane do przeprowadzenia pełnej naprawy pojazdu. Itens requeridos para realizar um reparo veicular completo. Objetos requeridos para una reparación completa - Elementi necessari per eseguire una riparazione completa del veicolo. + Oggetti necessari per eseguire una riparazione completa del veicolo. Предметы, необходимые для полного ремонта техники. 차량 완전 수리 시 필요한 아이템을 정합니다. @@ -2020,7 +2043,7 @@ O motor deve estar desligado para manutenção Le moteur doit être arrêté pour la réparation. Двигатель должен быть выключен для ремонта - 修理のためにエンジンを停止させる必要があります。 + 修理するにはエンジンを停止する必要があります Silnik musi być wyłączony w celu naprawy 수리를 위해서는 엔진을 꺼야만 합니다 Il motore deve essere spento per poter riparare @@ -2045,8 +2068,8 @@ Number of spare tracks in cargo. Anzahl der Ersatzketten im Laderaum. - カーゴ内にある予備履帯の数を指定します。 - Numero dei cingoli di scorta nel cargo. + 貨物室内の予備履帯の数を指定 + Numero dei cingoli di scorta nel carico. 設定載具在貨艙內攜帶的備用履帶數量 设定载具在货舱内携带的备用履带数量。 Liczba zapasowych gąsienic w ładunku. @@ -2075,7 +2098,7 @@ Number of spare wheels in cargo. Anzahl der Ersatzreifen im Laderaum. - カーゴ内にある予備タイヤの数を指定します。 + 貨物室内の予備タイヤの数を指定 Numero delle ruote di scorta nel cargo. 設定載具在貨艙內攜帶的備用輪胎數量 设定载具在货舱内携带的备用轮胎数量。 @@ -2090,10 +2113,10 @@ Auto shut off engine on repair Motor automatisch ausschalten - 修理時にエンジン自動停止 + 修理時にエンジンを自動停止 维修时自动关闭发动机 維修時自動關閉引擎 - Motore spento automaticamente durante la riparazione + Spegnimento automatico motore durante riparazioni Automatycznie wyłącz silnik podczas napraw Автоотключение двигателя при ремонте Desligar motor automaticamente enquanto reparar @@ -2105,7 +2128,7 @@ Automatically shut off the engine when doing repairs. Schaltet den Motor automatisch aus, sobald das Fahrzeug repariert wird. - 修理時にエンジンを自動で停止します。 + 修理時は自動的にエンジンを停止します。 修理时自动关闭发动机。 維修時自動關閉引擎 Spegne automaticamente il motore quando si fanno riparazioni. @@ -2119,115 +2142,157 @@ Part Repair Time - 部分修理時間 + 部分修理所要時間 Czas Naprawy Części + Durata di riparazione componente Teilreparaturzeit 부품 수리 시간 Temps de réparation des pièces + Время ремонта детали + Tiempo de Reparación de Pieza Time in seconds to complete a repair. - 修理完了までの時間 + 修理完了までの所要時間 (秒単位) Czas w sekundach do przeprowadzenia naprawy + Tempo in secondi richiesto per completare una riparazione. Zeit in Sekunden, um eine Reparatur abzuschließen. 수리를 완료하는 시간(초 단위) Durée en secondes pour terminer une réparation. + Время завершения ремонта в секундах. + Tiempo en segundos para completar una reparación. Wheel Change Time - タイヤ交換時間 + タイヤ交換所要時間 Czas Zmiany Koła + Durata di sostituzione ruote Radwechselzeit 바퀴 교체 시간 Temps de changement d'une roue + Время замены колеса + Tiempo de Cambio de Rueda Time in seconds to remove or change a wheel. - タイヤの取り外しまたは交換にかかる時間。 + タイヤの取り外しまたは交換に掛かる時間。 (秒単位) Czas w sekundach do zdjęcia lub zmienienia koła. + Tempo in secondi richiesto per rimuovere o sostituire una ruota. Zeit in Sekunden, um ein Rad zu entfernen oder zu wechseln. 바퀴를 제거하거나 교체하는 데 걸리는 시간(초 단위) Durée en seconde pour enlever ou changer une roue. + Время в секундах на снятие или замену колеса. + Tiempo en segundos para quitar o cambiar una rueda. Patch Wheel Rad flicken + Rattoppa ruota タイヤを補修する Załataj Koło 바퀴 수리 Rafistoler la roue + Чинить колесо + Parchear Rueda Patching Wheel... Rad flicken... + Rattoppando ruota... タイヤを補修しています・・・ Łatanie Koła... 바퀴 수리 중... Rafistolage de la roue... + Починка колеса... + Parcheando Rueda... Wheel Patch Time - タイヤ補修時間 + タイヤ補修所要時間 Czas Łatania Koła + Durata di rattoppamento ruote Zeit um Räder zu flicken 바퀴 수리 시간 Temps de rafistolage d'une roue + Время починки полеса + Tiempo de Parcheo de Rueda Time it takes to patch a wheel by 5%. - タイヤを5%補修するのにかかる時間。 + タイヤを5%補修するのに掛かる時間。 Czas potrzebny na załatanie koła o 5%. + Tempo richiesto per ridurre i danni di una ruota del 5%. Zeit, die benötigt wird, um ein Rad um 5 % zu flicken. 바퀴를 5% 수리하는 데 걸리는 시간(초 단위) Durée pour rafistoler une roue de 5%. + Время, необходимое для починки колеса, сокращается на 5%. + Tiempo que lleva parchear una rueda por cada 5%. Patch Wheel Threshold タイヤ補修しきい値 Próg Łatania Koła + Limite rattoppamento ruota Rad flicken Schwellenwert 바퀴 수리 한계점 Seuil de rafistolage d'une roue + Порог починки колеса + Umbral de Parcheo de Rueda - Maximum level to which a wheel can be patched. - タイヤを補修できる最大の度合い。 - Maksymalny poziom, do którego koło może zostać załatane. - Maximales Level, bis zu dem ein Rad geflickt werden kann. + 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.\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. + Максимальный уровень, до которого колесо может быть починено. + Máximo daño que permite a una rueda ser parcheada.\n0% significa que todo el daño puede ser reparado. Wheel Patch Location - タイヤ補修場所 + タイヤ補修可能な場所 Miejsce Łatania Koła + Luoghi rattoppamento ruote Räder Flick Ort 바퀴 수리 장소 Lieu de rafistolage des roues + Место починки колеса + Localización para el Parcheo de Rueda 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. + Где колесо можно починить. + Dónde puede ser parcheada la rueda. On the ground Auf dem Boden 地上 + Per terra Na ziemi 지면 위 Sur le terrain + На земле + En el suelo On a vehicle An einem Fahrzeug + Su un veicolo 車両上 Na pojeździe 차량 Sur un véhicule + На транспорте + En un vehículo diff --git a/addons/respawn/XEH_postInit.sqf b/addons/respawn/XEH_postInit.sqf index 6c1b1e9961..502f5f729f 100644 --- a/addons/respawn/XEH_postInit.sqf +++ b/addons/respawn/XEH_postInit.sqf @@ -1,7 +1,7 @@ // by commy2 #include "script_component.hpp" -["ace_rallypointMoved", FUNC(updateRallypoint)] call CBA_fnc_addEventHandler; -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; // hide enemy rallypoint markers +["ace_rallypointMoved", LINKFUNC(updateRallypoint)] call CBA_fnc_addEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; // hide enemy rallypoint markers -[QGVAR(showFriendlyFireMessageEvent), FUNC(showFriendlyFireMessage)] call CBA_fnc_addEventHandler; +[QGVAR(showFriendlyFireMessageEvent), LINKFUNC(showFriendlyFireMessage)] call CBA_fnc_addEventHandler; diff --git a/addons/respawn/XEH_preInit.sqf b/addons/respawn/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/respawn/XEH_preInit.sqf +++ b/addons/respawn/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/respawn/functions/fnc_handleKilled.sqf b/addons/respawn/functions/fnc_handleKilled.sqf index 1383561f2c..eeca8f96e5 100644 --- a/addons/respawn/functions/fnc_handleKilled.sqf +++ b/addons/respawn/functions/fnc_handleKilled.sqf @@ -21,7 +21,7 @@ params ["_unit"]; // Saves the gear when the player! (and only him) is killed if (ACE_player == _unit && {GVAR(SavePreDeathGear)}) then { _unit setVariable [QGVAR(unitGear), [_unit] call CBA_fnc_getLoadout]; - _unit setVariable [QGVAR(activeWeaponAndMuzzle), [currentWeapon _unit, currentMuzzle _unit, currentWeaponMode _unit]]; + _unit setVariable [QGVAR(activeWeaponAndMuzzle), (weaponState _unit) select [0, 3]]; [QGVAR(saveGear), _unit] call CBA_fnc_localEvent; }; diff --git a/addons/respawn/functions/fnc_handlePlayerChanged.sqf b/addons/respawn/functions/fnc_handlePlayerChanged.sqf index f94e14d644..9514966541 100644 --- a/addons/respawn/functions/fnc_handlePlayerChanged.sqf +++ b/addons/respawn/functions/fnc_handlePlayerChanged.sqf @@ -19,9 +19,9 @@ params ["_newUnit"]; private _side = side group _newUnit; -((GETMVAR(ACE_Rallypoint_West, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == west)); -((GETMVAR(ACE_Rallypoint_West_Base, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == west)); -((GETMVAR(ACE_Rallypoint_East, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == east)); -((GETMVAR(ACE_Rallypoint_East_Base, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == east)); -((GETMVAR(ACE_Rallypoint_Independent, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == independent)); -((GETMVAR(ACE_Rallypoint_Independent_Base, objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal ([0, 1] select (_side == independent)); +((GETMVAR(ACE_Rallypoint_West,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == west)); +((GETMVAR(ACE_Rallypoint_West_Base,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == west)); +((GETMVAR(ACE_Rallypoint_East,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == east)); +((GETMVAR(ACE_Rallypoint_East_Base,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == east)); +((GETMVAR(ACE_Rallypoint_Independent,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == independent)); +((GETMVAR(ACE_Rallypoint_Independent_Base,objNull)) getVariable [QGVAR(marker), ""]) setMarkerAlphaLocal (parseNumber (_side == independent)); diff --git a/addons/respawn/functions/fnc_initRallypoint.sqf b/addons/respawn/functions/fnc_initRallypoint.sqf index 50931a87f4..7e4651e1e9 100644 --- a/addons/respawn/functions/fnc_initRallypoint.sqf +++ b/addons/respawn/functions/fnc_initRallypoint.sqf @@ -53,7 +53,7 @@ if (hasInterface) then { private _type = ["selector_selectedFriendly", "selector_selectedEnemy"] select (_respawnMarker == ""); _marker setMarkerTypeLocal _type; - _marker setMarkerAlphaLocal ([0,1] select (_side == playerSide)); // playerSide to guarantee init + _marker setMarkerAlphaLocal (parseNumber (_side == playerSide)); // playerSide to guarantee init private _date = _rallypoint getVariable [QGVAR(markerDate), ""]; diff --git a/addons/respawn/functions/fnc_moduleRallypoint.sqf b/addons/respawn/functions/fnc_moduleRallypoint.sqf index 0af3357201..31ba68f1d6 100644 --- a/addons/respawn/functions/fnc_moduleRallypoint.sqf +++ b/addons/respawn/functions/fnc_moduleRallypoint.sqf @@ -23,7 +23,6 @@ if !(_activated) exitWith {}; { _x setVariable ["ACE_canMoveRallypoint", true]; - false -} count _units; +} forEach _units; INFO("Rallypoint Module Initialized."); diff --git a/addons/respawn/functions/fnc_restoreGear.sqf b/addons/respawn/functions/fnc_restoreGear.sqf index e0823fe6e0..34c5918383 100644 --- a/addons/respawn/functions/fnc_restoreGear.sqf +++ b/addons/respawn/functions/fnc_restoreGear.sqf @@ -5,7 +5,8 @@ * * Arguments: * 0: Unit - * 1: All Gear based on return value of ACE_common_fnc_getAllGear + * 1: All Gear based on return value of ace_common_fnc_getAllGear + * 2: All weapon info needed for restoring previous weapon status * * Return Value: * None @@ -17,38 +18,14 @@ */ params ["_unit", "_allGear", "_activeWeaponAndMuzzle"]; -TRACE_3("restoreGear",_unit, count _allGear, _activeWeaponAndMuzzle); +TRACE_3("restoreGear",_unit,count _allGear,_activeWeaponAndMuzzle); -// restore all gear +// Restore all gear if (!isNil "_allGear") then { [_unit, _allGear] call CBA_fnc_setLoadout; }; -// restore the last active weapon, muzzle and weaponMode +// Restore the last active weapon, muzzle and weapon mode if (!isNil "_activeWeaponAndMuzzle") then { - // @todo, replace this with CBA_fnc_selectWeapon after next CBA update - _activeWeaponAndMuzzle params ["_activeWeapon", "_activeMuzzle", "_activeWeaponMode"]; - - if ( - (_activeMuzzle != "") && - {_activeMuzzle != _activeWeapon} && - {_activeMuzzle in getArray (configFile >> "CfgWeapons" >> _activeWeapon >> "muzzles")} - ) then { - _unit selectWeapon _activeMuzzle; - } else { - if (_activeWeapon != "") then { - _unit selectWeapon _activeWeapon; - }; - }; - - if (currentWeapon _unit != "") then { - private _index = 0; - - while { - _index < 299 && {currentWeaponMode _unit != _activeWeaponMode} - } do { - _unit action ["SwitchWeapon", _unit, _unit, _index]; - _index = _index + 1; - }; - }; + _unit selectWeapon _activeWeaponAndMuzzle; }; diff --git a/addons/respawn/initSettings.sqf b/addons/respawn/initSettings.inc.sqf similarity index 100% rename from addons/respawn/initSettings.sqf rename to addons/respawn/initSettings.inc.sqf diff --git a/addons/respawn/stringtable.xml b/addons/respawn/stringtable.xml index 66bd2336bd..1de77a45d3 100644 --- a/addons/respawn/stringtable.xml +++ b/addons/respawn/stringtable.xml @@ -28,7 +28,7 @@ Kihelyezés 5 másodperc múlva... Dispiegamento in 5 secondi... Será posicionado em 5 segundos... - 設置まであと 5 秒・・・ + 5秒後に設置が完了します・・・ 5초 후 재투입... 5秒后完成部署... 5秒後完成佈署... @@ -59,7 +59,7 @@ Téléportation à la base Teletransportar para a Base Bázisra teleportálás - Teleporta alla base + Teleporta in base ベースへ移動 기지로 순간이동 传送至基地 @@ -122,11 +122,11 @@ Точка сбора Синих (База) Punkt zbiórki Zachodu (Baza) Point de ralliement OUEST (Base) - Rallypoint West (Base) + Rallypoint Ovest (Base) Gyülekezőpont, Nyugat (Bázis) Bod shromáždění Západ (Základna) Ponto de encontro Oeste (Base) - ラリーポイント 同盟軍 (ベース) + ラリーポイント BLUFOR軍 (ベース) 蓝方集合点(基地) 藍方集合點 (基地) 청군 집결지 (기지) @@ -138,7 +138,7 @@ Точка сбора Красных (База) Punkt zbiórki Wschodu (Baza) Point de ralliement EST (Base) - Rallypoint East (Base) + Rallypoint Est (Base) Gyülekezőpont, Kelet (Bázis) Bod shromáždění Východ (Základna) Ponto de encontro Leste (Base) @@ -154,11 +154,11 @@ Точка сбора Независимых (База) Punkt zbiórki Ruchu oporu (Baza) Point de ralliement Indépendant (Base) - Rallypoint Independent (Base) + Rallypoint Indipendenti (Base) Gyülekezőpont, Független (Bázis) Bod shromáždění Nezávislý (Základna) Ponto de encontro Independente (Base) - ラリーポイント 独立軍 (ベース) + ラリーポイント INDEPENDENT軍 (ベース) 独立方集合点(基地) 獨立方集合點 (基地) 무소속군 집결지 (기지) @@ -170,11 +170,11 @@ Точка сбора Синих Punkt zbiórki Zachodu Point de ralliement OUEST - Rallypoint West + Rallypoint Ovest Gyülekezőpont, Nyugat Bod shromáždění Západ Ponto de encontro Oeste - ラリーポイント 同盟軍 + ラリーポイント BLUFOR軍 蓝方集合点 藍方集合點 청군 집결지 @@ -186,7 +186,7 @@ Точка сбора Красных Punkt zbiórki Wschodu Point de ralliement EST - Rallypoint East + Rallypoint Est Gyülekezőpont, Kelet Bod shromáždění Východ Ponto de encontro Leste @@ -202,11 +202,11 @@ Точка сбора Независимых Punkt zbiórki Ruchu oporu Point de ralliement Indépendant - Rallypoint Independent + Rallypoint Indipendenti Gyülekezőpont, Független Bod shromáždění Nezávislý Ponto de encontro Independente - ラリーポイント 独立軍 + ラリーポイント INDEPENDENT軍 独立方集合点 獨立方集合點 무소속군 집결지 @@ -222,7 +222,7 @@ Respawn-rendszer Возрождение Sistema Respawn - リスポン システム + リスポーン システム 재투입 시스템 重生系统 重生系統 @@ -288,7 +288,7 @@ Játékosi testek eltávolítása távozás után? Удалять трупы игроков после дисконнекта? Rimuovi i corpi dei giocatori quando si disconnettono? - 切断後はプレイヤーの死体を削除するかどうかを設定できます。 + 切断したプレイヤーの死体を削除するかどうかを設定できます。 접속이 끊긴 플레이어의 시체를 제거합니까? 要删除已离线的玩家尸体吗? 要刪除已離線的玩家屍體嗎? @@ -319,7 +319,7 @@ Ce module vous permet de configurer les fonctionnalités ACE spécifiques à la réapparition des joueurs. Questo modulo ti permette di configurare le funzionalità ACE specifiche dei respawn. Este módulo permite configurar parámetros relacionados con la reaparición - 有効化するとリスポンへ ACE 機能を設定できます。 + このモジュールを使用すると、リスポーンに ACE 固有の機能を設定できます。 이 모듈은 ACE 재투입의 자세한 설정을 변경할 수 있게 해줍니다. 该模块使您可以设定 ACE 的重生功能 該模塊使您可以設定ACE的重生功能 @@ -335,7 +335,7 @@ Baráti tűz üzenetek Сообщения об огне по своим Messaggi Fuoco Amico - 友軍誤射の表示 + フレンドリーファイア通知 아군 오인사격 메시지 友军误击信息 友軍誤擊訊息 @@ -350,7 +350,7 @@ L'utilisation de ce module fait en sorte qu'à chaque joueur mort par un tir ami, un rapport sera affiché dans le chat, indiquant qui a tué qui. Usando questo modulo nella tua missione farà in modo che ogni uccisione per fuoco amico venga mostrata in forma di messaggio in chat. El usar este módulo, todas las muertes por fuego amigo serán indicadas en el chat. - もし友軍誤射による死者が出た場合は、チャットにてその旨を表示します。 + ミッションでこのモジュールを使用すると、誤射による友軍キルがチャット上のメッセージとして表示されるようになります。 이 모듈은 미션 중 아군 오인사격으로 인한 사망자 발생 시 채팅창에 메시지를 표시해줍니다. 摆放此模块后,当有发生友军误击致死的事件,会显示提示信息在聊天视窗中。 擺放此模塊後,當有發生友軍誤擊致死的事件,會顯示提示訊息在聊天視窗中 @@ -365,7 +365,7 @@ Système de points de ralliement Gyülekezőpont-rendszer Система точек сбора - Sistema Punto di Raccolta + Sistema Rallypoint ラリーポイント システム 집결지 시스템 集合点系统 @@ -378,11 +378,11 @@ Tento modul umožňuje určit místo shromaždiště, kam se mohou jednokty rychle teleportovat ze "základny". Toto vyžaduje vhodné objekty v mapě - základna a vlajka. Oba dva můžete najít v kategorii Prázdné -> ACE Oživení. Este módulo permite que você aplique em uma missão "pontos de encontro", que pode rapidamente se teletransportar para a "base". Ele requer colocar objetos apropriados no mapa - base e bandeiras. Ambos estão disponíveis na categoria em branco -> ACE Revival. Этот модуль позволяет вам указать место сбора, куда вы можете быстро телепортироваться с "базы". Требуется наличие соответствующих объектов на карте - базы и флага. Они могут быть найдены в категории Пусто -> ACE Возрождения. - Questo modulo ti consente di usare Punti di Raccolta in missione, a cui ti puoi teleportare rapidamente dalla bandiera in base. Richiede il piazzamento di oggetti speciali in mappa - base e bandiera. Entrambi disponibili nella categoria Vuoto -> Respawn ACE + Questo modulo ti consente di usare Rallypoint in missione, a cui ti puoi teleportare rapidamente dalla bandiera in base. Richiede il piazzamento di oggetti speciali in mappa - base e bandiera. Entrambi disponibili nella categoria Vuoto -> ACE Riapparizione Este módulo permite usar puntos de reunión en la misión, a los que pueden teletransportarse las unidades desde la bandera de base. Requiere colocar objetos especiales en el mapa: las banderas de base y de reunión, ambas disponibles en la categoría Vacio-> Reaparición ACE Ce module vous permet d'utiliser des points de ralliement dans les missions, vers lesquels vous pouvez vous téléporter rapidement depuis le drapeau de la base.\nNécessite de placer des objets spéciaux sur la carte - base et drapeau, tous deux disponibles dans la catégorie "Vide -> ACE Réapparition". - ミッションでベースから素早く移動できるラリーポイントを使えるようにします。ゲーム内に専用オブジェクトとなるベースとフラッグを設置している必要があります。両オブジェクトは Empty 下の ACE リスポンから設置できます。 - 이 모듈은 미션 중에 기지 깃발에서 집결지로 빠르게 텔레포트 시켜주는 역할을 합니다. 지도 상에 기지 및 깃발이 필요합니다. 두 가지 모두 Empty->ACE Respawn 카테고리에서 찾을 수 있습니다. + このモジュールを使用すると、ミッションでラリーポイントを使用できるようになります。ラリーポイントには、ベース旗からすばやくテレポートできます。マップ上に特別なラリー/ベース旗オブジェクトを配置する必要があります。両オブジェクトは道具カテゴリ下の看板サブカテゴリ内、旗から設置できます。 + 이 모듈은 미션 중에 기지 깃발에서 집결지로 빠르게 텔레포트 시켜주는 역할을 합니다. 지도 상에 기지 및 깃발이 필요합니다. 두 가지 모두 비어 있음->ACE 재투입 카테고리에서 찾을 수 있습니다. 摆放此模块后,你将能在任务中部署集合点,使你可以快速往返基地与前线。要使用本功能,请记得放上空物体->ACE 重生里面的基地与旗帜。 擺放此模塊後,你將能在任務中佈署集合點,使你可以快速往返基地與前線。要使用本功能,請記得放上空物件->ACE 重生裡面的基地與旗幟 @@ -396,7 +396,7 @@ Déplacer le point de ralliement Gyülekezőpont mozgatása Двигать точку сбора - Sposta Punto di Raccolta + Sposta Rallypoint ラリーポイントを移動 집결지 이동 移动集合点 @@ -412,8 +412,8 @@ ACE Réapparition ACE Respawn ACE Возрождение - Rigenerazione ACE - ACE リスポン + ACE Riapparizione + ACE リスポーン ACE 재투입 ACE 重生 ACE 重生 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/safemode/functions/fnc_unlockSafety.sqf b/addons/safemode/functions/fnc_unlockSafety.sqf index 8afc6802c1..10372f1a2e 100644 --- a/addons/safemode/functions/fnc_unlockSafety.sqf +++ b/addons/safemode/functions/fnc_unlockSafety.sqf @@ -56,8 +56,7 @@ if (inputAction "nextWeapon" > 0) then { if (_x == "this") then { _modes pushBack _weapon; }; - nil - } count getArray (configFile >> "CfgWeapons" >> _weapon >> "modes"); + } forEach getArray (configFile >> "CfgWeapons" >> _weapon >> "modes"); // select last mode private _mode = _modes select (count _modes - 1); diff --git a/addons/sandbag/XEH_postInit.sqf b/addons/sandbag/XEH_postInit.sqf index a03f6076a1..24122aed8e 100644 --- a/addons/sandbag/XEH_postInit.sqf +++ b/addons/sandbag/XEH_postInit.sqf @@ -15,11 +15,11 @@ GVAR(deployDirection) = 0; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel deploy on player change. This does work when returning to lobby, but not when hard disconnecting. -["unit", {_this call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; -["loadout", {_this call FUNC(handlePlayerInventoryChanged)}] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handlePlayerInventoryChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle waking up dragged unit and falling unconscious while dragging -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; //@todo Captivity? diff --git a/addons/sandbag/functions/fnc_pickup.sqf b/addons/sandbag/functions/fnc_pickup.sqf index 7c21656ca0..2bcc418f4c 100644 --- a/addons/sandbag/functions/fnc_pickup.sqf +++ b/addons/sandbag/functions/fnc_pickup.sqf @@ -34,7 +34,7 @@ _unit setVariable [QGVAR(isUsingSandbag), true]; // Force physx update { _x setPosASL (getPosASL _x); - } count (_unit nearObjects ["ACE_SandbagObject", 5]); + } forEach (_unit nearObjects ["ACE_SandbagObject", 5]); [_unit, "ACE_Sandbag_empty"] call EFUNC(common,addToInventory); }, [_unit, _sandbag], 1.5] call CBA_fnc_waitAndExecute; diff --git a/addons/sandbag/stringtable.xml b/addons/sandbag/stringtable.xml index f9a5ac6773..d6bdab2556 100644 --- a/addons/sandbag/stringtable.xml +++ b/addons/sandbag/stringtable.xml @@ -94,10 +94,10 @@ Dejar de portar Arrêter de porter Položit - Fine Trasporto + Termina Trasporto Cipelés abbahagyása Parar de carregar - 下ろす + 降ろす 그만 옮기기 停止搬运 停止搬運 @@ -179,7 +179,7 @@ Caja de sacos de arena Caisse de sacs de sable Bedna na pytle s pískem - Contenitore Sacchi di Sabbia + Scatola Sacchi di Sabbia Homokzsákos láda Caixa de saco de areia 土のう入れ @@ -196,7 +196,7 @@ Aqui no hay arena Il n'y a pas de sable ici. Tady není písek - Qui non cè Sabbia + Qui non c'è Sabbia Itt nincs homok Aqui não tem areia ここに土はありません diff --git a/addons/scopes/XEH_postInit.sqf b/addons/scopes/XEH_postInit.sqf index 8c221a4651..997fe8d6dd 100644 --- a/addons/scopes/XEH_postInit.sqf +++ b/addons/scopes/XEH_postInit.sqf @@ -9,6 +9,9 @@ if (!hasInterface) exitWith {}; +// Add keybinds +#include "initKeybinds.inc.sqf" + GVAR(Optics) = ["", "", ""]; GVAR(Guns) = ["", "", ""]; GVAR(canAdjustElevation) = [false, false, false]; @@ -16,15 +19,17 @@ GVAR(canAdjustWindage) = [false, false, false]; GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; ["CBA_settingsInitialized", { - if (!GVAR(enabled)) exitWith {}; - if (GVAR(deduceBarometricPressureFromTerrainAltitude)) then { - GVAR(zeroReferenceBarometricPressure) = 1013.25 * (1 - (0.0065 * EGVAR(common,mapAltitude)) / 288.15) ^ 5.255754495; + // Overwrite setting if automatic pressure deduction is wanted + if (isServer && GVAR(deduceBarometricPressureFromTerrainAltitude)) then { + private _referencePressure = 1013.25 * (1 - (0.0065 * EGVAR(common,mapAltitude)) / 288.15) ^ 5.255754495; + + [QGVAR(zeroReferenceBarometricPressure), _referencePressure, 2, "server"] call CBA_settings_fnc_set; }; // Check inventory when it changes - ["loadout", FUNC(inventoryCheck), true] call CBA_fnc_addPlayerEventHandler; + ["loadout", LINKFUNC(inventoryCheck), true] call CBA_fnc_addPlayerEventHandler; // Instantly hide knobs when scoping in ["cameraView", { @@ -41,106 +46,7 @@ GVAR(scopeAdjust) = [[[0,0],0,[0,0],0], [[0,0],0,[0,0],0], [[0,0],0,[0,0],0]]; }; }] call CBA_fnc_addPlayerEventHandler; - // Add keybinds - ["ACE3 Scope Adjustment", QGVAR(AdjustUpMinor), localize LSTRING(AdjustUpMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_UP, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [false, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustDownMinor), localize LSTRING(AdjustDownMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_DOWN, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [false, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustLeftMinor), localize LSTRING(AdjustLeftMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_LEFT, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [false, true, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustRightMinor), localize LSTRING(AdjustRightMinor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_RIGHT, MINOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [false, true, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustUpMajor), localize LSTRING(AdjustUpMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_UP, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [true, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustDownMajor), localize LSTRING(AdjustDownMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, ELEVATION_DOWN, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [true, false, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustLeftMajor), localize LSTRING(AdjustLeftMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_LEFT, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [209, [true, true, false]], true] call CBA_fnc_addKeybind; - - ["ACE3 Scope Adjustment", QGVAR(AdjustRightMajor), localize LSTRING(AdjustRightMajor), { - // Conditions: canInteract - if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; - // Conditions: specific - if (!([ACE_player] call CBA_fnc_canUseWeapon)) exitWith {false}; - - [ACE_player] call FUNC(inventoryCheck); - - // Statement - [ACE_player, WINDAGE_RIGHT, MAJOR_INCREMENT] call FUNC(adjustScope); - }, {false}, [201, [true, true, false]], true] call CBA_fnc_addKeybind; - - // Register fire event handler - ["ace_firedPlayer", DFUNC(firedEH)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", DFUNC(firedEH)] call CBA_fnc_addEventHandler; - + ["ace_firedPlayer", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(firedEH)] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/scopes/XEH_preInit.sqf b/addons/scopes/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/scopes/XEH_preInit.sqf +++ b/addons/scopes/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/scopes/functions/fnc_adjustScope.sqf b/addons/scopes/functions/fnc_adjustScope.sqf index bd2d2d1da6..a760065cde 100644 --- a/addons/scopes/functions/fnc_adjustScope.sqf +++ b/addons/scopes/functions/fnc_adjustScope.sqf @@ -17,12 +17,13 @@ * Public: No */ +if (!GVAR(enabled)) exitWith {false}; + params ["_unit", "_turretAndDirection", "_majorStep"]; TRACE_3("adjustScope",_unit,_turretAndDirection,_majorStep); -if (!(_unit isKindOf "Man")) exitWith {false}; +if !(_unit isKindOf "Man") exitWith {false}; if (currentMuzzle _unit != currentWeapon _unit) exitWith {false}; -if (!GVAR(enabled)) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_adjustZero.sqf b/addons/scopes/functions/fnc_adjustZero.sqf index 1a130840ed..44e64b7674 100644 --- a/addons/scopes/functions/fnc_adjustZero.sqf +++ b/addons/scopes/functions/fnc_adjustZero.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -if (vehicle _unit != _unit) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; private _weaponClass = currentWeapon _unit; private _weaponIndex = [_unit, _weaponClass] call EFUNC(common,getWeaponIndex); diff --git a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf index 6cb53c3898..ab84db7cde 100644 --- a/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf +++ b/addons/scopes/functions/fnc_calculateZeroAngleCorrection.sqf @@ -4,24 +4,28 @@ * Calculates the zero angle correction for the new zero range based on current zero range and bore height (distance between bore- and sight axis) * * Arguments: - * 0: Zero range - * 1: Bore height - * 2: Weapon - * 3: Ammo - * 4: Magazine - * 5: Advanced Ballistics enabled? + * 0: Old Zero range + * 1: New Zero range + * 2: Bore height + * 3: Weapon + * 4: Ammo + * 5: Magazine + * 6: Advanced Ballistics enabled? * * Return Value: * zeroAngleCorrection * * Example: - * [5, 6, gun, ammo, magazine, true] call ace_scopes_fnc_calculateZeroAngleCorrection + * [5, 6, 7, gun, ammo, magazine, true] call ace_scopes_fnc_calculateZeroAngleCorrection * * Public: No */ params ["_oldZeroRange", "_newZeroRange", "_boreHeight"/*in cm*/, "_weapon", "_ammo", "_magazine", "_advancedBallistics"]; +// When FFV from vehicles currentZeroing will report 0 so just bail +if (_oldZeroRange <= 0) exitWith { 0 }; + private _airFriction = getNumber (configFile >> "CfgAmmo" >> _ammo >> "airFriction"); private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed"); private _initSpeedCoef = getNumber(configFile >> "CfgWeapons" >> _weapon >> "initSpeed"); diff --git a/addons/scopes/functions/fnc_canAdjustZero.sqf b/addons/scopes/functions/fnc_canAdjustZero.sqf index 58a8807480..1461d91d20 100644 --- a/addons/scopes/functions/fnc_canAdjustZero.sqf +++ b/addons/scopes/functions/fnc_canAdjustZero.sqf @@ -18,9 +18,9 @@ params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; -if (vehicle _unit != _unit) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; if (GVAR(simplifiedZeroing)) exitWith {false}; -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_canResetZero.sqf b/addons/scopes/functions/fnc_canResetZero.sqf index cd3f1fb4eb..92bbda1a4d 100644 --- a/addons/scopes/functions/fnc_canResetZero.sqf +++ b/addons/scopes/functions/fnc_canResetZero.sqf @@ -18,8 +18,8 @@ params ["_unit"]; if (cameraView == "GUNNER") exitWith {false}; -if (vehicle _unit != _unit) exitWith {false}; -if (!(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false])) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; +if !(missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) exitWith {false}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {false}; diff --git a/addons/scopes/functions/fnc_firedEH.sqf b/addons/scopes/functions/fnc_firedEH.sqf index 86d9848162..5ff78a44b7 100644 --- a/addons/scopes/functions/fnc_firedEH.sqf +++ b/addons/scopes/functions/fnc_firedEH.sqf @@ -16,9 +16,9 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); -if (!(_ammo isKindOf "BulletBase")) exitWith {}; +if !(_ammo isKindOf "BulletBase") exitWith {}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith {}; diff --git a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf index 001e5e8b79..d1bc3b7790 100644 --- a/addons/scopes/functions/fnc_getCurrentZeroRange.sqf +++ b/addons/scopes/functions/fnc_getCurrentZeroRange.sqf @@ -17,12 +17,12 @@ params ["_unit"]; -if (!GVAR(enabled)) exitWith { currentZeroing _unit }; +if (!GVAR(enabled)) exitWith {currentZeroing _unit}; private _weaponIndex = [_unit, currentWeapon _unit] call EFUNC(common,getWeaponIndex); if (_weaponIndex < 0) exitWith { currentZeroing _unit }; if (GVAR(simplifiedZeroing)) exitWith { - if (!(GVAR(canAdjustElevation) select _weaponIndex)) exitWith { currentZeroing _unit }; + if !(GVAR(canAdjustElevation) select _weaponIndex) exitWith {currentZeroing _unit}; private _adjustment = _unit getVariable [QGVAR(Adjustment), [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]; ((_adjustment select _weaponIndex) select 0) }; diff --git a/addons/scopes/functions/fnc_getOptics.sqf b/addons/scopes/functions/fnc_getOptics.sqf index 6be1952b6f..d419d8d7f0 100644 --- a/addons/scopes/functions/fnc_getOptics.sqf +++ b/addons/scopes/functions/fnc_getOptics.sqf @@ -21,7 +21,7 @@ params ["_unit"]; private _optics = ["", "", ""]; -if (!(_unit isKindOf "CAManBase")) exitWith {_optics}; +if !(_unit isKindOf "CAManBase") exitWith {_optics}; { if (count _x >= 2) then { diff --git a/addons/scopes/functions/fnc_resetZero.sqf b/addons/scopes/functions/fnc_resetZero.sqf index 76ee6355a8..c22df8bb0f 100644 --- a/addons/scopes/functions/fnc_resetZero.sqf +++ b/addons/scopes/functions/fnc_resetZero.sqf @@ -17,7 +17,7 @@ params ["_unit"]; -if (vehicle _unit != _unit) exitWith {false}; +if (!isNull objectParent _unit) exitWith {false}; private _weaponClass = currentWeapon _unit; private _weaponIndex = [_unit, _weaponClass] call EFUNC(common,getWeaponIndex); diff --git a/addons/scopes/initKeybinds.inc.sqf b/addons/scopes/initKeybinds.inc.sqf new file mode 100644 index 0000000000..0e8db97238 --- /dev/null +++ b/addons/scopes/initKeybinds.inc.sqf @@ -0,0 +1,95 @@ +["ACE3 Scope Adjustment", QGVAR(AdjustUpMinor), LLSTRING(AdjustUpMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, ELEVATION_UP, MINOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [201, [false, false, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustDownMinor), LLSTRING(AdjustDownMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, ELEVATION_DOWN, MINOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [209, [false, false, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustLeftMinor), LLSTRING(AdjustLeftMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, WINDAGE_LEFT, MINOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [209, [false, true, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustRightMinor), LLSTRING(AdjustRightMinor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, WINDAGE_RIGHT, MINOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [201, [false, true, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustUpMajor), LLSTRING(AdjustUpMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, ELEVATION_UP, MAJOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [201, [true, false, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustDownMajor), LLSTRING(AdjustDownMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, ELEVATION_DOWN, MAJOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [209, [true, false, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustLeftMajor), LLSTRING(AdjustLeftMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, WINDAGE_LEFT, MAJOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [209, [true, true, false]], true] call CBA_fnc_addKeybind; + +["ACE3 Scope Adjustment", QGVAR(AdjustRightMajor), LLSTRING(AdjustRightMajor), { + // Conditions: canInteract + if !([ACE_player, objNull, ["isNotInside", "isNotSwimming"]] call EFUNC(common,canInteractWith)) exitWith {false}; + // Conditions: specific + if !([ACE_player] call CBA_fnc_canUseWeapon) exitWith {false}; + + [ACE_player] call FUNC(inventoryCheck); + + // Statement + [ACE_player, WINDAGE_RIGHT, MAJOR_INCREMENT] call FUNC(adjustScope); +}, {false}, [201, [true, true, false]], true] call CBA_fnc_addKeybind; diff --git a/addons/scopes/initSettings.sqf b/addons/scopes/initSettings.inc.sqf similarity index 89% rename from addons/scopes/initSettings.sqf rename to addons/scopes/initSettings.inc.sqf index 917587be8e..40ed62cbcc 100644 --- a/addons/scopes/initSettings.sqf +++ b/addons/scopes/initSettings.inc.sqf @@ -5,7 +5,9 @@ private _category = format ["ACE %1", localize LSTRING(DisplayName)]; [LSTRING(enabled_displayName), LSTRING(enabled_description)], _category, true, - 1 + 1, + {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -69,7 +71,9 @@ private _category = format ["ACE %1", localize LSTRING(DisplayName)]; [LSTRING(deduceBarometricPressureFromTerrainAltitude_displayName), LSTRING(deduceBarometricPressureFromTerrainAltitude_description)], _category, false, - 1 + 1, + {[QGVAR(deduceBarometricPressureFromTerrainAltitude), _this] call EFUNC(common,cbaSettings_settingChanged)}, + true // Needs mission restart ] call CBA_fnc_addSetting; [ diff --git a/addons/scopes/stringtable.xml b/addons/scopes/stringtable.xml index 7c97a8ac14..9a47f657cc 100644 --- a/addons/scopes/stringtable.xml +++ b/addons/scopes/stringtable.xml @@ -24,7 +24,7 @@ ACE 조준경 영점조작 활성화 Włącz ustawienia celowników optycznych ACE Activer le réglage ACE des lunettes - Abilita Regolazione mirino ACE + Abilita Regolazione Mirino ACE 开启 ACE 瞄准镜归零调节 開啟ACE瞄準鏡歸零調節 Вкл. настройку прицелов ACE @@ -35,11 +35,11 @@ Enable adjustment turrets on high powered scopes Aktiviere Absehenverstellungen für Waffen mit Zielfernrohren - 高倍率スコープでACE スコープ調節を有効化 + 高倍率スコープでのタレット調整を有効化します 고성능 조준경 조절 나사 활성화 Włącz pokrętła regulacyjne Active les tourelles de réglage des lunettes de visée à fort grossissement. - Abilita la regolazione delle torrette nei mirini a lunga gittata + Abilita la regolazione delle manopole sui mirini a lunga gittata 开启高倍率瞄准镜归零调节 開啟高倍率瞄準鏡歸零調節 Включает регулировочные барабанчики ввода поправок на прицелах с высокой кратностью @@ -50,11 +50,11 @@ Force adjustment turrets Erzwinge Absehenverstellungen - ACE スコープ調節を有効化 + タレット調整を強制 조절 나사 강제 Wymuś użycie pokręteł regulacyjnych Forcer les tourelles de réglage - Forza la regolazione delle torrette + Forza la regolazione delle manopole 强制使用归零调节 強制使用歸零調節 Регулировка ненастроенных прицелов @@ -65,11 +65,11 @@ Force usage of adjustment turrets on high powered scopes Erzwinge Absehenverstellungen für Waffen mit Zielfernrohren - 高倍率スコープで調整の使用を強制させます + 高倍率スコープでタレット調整の使用を強制させます 고성능 조준경의 조절 나사 사용을 강제합니다 Wymuś użycie pokręteł regulacyjnych dla celowników o dużym powiększeniu Force l'utilisation des tourelles de réglage sur les lunettes de visée à fort grossissement. - Forza l'uso della regolazione nei mirini a lunga gittata + Forza l'uso delle manopole sui mirini a lunga gittata 强制为高倍率瞄准镜开启归零调节 強制為高倍率瞄準鏡開啟歸零調節 Принудительно использовать барабанчики ввода поправок для ненастроенных прицелов с высокой кратностью @@ -80,7 +80,7 @@ Correct zeroing Nullungsanpassung - ゼロイン調節 + ゼロイン規整 영점 고치기 Poprawka zerowania Corriger le zérotage @@ -95,7 +95,7 @@ Corrects the zeroing of all small arms sights Korrigiert alle Nullungen von Handfeuerwaffen - 全ての小口径用照準器のゼロインを調節します + 全ての小火器用照準器のゼロインを規整します 모든 소화기의 영점을 고칩니다 Poprawia zerowanie wszystkich celowników broni ręcznej Corrige le zérotage de tous les viseurs d'armes légères. @@ -114,7 +114,7 @@ 영점거리 덮어쓰기 Nadpisuje ustawienie dla zerowego dystansu Écraser la distance de zérotage - Sovrascrivi la distanza zero + Sovrascrivi distanza di azzeramento 覆写归零距离 覆寫歸零距離 Перезаписать дальность пристрелки @@ -125,11 +125,11 @@ Uses the 'defaultZeroRange' setting to overwrite the zero range of high power scopes Nutzt die Einstellung 'defaultZeroRange' um Zielfernrohre anzupassen - 'defaultZeroRange'設定を使う高倍率スコープのゼロイン距離を上書きします + '標準のゼロイン距離'設定を使用して、高倍率スコープのゼロイン距離を上書きします。 기존 고성능 조준경의 영점거리에 'defaultZeroRange'를 덮어씌웁니다 Używa 'defaultZeroRange' zamiast ustawionej odległości zerowania dla celowników o duzym przybliżeniu Utilise le paramètre "Distance de zérotage par défaut" pour remplacer la distance de zérotage des lunettes de visée à fort grossissement. - Usa le impostazioni di "defaultZeroRange" (Portata Zero Predefinita) per sovrascrivere la portata zero dei mirini a lunga gittata + Usa l'impostazione "defaultZeroRange" (Distanza di Azzeramento Predefinita) per sovrascrivere la distanza di azzeramento dei mirini a lunga gittata 使用'defaultZeroRange'来为高倍率瞄准镜覆写预设归零距离 使用'defaultZeroRange'來為高倍率瞄準鏡覆寫預設歸零距離 Использует настройку 'defaultZeroRange' для перенастройки дальности пристрелки прицелов с высокой кратностью @@ -144,7 +144,7 @@ 기본설정 영점거리 Domyślne zerowanie Distance de zérotage par défaut - Distanza zero predefinita + Distanza di Azzeramento Predefinita 预设归零距离 預設歸零距離 Дальность пристрелки по умолчанию @@ -155,7 +155,7 @@ High powered scopes will be zeroed at this distance Zielfernrohre werden auf diese Entfernung genullt - 高倍率スコープのゼロイン距離はこの設定になります + 高倍率スコープのゼロイン位置はこの設定になります 고성능 조준경이 정해진 수만큼 영점거리를 맞추게 됩니다. Celowniki o dużym powiększeniu będą zerowane dla tej odległości Distance de zérotage des lunettes de visée à fort grossissement. @@ -170,7 +170,7 @@ Reference temperature Bezugstemperatur - 温度の参照 + 参照温度 기준 온도 Referencyjna temperatura Température de référence @@ -200,7 +200,7 @@ Reference barometric pressure Bezugsluftdruck - 気圧の参照 + 参照気圧 기준 기압 Referencyjne ciśnienie barometryczne Pression barométrique de référence @@ -230,7 +230,7 @@ Reference humidity Bezugsluftfeuchtigkeit - 湿度の参照 + 参照湿度 기준 습도 Referencyjna wilgotność Humidité de référence @@ -260,11 +260,11 @@ Deduce pressure from altitude Abgeleiteter Luftdruck von der Höhe - 高度により圧が減少 + 高度で減圧する 고도에 맞춰 기압 설정 Ciśnienie określone na podstawie wysokości Déterminer la pression selon l'altitude - Ricava la pressione dall'altitudine + Stima la pressione dall'altitudine 高度影响大气压力 高度影響大氣壓力 Просчитать давление из высоты @@ -275,11 +275,11 @@ Deduce the barometric pressure from the terrain altitude Abgeleiteter Luftdruck der Geländeumgebung - 標高により気圧が減少されます + 地形高度の標高から気圧を減圧します 주변 고도에 맞춰 기압을 설정합니다 Określ ciśnienie barometryczne na podstawie wysokości terenu Détermine la pression barométrique en fonction de l'altitude du terrain. - Ricava la pressione barometrica dall'altitudine del terreno + Stima la pressione barometrica dall'altitudine del terreno 在不同高度上会有不同的大气压力 在不同高度上會有不同的大氣壓力 Давление определяется по высоте @@ -290,10 +290,10 @@ Use legacy UI Vorheriges UI verwenden - Usa UI precedente + Usa UI Vecchio 使用舊版介面 使用旧版界面 - 昔の UI を使用 + レガシー UI を使用 기존 UI 사용 Wykorzystaj legacy UI Использовать устаревший интерфейс @@ -305,10 +305,10 @@ Displays elevation and windage with signed numbers Anzeige der Absehenverstellungen mit vorzeichenbehafteten Zahlen - Visualizza l'elevazione e la derivazione con i numeri firmati + Visualizza Alzo e Deriva con numeri firmati 使用帶著標籤的數字顯示歸零遠近與風偏程度 使用带着标签的数字显示归零远近与风偏程度 - 印付きの数字で仰角と横風を表示 + ウィンデージとエレベーションを符号付き数字で表示します 기존의 부호가 있는 숫자로 표고와 폭을 표시합니다. Wyświetla elewację i tarcie powietrza poprzez podpisane liczby Отображает горизонтальные и вертикальные поправки с подписанными числами @@ -320,7 +320,7 @@ Simplified zeroing Vereinfachte Nullung - 簡略なゼロイン + 簡素化ゼロイン Azzeramento semplificato 단순화된 영점 조정 簡單歸零 @@ -335,7 +335,7 @@ Replicates the vanilla zeroing system for riflescopes. Repliziert das Vanilla-Zeroing-System für Zielfernrohre. - 標準で使われるライフルスコープ用のゼロイン システムを複製します。 + バニラ(ゲーム標準)のライフルスコープ用ゼロイン調整システムを再現します。 Replica il sistema di azzeramento vanilla per le ottiche. 라이플 스코프용 바닐라 영점조정 시스템을 복제합니다. 使用原版的歸零系統來取代ACE複雜的歸零模擬。 @@ -353,12 +353,12 @@ Zerowanie powoli w górę Малая поправка ВВЕРХ Ajuste menor arriba - Regola leggermente alzata in alto + Regola Alzo leggermente verso l'alto Hausse + Enyhe állítás fel Pequeno ajuste para cima Korekce nahoru (mírně) - 僅かに上へ調節 + 小さく上へ調節 위로 조절 向上微调 向上微調 @@ -369,12 +369,12 @@ Zerowanie powoli w dół Малая поправка ВНИЗ Ajuste menor abajo - Regola leggermente alzata in basso + Regola Alzo leggermente verso il basso Hausse - Enyhe állítás le Pequeno ajuste para baixo Korekce dolů (mírně) - 僅かに下へ調節 + 小さく下へ調節 아래로 조절 向下微调 向下微調 @@ -385,12 +385,12 @@ Zerowanie powoli w prawo Малая поправка ВПРАВО Ajuste menor derecha - Regola leggermente il tiro a destra + Regola Deriva leggermente a destra Dérive + Enyhe állítás jobbra Pequeno ajuste para direita Korekce doprava (mírně) - 僅かに右へ調節 + 小さく右へ調節 오른쪽으로 조절 向右微调 向右微調 @@ -401,12 +401,12 @@ Zerowanie powoli w lewo Малая поправка ВЛЕВО Ajuste menor izquierda - Regola leggermete il tiro a sinistra + Regola Deriva leggermente a sinistra Dérive - Enyhe állítás balra Pequeno ajuste para esquerda Korekce doleva (mírně) - 僅かに左へ調節 + 小さく左へ調節 왼쪽으로 조절 向左微调 向左微調 @@ -433,7 +433,7 @@ Zerowanie w dół Большая поправка ВНИЗ Ajuste mayor abajo - Regola l'alzata in basso + Regola Alzo verso il basso Hausse - - - Nagy állítás le Ajuste grande para baixo @@ -449,7 +449,7 @@ Zerowanie w prawo Большая поправка ВПРАВО Ajuste mayor derecha - Regola il tiro a destra + Regola Deriva a destra Dérive +++ Nagy állítás jobbra Ajuste grande para direita @@ -465,7 +465,7 @@ Zerowanie w lewo Большая поправка ВЛЕВО Ajuste mayor izquierda - Regola il tiro a sinistra + Regola Deriva a sinistra Dérive - - - Nagy állítás balra Ajuste grande para esquerda @@ -481,12 +481,12 @@ Ustaw wyzerowanie Установить дальность пристрелки Establecer ajuste a cero - Imposta i valori dell'azzeramento + Imposta l'azzeramento Réglage du zéro Állítások nullázása Zerar ajuste Vynulovat korekci - ゼロインを調節 + ゼロイン調節をセット 영점 초기화 设定归零 設定歸零 @@ -495,7 +495,7 @@ Reset zero adjustment Nullung zurücksetzen ゼロイン調節を初期化 - Resetta i valori dell'azzeramento + Resetta l'azzeramento 영점 조정 재설정 重設歸零 重设归零 @@ -509,11 +509,11 @@ This module adds windage and elevation adjustment turrets on high power rifle scopes. Dieses Modul fügt Absehenverstellung (horizontal und vertikal) zu Zielfernrohren hinzu. - このモジュールは高倍率ライフル スコープにおいて横風と仰角の調節ができます。 + このモジュールは高倍率ライフル スコープにおいてウィンデージとエレベーションの調節ができます。 이 모듈은 고성능 조준경에 조준 나사를 이용한 편차 및 고도 조절 기능을 더해줍니다. Ten moduł włącza pokrętła kalibracyjne poprawki na wiatr oraz poprawki wysokości dla celowników o dużym powiększeniu. Ce module ajoute les tourelles de correction de hausse et de dérive sur les lunettes de visée à fort grossissement. - Questo modulo aggiunge lo spostamento dell'aria e la regolazione dell'elevazione delle torrette in mirini a lunga gittata + Questo modulo aggiunge lo spostamento dell'aria e la regolazione dell'elevazione delle manopole in mirini a lunga gittata 此模块可为高倍率瞄准镜新增归零风偏,距离用的调整纽。 此模塊可為高倍率瞄準鏡新增歸零風偏,距離用的調整紐。 Этот модуль добавляет барабанчики ввода горизонтальных и вертикальных поправок для прицелов с высокой кратностью @@ -541,7 +541,7 @@ %1L %1L %1G - %1L + %1Sx %1L %1L %1L @@ -557,7 +557,7 @@ %1R %1R %1D - %1R + %1Dx %1R %1R %1R @@ -575,7 +575,7 @@ 水平限制 水平限制 水平制限 - Limite orrizontale + Limiti orizzontali Limit poziomy Лимит по горизонтали Limite Horizontal @@ -590,7 +590,7 @@ 垂直限制 垂直限制 垂直制限 - Limite verticale + Limiti verticali Limit pionowy Лимит по вертикали Limite Vertical diff --git a/addons/sitting/XEH_clientInit.sqf b/addons/sitting/XEH_clientInit.sqf index 12adfb9f6c..5495ef0e97 100644 --- a/addons/sitting/XEH_clientInit.sqf +++ b/addons/sitting/XEH_clientInit.sqf @@ -4,13 +4,13 @@ if (!hasInterface) exitWith {}; ["ace_settingsInitialized", { - TRACE_1("SettingInit", XGVAR(enable)); + TRACE_1("SettingInit",XGVAR(enable)); // If not enabled, then do not add CanInteractWith Condition or event handlers if (!XGVAR(enable)) exitWith {}; // Initialize classes as they spawn - ["ThingX", "init", FUNC(addSitActions), nil, nil, true] call CBA_fnc_addClassEventHandler; + ["ThingX", "init", LINKFUNC(addSitActions), nil, nil, true] call CBA_fnc_addClassEventHandler; // Initialize statically defined benches (also appear as world objects, no class EH thrown) { @@ -21,6 +21,6 @@ if (!hasInterface) exitWith {}; ["isNotSitting", {isNil {(_this select 0) getVariable QGVAR(sittingStatus)}}] call EFUNC(common,addCanInteractWithCondition); // Handle interruptions - ["ace_unconscious", {_this call DFUNC(handleInterrupt)}] call CBA_fnc_addEventHandler; - ["ace_captives_SetHandcuffed", {_this call DFUNC(handleInterrupt)}] call CBA_fnc_addEventHandler; + ["ace_unconscious", LINKFUNC(handleInterrupt)] call CBA_fnc_addEventHandler; + ["ace_captives_SetHandcuffed", LINKFUNC(handleInterrupt)] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/sitting/XEH_preInit.sqf b/addons/sitting/XEH_preInit.sqf index 4fc8d6e9d0..e626c67e76 100644 --- a/addons/sitting/XEH_preInit.sqf +++ b/addons/sitting/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" if (hasInterface) then { GVAR(initializedClasses) = []; diff --git a/addons/sitting/functions/fnc_getRandomAnimation.sqf b/addons/sitting/functions/fnc_getRandomAnimation.sqf index ac8bd9e68d..b0aa2ba270 100644 --- a/addons/sitting/functions/fnc_getRandomAnimation.sqf +++ b/addons/sitting/functions/fnc_getRandomAnimation.sqf @@ -4,7 +4,7 @@ * Gets a random animations from the list. * * Arguments: - * None + * 0: Object to get animation pool from (default: objNull) * * Return Value: * Random Animation @@ -15,30 +15,42 @@ * Public: No */ +params [["_object", objNull, [objNull]]]; + +private _animations = []; + +if (!isNull _object) then { + _animations = getArray (configOf _object >> QGVAR(animations)); +}; + +if (_animations isEqualTo []) then { + _animations = [ + QGVAR(HubSittingChairA_idle1), + QGVAR(HubSittingChairA_idle2), + QGVAR(HubSittingChairA_idle3), + QGVAR(HubSittingChairA_move1), + QGVAR(HubSittingChairB_idle1), + QGVAR(HubSittingChairB_idle2), + QGVAR(HubSittingChairB_idle3), + QGVAR(HubSittingChairB_move1), + QGVAR(HubSittingChairC_idle1), + QGVAR(HubSittingChairC_idle2), + QGVAR(HubSittingChairC_idle3), + QGVAR(HubSittingChairC_move1), + QGVAR(HubSittingChairUA_idle1), + QGVAR(HubSittingChairUA_idle2), + QGVAR(HubSittingChairUA_idle3), + QGVAR(HubSittingChairUA_move1), + QGVAR(HubSittingChairUB_idle1), + QGVAR(HubSittingChairUB_idle2), + QGVAR(HubSittingChairUB_idle3), + QGVAR(HubSittingChairUB_move1), + QGVAR(HubSittingChairUC_idle1), + QGVAR(HubSittingChairUC_idle2), + QGVAR(HubSittingChairUC_idle3), + QGVAR(HubSittingChairUC_move1) + ]; +}; + // Select random animation from Animations Pool -selectRandom [ - QGVAR(HubSittingChairA_idle1), - QGVAR(HubSittingChairA_idle2), - QGVAR(HubSittingChairA_idle3), - QGVAR(HubSittingChairA_move1), - QGVAR(HubSittingChairB_idle1), - QGVAR(HubSittingChairB_idle2), - QGVAR(HubSittingChairB_idle3), - QGVAR(HubSittingChairB_move1), - QGVAR(HubSittingChairC_idle1), - QGVAR(HubSittingChairC_idle2), - QGVAR(HubSittingChairC_idle3), - QGVAR(HubSittingChairC_move1), - QGVAR(HubSittingChairUA_idle1), - QGVAR(HubSittingChairUA_idle2), - QGVAR(HubSittingChairUA_idle3), - QGVAR(HubSittingChairUA_move1), - QGVAR(HubSittingChairUB_idle1), - QGVAR(HubSittingChairUB_idle2), - QGVAR(HubSittingChairUB_idle3), - QGVAR(HubSittingChairUB_move1), - QGVAR(HubSittingChairUC_idle1), - QGVAR(HubSittingChairUC_idle2), - QGVAR(HubSittingChairUC_idle3), - QGVAR(HubSittingChairUC_move1) -] +selectRandom _animations diff --git a/addons/sitting/functions/fnc_sit.sqf b/addons/sitting/functions/fnc_sit.sqf index 98ece0c62f..033a1f4d2c 100644 --- a/addons/sitting/functions/fnc_sit.sqf +++ b/addons/sitting/functions/fnc_sit.sqf @@ -48,7 +48,7 @@ if (_multiSitting) then { }; // Get random animation and perform it (before moving player to ensure correct placement) -[_player, call FUNC(getRandomAnimation), 2] call EFUNC(common,doAnimation); // Correctly places when using non-transitional animations +[_player, [_seat] call FUNC(getRandomAnimation), 2] call EFUNC(common,doAnimation); // Correctly places when using non-transitional animations [_player, "", 1] call EFUNC(common,doAnimation); // Correctly applies animation's config values (such as disallow throwing of grenades, intercept keybinds... etc). TRACE_2("Sit pos and dir",_sitPosition,_sitDirection); @@ -78,7 +78,7 @@ if (_seatsClaimed isEqualTo []) then { _seat setVariable [QGVAR(seatsClaimed), _seatsClaimed, true]; // Also prevent dragging/carrying -if (!([_seat] call EFUNC(common,owned))) then { +if !([_seat] call EFUNC(common,owned)) then { [_player, _seat] call EFUNC(common,claim); }; @@ -92,7 +92,7 @@ private _seatDistOrig = (getPosASL _player) distance _seat; // Remove PFH if not sitting any more if (isNil {_player getVariable QGVAR(sittingStatus)}) exitWith { [_pfhId] call CBA_fnc_removePerFrameHandler; - TRACE_1("Remove PFH",_player getVariable [ARR_2(QGVAR(sittingStatus), false)]); + TRACE_1("Remove PFH",_player getVariable [ARR_2(QGVAR(sittingStatus),false)]); }; // Stand up if chair gets deleted or moved diff --git a/addons/sitting/initSettings.sqf b/addons/sitting/initSettings.inc.sqf similarity index 88% rename from addons/sitting/initSettings.sqf rename to addons/sitting/initSettings.inc.sqf index 744c188e9f..ee1af1ec8e 100644 --- a/addons/sitting/initSettings.sqf +++ b/addons/sitting/initSettings.inc.sqf @@ -6,5 +6,5 @@ true, true, {[QGVAR(enable), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; diff --git a/addons/slideshow/functions/fnc_addSlideActions.sqf b/addons/slideshow/functions/fnc_addSlideActions.sqf index 8ec804d577..409c724943 100644 --- a/addons/slideshow/functions/fnc_addSlideActions.sqf +++ b/addons/slideshow/functions/fnc_addSlideActions.sqf @@ -34,7 +34,7 @@ private _actions = []; (_this select 2) params ["_objects", "_image", "_currentSlideshow", "_selection"]; { _x setObjectTextureGlobal [_selection, _image] - } count _objects; + } forEach _objects; [QGVAR(slideChanged), [_image, _currentSlideshow]] call CBA_fnc_localEvent; }, {true}, diff --git a/addons/slideshow/functions/fnc_autoTransition.sqf b/addons/slideshow/functions/fnc_autoTransition.sqf index 793b8baf1b..6a18a041c4 100644 --- a/addons/slideshow/functions/fnc_autoTransition.sqf +++ b/addons/slideshow/functions/fnc_autoTransition.sqf @@ -36,7 +36,7 @@ private _image = _images select _currentSlide; // Set slide { _x setObjectTextureGlobal [_selection, _image]; -} count _objects; +} forEach _objects; [QGVAR(slideChanged), [_image, _currentSlideshow]] call CBA_fnc_localEvent; diff --git a/addons/slideshow/functions/fnc_createSlideshow.sqf b/addons/slideshow/functions/fnc_createSlideshow.sqf index 87fd40bbbe..c24d302346 100644 --- a/addons/slideshow/functions/fnc_createSlideshow.sqf +++ b/addons/slideshow/functions/fnc_createSlideshow.sqf @@ -50,7 +50,7 @@ if (isServer) then { // Default images on whiteboards (first image) { _x setObjectTextureGlobal [_selection, _images select 0]; - } count _objects; + } forEach _objects; }; // Number of slideshows (multiple modules support) @@ -61,7 +61,7 @@ private _currentSlideshow = GVAR(slideshows); // Local variable in case GVAR get // If interaction menu module is not present, set default duration value if !(["ace_interact_menu"] call EFUNC(common,isModLoaded)) then { _duration = NOINTERACTMENU_DURATION; - INFO_1("Interaction Menu module not present, defaulting duration value to %1",_duration); + INFO_1("Interaction Menu module not present,defaulting duration value to %1",_duration); }; // Add interactions if automatic transitions are disabled, else setup automatic transitions @@ -89,8 +89,7 @@ if (_duration == 0) then { 2 ] call EFUNC(interact_menu,createAction); [_x, 0, ["ACE_MainActions"], _slidesAction] call EFUNC(interact_menu,addActionToObject); - nil - } count _controllers; + } forEach _controllers; } else { if !(isServer) exitWith {}; diff --git a/addons/slideshow/functions/fnc_mapImage_init.sqf b/addons/slideshow/functions/fnc_mapImage_init.sqf index 5235315bd0..3fb6e4c7f8 100644 --- a/addons/slideshow/functions/fnc_mapImage_init.sqf +++ b/addons/slideshow/functions/fnc_mapImage_init.sqf @@ -50,7 +50,7 @@ ctrlMapAnimCommit _map; // add drawEH to draw markers next update (they will get drawn 3 times total) _map setVariable ["markers", _markers]; -_map ctrlAddEventHandler ["draw", { +_map ctrlAddEventHandler ["Draw", { params ["_map"]; private _markers = _map getVariable ["markers", []]; TRACE_2("drawing markers",_map,count _markers); diff --git a/addons/slideshow/functions/fnc_moduleInit.sqf b/addons/slideshow/functions/fnc_moduleInit.sqf index 896c64eb50..7e6a78dc95 100644 --- a/addons/slideshow/functions/fnc_moduleInit.sqf +++ b/addons/slideshow/functions/fnc_moduleInit.sqf @@ -37,8 +37,7 @@ private _selection = _logic getVariable ["Selection", 0]; // Objects synced to the module { _objects pushBack _x; - nil -} count (synchronizedObjects _logic); +} forEach (synchronizedObjects _logic); // Prepare with actions [_objects, _controllers, _images, _names, _duration, _setName, _selection] call FUNC(createSlideshow); diff --git a/addons/slideshow/stringtable.xml b/addons/slideshow/stringtable.xml index 665f8e5808..358e3ed3a1 100644 --- a/addons/slideshow/stringtable.xml +++ b/addons/slideshow/stringtable.xml @@ -11,7 +11,7 @@ Слайд-шоу Prezentace Presentación de diapositivas - Mostra Diapositive + Presentazione Diapositive スライドショー 슬라이드 쇼 幻燈片 @@ -28,7 +28,7 @@ Этот модуль позволяет вам устроить слайд-шоу на различных объектах. Один модуль на один список изображений. Поддерживаются только объекты с hiddenSelection 0. Este módulo permite configurar una presentación de diapositivas en diferentes objetos. Un módulo por lista de imágenes. Sólo son soportados objetos con hiddenSelection 0. Tento modul umožňuje nastavit prezentaci na různé objekty. Jeden modul na seznam s obrázky. Podporované jsou pouze objekty s hiddenSelection 0. - Questo modulo ti permette di creare una presentazione con diapositive su vari oggetti. Un modulo per lista immagini. Solo oggetti con hiddenSelection 0 sono supportati. + Questo modulo ti permette di creare una presentazione con diapositive su vari oggetti. Un modulo per ogni lista immagini. Solo oggetti con hiddenSelection 0 sono supportati. さまざまなオブジェクトへスライドショーを設定することができます。1つのモジュールは各画像リストになっています。オブジェクトが hiddenSelection 0へ対応している必要があります。 이 모듈은 다른 물체에 대해 슬라이드 쇼를 놓을 수 있게 해줍니다. 한 모듈 당 한 이미지 목록만 가능합니다. 또한 hiddenSelection 0가 있는 물체만 지원됩니다. 此模塊可讓圖片以幻燈片的形式顯示在物件上,每個模塊都能設定一串幻燈片清單,被設定的物件不能有隱藏部位(hiddenSelection) @@ -61,7 +61,7 @@ Имена объектов (так же могут использоваться синхронизированные объекты), на которых будет отображаться слайд-шоу, разделенные запятыми. Los nombres de objetos (también pueden ser objetos sincronizados) de diapositivas se mostrarán en, separados por comas. Jména objektů (lze také použít synchronizované objekty) které se budou zobrazovat v prezentaci, oddělit čárkou pokud jich je více. - Nomi di oggetti (possono anche essere oggetti sincronizzati) che verranno usati per la presentazione di diapositive, separato da virgole se più di uno. + Nomi di oggetti (possono anche essere oggetti sincronizzati) che verranno usati per la presentazione di diapositive, separati da virgole se più di uno. スライドショーを表示するオブジェクト名 (オブジェクトとの同期も可)。複数ある場合はコンマで区切れます 슬라이드 쇼가 보여질 물체(동기화 되는 물체도 가능합니다) 명칭, 다수의 경우 쉼표로 구분합니다. 物件名稱 (也可使用同步線來設定),幻燈片將會顯示在該物件上,如有多個物件,請以逗號作區隔 @@ -127,8 +127,8 @@ Список изображений, которые будут использованы для слайд-шоу, разделенные запятыми, с полными путями в правильном формате (например, images\image.paa). Lista de imágenes que se utilizarán para la presentación de diapositivas, separadas por comas, con la ruta completa en formato correcto (ej. imágenes\image.paa). Seznam obrázků které budou použity v prezentaci, oddělené čárkami, s kompletní cestou ve správném formátu (např. image\image.paa). - Lista di immagini che verranno usate durante la presentazione, separati da virgole, con il formato completo del percorso (es. images\image.paa) - 完全なパスでスライドショーに使う画像一覧を入力してください。コンマで区別できます。(例: images\image.paa) + Lista di immagini che verranno usate durante la presentazione, separate da virgole, con percorso completo formattato correttamente (es. images\image.paa) + スライド ショーに使用される画像のリスト。完全パスで入力してください。コンマで区切ります。(例: images\image.paa) 슬라이드 쇼에 쓰일 사진목록입니다, 쉼표로 구분됩니다, 경로설정을 정확히 하십시요. (예: 사진\사진.ppa) 要做為幻燈片的圖片清單,每個圖片請已逗號區隔,並輸入完整路徑位址 (例如:images\image.paa) 要做为幻灯片的图片清单,每个图片请已逗号区隔,并输入完整路径位址(例如:images\image.paa) @@ -157,7 +157,7 @@ Lista dos nomes que serão usados para entradas de interação, separados por vírgulas, na ordem das imagens. Список имен, которые будут использованы при взаимодействии, разделенные запятыми, в порядке следования изображений. Lista de nombres que se utilizarán para las entradas de interacción, separados por comas, en el orden de las imágenes. - Lista di nomi che verranno usati per per le interazioni, separati da virgole, in ordine per immagini. + Lista di nomi che verranno usati per le interazioni, separati da virgole, nell'ordine delle immagini. Liste aller Namen, die für Interaktionseinträge genutzt werden. Mit Kommata getrennt, in Reihenfolge der Bilder. 画像を操作できるインタラクション エントリ名の一覧を入力してください。コンマで区切り複数を指定できます。 상호작용 메시지에 쓰일 명칭입니다, 쉼표로 구분합니다, 이미지의 순서입니다. @@ -184,9 +184,9 @@ Name that will be used for main interaction entry (to distinguish multiple slideshows). Default: "Slides" Name der für den Hauptinteraktionseintrag benutzt wird (um mehrere Diavorführungen voneinander zu trennen). Nazwa, która będzie użyta w głównym menu interakcji (w celu rozróżnienia różnych slajdów). Domyślnie: "Slides" - メイン インタラクション エントリで使われる名前を設定します。(複数のスライドショーを区別するため)。標準: "Slides" + メイン インタラクション エントリで使われる名前を設定します。(複数のスライドショーを区別するため)。 デフォルト: "Slides" Nom qui sera utilisé pour l'entrée d'interaction principale (pour distinguer plusieurs diaporamas). Valeur par défaut : "Slides". - Nome che sarà utilizzato per le principali interazioni (per distinguere le multiple diapositive). Predefinito: "Slides" + Nome che verrà utilizzato per le principali interazioni (per distinguere multiple diapositive). Predefinito: "Slides" 設定該幻燈片的標題名稱 (用來區分多個不同標題的幻燈片) 預設名稱: "幻燈片" 设定该幻灯片的标题名称(用来区分多个不同标题的幻灯片)预设名称:"幻灯片" 상위 상호작용 이름 (여러 개의 슬라이드 쇼를 구분하기 위해 사용됨) 기본: "Slides" @@ -206,7 +206,7 @@ Doba trvání snímku Durata Diapositiva Länge der Diavorführung pro Bild - スライドの持続時間 + スライドの継続時間 슬라이드 지속 시간 幻燈片顯示時間 幻灯片显示时间 @@ -220,9 +220,9 @@ Длительность каждого слайда. По умолчанию: 0 (автоматический переход отключен) Duración de cada diapositiva. Por defecto: 0 (Transiciones automáticas desactivadas) Doba trvání každého snímku. Výchozí: 0 (Automatické posouvání je zakázáno) - Durata di ogni diapositiva. Default: 0 (Transizioni Automatiche Disabilitate) + Durata di ogni diapositiva. Predefinito: 0 (Transizioni Automatiche Disabilitate) Länge der Diavorführung pro Bild. Standard: 0 (Automatischer Wechsel deaktiviert) - 各スライドの持続時間。標準:0 (自動的な切り替えは無効) + 各スライドの継続時間。 デフォルト: 0 (自動的な切り替えは無効) 매 슬라이드의 지속 시간. 기본설정: 0 (자동 전환 비활성화) 每張幻燈片顯示的時間。 預設:0 (自動換圖已禁用) 每张幻灯片显示的时间。 预设:0(自动换图已禁用) @@ -233,6 +233,7 @@ 텍스쳐 선택 텍스쳐 선택 Auswahl der Textur + Selezione della texture Wybór Tekstury テクスチャの選択 Выбор текстуры @@ -245,8 +246,9 @@ 개체 텍스처 선택(기본값: 0) 물체의 텍스쳐를 선택합니다. 기본: 0 Auswahl der Objekttextur. Standard: 0 + Selezione della texture dell'oggetto. Predefinito: 0 Wybór tekstury obiektu. Domyślnie: 0 - オブジェクトテクスチャの選択。デフォルト: 0 + オブジェクトテクスチャの選択。 デフォルト: 0 Выбор текстуры объекта. По умолчанию: 0 Selección de textura de objeto. Defecto: 0 Sélection de la texture de l'objet. Valeur par défaut : 0 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/smallarms/stringtable.xml b/addons/smallarms/stringtable.xml index 71a1ecb615..0b89a38b0d 100644 --- a/addons/smallarms/stringtable.xml +++ b/addons/smallarms/stringtable.xml @@ -6,7 +6,7 @@ 9 mm 17 發彈匣 Mag. 17 balles 9 mm Cargador de 17 proyectiles de 9 mm - Caricatore 17 colpi 9 mm + Caricatore 17cp 9mm 17-nab. mag. 9 mm Магазин, 17 патр. 9 мм 17-Schuss-9mm-Magazin @@ -23,6 +23,7 @@ Магазин, 25 патр. .45 ACP Mag. 25 balles .45 ACP Cargador de 25 proyectiles de .45 ACP + Caricatore 25cp .45 ACP 25-Schuss-.45-ACP-Magazin .45 ACP, 25ks zásobník .45 ACP 25 Merm. Şarjör @@ -32,14 +33,15 @@ .45 ACP 25Rnd Tracers (Green) Mag - 25-nab. mag. .45 ACP (zielony smugacz) + 25-nab. mag. .45 ACP (Zielony smugacz) Магазин, 25 патр. .45 ACP (зелёные трассеры) - Mag. 25 traçantes (vertes) .45 ACP - Cargador de 25 balas trazadoras (verde) de .45 ACP + Mag. 25 traçantes (Vertes) .45 ACP + Cargador de 25 balas trazadoras (Verde) de .45 ACP + Caricatore 25cp .45 ACP Traccianti (Verdi) 25-Schuss-.45-ACP-Vermin-Magazin (Leuchtspur Grün) - .45 ACP, 25ks zásobník stopovky (zelené) + .45 ACP, 25ks zásobník stopovky (Zelené) .45 ACP 25 Merm. İzli (Yeşil) Şarjör - .45 ACP 25Rnd 曳光弾 (緑) マガジン + .45 ACP 25Rnd トレーサー (緑) マガジン .45 ACP 25发 弹匣(曳光,绿) .45 ACP 25발 예광탄 (초록) 탄창 @@ -49,10 +51,11 @@ Магазин, 25 патр. .45 ACP (красные трассеры) Mag. 25 traçantes (rouges) .45 ACP Cargador de 25 balas trazadoras (rojo) de .45 ACP + Caricatore 25cp .45 ACP Traccianti (Rossi) 25-Schuss-.45-ACP-Vermin-Magazin (Leuchtspur Rot) .45 ACP, 25ks zásobník stopovky (červené) .45 ACP 25 Merm. İzli (Kırmızı) Şarjör - .45 ACP 25Rnd 曳光弾 (赤) マガジン + .45 ACP 25Rnd トレーサー (赤) マガジン .45 ACP 25发 弹匣(曳光,红) .45 ACP 25발 예광탄 (빨강) 탄창 @@ -62,10 +65,11 @@ Магазин, 25 патр. .45 ACP (жёлтые трассеры) Mag. 25 traçantes (jaunes) .45 ACP Cargador de 25 balas trazadoras (amarillo) de .45 ACP + Caricatore 25cp .45 ACP Traccianti (Gialli) 25-Schuss-.45-ACP-Vermin-Magazin (Nachlade-Leuchtspur Gelb) .45 ACP, 25ks zásobník stopovky (žluté) .45 ACP 25 Merm. İzli (Sarı) Şarjör - .45 ACP 25Rnd 曳光弾 (黄) マガジン + .45 ACP 25Rnd トレーサー (黄) マガジン .45 ACP 25发 弹匣(曳光,黄) .45 ACP 25발 예광탄 (노랑) 탄창 @@ -75,6 +79,7 @@ Магазин, 8 патр. .45 ACP Mag. 8 balles .45 ACP Cargador de 8 proyectiles de .45 ACP + Caricatore 8cp .45 ACP 8-Schuss-.45-ACP-Magazin .45 ACP, 8ks zásobník .45 ACP 8 Merm. Şarjör @@ -88,6 +93,7 @@ Магазин, 15 патр. .45 ACP Mag. 15 balles .45 ACP Cargador de 15 proyectiles de .45 ACP + Caricatore 15cp .45 ACP 15-Schuss-.45-ACP-Magazin .45 ACP, 15ks zásobník .45 ACP 15 Merm. Şarjör diff --git a/addons/spectator/XEH_preInit.sqf b/addons/spectator/XEH_preInit.sqf index 1e3d019177..7ef6aadb6f 100644 --- a/addons/spectator/XEH_preInit.sqf +++ b/addons/spectator/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // Used by public functions GVAR(availableModes) = [MODE_FREE, MODE_FPS, MODE_FOLLOW]; diff --git a/addons/spectator/functions/fnc_cam.sqf b/addons/spectator/functions/fnc_cam.sqf index d63a3c24a8..a9f8e97522 100644 --- a/addons/spectator/functions/fnc_cam.sqf +++ b/addons/spectator/functions/fnc_cam.sqf @@ -132,6 +132,9 @@ if (_init) then { GVAR(camDummy) = nil; // Stop tracking everything + { deleteVehicle _x; } forEach GVAR(camLights); + GVAR(camLights) = nil; + GVAR(camMode) = nil; GVAR(camVision) = nil; GVAR(camFocus) = nil; @@ -144,6 +147,5 @@ if (_init) then { GVAR(camYaw) = nil; GVAR(camPitch) = nil; GVAR(camSlow) = nil; - GVAR(camLights) = nil; GVAR(camLight) = nil; }; 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/spectator/initSettings.sqf b/addons/spectator/initSettings.inc.sqf similarity index 100% rename from addons/spectator/initSettings.sqf rename to addons/spectator/initSettings.inc.sqf diff --git a/addons/spectator/stringtable.xml b/addons/spectator/stringtable.xml index 1ddd9f14e6..7f55998d9f 100644 --- a/addons/spectator/stringtable.xml +++ b/addons/spectator/stringtable.xml @@ -7,7 +7,7 @@ Spettatore 旁觀者 旁观者 - スペクテイター + 観戦者 관전자 Spectateur Obserwator @@ -20,8 +20,8 @@ ACE Spectator ACE Zuschauer - ACE スペクテイター - Spettatore ACE + ACE 観戦者 + ACE Spettatore ACE Spectateur ACE 旁观者 ACE 旁觀者 @@ -41,9 +41,9 @@ Определяют, как система спектатора будет функционировать по умолчанию. Configurar cómo el sistema de espectador funcionará por defecto. Konfigurovat výchozí nastavení pozorovatele - Configura come il sistema spettatore si comporterà di default. + Configura come il sistema spettatore si comporterà di base. Configure le fonctionnement par défaut du système spectateur. - スペクテイター システムが標準でどのように動作するか設定できます。 + 観戦者システムが標準でどのように動作するか設定できます。 어떻게 관전자 시스템이 기본적으로 작동되는지 설정합니다 设定旁观者系统相关配置 設定旁觀者系統相關配置 @@ -52,7 +52,7 @@ AI Enabled KI Sichtbarkeit AIにも有効化 - AI Abilitate + IA Abilitate 可觀察AI 可观察 AI AI 활성 @@ -67,8 +67,8 @@ Make AI viewable in spectator Macht KI-Einheiten den Zuschauern sichtbar - スペクテイターでAI視点を可能に - Permette la visibilità delle AI in spettatore + 観戦者でAI視点を可能に + Rende le IA visibili come spettatore 開啟此功能後可在觀察者模式下觀察AI單位 开启此功能后可在观察者模式下观察 AI 单位。 관전자가 AI를 관전할 수 있습니다. @@ -87,7 +87,7 @@ Режимы камеры Módy kamery Modos de cámara - Modalità camera + Modalità Videocamera Modes de caméra カメラ モード 카메라 모드 @@ -103,7 +103,7 @@ Режимы камеры, которые могут быть использованы Modos de la cámara que se pueden utilizar. Módy kamery které mohou být použity. - Modalità che la camera può utilizzare. + Modalità utilizzabili dalla videocamera spettatore. Modes de caméra pouvant être utilisés. カメラ モードを設定できます。 사용할 수 있는 카메라 모드들입니다 @@ -224,11 +224,11 @@ Maximum distance the follow camera can be from the target Maximale Distanz in welcher die Kamera dem Ziel folgen kann. Максимальная дистанция от камеры слежения до цели - カメラが目標へ追随できる最大距離を決定できます。 + カメラが目標へ追随できる最大距離 A distância máxima que a câmera de acompanhamento pode estar do alvo. 攝影機能追隨目標的最大距離 摄影机能追随目标的最大距离 - Distanza massima che la telecamera seguente può percorrere dall'obiettivo + Distanza massima che la telecamera seguente può allontanarsi dall'obiettivo Distance maximale à laquelle la caméra de suivi peut se trouver par rapport à la cible. Maximální vzdálenost při které může kamera sledovat cíl Maksymalna odległość na jakiej kamera może podążać od celu @@ -302,13 +302,13 @@ Thermal - Wärme + Wärmebild Termo Térmica Тепловизор Termální Térmica - Termico + Termica Thermique 熱源画像 열상 @@ -400,7 +400,7 @@ Slow Speed Langsam - 速度低下 + 速度を下げる Bassa Velocità 慢速度 慢速度 diff --git a/addons/spottingscope/CfgVehicles.hpp b/addons/spottingscope/CfgVehicles.hpp index 6be6d70d63..93fa00a7bc 100644 --- a/addons/spottingscope/CfgVehicles.hpp +++ b/addons/spottingscope/CfgVehicles.hpp @@ -48,7 +48,7 @@ class CfgVehicles { selection = ""; displayName = CSTRING(PickUp); distance = 5; - condition = QUOTE((alive _target) && (count (crew _target) == 0)); + condition = QUOTE((alive _target) && {(crew _target) isEqualTo []}); statement = QUOTE([ARR_2(_target,_player)] call FUNC(pickup)); showDisabled = 0; exceptions[] = {}; diff --git a/addons/switchunits/XEH_preInit.sqf b/addons/switchunits/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/switchunits/XEH_preInit.sqf +++ b/addons/switchunits/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/switchunits/functions/fnc_isValidAi.sqf b/addons/switchunits/functions/fnc_isValidAi.sqf index e78e990924..53ebcdaac2 100644 --- a/addons/switchunits/functions/fnc_isValidAi.sqf +++ b/addons/switchunits/functions/fnc_isValidAi.sqf @@ -19,6 +19,6 @@ params ["_unit"]; !([_unit] call EFUNC(common,isPlayer) || {_unit in playableUnits} -|| {vehicle _unit != _unit} +|| {!isNull objectParent _unit} || {_unit getVariable [QGVAR(IsPlayerUnit), false]} || {_unit getVariable [QGVAR(IsPlayerControlled), false]}) // return diff --git a/addons/switchunits/functions/fnc_markAiOnMap.sqf b/addons/switchunits/functions/fnc_markAiOnMap.sqf index 8c7dc4924c..203ba426ff 100644 --- a/addons/switchunits/functions/fnc_markAiOnMap.sqf +++ b/addons/switchunits/functions/fnc_markAiOnMap.sqf @@ -27,7 +27,7 @@ GVAR(AllMarkerNames) = []; // delete markers { deleteMarkerLocal _x; - } count GVAR(AllMarkerNames); + } forEach GVAR(AllMarkerNames); // reset the array GVAR(AllMarkerNames) = []; @@ -58,8 +58,7 @@ GVAR(AllMarkerNames) = []; }; GVAR(AllMarkerNames) pushBack _markerName; - nil }; - } count allUnits; + } forEach allUnits; }; }, 1.5, [_sidesToShow]] call CBA_fnc_addPerFrameHandler; diff --git a/addons/switchunits/functions/fnc_switchUnit.sqf b/addons/switchunits/functions/fnc_switchUnit.sqf index 6fc8fa35c9..9ce074eecb 100644 --- a/addons/switchunits/functions/fnc_switchUnit.sqf +++ b/addons/switchunits/functions/fnc_switchUnit.sqf @@ -18,7 +18,7 @@ params ["_unit"]; // don't switch to original player units -if (!([_unit] call FUNC(isValidAi))) exitWith {}; +if !([_unit] call FUNC(isValidAi)) exitWith {}; // exit var private _leave = false; @@ -27,7 +27,7 @@ if (GVAR(EnableSafeZone)) then { private _allNearestPlayers = [position _unit, GVAR(SafeZoneRadius)] call FUNC(nearestPlayers); private _nearestEnemyPlayers = _allNearestPlayers select {((side GVAR(OriginalGroup)) getFriend side _x < 0.6) && !(_x getVariable [QGVAR(IsPlayerControlled), false])}; - if (count _nearestEnemyPlayers > 0) exitWith { + if (_nearestEnemyPlayers isNotEqualTo []) exitWith { _leave = true; }; }; diff --git a/addons/switchunits/initSettings.sqf b/addons/switchunits/initSettings.inc.sqf similarity index 100% rename from addons/switchunits/initSettings.sqf rename to addons/switchunits/initSettings.inc.sqf diff --git a/addons/switchunits/stringtable.xml b/addons/switchunits/stringtable.xml index c3165e6c58..11e54342aa 100644 --- a/addons/switchunits/stringtable.xml +++ b/addons/switchunits/stringtable.xml @@ -6,7 +6,7 @@ Cambia Unità 切換單位 单位切换 - ユニット切り替え + ユニットを切り替え 유닛 변경 Einheitenwechsel Przełącz Jednostki @@ -28,7 +28,7 @@ Egység átváltva Unità cambiata Trocado de unidade - ユニットを切り替え + 切り替えたユニット 切换单位 切換單位 유닛 변경됨 @@ -69,6 +69,7 @@ Enable switch side Ermögliche Seitenwechsel + Permetti cambio fazione Permettre le changement de camp 啟用陣營切換 启用阵营切换 @@ -91,7 +92,7 @@ Átváltás BLUFOR-ra? На синих? Cambia per BLUFOR? - 同盟軍へ切り替え許可 + BLUFOR軍へ切り替える? 切换至蓝方? 切換至藍方? 청군으로 변경합니까? @@ -108,7 +109,7 @@ Nyugat-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на синих юнитов? Consenti passaggio ad unità BLUFOR? - 同盟軍側ユニットへ切り替えられるようにします。 + BLUFOR軍ユニットへの切り替えを許可しますか? 允许切换至蓝方? 允許切換至藍方? 청군 인원으로 변경하는 것을 허락합니까? @@ -124,7 +125,7 @@ Átváltás OPFOR-ra? На красных? Cambia per OPFOR? - OPFOR軍側へ切り替え許可 + OPFOR軍へ切り替える? 切换至红方? 切換至紅方? 대항군으로 변경합니까? @@ -141,7 +142,7 @@ Kelet-fakciós egységekre való váltás engedélyezése? Разрешить переключаться на красных юнитов? Consenti passaggio ad unità OPFOR? - OPFOR軍側ユニットへ切り替えられるようにします。 + OPFOR軍ユニットへの切り替えを許可しますか? 允许切换至红方? 允許切換至紅方? 대항군 인원으로 변경하는 것을 허락합니까? @@ -157,7 +158,7 @@ Átváltás INDFOR-ra? На независимых? Cambia per INDFOR? - 独立軍へ切り替え許可 + INDEPENDENT軍へ切り替える? 切换至独立方? 切換至獨立方? 무소속군으로 전환합니까? @@ -174,7 +175,7 @@ Független egységekre való váltás engedélyezése? Разрешить переключаться на независимых юнитов? Consenti passaggio ad unità INDFOR? - 独立軍側ユニットへ切り替えられるようにします。 + INDEPENDENT軍ユニットへの切り替えを許可しますか? 允许切换至独立方? 允許切換至獨立方? 무소속군 인원으로 변경하는 것을 허락합니까? @@ -190,7 +191,7 @@ Átváltás civilre? На гражданских? Cambia per Civili? - 市民へ切り替え許可 + 市民へ切り替える? 민간인으로 전환합니까? 切换至平民方? 切換至平民方? @@ -207,7 +208,7 @@ Civil egységekre való váltás engedélyezése? Разрешить переключаться на гражданских юнитов? Consenti passaggio ad unità civili? - 市民側ユニットへ切り替えられるようにします。 + 市民ユニットへの切り替えを許可しますか? 민간인으로 변경하는걸 허가합니까? 允许切换至平民方? 允許切換至平民方? @@ -239,7 +240,7 @@ Engedélyezve legyen-e egy biztonságos zóna az ellenségek körül? A játékosok nem tudnak a biztonságos zónán belüli egységekre váltani. Включить безопасную зону вокруг вражеских юнитов? Игроки не могут переключаться на юнитов, находящихся в безопасной зоне. Abilita una zona sicura attorno ad unità nemiche? I giocatori non possono cambiare ad unità dentro la zona sicura. - 敵ユニットから逃れる安全地帯を生成できます。プレイヤーは安全地帯内のユニットへ切り替えできません。 + 敵ユニットの周囲に安全地帯を確保しますか? プレイヤーは安全地帯内のユニットに切り替えることはできません。 적 주위로 안전지대를 활성화합니까? 안전지대 내에서는 플레이어가 인원 전환을 할 수 없습니다. 启用敌方周围安全地带? 玩家不能切换到安全区内的单位 啟用敵方周圍安全地帶? 玩家不能切換到安全區內的單位 @@ -271,7 +272,7 @@ A biztonságos zóna más csapatból lévő játékosok körül. Alapértelmezett: 100 Радиус безопасной зоны вокруг ироков из противоположной команды. По умолчанию: 100 La zona sicura attorno ai giocatori di un team diverso. Default: 100 - 別のチームへのプレイヤーの周囲にある安全地帯の範囲。標準: 100 + 別のチームのプレイヤーの周囲にある安全地帯の範囲。 デフォルト: 100 다른 진영으로 부터의 플레이어 안전 지대. 기본설정: 100 安全区的范围。预设值:100 安全區的範圍。預設值:100 @@ -286,7 +287,7 @@ Ce module vous permet de changer de camp en cours de partie. Questo modulo ti permette di cambiare lato durante la partita. El módulo permite a las unidades cambiar de bando durante el juego. - モジュールはゲームにおいて、陣営の切り替えを有効にします。 + モジュールを使用すると、ゲーム中に陣営を切り替えることが出来るようになります。 이 모듈은 당신을 게임 중에 진영을 바꿀 수 있게 해줍니다. 此模块允许你在游戏中切换至另一方 此模塊允許你在遊戲中切換至另一方 diff --git a/addons/tacticalladder/XEH_postInit.sqf b/addons/tacticalladder/XEH_postInit.sqf index 1a6f356fb0..c4b25a77ab 100644 --- a/addons/tacticalladder/XEH_postInit.sqf +++ b/addons/tacticalladder/XEH_postInit.sqf @@ -17,10 +17,10 @@ GVAR(currentAngle) = 0; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel adjusting on player change. -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle falling unconscious -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; // @todo captivity? diff --git a/addons/tacticalladder/functions/fnc_deployTL.sqf b/addons/tacticalladder/functions/fnc_deployTL.sqf index 85804e091f..0f399536f4 100644 --- a/addons/tacticalladder/functions/fnc_deployTL.sqf +++ b/addons/tacticalladder/functions/fnc_deployTL.sqf @@ -23,7 +23,7 @@ removeBackpack _unit; private _pos = _unit modelToWorld [0,0,0]; -private _offset = if ((_unit call CBA_fnc_getUnitAnim select 0) == "prone") then { 1 } else {0.8}; +private _offset = [0.8, 1] select (_unit call CBA_fnc_getUnitAnim select 0 == "prone"); _pos set [0, (_pos select 0) + (sin getDir _unit) * _offset]; _pos set [1, (_pos select 1) + (cos getDir _unit) * _offset]; diff --git a/addons/tacticalladder/functions/fnc_positionTL.sqf b/addons/tacticalladder/functions/fnc_positionTL.sqf index 1ea19e737b..6d6f78f1a3 100644 --- a/addons/tacticalladder/functions/fnc_positionTL.sqf +++ b/addons/tacticalladder/functions/fnc_positionTL.sqf @@ -26,7 +26,7 @@ params ["_unit", "_ladder"]; { _ladder animate [_x, 0]; -} count __ANIMS; +} forEach __ANIMS; [_unit, "amovpercmstpslowwrfldnon_player_idlesteady03", 2] call EFUNC(common,doAnimation); @@ -35,7 +35,7 @@ _ladder attachTo [_unit, [0, 0.75, 0], ""]; // Position ladder in front of playe _ladder animate ["rotate", 0]; { _ladder animate [_x, 1]; -} count ["extract_1", "extract_2", "extract_3"]; // Extract ladder at head height (extract_3) +} forEach ["extract_1", "extract_2", "extract_3"]; // Extract ladder at head height (extract_3) GVAR(ladder) = _ladder; GVAR(cancelTime) = CBA_missionTime + 1; // Workaround to prevent accidental canceling diff --git a/addons/tagging/XEH_postInit.sqf b/addons/tagging/XEH_postInit.sqf index 7fefa5757e..02e082648a 100644 --- a/addons/tagging/XEH_postInit.sqf +++ b/addons/tagging/XEH_postInit.sqf @@ -1,20 +1,12 @@ // by esteldunedain #include "script_component.hpp" - -// Cache for static objects -GVAR(cacheStaticModels) = [false] call CBA_fnc_createNamespace; -private _cacheStaticModels = call (uiNamespace getVariable [QGVAR(cacheStaticModels), {[]}]); -{ - GVAR(cacheStaticModels) setVariable [_x, true]; -} forEach _cacheStaticModels; - if (hasInterface) then { // Compile and cache config tags call FUNC(compileConfigTags); // Scripted tag adding EH - [QGVAR(applyCustomTag), FUNC(applyCustomTag)] call CBA_fnc_addEventHandler; + [QGVAR(applyCustomTag), LINKFUNC(applyCustomTag)] call CBA_fnc_addEventHandler; // Keybind ["ACE3 Equipment", QGVAR(quickTag), localize LSTRING(QuickTag), { @@ -32,4 +24,4 @@ if (!isServer) exitWith {}; GVAR(testingThread) = false; GVAR(tagsToTest) = []; -[QGVAR(createTag), DFUNC(createTag)] call CBA_fnc_addEventHandler; +[QGVAR(createTag), LINKFUNC(createTag)] call CBA_fnc_addEventHandler; diff --git a/addons/tagging/XEH_preInit.sqf b/addons/tagging/XEH_preInit.sqf index 34b4928b2a..d368b7c1c6 100644 --- a/addons/tagging/XEH_preInit.sqf +++ b/addons/tagging/XEH_preInit.sqf @@ -9,6 +9,6 @@ PREP_RECOMPILE_END; GVAR(cachedTags) = []; GVAR(itemActions) = createHashMap; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/tagging/XEH_preStart.sqf b/addons/tagging/XEH_preStart.sqf index 9303bdb135..eb8f7ab767 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,11 +24,11 @@ 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]}); +} forEach (_nonAIVehicleClasses select {(configName _x) isKindOf ["Bridge_base_F", _cfgBase]}); -uiNamespace setVariable [QGVAR(cacheStaticModels), compileFinal str _cacheStaticModels]; +uiNamespace setVariable [QGVAR(cacheStaticModels), compileFinal (_cacheStaticModels createHashMapFromArray [])]; TRACE_1("compiled",count _cacheStaticModels); // force preload of stencil texture to avoid error popup diff --git a/addons/tagging/functions/fnc_checkTaggable.sqf b/addons/tagging/functions/fnc_checkTaggable.sqf index 7eab60c1ba..ef20062a32 100644 --- a/addons/tagging/functions/fnc_checkTaggable.sqf +++ b/addons/tagging/functions/fnc_checkTaggable.sqf @@ -43,14 +43,14 @@ if (_object isKindOf "Static") exitWith {false}; // Taggable vehicle, do not exit - if (((_object getVariable [QGVAR(canTag), getNumber (configOf _object >> QGVAR(canTag))]) in [1, true]) + if (((_object getVariable [QGVAR(canTag), getNumber (configOf _object >> QGVAR(canTag))]) in [1, true]) && {getText (configOf _object >> "selectionClan") in selectionNames _object}) exitWith { false }; // If the class is not categorized correctly search the cache - private _modelName = (getModelInfo _object) select 0; - private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + private _modelName = toLowerANSI ((getModelInfo _object) select 0); + private _isStatic = _modelName in (uiNamespace getVariable QGVAR(cacheStaticModels)); TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit (!_isStatic) diff --git a/addons/tagging/functions/fnc_generateStencilTexture.sqf b/addons/tagging/functions/fnc_generateStencilTexture.sqf index 1870d67114..6d8dffdc55 100644 --- a/addons/tagging/functions/fnc_generateStencilTexture.sqf +++ b/addons/tagging/functions/fnc_generateStencilTexture.sqf @@ -29,10 +29,10 @@ params [ ["_dimension", 512, [0]] ]; -if (_textColor select [0, 1] == "#") then { _textColor = _textColor select [1]; }; -if (_backgroundColor select [0, 1] == "#") then { _backgroundColor = _backgroundColor select [1]; }; -if (!((count _textColor) in [6,8])) exitWith { ERROR_1("bad Tcolor %1",_textColor); "" }; -if (!((count _backgroundColor) in [6,8])) exitWith { ERROR_1("bad Bcolor %1",_textColor); "" }; +if (_textColor select [0, 1] == "#") then {_textColor = _textColor select [1];}; +if (_backgroundColor select [0, 1] == "#") then {_backgroundColor = _backgroundColor select [1];}; +if !((count _textColor) in [6,8]) exitWith {ERROR_1("bad Tcolor %1",_textColor); ""}; +if !((count _backgroundColor) in [6,8]) exitWith {ERROR_1("bad Bcolor %1",_textColor); ""}; if (_autoMultiline) then { private _magicWidth = 0.75; diff --git a/addons/tagging/functions/fnc_stencilVehicle.sqf b/addons/tagging/functions/fnc_stencilVehicle.sqf index b2ee99c241..1dfd86a2f9 100644 --- a/addons/tagging/functions/fnc_stencilVehicle.sqf +++ b/addons/tagging/functions/fnc_stencilVehicle.sqf @@ -29,7 +29,7 @@ TRACE_2("",_vehicle,_text); if (!isServer) exitWith {}; if (_text == "") exitWith {}; private _clanSel = getText (configOf _vehicle >> "selectionClan"); -if (!(_clanSel in selectionNames _vehicle)) exitWith { TRACE_1("no tag",_clanSel); }; +if !(_clanSel in selectionNames _vehicle) exitWith {TRACE_1("no tag",_clanSel);}; private _texture = [_text, _textSize, _textColor, "00000000", true] call FUNC(generateStencilTexture); TRACE_1("",_texture); diff --git a/addons/tagging/functions/fnc_tag.sqf b/addons/tagging/functions/fnc_tag.sqf index 4e4310a0cf..f130e1322b 100644 --- a/addons/tagging/functions/fnc_tag.sqf +++ b/addons/tagging/functions/fnc_tag.sqf @@ -45,7 +45,7 @@ if (_intersections isEqualTo []) exitWith { }; (_intersections select 0) params ["_touchingPoint", "_surfaceNormal", "", "_object"]; -TRACE_3("",_touchingPoint, _surfaceNormal, _object); +TRACE_3("",_touchingPoint,_surfaceNormal,_object); // Exit if trying to tag a non static object if ((!isNull _object) && { @@ -60,8 +60,8 @@ if ((!isNull _object) && { }; // If the class is not categorized correctly search the cache - private _modelName = (getModelInfo _object) select 0; - private _isStatic = GVAR(cacheStaticModels) getVariable [_modelName, false]; + private _modelName = toLowerANSI ((getModelInfo _object) select 0); + private _isStatic = _modelName in (uiNamespace getVariable QGVAR(cacheStaticModels)); TRACE_2("Object:",_modelName,_isStatic); // If the class in not on the cache, exit (!_isStatic) @@ -93,7 +93,7 @@ private _vectorDirAndUp = if (abs (_v1 select 2) < 0.94) then { [_v1, _v3] }; -TRACE_3("Reference:", _v1, _v2, _v3); +TRACE_3("Reference:",_v1,_v2,_v3); private _fnc_isOk = { params ["_rx", "_ry"]; diff --git a/addons/tagging/initSettings.sqf b/addons/tagging/initSettings.inc.sqf similarity index 55% rename from addons/tagging/initSettings.sqf rename to addons/tagging/initSettings.inc.sqf index 4fc35b83d1..e05146c081 100644 --- a/addons/tagging/initSettings.sqf +++ b/addons/tagging/initSettings.inc.sqf @@ -4,8 +4,5 @@ private _category = [LELSTRING(common,categoryUncategorized), LLSTRING(Tagging)] QGVAR(quickTag), "LIST", [LLSTRING(QuickTag), LLSTRING(QuickTagDesc)], _category, - [[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1], // [values, titles, defaultIndex] - false, // isGlobal - {[QGVAR(quickTag), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart + [[0,1,2,3], [LELSTRING(Common,Disabled), LLSTRING(LastUsed), LLSTRING(RandomX), LLSTRING(Random)], 1] // [values, titles, defaultIndex] ] call CBA_fnc_addSetting; diff --git a/addons/tagging/stringtable.xml b/addons/tagging/stringtable.xml index 2e2a6d175d..fa54b56b54 100644 --- a/addons/tagging/stringtable.xml +++ b/addons/tagging/stringtable.xml @@ -25,7 +25,7 @@ Konfiguriert, wie das Markieren standardmäßig funktioniert. 태그 시스템의 기본사항을 설정합니다. Configure le fonctionnement par défaut du système de marquage. - Configura quanto il sistema di marcamento agirà da se. + Configura come il sistema di marcamento agirà in maniera predefinita. 定义喷漆系统预设设定 定義噴漆系統預設設定 Configura como o sistema de Marcação funcionará como padrão. (Tagging) @@ -40,7 +40,7 @@ Schnelle Markierung (Spraydose) 스프레이 페인트 - 빠른 태그 Peinture en spray - Marquage rapide - Marcamento Rapido + Marcamento Spray - Rapido 快速喷漆 快速噴漆 Lata de Tinta - Marcação Rápida @@ -51,12 +51,12 @@ Action performed on main tag interaction point. Действие, выполняемое при выборе главного пункта меню маркировки. - メインのインタラクションポイント(タグ)を選択した際に行われる動作。 + メインのインタラクションポイント(タグ)を選択した際に行われるアクション。 Akcja wykonywana na głównym punkcie interakcji tagu. Aktion, die am Haupt-Interaktionspunkt ausgeführt werden soll. 상호작용 시 표시할 낙서를 고릅니다. Type de marquage à appliquer sur le point visé. - Azione eseguita sul punto di interazione dei tag principali. + Azione eseguita sul punto di interazione del tag principale. 直接喷漆在互动菜单瞄准的点上。 直接噴漆在互動選單瞄準的點上。 Ação executada no ponto principal de marcação @@ -87,7 +87,7 @@ Zufällig X 무작위 X X aléatoire - Random X + Randomico X 随机X标记 隨機X標記 Aleatório X @@ -103,7 +103,7 @@ Zufällig 무작위 Aléatoire - Random + Randomico 随机 隨機 Aleatório @@ -151,6 +151,7 @@ Стрелка вверх Flecha Arriba Pfeil Hoch + Freccia in alto Flèche du haut @@ -161,6 +162,7 @@ Стрелка вниз Flecha Abajo Pfeil Runter + Freccia in basso Flèche du bas @@ -171,6 +173,7 @@ Стрелка влево Flecha Izquierda Pfeil Links + Freccia a sinistra Flèche gauche @@ -181,6 +184,7 @@ Стрелка вправо Flecha Derecha Pfeil Rechts + Freccia a destra Flèche droite @@ -191,6 +195,7 @@ Круг Círculo Kreis + Cerchio Cercle @@ -201,16 +206,18 @@ Перекрестие Cruz Kreuz + Croce Croix Diamond - ひし形 + 菱形 Diament 마름모 Алмаз Diamante Diamant + Diamante Losange @@ -221,6 +228,7 @@ Квадрат Cuadrado Quadrat + Quadrato Carré @@ -231,6 +239,7 @@ Заполненный Квадрат Cuadrado Lleno Gefülltes Quadrat + Quadrato pieno Carré rempli @@ -241,6 +250,7 @@ Треугольник Triángulo Dreieck + Triangolo Triangle @@ -251,6 +261,7 @@ Обратный треугольник Triángulo invertido Invertiertes Dreieck + Triangolo capovolto Triangle inversé @@ -263,7 +274,7 @@ Černý sprej Spray de tinta preta Черный спрей - ペイントスプレー缶 (黒色) + スプレーペイント缶 (黒色) 검정 스프레이 黑色喷漆 黑色噴漆 @@ -279,7 +290,7 @@ Červený sprej Spray de tinta vermelha Красный спрей - ペイントスプレー缶 (赤色) + スプレーペイント缶 (赤色) 빨강 스프레이 红色喷漆 紅色噴漆 @@ -295,7 +306,7 @@ Zelený sprej Spray de tinta verde Зелёный спрей - ペイントスプレー缶 (緑色) + スプレーペイント缶 (緑色) 초록 스프레이 绿色喷漆 綠色噴漆 @@ -311,7 +322,7 @@ Modrý sprej Spray de tinta azul Синий спрей - ペイントスプレー缶 (青色) + スプレーペイント缶 (青色) 파랑 스프레이 蓝色喷漆 藍色噴漆 @@ -327,7 +338,7 @@ Žlutý sprej Spray de tinta amarela Желтый спрей - ペイントスプレー缶 (黄色) + スプレーペイント缶 (黄色) 노랑 스프레이 黄色喷漆 黃色噴漆 @@ -343,7 +354,7 @@ Bílý sprej Spray de tinta branca Белый спрей - ペイントスプレー缶 (白色) + スプレーペイント缶 (白色) 하양 스프레이 白色喷漆 白色噴漆 @@ -355,11 +366,11 @@ Lata de pintura en aerosol para marcar. Farba w sprayu, służy do oznakowywania terenu. Une bombe de peinture en spray pour tagger les murs. - Una bomboletta di spay per contrassegnare i muri. + Una bomboletta spay per applicare marker sui muri. Plechovka se sprejem k vytváření značek. Uma lata de tinta spray para marcar paredes. Балончик спрея для рисования маркеров на стенах. - 壁にタグを描くためのペイントスプレー缶。 + 壁にタグを描くためのスプレーペイント缶。 벽에 낙서할 수 있는 스프레이캔 입니다. 喷漆可喷涂在墙壁上 噴漆可噴塗在牆壁上 @@ -369,16 +380,22 @@ 車両IDマーキング Oznaczenie identyfikacyjne pojazdu Fahrzeug ID Markierung + Marcatore identificativo sui veicoli 차량 ID 마킹 Marquage ID des véhicules + Идентификационная маркировка транспортного средства + Marcado Identificativo de Vehículo Replaces clan tag with stenciled text 部隊タグをステンシルテキストに置き換える Zastępuje tag klanu tekstem z szablonu Ersetzt das Clan-Tag durch Schablonentext + Sostituisce l'icona del clan con testo in stampatello 클랜 태그를 스텐실 텍스트로 바꿉니다. Remplace le tag du clan par un texte au pochoir + Заменяет тег клана трафаретным текстом + Reemplaza marca del clan con un texto serigrafiado diff --git a/addons/towing/CfgVehicles.hpp b/addons/towing/CfgVehicles.hpp index df791d95d3..6775a8c9e2 100644 --- a/addons/towing/CfgVehicles.hpp +++ b/addons/towing/CfgVehicles.hpp @@ -1,84 +1,61 @@ -#define TOW_ACTION \ -class ACE_Actions {\ - class ACE_MainActions {\ - class ADDON {\ - displayName = CSTRING(displayName);\ - distance = TOW_ACTION_DISTANCE;\ - condition = QUOTE([ARR_1(_target)] call FUNC(isSuitableSimulation));\ - statement = "";\ - exceptions[] = { INTERACTION_EXCEPTIONS };\ - showDisabled = 0;\ - icon = "";\ - class GVAR(startTow3) {\ - displayName = CSTRING(start3);\ - condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope3')] call EFUNC(common,hasItem));\ - statement = QUOTE([ARR_3(_player,_target,'ACE_rope3')] call FUNC(startTow));\ - exceptions[] = { INTERACTION_EXCEPTIONS };\ - };\ - class GVAR(startTow6) {\ - displayName = CSTRING(start6);\ - condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope6')] call EFUNC(common,hasItem));\ - statement = QUOTE([ARR_3(_player,_target,'ACE_rope6')] call FUNC(startTow));\ - exceptions[] = { INTERACTION_EXCEPTIONS };\ - };\ - class GVAR(startTow12) {\ - displayName = CSTRING(start12);\ - condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope12')] call EFUNC(common,hasItem));\ - statement = QUOTE([ARR_3(_player,_target,'ACE_rope12')] call FUNC(startTow));\ - exceptions[] = { INTERACTION_EXCEPTIONS };\ - };\ - class GVAR(startTow15) {\ - displayName = CSTRING(start15);\ - condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope15')] call EFUNC(common,hasItem));\ - statement = QUOTE([ARR_3(_player,_target,'ACE_rope15')] call FUNC(startTow));\ - exceptions[] = { INTERACTION_EXCEPTIONS };\ - };\ - class GVAR(startTow18) {\ - displayName = CSTRING(start18);\ - condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope18')] call EFUNC(common,hasItem));\ - statement = QUOTE([ARR_3(_player,_target,'ACE_rope18')] call FUNC(startTow));\ - exceptions[] = { INTERACTION_EXCEPTIONS };\ - };\ - class GVAR(startTow27) {\ - displayName = CSTRING(start27);\ - condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope27')] call EFUNC(common,hasItem));\ - statement = QUOTE([ARR_3(_player,_target,'ACE_rope27')] call FUNC(startTow));\ - exceptions[] = { INTERACTION_EXCEPTIONS };\ - };\ - class GVAR(startTow36) {\ - displayName = CSTRING(start36);\ - condition = QUOTE(([ARR_2(_player,_target)] call FUNC(canStartTow)) && [ARR_2(_player,'ACE_rope36')] call EFUNC(common,hasItem));\ - statement = QUOTE([ARR_3(_player,_target,'ACE_rope36')] call FUNC(startTow));\ +#define CONCAT(a,b) a##b +#define TOW_ACTION(length) \ + class GVAR(CONCAT(startTow,length)) {\ + displayName = CSTRING(CONCAT(start,length));\ + condition = QUOTE([ARR_2(_player,'CONCAT(ACE_rope,length)')] call DEFUNC(common,hasItem));\ + statement = QUOTE([ARR_3(_player,_target,'CONCAT(ACE_rope,length)')] call DFUNC(startTow));\ + exceptions[] = { INTERACTION_EXCEPTIONS };\ + } +#define TOW_ACTIONS \ + class ACE_Actions {\ + class ACE_MainActions {\ + class ADDON {\ + displayName = CSTRING(displayName);\ + distance = TOW_ACTION_DISTANCE;\ + condition = QUOTE(alive _target && {_target call DFUNC(isSuitableSimulation)});\ exceptions[] = { INTERACTION_EXCEPTIONS };\ + insertChildren = QUOTE(_target call DFUNC(getDetachActions));\ + TOW_ACTION(3);\ + TOW_ACTION(6);\ + TOW_ACTION(12);\ + TOW_ACTION(15);\ + TOW_ACTION(18);\ + TOW_ACTION(27);\ + TOW_ACTION(36);\ };\ };\ - };\ -} + } class CfgVehicles { class LandVehicle; class Car: LandVehicle { - TOW_ACTION; + TOW_ACTIONS; }; class Tank: LandVehicle { - TOW_ACTION; + TOW_ACTIONS; + }; + + class Ship; + class Ship_F: Ship { + TOW_ACTIONS; }; class ThingX; - class GVAR(hook): ThingX { - displayName = "hook"; // not publicly visible, no stringtable needed + class GVAR(helper): ThingX { + displayName = "helper"; // not publicly visible, no stringtable needed scope = 1; scopeCurator = 1; - model = "\a3\Structures_F_Orange\VR\Helpers\Sign_sphere10cm_Geometry_F.p3d"; + model = "\A3\Weapons_f\empty"; destrType = "DestructNo"; - + }; + class GVAR(hook): GVAR(helper) { + displayName = "hook"; class ACE_Actions { class ACE_MainActions { displayName = CSTRING(detach); - condition = "true"; - statement = QUOTE(private _parent = _target getVariable [ARR_2(QQGVAR(parent),objNull)]; private _child = _target getVariable [ARR_2(QQGVAR(child),objNull)]; [ARR_3(_player,_parent,_child)] call FUNC(detach)); - distance = 2; + statement = QUOTE([ARR_2(_player,_target)] call DFUNC(detachRope)); + distance = TOW_ACTION_DISTANCE; }; }; }; diff --git a/addons/towing/XEH_PREP.hpp b/addons/towing/XEH_PREP.hpp index d26b29e5f0..b72f70c55b 100644 --- a/addons/towing/XEH_PREP.hpp +++ b/addons/towing/XEH_PREP.hpp @@ -1,7 +1,9 @@ PREP(addRopeToVehicle); PREP(attachRopePFH); -PREP(canStartTow); -PREP(detach); +PREP(attachVehicles); +PREP(detachChild); +PREP(detachRope); +PREP(getDetachActions); PREP(isSuitableSimulation); PREP(onMouseButtonDown); PREP(onMouseButtonUp); diff --git a/addons/towing/XEH_postInit.sqf b/addons/towing/XEH_postInit.sqf index 187af19244..01c7d6e48e 100644 --- a/addons/towing/XEH_postInit.sqf +++ b/addons/towing/XEH_postInit.sqf @@ -1,14 +1,40 @@ #include "script_component.hpp" -["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; + ["MouseButtonUp", LINKFUNC(onMouseButtonUp)] call CBA_fnc_addDisplayHandler; GVAR(mouseLeft) = false; GVAR(mouseRight) = false; GVAR(blockFireEHID) = -1; -GVAR(cancel) = false; -GVAR(canAttach) = false; - -[QGVAR(setTowParent), { - params ["_parent", "_child"]; - _child setTowParent _parent; +[QGVAR(ropeAttachTo), { + params ["_child", "_relativeAttachPos", "_rope", "_helper"]; + TRACE_4("ropeAttachTo",_child,_relativeAttachPos,_rope,_helper); + _helper ropeDetach _rope; + [_child, _relativeAttachPos] ropeAttachTo _rope; + deleteVehicle _helper; }] call CBA_fnc_addEventHandler; + +[QGVAR(attachVehicles), LINKFUNC(attachVehicles)] call CBA_fnc_addEventHandler; +[QGVAR(detachChild), LINKFUNC(detachChild)] call CBA_fnc_addEventHandler; + +if (!isServer) exitWith {}; + +[QGVAR(cleanupParent), { + params ["_parent"]; + TRACE_1("cleanupParent",_parent); + _parent removeEventHandler ["RopeBreak", _parent getVariable [QGVAR(RopeBreakEHID), -1]]; + _parent setVariable [QGVAR(RopeBreakEHID), -1]; + private _parentParentHooks = _parent getVariable [QGVAR(parentHooks), []]; + if (_parentParentHooks isEqualTo []) then { + TRACE_1("remove Deleted EH",_parent); + _parent removeEventHandler ["Deleted", _parent getVariable [QGVAR(DeletedEHID), -1]]; + _parent setVariable [QGVAR(DeletedEHID), -1]; + }; +}] call CBA_fnc_addEventHandler; + +addMissionEventHandler ["PlayerConnected", { + if (GVAR(allChildren) isEqualTo []) exitWith {}; + params ["", "", "", "_jip", "_owner"]; + if (!_jip) exitWith {}; + TRACE_2("pushing children",_owner,GVAR(allChildren)); + [QGVAR(setTowParentAllChildren), [GVAR(allChildren)], _owner] call CBA_fnc_ownerEvent; +}]; diff --git a/addons/towing/XEH_preInit.sqf b/addons/towing/XEH_preInit.sqf index 9361d05015..6a85ba442f 100644 --- a/addons/towing/XEH_preInit.sqf +++ b/addons/towing/XEH_preInit.sqf @@ -6,6 +6,22 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" + +// handle JIP +if (isServer) then { + GVAR(allChildren) = []; +} else { + // can't use CBA EH in postInit because too late for server PlayerConnected EH + [QGVAR(setTowParentAllChildren), { + params ["_children"]; + TRACE_1("setTowParentAllChildren",_children); + { + private _parent = _x getVariable QGVAR(parent); + TRACE_2("setTowParent",_x,_parent); + _x setTowParent _parent; + } forEach _children; + }] call CBA_fnc_addEventHandler; +}; ADDON = true; diff --git a/addons/towing/functions/fnc_addRopeToVehicle.sqf b/addons/towing/functions/fnc_addRopeToVehicle.sqf index 4ff0fce62d..9dec1257d0 100644 --- a/addons/towing/functions/fnc_addRopeToVehicle.sqf +++ b/addons/towing/functions/fnc_addRopeToVehicle.sqf @@ -20,8 +20,8 @@ params ["_vehicle"]; if (0 == getNumber (configOf _vehicle >> QEGVAR(cargo,hasCargo))) exitWith {}; -private _ropeType = if ( +private _ropeType = ["ACE_rope6", "ACE_rope12"] select ( -1 < ["Tank", "Wheeled_APC_F", "Truck_F"] findIf {_vehicle isKindOf _x} -) then {"ACE_rope12"} else {"ACE_rope6"}; +); _vehicle addItemCargoGlobal [_ropeType, 1]; diff --git a/addons/towing/functions/fnc_attachRopePFH.sqf b/addons/towing/functions/fnc_attachRopePFH.sqf index e8336ecc25..37f626e0a9 100644 --- a/addons/towing/functions/fnc_attachRopePFH.sqf +++ b/addons/towing/functions/fnc_attachRopePFH.sqf @@ -40,13 +40,32 @@ if (_intersections isNotEqualTo []) then { _intersectionToUse params ["_intersectPosition", "", "_intersectObject"]; - // if we have a target object, we assume we are attaching to the parent. If no target object, we are attaching to child - GVAR(canAttach) = (_intersectObject isNotEqualTo _ignoreParent) && { (!isNull _target && { _intersectObject isEqualTo _target }) || { isNull _target && { [_intersectObject] call FUNC(isSuitableSimulation) }}} && { !(_intersectObject getVariable [QGVAR(towing), false]) }; + GVAR(canAttach) = + _intersectObject isNotEqualTo _ignoreParent + && { + // if we have a target object, we assume we are attaching to the parent. If no target object, we are attaching to child + if (!isNull _target) then { + _intersectObject isEqualTo _target + } else { + [_intersectObject] call FUNC(isSuitableSimulation) + && { // ignore _intersectObject which has parent != _ignoreParent + private _intersectObjectParent = _intersectObject getVariable [QGVAR(parent), objNull]; + isNull _intersectObjectParent || {_intersectObjectParent == _ignoreParent} + } && { // arma prevents making rings (ropeAttachTo silently fails) + private _ancestor = _ignoreParent getVariable [QGVAR(parent), objNull]; + while {!isNull _ancestor && {_ancestor != _intersectObject}} do { + _ancestor = _ancestor getVariable [QGVAR(parent), objNull]; + }; + isNull _ancestor + } + } + } + ; if (GVAR(canAttach)) then { - TRACE_4("can attach",_target,_intersectObject,_ignoreParent,_ignoreRope); + // TRACE_4("can attach",_target,_intersectObject,_ignoreParent,_ignoreRope); GVAR(attachHelper) setPosASL _intersectPosition; - _hintLMB = localize LSTRING(attach); + _hintLMB = LLSTRING(attach); GVAR(attachHelper) setVariable [QGVAR(object), _intersectObject]; }; @@ -76,4 +95,3 @@ if (_hint isNotEqualTo (_unit getVariable [QGVAR(hint), []])) then { _unit setVariable [QGVAR(hint), _hint]; _hint call EFUNC(interaction,showMouseHint); }; - diff --git a/addons/towing/functions/fnc_attachVehicles.sqf b/addons/towing/functions/fnc_attachVehicles.sqf new file mode 100644 index 0000000000..9fd95f3742 --- /dev/null +++ b/addons/towing/functions/fnc_attachVehicles.sqf @@ -0,0 +1,65 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Attaches child to parent vehicle. + * Run globally. + * + * Arguments: + * 0: Vehicle to tow from + * 1: Vehicle to tow + * 2: Rope End Position + * 3: Rope + * 4: Attached Helper Object + * + * Return Value: + * None + * + * Example: + * [parent, cursorObject, [0,0,0], ropes parent select 0] call ace_towing_fnc_attachVehicles + * + * Public: No + */ +params ["_parent", "_child", "_relativeAttachPos", "_rope", "_helper"]; +TRACE_5("attachVehicles",_parent,_child,_relativeAttachPos,_rope,_helper); + +if (local _parent) then { + _helper ropeDetach _rope; + [_child, _relativeAttachPos] ropeAttachTo _rope; + deleteVehicle _helper; +}; + +_child setTowParent _parent; +if (!isServer) exitWith {}; + +_child setVariable [QGVAR(parent), _parent, true]; +GVAR(allChildren) pushBack _child; + +{ + if (-1 == _x getVariable [QGVAR(DeletedEHID), -1]) then { + _x setVariable [QGVAR(DeletedEHID), _x addEventHandler ["Deleted", { + params ["_entity"]; + private _childHooks = _entity getVariable [QGVAR(childHooks), []]; + private _parentHooks = _entity getVariable [QGVAR(parentHooks), []]; + TRACE_3("Deleted EH",_entity,_childHooks,_parentHooks); + { + [objNull, _x, _entity] call FUNC(detachRope); + } forEach (_childHooks + _parentHooks); + if (_childHooks isNotEqualTo []) then { // only for parent + // because deleting lasts for several frames we have to delete RB EH to fix double cleanup + _entity removeEventHandler ["RopeBreak", _entity getVariable QGVAR(RopeBreakEHID)]; + }; + }]]; + }; +} forEach [_parent, _child]; + +if (-1 == _parent getVariable [QGVAR(RopeBreakEHID), -1]) then { + _parent setVariable [QGVAR(RopeBreakEHID), _parent addEventHandler ["RopeBreak", { + params ["_parent", "_rope", "_child"]; + if (isNull _rope) exitWith {}; // happens + private _hook = _rope getVariable [QGVAR(hook), objNull]; + private _hookChild = _hook getVariable [QGVAR(vars), []] param [1, objNull]; + if (isNull _hook || {_child != _hookChild}) exitWith {}; // handle helper detach + TRACE_4("RopeBreak EH",_parent,_rope,_child,_hook); + [objNull, _hook] call FUNC(detachRope); + }]]; +}; diff --git a/addons/towing/functions/fnc_canStartTow.sqf b/addons/towing/functions/fnc_canStartTow.sqf deleted file mode 100644 index 1ffca3df86..0000000000 --- a/addons/towing/functions/fnc_canStartTow.sqf +++ /dev/null @@ -1,21 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Condition for whether or not we can tow from this object - * - * Arguments: - * 0: Unit wanting to start towing - * 1: Vehicle to tow from - * - * Return Value: - * Whether or not we can start towing - * - * Example: - * [player, cursorObject] call ace_towing_fnc_canStartTow - * - * Public: No - */ -params ["_unit", "_target"]; -private _isTowing = _target getVariable [QGVAR(towing), false]; -TRACE_1("is towing",_isTowing); -!_isTowing diff --git a/addons/towing/functions/fnc_detach.sqf b/addons/towing/functions/fnc_detach.sqf deleted file mode 100644 index 92494eae0e..0000000000 --- a/addons/towing/functions/fnc_detach.sqf +++ /dev/null @@ -1,48 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: tcvm - * Detaches child from parent, and gives rope item back - * - * Arguments: - * 0: Parent - * 1: Child - * - * Return Value: - * None - * - * Example: - * [player, cursorObject] call ace_towing_fnc_detach - * - * Public: No - */ -params ["_unit", "_parent", "_child"]; -TRACE_3("detach",_unit,_parent,_child); - -private _hook = _child getVariable [QGVAR(hook), objNull]; - -_parent removeEventHandler ["Deleted", _hook getVariable QGVAR(parentDeleteEventHandler)]; -_hook setVariable [QGVAR(parentDeleteEventHandler), -1]; - -_child removeEventHandler ["Deleted", _hook getVariable QGVAR(childDeleteEventHandler)]; -_hook setVariable [QGVAR(childDeleteEventHandler), -1]; - -_parent removeEventHandler ["RopeBreak", _parent getVariable QGVAR(ropeBreakEventHandler)]; -_parent setVariable [QGVAR(ropeBreakEventHandler), -1]; - -private _rope = _child getVariable [QGVAR(rope), objNull]; -ropeDestroy _rope; - -private _ropeClass = _hook getVariable [QGVAR(ropeClass), ""]; -deleteVehicle _hook; - -TRACE_1("rope",_ropeClass); - -if (_ropeClass isNotEqualTo "") then { - [_unit, _ropeClass, true] call CBA_fnc_addItem; -}; - -[QGVAR(setTowParent), [objNull, _child], _child] call CBA_fnc_targetEvent; - -_child setVariable [QGVAR(towing), false, true]; -_parent setVariable [QGVAR(towing), false, true]; - diff --git a/addons/towing/functions/fnc_detachChild.sqf b/addons/towing/functions/fnc_detachChild.sqf new file mode 100644 index 0000000000..a30f90d8c6 --- /dev/null +++ b/addons/towing/functions/fnc_detachChild.sqf @@ -0,0 +1,33 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Detaches child. + * Run globally. + * + * Arguments: + * 0: Child + * + * Return Value: + * None + * + * Example: + * cursorObject call ace_towing_fnc_detachChild + * + * Public: No + */ +params ["_child"]; +TRACE_1("detachChild",_child); + +_child setTowParent objNull; + +if (!isServer) exitWith {}; + +_child setVariable [QGVAR(parent), objNull, true]; +GVAR(allChildren) = GVAR(allChildren) - [_child]; + +private _childChildHooks = _child getVariable [QGVAR(childHooks), []]; +if (_childChildHooks isEqualTo []) then { + TRACE_1("remove Deleted EH",_child); + _child removeEventHandler ["Deleted", _child getVariable [QGVAR(DeletedEHID), -1]]; + _child setVariable [QGVAR(DeletedEHID), -1]; +}; diff --git a/addons/towing/functions/fnc_detachRope.sqf b/addons/towing/functions/fnc_detachRope.sqf new file mode 100644 index 0000000000..8baed5532d --- /dev/null +++ b/addons/towing/functions/fnc_detachRope.sqf @@ -0,0 +1,60 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Detaches rope of given hook and gives rope item back. + * + * Arguments: + * 0: Player + * 1: Rope Hook + * 2: Deleted object (default: objNull) + * + * Return Value: + * None + * + * Example: + * [player, cursorObject] call ace_towing_fnc_detachRope + * + * Public: No + */ +params ["_unit", "_hook", ["_deletedObject", objNull]]; + +private _hookVars = _hook getVariable QGVAR(vars); +if (isNil "_hookVars") then { // this is hookParent + _hook = _hook getVariable QGVAR(hook); + _hookVars = _hook getVariable QGVAR(vars); +}; + +_hookVars params ["_parent", "_child", "_rope", "_ropeClass", "_hookParent"]; + +TRACE_8("detachRope",_unit,_parent,_child,_hook,_hookParent,_rope,_ropeClass,_deletedObject); + +ropeDestroy _rope; // can run on client + +if (!isNull _unit && {_ropeClass isNotEqualTo ""}) then { + [_unit, _ropeClass, true] call CBA_fnc_addItem; +}; + +{ + detach _x; + deleteVehicle _x; +} forEach [_hook, _hookParent]; + +// cleanup object variables and EHs only if function isn't called from Deleted EH +if (isNull _deletedObject || {_parent isNotEqualTo _deletedObject}) then { + private _parentChildHooks = _parent getVariable [QGVAR(childHooks), []]; + _parentChildHooks = _parentChildHooks - [_hook]; + _parent setVariable [QGVAR(childHooks), _parentChildHooks, true]; + + if (_parentChildHooks isEqualTo []) then { + [QGVAR(cleanupParent), _parent] call CBA_fnc_serverEvent; + }; +}; +if (isNull _deletedObject || {_child isNotEqualTo _deletedObject}) then { + private _childParentHooks = _child getVariable [QGVAR(parentHooks), []]; + _childParentHooks = _childParentHooks - [_hook]; + _child setVariable [QGVAR(parentHooks), _childParentHooks, true]; + + if (_childParentHooks isEqualTo []) then { + [QGVAR(detachChild), _child] call CBA_fnc_globalEvent; + }; +}; diff --git a/addons/towing/functions/fnc_getDetachActions.sqf b/addons/towing/functions/fnc_getDetachActions.sqf new file mode 100644 index 0000000000..4f86220797 --- /dev/null +++ b/addons/towing/functions/fnc_getDetachActions.sqf @@ -0,0 +1,40 @@ +#include "..\script_component.hpp" +/* + * Author: Dystopian + * Creates vehicle detach actions for attached ropes. + * + * Arguments: + * 0: Vehicle + * + * Return Value: + * Detach actions + * + * Example: + * cursorObject call ace_towing_fnc_getDetachActions + * + * Public: No + */ +params ["_vehicle"]; + +private _statement = { + params ["", "_player", "_hook"]; + [_player, _hook] call FUNC(detachRope); +}; + +private _parentHooks = _vehicle getVariable [QGVAR(parentHooks), []]; +private _childHooks = _vehicle getVariable [QGVAR(childHooks), []]; + +(_parentHooks + _childHooks) apply { + private _hook = _x; + _hook getVariable QGVAR(vars) params ["_hookParent", "_hookChild"]; + private _partner = [_hookParent, _hookChild] select (_vehicle == _hookParent); + private _partnerName = getText (configOf _partner >> "displayName"); + private _partnerOwnerName = [_partner, true] call EFUNC(common,getName); + if (_partnerOwnerName != "") then { + _partnerName = format ["%1, %2", _partnerName, _partnerOwnerName]; + }; + private _name = format ["%1 (%2)", LLSTRING(detach), _partnerName]; + private _icon = [_partner] call EFUNC(common,getVehicleIcon); + private _action = [format ["%1", _hook], _name, _icon, _statement, {true}, {}, _hook] call EFUNC(interact_menu,createAction); + [_action, [], _vehicle] +} diff --git a/addons/towing/functions/fnc_isSuitableSimulation.sqf b/addons/towing/functions/fnc_isSuitableSimulation.sqf index c808dc20c4..a4131e6a91 100644 --- a/addons/towing/functions/fnc_isSuitableSimulation.sqf +++ b/addons/towing/functions/fnc_isSuitableSimulation.sqf @@ -19,8 +19,7 @@ params ["_target"]; // need toLower since apparently this isn't case sensitive private _simulationType = getText ((configOf _target) >> "simulation"); -TRACE_1("sim type",_simulationType); +// TRACE_1("sim type",_simulationType); // Biki lies, you can both tow and tow as either TankX or CarX -(toLower _simulationType) in ["tankx", "carx"] - +(toLowerANSI _simulationType) in ["tankx", "carx", "shipx"] diff --git a/addons/towing/functions/fnc_startTow.sqf b/addons/towing/functions/fnc_startTow.sqf index fa70d91cff..33cee1cb7b 100644 --- a/addons/towing/functions/fnc_startTow.sqf +++ b/addons/towing/functions/fnc_startTow.sqf @@ -32,5 +32,6 @@ GVAR(isSwimming) = _unit call EFUNC(common,isSwimming); GVAR(putWeaponAwayNextFrame) = false; GVAR(cancel) = false; GVAR(canAttach) = false; +GVAR(onMouseButtonDownEHID) = ["MouseButtonDown", LINKFUNC(onMouseButtonDown)] call CBA_fnc_addDisplayHandler; [LINKFUNC(towStateMachinePFH), 0, [TOW_STATE_ATTACH_PARENT, _unit, _target, objNull, _ropeLength, _ropeClass]] call CBA_fnc_addPerFrameHandler; [QGVAR(ropeDeployed), [_unit, _target, _ropeClass]] call CBA_fnc_localEvent; diff --git a/addons/towing/functions/fnc_towStateMachinePFH.sqf b/addons/towing/functions/fnc_towStateMachinePFH.sqf index 0adcce76e6..7b295754fa 100644 --- a/addons/towing/functions/fnc_towStateMachinePFH.sqf +++ b/addons/towing/functions/fnc_towStateMachinePFH.sqf @@ -1,7 +1,7 @@ #include "..\script_component.hpp" /* * Author: tcvm - * Called per frame. Handles current unit state for attaching a rope to two vehicles + * Called per frame. Handles current unit state for attaching a rope to two vehicles. * * Arguments: * 0: PFEH Args @@ -44,15 +44,14 @@ if (GVAR(isSwimming) && {currentWeapon _unit isNotEqualTo ""}) then { private _exitCondition = !( (alive GVAR(attachHelper)) && { alive _parent } && - { alive _unit } && + { _unit call EFUNC(common,isAwake) } && { currentWeapon _unit isEqualTo "" || {_unit call EFUNC(common,isSwimming)} // swimming in wetsuit forces weapon in hands || {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 } && - { !(_unit getVariable ["ACE_isUnconscious", false]) } && + { "unconscious" != animationState _unit } && { ACE_player == _unit } ); @@ -62,14 +61,16 @@ if (_exitCondition && {_state < TOW_STATE_CANCEL}) then { switch (_state) do { case TOW_STATE_ATTACH_PARENT: { - TRACE_2("state attach parent",_unit,_parent); + // TRACE_2("state attach parent",_unit,_parent); [_unit, _parent, objNull, objNull, [0, 0, 0], _length] call FUNC(attachRopePFH); if (GVAR(canAttach) && { GVAR(mouseLeft) }) then { _args set [0, TOW_STATE_ATTACH_CHILD]; - _rope = ropeCreate [_parent, _parent worldToModelVisual ASLtoAGL getPosASLVisual GVAR(attachHelper), _length]; - [GVAR(attachHelper), [0, 0, 0]] ropeAttachTo _rope; - + // can't use unit hand because rope doesn't change position when hand moving + // can't use createVehicleLocal because rope can be non-local (like parent) and it must be attached to global vehicle + GVAR(helper) = createVehicle [QGVAR(helper), [0, 0, 0], [], 0, "CAN_COLLIDE"]; + GVAR(helper) attachTo [_unit, [0, 0, 0], "LeftHand", true]; + _rope = ropeCreate [_parent, _parent worldToModelVisual ASLtoAGL getPosASLVisual GVAR(attachHelper), GVAR(helper), [0, 0, 0], _length]; _args set [3, _rope]; }; @@ -79,7 +80,7 @@ switch (_state) do { }; }; case TOW_STATE_ATTACH_CHILD: { - TRACE_3("state attach child",_unit,_parent,_rope); + // TRACE_3("state attach child",_unit,_parent,_rope); [_unit, objNull, _parent, _rope, getPosASLVisual _rope, _length] call FUNC(attachRopePFH); if (GVAR(canAttach) && { GVAR(mouseLeft) }) then { @@ -108,60 +109,42 @@ switch (_state) do { GVAR(cancel) = false; }; - [QGVAR(setTowParent), [_parent, _child], _parent] call CBA_fnc_targetEvent; + detach GVAR(helper); + // can't delete GVAR(helper) without ropeDetach which requires local rope (==parent), so pass it to owner + if (isNull (_child getVariable [QGVAR(parent), objNull])) then { + [QGVAR(attachVehicles), [_parent, _child, _relativeAttachPos, _rope, GVAR(helper)]] call CBA_fnc_globalEvent; + } else { + [QGVAR(ropeAttachTo), [_child, _relativeAttachPos, _rope, GVAR(helper)], _parent] call CBA_fnc_targetEvent; + }; - GVAR(attachHelper) ropeDetach _rope; - [_child, _relativeAttachPos] ropeAttachTo _rope; + private _hookParent = createVehicle [QGVAR(hook), [0, 0, 0], [], 0, "CAN_COLLIDE"]; + _hookParent attachTo [_parent, _parent worldToModelVisual ASLtoAGL getPosASLVisual _rope]; - private _hook = createVehicle [QGVAR(hook), [0, 0, 0], [], 0, "NONE"]; + private _hook = createVehicle [QGVAR(hook), [0, 0, 0], [], 0, "CAN_COLLIDE"]; _hook attachTo [_child, _relativeAttachPos]; - _hook setVariable [QGVAR(parent), _parent, true]; - _hook setVariable [QGVAR(child), _child, true]; - _child setVariable [QGVAR(rope), _rope, true]; - _child setVariable [QGVAR(hook), _hook, true]; + // use array to decrease public setVar count + private _hookVars = [_parent, _child, _rope, _ropeClass, _hookParent]; + _hook setVariable [QGVAR(vars), _hookVars, true]; - _parent setVariable [QGVAR(hook), _hook, true]; + _hookParent setVariable [QGVAR(hook), _hook, true]; + _rope setVariable [QGVAR(hook), _hook, true]; - _hook setVariable [QGVAR(ropeClass), _ropeClass, true]; + private _childParentHooks = _child getVariable [QGVAR(parentHooks), []]; + _childParentHooks pushBack _hook; + _child setVariable [QGVAR(parentHooks), _childParentHooks, true]; - _child setVariable [QGVAR(towing), true, true]; - _parent setVariable [QGVAR(towing), true, true]; - - _hook setVariable [QGVAR(parentDeleteEventHandler), _parent addEventHandler ["Deleted", { - params ["_entity"]; - - private _hook = _entity getVariable [QGVAR(hook), objNull]; - private _child = _hook getVariable [QGVAR(child), objNull]; - private _parent = _hook getVariable [QGVAR(parent), objNull]; - - [objNull, _parent, _child] call FUNC(detach); - }], true]; - - _hook setVariable [QGVAR(childDeleteEventHandler), _child addEventHandler ["Deleted", { - params ["_entity"]; - - private _hook = _entity getVariable [QGVAR(hook), objNull]; - private _child = _hook getVariable [QGVAR(child), objNull]; - private _parent = _hook getVariable [QGVAR(parent), objNull]; - - [objNull, _parent, _child] call FUNC(detach); - }], true]; - - _parent setVariable [QGVAR(ropeBreakEventHandler), _parent addEventHandler ["RopeBreak", { - params ["_parent", "_rope", "_child"]; - - [objNull, _parent, _child] call FUNC(detach); - - _parent removeEventHandler ["RopeBreak", _parent getVariable QGVAR(ropeBreakEventHandler)]; - _parent setVariable [QGVAR(ropeBreakEventHandler), -1]; - }], true]; + private _parentChildHooks = _parent getVariable [QGVAR(childHooks), []]; + _parentChildHooks pushBack _hook; + _parent setVariable [QGVAR(childHooks), _parentChildHooks, true]; _args set [0, TOW_STATE_CLEANUP]; }; case TOW_STATE_CANCEL: { TRACE_1("state cancel",_rope); if !(isNull _rope) then { + detach GVAR(helper); + deleteVehicle GVAR(helper); ropeDestroy _rope; }; [_unit, _ropeClass, true] call CBA_fnc_addItem; @@ -174,6 +157,7 @@ switch (_state) do { TRACE_2("state cleanup",GVAR(attachHelper),_handle); deleteVehicle GVAR(attachHelper); [_handle] call CBA_fnc_removePerFrameHandler; + ["MouseButtonDown", GVAR(onMouseButtonDownEHID)] call CBA_fnc_removeDisplayHandler; _unit setVariable [QGVAR(hint), []]; call EFUNC(interaction,hideMouseHint); if (GVAR(blockFireEHID) != -1) then { diff --git a/addons/towing/initSettings.sqf b/addons/towing/initSettings.inc.sqf similarity index 63% rename from addons/towing/initSettings.sqf rename to addons/towing/initSettings.inc.sqf index 8361dccccd..dbfe326d4c 100644 --- a/addons/towing/initSettings.sqf +++ b/addons/towing/initSettings.inc.sqf @@ -1,13 +1,14 @@ [ QGVAR(addRopeToVehicleInventory), "CHECKBOX", LSTRING(Setting_addRopeToVehicleInventory_DisplayName), - LELSTRING(OptionsMenu,CategoryLogistics), + ELSTRING(main,Category_Logistics), true, true, { if !(_this && {isServer} && {isNil QGVAR(addRopeToVehicleInventory_initialized)}) exitWith {}; GVAR(addRopeToVehicleInventory_initialized) = true; - ["Tank", "initPost", LINKFUNC(addRopeToVehicle), true, [], true] call CBA_fnc_addClassEventHandler; - ["Car", "initPost", LINKFUNC(addRopeToVehicle), true, [], true] call CBA_fnc_addClassEventHandler; + { + [_x, "initPost", LINKFUNC(addRopeToVehicle), true, [], true] call CBA_fnc_addClassEventHandler; + } forEach ["Car", "Ship", "Tank"]; } ] call CBA_fnc_addSetting; diff --git a/addons/towing/script_component.hpp b/addons/towing/script_component.hpp index 2d9790ac20..c52e84046e 100644 --- a/addons/towing/script_component.hpp +++ b/addons/towing/script_component.hpp @@ -24,4 +24,3 @@ #define TOW_STATE_ATTACH 2 #define TOW_STATE_CANCEL 3 #define TOW_STATE_CLEANUP 4 - diff --git a/addons/towing/stringtable.xml b/addons/towing/stringtable.xml index b5cd141bd4..949d36dd48 100644 --- a/addons/towing/stringtable.xml +++ b/addons/towing/stringtable.xml @@ -5,6 +5,7 @@ Towing けん引 Remorquage + Traino Буксирование Abschleppen Holowanie @@ -16,6 +17,7 @@ Attach Tow Rope けん引ロープを取り付け Attacher la corde de remorquage + Attacca la corda di traino Прикрепить буксировочный канат Abschleppseil befestigen Przypnij linkę holowniczą @@ -27,6 +29,7 @@ Attaching Cancelled 取り付けを中止しました Attachage annulé + Attaccamento interrotto Прикрепление отменено Befestigen Abgebrochen Przyczepianie anulowane @@ -38,6 +41,7 @@ Attach Tow Rope (3.2m) けん引ロープ (3.2m) を取り付け Attacher la corde (3,2 m) + Attacca corda di traino (3,2m) Прикрепить буксировочный канат (3.2м) Befestige Seil (3.2m) Przypnij linkę holowniczą (3,2m) @@ -49,6 +53,7 @@ Attach Tow Rope (6.2m) けん引ロープ (6.2m) を取り付け Attacher la corde (6,2 m) + Attacca corda di traino (6,2m) Прикрепить буксировочный канат (6.2м) Befestige Seil (6.2m) Przypnij linkę holowniczą (6,2m) @@ -60,6 +65,7 @@ Attach Tow Rope (12.2m) けん引ロープ (12.2m) を取り付け Attacher la corde (12,2 m) + Attacca corda di traino (12,2m) Прикрепить буксировочный канат (12.2м) Befestige Seil (12.2m) Przypnij linkę holowniczą (12,2m) @@ -71,6 +77,7 @@ Attach Tow Rope (15.2m) けん引ロープ (15.2m) を取り付け Attacher la corde (15,2 m) + Attacca corda di traino (15,2m) Прикрепить буксировочный канат (15.2м) Befestige Seil (15.2m) Przypnij linkę holowniczą (15,2m) @@ -82,6 +89,7 @@ Attach Tow Rope (18.3m) けん引ロープ (18.3m) を取り付け Attacher la corde (18,3 m) + Attacca corda di traino (18,3m) Прикрепить буксировочный канат (18.3м) Befestige Seil (18.3m) Przypnij linkę holowniczą (18,3m) @@ -93,6 +101,7 @@ Attach Tow Rope (27.4m) けん引ロープ (27.4m) を取り付け Attacher la corde (27,4 m) + Attacca corda di traino (27,4m) Прикрепить буксировочный канат (27.4м) Befestige Seil (27.4m) Przypnij linkę holowniczą (27,4m) @@ -104,6 +113,7 @@ Attach Tow Rope (36.6m) けん引ロープ (36.6m) を取り付け Attacher la corde (36,6 m) + Attacca corda di traino (36,6m) Прикрепить буксировочный канат (36.6м) Befestige Seil (36.6m) Przypnij linkę holowniczą (36,6m) @@ -115,6 +125,7 @@ Detach Tow Rope けん引ロープを外す Détacher la corde + Stacca corda di traino Отцепить буксировочный канат Entferne Abschleppseil Odepnij linkę holowniczą @@ -126,6 +137,7 @@ Add Tow Rope to Vehicle Inventory Добавить буксировочный трос в инвентарь машин Dodaj linkę holowniczą do ekwipunku pojazdów + Aggiungi corde di traino all'inventario dei veicoli 차량 소지품에 견인줄 추가 Añadir cuerda de remolcado al inventario del vehículo 車両のインベントリに牽引ロープを追加する diff --git a/addons/trenches/XEH_postInit.sqf b/addons/trenches/XEH_postInit.sqf index ea8ff7e24f..59a6fb8a08 100644 --- a/addons/trenches/XEH_postInit.sqf +++ b/addons/trenches/XEH_postInit.sqf @@ -27,11 +27,11 @@ GVAR(digDirection) = 0; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel dig on player change. This does work when returning to lobby, but not when hard disconnecting. -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; -["loadout", FUNC(handlePlayerInventoryChanged)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["loadout", LINKFUNC(handlePlayerInventoryChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle waking up dragged unit and falling unconscious while dragging -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; //@todo Captivity? diff --git a/addons/trenches/XEH_preInit.sqf b/addons/trenches/XEH_preInit.sqf index 47d20d7c2b..94decd550a 100644 --- a/addons/trenches/XEH_preInit.sqf +++ b/addons/trenches/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(entrenchingTools) = call (uiNamespace getVariable QGVAR(entrenchingTools)); diff --git a/addons/trenches/functions/fnc_blockTrench_place.sqf b/addons/trenches/functions/fnc_blockTrench_place.sqf index f602a871e0..4c0a218307 100644 --- a/addons/trenches/functions/fnc_blockTrench_place.sqf +++ b/addons/trenches/functions/fnc_blockTrench_place.sqf @@ -63,10 +63,10 @@ private _east = (abs (_ax - _bx)) >= (abs (_ay - _by)); private _origin2D = []; private _length = 0; if (_east) then { - _origin2D = if (_ax < _bx) then { _start2d } else { _end2d }; + _origin2D = [_end2d, _start2d] select (_ax < _bx); _length = (abs (_ax - _bx)) / _cellsize; } else { - _origin2D = if (_ay < _by) then { _start2d } else { _end2d }; + _origin2D = [_end2d, _start2d] select (_ay < _by); _length = (abs (_ay - _by)) / _cellsize; }; TRACE_3("",_east,_origin2D,_length); diff --git a/addons/trenches/initSettings.sqf b/addons/trenches/initSettings.inc.sqf similarity index 100% rename from addons/trenches/initSettings.sqf rename to addons/trenches/initSettings.inc.sqf diff --git a/addons/trenches/stringtable.xml b/addons/trenches/stringtable.xml index aaf9c3dd2d..4b47ee6a14 100644 --- a/addons/trenches/stringtable.xml +++ b/addons/trenches/stringtable.xml @@ -20,8 +20,8 @@ Entrenching Tool Saperka, używana do budowy okopów - Mit dem Klappspaten können Erdwälle oder Gräben ausgehoben werden. - Pala da Trincea + Mit dem Klappspaten können Erdwälle oder Gräben ausgehoben werden. + Usata per costruire barriere o scavare trincee. Pala para trincheras Outil permettant de creuser des tranchées. Polní lopatky se používají k zákopovým a jiným pracem. @@ -37,7 +37,7 @@ Envelope - Small Rund - Klein Okop - mały - Fascia - Piccola + Trincea - Piccola Trinchera pequeña Tranchée individuelle Trincheira - Pequena @@ -85,7 +85,7 @@ Envelope - Big Rund - Groß Okop - duży - Fascia - Grande + Trincea - Grande Trinchera grande Grande tranchée Trincheira - Grande @@ -107,7 +107,7 @@ Velký zákop pro jednoho Trincheira pessoal grande Большой персональный окоп - 大型の塹壕を掘る + 大型の個人用塹壕 대형 참호 大型个人掩体 大型個人掩體 @@ -204,7 +204,7 @@ 塹壕を掘りつづける Graben fortsetzen 계속해서 참호파기 - Continuando a Scavare la Trincea + Continua a Scavare la Trincea 继续挖掘掩体 繼續蓋掩體 Kazmaya Devam Et @@ -217,7 +217,7 @@ Retirer la tranchée Убрать окоп Odstranit zákop - 塹壕を消す + 塹壕を撤去 Schützengraben entfernen 참호 제거 Rimuovi Trincea @@ -234,6 +234,7 @@ 참호 위장시키기 Камуфлировать окоп Camuflar trinchera + Camuffa la trincea 塹壕を偽装 Graben tarnen @@ -244,7 +245,7 @@ Retrait de la tranchée Убирание окопа Odstraňuji zákop - 塹壕を消しています + 塹壕を撤去しています Entferne Schützengraben 참호 제거 중 Rimuovendo la Trincea @@ -261,6 +262,7 @@ ACETrincheras ACE Okopy ACE Gräben + ACE Trincee ACE 战壕 ACE 참호 @@ -268,10 +270,11 @@ Small Trench Dig Duration Время копания малого окопа Petites tranchées - durée d'excavation - 小型塹壕の完成時間 + 小型塹壕造成の所要時間 Tiempo de cavar trinchera pequeña Czas kopania małego okopu Kleiner Graben - Aushebungsdauer + Trincea piccola - Durata di scavo 小型战壕挖掘时间 소형참호 건설 시간 @@ -279,10 +282,11 @@ Time, in seconds, required to dig a small trench. Время в секундах, необходимое для рытья малого окопа Définit le temps nécessaire au déploiement des petites tranchées (en secondes). - 小型塹壕が完成するまでの時間 (秒) を設定できます。 + 小型塹壕の造成が完了するまで掛かる時間。 (秒単位) Tiempo, en segundos, requerido para cavar una trinchera pequeña. Czas, w sekundach wymagany do wykopania małego okopu Zeit in Sekunden, um einen kleinen Graben auszuheben. + Tempo in secondi per scavare una trincea piccola. 挖一条小型战壕所需的时间(秒)。 소형 참호를 팔 때 필요한 시간을 설정합니다. (초 단위) @@ -290,10 +294,11 @@ Small Trench Remove Duration Время удаления малого окопа Petites tranchées - durée de retrait - 小型塹壕の削除時間 + 小型塹壕撤去の所要時間 Tiempo de eliminar trinchera pequeña Czas usuwania małego okopu Kleiner Graben - Aufschüttdauer + Trincea piccola - Durata di rimozione 小型战壕回填时间 소형참호 제거 시간 @@ -301,10 +306,11 @@ Time, in seconds, required to remove a small trench. Время в секундах, необходимое для удаления малого окопа Définit le temps nécessaire pour le retrait des petites tranchées (en secondes). - 小型塹壕が削除されるまでの時間 (秒) を設定できます。 + 小型塹壕の撤去が完了するまで掛かる時間。 (秒単位) Tiempo, en segundos, requerido para eliminar una trinchera pequeña. Czas, w sekundach wymagany do usunięcia małego okopu Zeit in Sekunden, um einen kleinen Graben aufzuschütten. + Tempo in secondi per rimuovere una trincea piccola. 回填一条小型战壕所需的时间(秒)。 소형 참호를 제거할때 필요한 시간을 설정합니다. (초 단위) @@ -312,10 +318,11 @@ Big Trench Dig Duration Время рытья большого окопа Grandes tranchées - durée d'excavation - 大型塹壕の完成時間 + 大型塹壕造成の所要時間 Tiempo de cavar trinchera grande Czas kopania dużego okopu Große Graben - Aushebungsdauer + Trincea grande - Durata di scavo 大型战壕挖掘时间 대형참호 건설 시간 @@ -323,10 +330,11 @@ Time, in seconds, required to dig a big trench. Время в секундах, необходимое для рытья большого окопа Définit le temps nécessaire au déploiement des grandes tranchées (en secondes). - 大型塹壕が完成するまでの時間 (秒) を設定できます。 + 大型塹壕の造成が完了するまで掛かる時間。 (秒単位) Tiempo, en segundos, requerido para cavar una trinchera grande Czas, w sekundach wymagany do wykopania dużego okopu Zeit in Sekunden, um einen großen Graben auszuheben. + Tempo in secondi per scavare una trincea grande. 挖一条大型战壕所需的时间(秒)。 대형 참호를 팔때 필요한 시간을 설정합니다. (초 단위) @@ -334,10 +342,11 @@ Big Trench Remove Duration Время удаления большого окопа Grandes tranchées - durée de retrait - 大型塹壕の削除時間 + 大型塹壕撤去の所要時間 Tiempo de eliminar trinchera grande Czas usuwania dużego okopu Kleiner Graben - Aufschüttdauer + Trincea grande - Durata di rimozione 大型战壕回填时间 대형참호 제거 시간 @@ -345,10 +354,11 @@ Time, in seconds, required to remove a big trench. Время в секундах, необходимое для удаления большого окопа Définit le temps nécessaire pour le retrait des grandes tranchées (en secondes). - 大型塹壕が削除されるまでの時間 (秒) を設定できます。 + 大型塹壕の撤去が完了するまで掛かる時間。 (秒単位) Tiempo, en segundos, requerido para eliminar una trinchera grande Czas, w sekundach wymagany do usunięcia dużego okopu Zeit in Sekunden, um einen großen Graben aufzuschütten. + Tempo in secondi per rimuovere una trincea grande. 回填一条大型战壕所需的时间(秒)。 대형 참호를 제거할때 필요한 시간을 설정합니다. (초 단위) diff --git a/addons/tripod/XEH_postInit.sqf b/addons/tripod/XEH_postInit.sqf index 9fbfaa6c8d..febd71390b 100644 --- a/addons/tripod/XEH_postInit.sqf +++ b/addons/tripod/XEH_postInit.sqf @@ -10,10 +10,10 @@ GVAR(height) = 0.5; ["ace_interactMenuOpened", {[ACE_player] call FUNC(handleInteractMenuOpened)}] call CBA_fnc_addEventHandler; // Cancel adjusting on player change. -["unit", FUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; +["unit", LINKFUNC(handlePlayerChanged)] call CBA_fnc_addPlayerEventHandler; ["vehicle", {[ACE_player, objNull] call FUNC(handlePlayerChanged)}] call CBA_fnc_addPlayerEventHandler; // handle falling unconscious -["ace_unconscious", {_this call FUNC(handleUnconscious)}] call CBA_fnc_addEventHandler; +["ace_unconscious", LINKFUNC(handleUnconscious)] call CBA_fnc_addEventHandler; // @todo captivity? diff --git a/addons/tripod/functions/fnc_adjust.sqf b/addons/tripod/functions/fnc_adjust.sqf index db31a0733f..b7cdc842e9 100644 --- a/addons/tripod/functions/fnc_adjust.sqf +++ b/addons/tripod/functions/fnc_adjust.sqf @@ -35,8 +35,7 @@ GVAR(adjustPFH) = [{ { _tripod animate [_x, 1 - GVAR(height)]; - } count ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; - + } forEach ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; }, 0, [_unit, _tripod]] call CBA_fnc_addPerFrameHandler; [_unit, "blockThrow", QUOTE(ADDON), true] call EFUNC(common,statusEffect_set); diff --git a/addons/tripod/functions/fnc_place.sqf b/addons/tripod/functions/fnc_place.sqf index ecefe12784..0109990ded 100644 --- a/addons/tripod/functions/fnc_place.sqf +++ b/addons/tripod/functions/fnc_place.sqf @@ -34,7 +34,7 @@ if (stance _unit == "STAND") then { { _tripod animate [_x, 0.5]; - } count ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; + } forEach ["slide_down_tripod", "retract_leg_1", "retract_leg_2", "retract_leg_3"]; [{ (_this select 0) params ["_tripod", "_direction", "_position"]; diff --git a/addons/tripod/stringtable.xml b/addons/tripod/stringtable.xml index 7934238dfe..8b1c1f6eb8 100644 --- a/addons/tripod/stringtable.xml +++ b/addons/tripod/stringtable.xml @@ -9,7 +9,7 @@ Equipo SSWT Kit SSWT SSWT souprava - SSWT Kit + Kit SSWT SSWT Készlet Kit SSWT SSWT キット @@ -26,7 +26,7 @@ Colocar equipo SSWT Placer le kit SSWT Rozlož souprava SSWT - Place SSWT Kit + Piazza Kit SSWT SSWT készlet elhelyezése Colocar kit SSWT SSWT キットを置く @@ -62,7 +62,7 @@ Régler le kit SSWT SSWT készlet állítása Выровнять снайперский штатив - Aggiusta Kit SSWT + Regola Kit SSWT SSWT キットを調節 SSWT 키트 조절 调整狙击手专用三脚架 diff --git a/addons/ui/XEH_PREP.hpp b/addons/ui/XEH_PREP.hpp index f7edabcc3f..436e59361c 100644 --- a/addons/ui/XEH_PREP.hpp +++ b/addons/ui/XEH_PREP.hpp @@ -1,5 +1,4 @@ PREP(compileConfigUI); -PREP(handlePlayerChanged); PREP(handleSpeedIndicator); PREP(moduleInit); PREP(onAnimChanged); diff --git a/addons/ui/XEH_clientInit.sqf b/addons/ui/XEH_clientInit.sqf index 66aa0b3650..d9d3fa5717 100644 --- a/addons/ui/XEH_clientInit.sqf +++ b/addons/ui/XEH_clientInit.sqf @@ -4,11 +4,11 @@ if (!hasInterface) exitWith {}; // Compile and cache config UI -GVAR(configCache) = call CBA_fnc_createNamespace; +GVAR(configCache) = createHashMap; call FUNC(compileConfigUI); // Scripted API namespace -GVAR(elementsSet) = call CBA_fnc_createNamespace; +GVAR(elementsSet) = createHashMap; // Attach all event handlers where UI has to be updated ["CBA_settingsInitialized", { @@ -19,10 +19,9 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; ["ace_infoDisplayChanged", { // Selective UI Advanced // Defaults must be set in this EH to make sure controls are activated and advanced settings can be modified - private _force = [true, false] select (GVAR(allowSelectiveUI)); { - [_x, missionNamespace getVariable (format [QGVAR(%1), _x]), false, _force] call FUNC(setAdvancedElement); - } forEach (allVariables GVAR(configCache)); + [_x, missionNamespace getVariable (format [QGVAR(%1), _x]), false, !GVAR(allowSelectiveUI)] call FUNC(setAdvancedElement); + } forEach (keys GVAR(configCache)); // Execute local event for when it's safe to modify UI through this API // infoDisplayChanged can execute multiple times, make sure it only happens once @@ -40,13 +39,12 @@ GVAR(elementsSet) = call CBA_fnc_createNamespace; if (_name in ELEMENTS_BASIC) then { [true] call FUNC(setElements); } else { - private _nameNoPrefix = toLower (_name select [7]); - private _cachedElement = GVAR(configCache) getVariable _nameNoPrefix; - if (!isNil "_cachedElement") then { + private _nameNoPrefix = toLowerANSI (_name select [7]); + if (_nameNoPrefix in GVAR(configCache)) then { [_nameNoPrefix, _value, true] call FUNC(setAdvancedElement); }; }; }] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler; -["unit", FUNC(handlePlayerChanged), true] call CBA_fnc_addPlayerEventHandler; +[QUOTE(ADDON), "AnimChanged", LINKFUNC(onAnimChanged), true] call EFUNC(common,addPlayerEH); diff --git a/addons/ui/XEH_preInit.sqf b/addons/ui/XEH_preInit.sqf index 9f2cfd9824..b85b7329b0 100644 --- a/addons/ui/XEH_preInit.sqf +++ b/addons/ui/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(interfaceInitialized) = false; diff --git a/addons/ui/functions/fnc_compileConfigUI.sqf b/addons/ui/functions/fnc_compileConfigUI.sqf index 17eaa27308..960db9aed4 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"); @@ -40,6 +40,6 @@ TRACE_1("Caching Condition",_x); } forEach (configProperties [_x >> "conditions"]); - GVAR(configCache) setVariable [_class, [_idd, _elements, _location, _conditions]]; + GVAR(configCache) set [_class, [_idd, _elements, _location, _conditions]]; }; } forEach ("true" configClasses (configFile >> "ACE_UI")); diff --git a/addons/ui/functions/fnc_handlePlayerChanged.sqf b/addons/ui/functions/fnc_handlePlayerChanged.sqf deleted file mode 100644 index 94f317a18c..0000000000 --- a/addons/ui/functions/fnc_handlePlayerChanged.sqf +++ /dev/null @@ -1,32 +0,0 @@ -#include "..\script_component.hpp" -/* - * Author: veteran29 - * Handles switching units. - * - * Arguments: - * 0: New Unit - * 1: Old Unit - * - * Return Value: - * None - * - * Example: - * [newbob, oldbob] call ace_ui_fnc_handlePlayerChanged - * - * Public: No - */ -params ["_newUnit", "_oldUnit"]; -TRACE_2("unit changed",_newUnit,_oldUnit); - -if (!isNull _oldUnit) then { - _oldUnit removeEventHandler ["AnimChanged", _oldUnit getVariable [QGVAR(animHandler), -1]]; - _oldUnit setVariable [QGVAR(animHandler), nil]; - TRACE_1("remove old",_oldUnit getVariable QGVAR(animHandler)); -}; - -// Don't add a new EH if the unit respawned -if (_newUnit getVariable [QGVAR(animHandler), -1] == -1) then { - private _animHandler = _newUnit addEventHandler ["AnimChanged", LINKFUNC(onAnimChanged)]; - TRACE_1("add new",_animHandler); - _newUnit setVariable [QGVAR(animHandler), _animHandler]; -}; diff --git a/addons/ui/functions/fnc_setAdvancedElement.sqf b/addons/ui/functions/fnc_setAdvancedElement.sqf index 3771bf840b..86a1134802 100644 --- a/addons/ui/functions/fnc_setAdvancedElement.sqf +++ b/addons/ui/functions/fnc_setAdvancedElement.sqf @@ -20,7 +20,9 @@ params ["_element", "_show", ["_showHint", false, [true]], ["_force", false, [true]]]; -private _cachedElement = GVAR(configCache) getVariable _element; +_element = toLowerANSI _element; + +private _cachedElement = GVAR(configCache) get _element; if (isNil "_cachedElement") exitWith {TRACE_1("nil element",_this)}; if (!_force && {!GVAR(allowSelectiveUI)}) exitWith { @@ -56,7 +58,7 @@ if ( // Get setting from scripted API if (!_force) then { - private _setElement = GVAR(elementsSet) getVariable _element; + private _setElement = GVAR(elementsSet) get _element; if (!isNil "_setElement") then { _setElement params ["_sourceSet", "_showSet"]; if (_showHint) then { @@ -68,7 +70,7 @@ if (!_force) then { }; private _displays = ((uiNamespace getVariable "IGUI_displays") + [findDisplay IDD_MISSION]) select {_idd == ctrlIDD _x}; -private _fade = [1, 0] select _show; +private _fade = parseNumber !_show; // Disable/Enable elements private _success = false; diff --git a/addons/ui/functions/fnc_setElementVisibility.sqf b/addons/ui/functions/fnc_setElementVisibility.sqf index 89b8684af7..938fb2da7d 100644 --- a/addons/ui/functions/fnc_setElementVisibility.sqf +++ b/addons/ui/functions/fnc_setElementVisibility.sqf @@ -29,15 +29,14 @@ 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; -if (isNil "_cachedElement") exitWith { +if !(_element in GVAR(configCache)) exitWith { WARNING_2("Element '%1' does not exist - modification by '%2' failed.",_element,_source); }; -private _setElement = GVAR(elementsSet) getVariable _element; +private _setElement = GVAR(elementsSet) get _element; private _return = false; if (isNil "_setElement") then { @@ -45,7 +44,7 @@ if (isNil "_setElement") then { private _success = [_element, _show, false, true] call FUNC(setAdvancedElement); if (_success) then { - GVAR(elementsSet) setVariable [_element, [_source, _show]]; + GVAR(elementsSet) set [_element, [_source, _show]]; _return = true; }; } else { @@ -57,7 +56,7 @@ if (isNil "_setElement") then { }; } else { TRACE_3("Unsetting element",_sourceSet,_element,_show); - GVAR(elementsSet) setVariable [_element, nil]; + GVAR(elementsSet) set [_element, nil]; [_element, _show, false, true] call FUNC(setAdvancedElement); _return = true; diff --git a/addons/ui/initSettings.sqf b/addons/ui/initSettings.inc.sqf similarity index 100% rename from addons/ui/initSettings.sqf rename to addons/ui/initSettings.inc.sqf diff --git a/addons/ui/stringtable.xml b/addons/ui/stringtable.xml index 3627cac678..2578f58c6d 100644 --- a/addons/ui/stringtable.xml +++ b/addons/ui/stringtable.xml @@ -7,7 +7,7 @@ Interface do usuário Interface Utilisateur Интерфейс - ユーザ インタフェイス + ユーザ インタフェース Interfejs użytkownika Benutzeroberfläche 사용자 인터페이스 @@ -23,7 +23,7 @@ Interface do usuário Interface Utilisateur Пользовательский интерфейс - ユーザ インタフェイス + ユーザ インタフェース Interfejs użytkownika Benutzeroberfläche 사용자 인터페이스 @@ -38,11 +38,11 @@ Este módulo permite ligar ou desligar partes da interface do usuário Ce module permet d'activer ou de désactiver certains éléments de l'Interface Utilisateur (IU). Этот модуль позволяет переключать видимость элементов пользовательского интерфейса. - モジュールではユーザ インタフェイスの一部表示を切り替えできます。 + このモジュールではユーザ インタフェースの表示部位の表示状態を切り替えることができます。 Moduł ten pozwala zmienić stan widoczności poszczególnych elementów UI. Dieses Modul erlaubt es, Teile der Benutzeroberfläche (UI) an- oder auszuschalten. 이 모듈은 사용자 인터페이스의 부분을 토글하는 것을 가능케 해줍니다. - Questo modulo consente di commutare parti di interfaccia utente visibili. + Questo modulo consente di selezionare quali parti dell'interfaccia utente sono visibili. 此模块允许你调整用户界面的任何一个控件 此模塊允許你調整使用者介面的任何一個元件 Tento modul umožňuje přepínání viditelných částí uživatelského rozhraní. @@ -54,7 +54,7 @@ Permitir IU Selecionável Autoriser la personnalisation de l'IU Вкл. настраиваемый интерфейс - UI 選択性を許可 + 選択性UIを許可 Zezwól na selektywne UI Erlaube selektives UI 선택적 사용자 인터페이스 허가 @@ -69,7 +69,7 @@ Permite o cliente modificar sua IU. Permet aux clients de modifier leur Interface Utilisateur. Позволить клиентам изменять их пользовательский интерфейс. - クライアントがユーザ インタフェイスを編集できるようにします。 + クライアントがユーザ インタフェースを編集できるようにします。 Zezwól klientowi na modyfikację UI. Erlaube Clients, ihr UI zu modifizieren. 클라이언트가 자신의 사용자 인터페이스를 사용하는 것을 허가합니다 @@ -99,11 +99,11 @@ Radar de Veículo Radar de véhicule Радар в технике - 車両のレーダ + 車両のレーダー Radar w pojeździe Fahrzeugradar 차량 레이더 - Rada Veicolo + Radar Veicolo 载具雷达 載具雷達 Radar de vehículos @@ -115,7 +115,7 @@ Bússola de Veículo Boussole de véhicule Компас в технике - 車両のレーダ + 車両のコンパス Kompas w pojeździe Fahrzeugkompass 차량 나침반 @@ -147,7 +147,7 @@ Barra de Grupo Barre de groupe Панель командира - 指揮メニュー + グループ バー Pasek grupy Gruppenleiste 그룹 막대 @@ -163,8 +163,9 @@ Marca de agua para compilación de desarrollo Filigrane version de développement Znak wodny wersji deweloperskiej - 開発版ウォーターマーク + 開発ビルドでの透かしマーク Wasserzeichen für Entwicklungsversion + Filigrana per versione in fase di sviluppo 开发建设水印 개발용 빌드 워터마크 @@ -190,11 +191,11 @@ Fundo do Nome do Armamento Fond pour le nom de l'arme Фон названия оружия - 武器名の背景表示 + 武器名の背景 Tło nazwy broni Waffenname Hintergrund 무기 이름 배경 - Nome Sfondo Arma + Sfondo Nome Arma 武器名称背景 武器名稱背景 Fondo de nombre de arma @@ -237,7 +238,7 @@ Quantidade de Munição Nombre de munitions Количество боеприпасов - 弾薬数 + 弾数 Ilość amunicji Munitionsanzahl 탄약수 @@ -253,11 +254,11 @@ Quantidade de Carregadores Nombre de chargeurs Количество магазинов - 弾倉装填数 + 弾倉数 Ilość magazynków Magazinanzahl 탄창수 - Contatore Caricatore + Contatore Caricatori 弹匣数量 彈匣數量 Recuento de cargadores @@ -269,11 +270,11 @@ Tipo de Arremessável Type d'objet lançable Тип гранаты - 投げる種類 + 投擲物の種類 Typ granatu Wurfobjekt-Typ 투척물 종류 - Tipo Lanciabile + Tipo di Lanciabile 投掷物类型 投擲物類型 Tipo arrojable @@ -285,7 +286,7 @@ Quantidade de Arremessável Nombre d'objets lançables Количество гранат - 投げられる数 + 投擲物の残数 Ilość granatów Wurfobjekt-Anzahl 투척물 개수 @@ -316,11 +317,11 @@ Informações na parte de baixo do fundo do Armamento Fond pour la barre d'informations inférieure de l'arme Фон информации об оружии снизу - 武器名の背景表示 (下側) + 武器名下部の情報表示の背景 Tło dolnej części informacji o broni Hintergrund der unteren Waffen-Info-Leiste 무기 상세 정보 배경 - Informazioni Sfondo Arma Bassa + Sfondo Informazioni Arma Bassa 武器底部信息栏背景 武器底部資訊欄背景 Fondo de información inferior de arma @@ -348,7 +349,7 @@ Barra de Energia Barre d'endurance Полоса выносливости - 体力バー + スタミナバー Pasek staminy Ausdaueranzeige 지구력 막대 @@ -379,11 +380,11 @@ Fundo do nome da arma do fuzileiro Fond pour le nom de l'arme (tireur) Фон названия орудия наводчика - 射手用の武器名の背景表示 + 射手用の武器名の背景 Tło nazwy broni strzelca Richtschütze Waffenname Hintergrund 사수 무기 명칭 배경 - Nome Sfondo Arma Artigliere + Sfondo Nome Arma Artigliere 炮手武器名称背景 砲手武器名稱背景 Pozadí jména zbraně vozidla @@ -446,7 +447,7 @@ Ilość magazynków strzelca Richtschütze Magazinanzahl 사수 탄창 수량 - Contatore Caricatore Artigliere + Contatore Caricatori Artigliere 炮手弹匣数量 砲手彈匣數量 Počet munice zbraně vozidla @@ -458,7 +459,7 @@ Tipo de Arremessável do fuzileiro Type d'objet lançable (tireur) Тип пусковой установки наводчика - 射手用のランチャーの種類 + 射手用ランチャーの種類 Typ rakiet strzelca Richtschütze Raketentyp 사수 발사체 종류 @@ -473,11 +474,11 @@ Quantidade de Arremessável do fuzileiro Nombre d'objets lançables (tireur) Кол-во снарядов ПУ наводчика - 射手用のランチャー弾薬数 + 射手用ランチャーの弾数 Ilość rakiet strzelca Richtschütze Raketenanzahl 사수 발사체 수량 - Contatore Lanciabili Artigliere + Contatore Missili Artigliere 炮手发射物数量 砲手發射物數量 Počet odpalitelných granátů vozidla @@ -503,11 +504,11 @@ Informações na parte de baixo do fundo do Armamento do fuzileiro Fond pour la barre d'informations inférieure (tireur) Фон информации об орудии наводчика снизу - 射手用の武器名の背景表示 (下側) + 射手用武器名下部の情報表示の背景 Tło dolnej części informacji o broni strzelca Hintergrund der unteren Waffen-Info-Leiste (Richtschütze) 사수 무기 상세 정보 배경 - Informazioni Sfondo Arma Artigliere Bassa + Sfondo Informazioni Arma Artigliere Bassa 炮手武器底部信息栏背景 砲手武器底部資訊欄背景 Nižší pozadí panelu s informacemi o zbrani vozidla @@ -539,7 +540,7 @@ Tło nazwy pojazdu Fahrzeugname Hintergrund 차량 명칭 배경 - Nome Sfondo Veicolo + Sfondo Nome Veicolo 载具名称背景 載具名稱背景 Fondo del nombre del vehículo @@ -598,11 +599,11 @@ Dano do Veículo Dégâts du véhicule Повреждение техники - 車両の損傷表示 + 車両の損傷状態 Uszkodzenia pojazdu Fahrzeugschaden 차량 피해 - Danno Veicolo + Danni Veicolo 载具伤害 載具傷害 Daño vehicular @@ -618,7 +619,7 @@ Tło informacji o pojeździe Fahrzeug Info Hintergrund 차량 정보 배경 - Informazioni Sfondo Veicolo + Sfondo Informazioni Veicolo 载具信息栏背景 載具資訊欄背景 Fondo de información del vehículo @@ -629,11 +630,11 @@ Requer informações de Soldado/Veículo/Armamento Requiert l'option "Information soldat/véhicule/arme". Требуется информация о солдате/технике/оружии. - 兵士/車両/武器の情報を必要とします。 + 兵士/車両/武器の情報 の表示が必要です。 Wymaga informacji o żołnierzu/pojeździe/broni. Benötigt Soldat/Fahrzeug/Waffe Information. 병사/차량/무기의 정보가 필요합니다. - Richiede informazione Soldato/Veicolo/Arma. + Richiede informazioni Soldato/Veicolo/Arma. 需要士兵/载具/武器的信息。 需要士兵/載具/武器的資訊. Requiere información de Soldado/Vehículo. @@ -644,7 +645,7 @@ A modificação da interface do usuário está desabilitada. La personnalisation de l'Interface Utilisateur est désactivée. Изменение пользовательского интерфейса запрещено. - ユーザ インタフェイスの変更は無効化されています。 + ユーザ インタフェースの変更は無効化されています。 Modyfikacja interfejsu użytkownika jest wyłączona. Die Modifizierung des UI ist deaktiviert. 사용자 인터페이스 변경이 비활성화 되어 있습니다. @@ -658,11 +659,11 @@ Não é possível modificar um elemento forçado da interface do usuário. Impossible de modifier un élément forcé de l'Interface Utilisateur. Невозможно изменить зафиксированный элемент пользовательского интерфейса. - ユーザー インタフェイス要素の強制はできません。 + ユーザ インタフェース要素の強制はできません。 Nie można modyfikować wymuszonego elementu interfejsu użytkownika. Gesperrte UI-Elemente können nicht modifiziert werden. 강제 사용자 인터페이스는 변경하실 수 없습니다. - Impossibile modificare un elemento forzato d' Interfaccia Utente. + Impossibile modificare un elemento forzato dell'Interfaccia Utente. 无法编辑已被锁定的用户界面控件 無法編輯已被鎖定的使用者介面元件 Nelze upravit prvek vynuceného uživatelského rozhraní. @@ -675,6 +676,7 @@ Indicateur de vitesse de déplacement Вкл. индикатор скорости передвижения Aktiviere Bewegungsgeschwindigkeits-Indikator + Attiva Indicatore di Velocità 启用移动速度指示器 이동 속도 표시기 활성화 Habilitar indicador de velocidad de movimiento @@ -686,6 +688,7 @@ Affiche un indicateur permettant de visualiser la vitesse de déplacement du personnage. Включает индикатор скорости передвижения персонажа игрока. Aktiviere den Bewegungsgeschwindigkeits-Indikator des Spielers. + Attiva Indicatore di Velocità del Giocatore 为玩家角色启用移动速度指示器。 플레이어 캐릭터를 위한 이동속도 표시기를 활성화합니다. Habilita el indicador de velocidad de movimiento para el personaje del jugador. @@ -700,6 +703,7 @@ Ocultar el icono de acción por defecto Standardaktionssymbol ausblenden Masquer l'icône d'action par défaut + Nascondi Icona dell'Interazione Standard Hides the icon shown automatically when something is in front of the cursor. Requires a game restart.\nWarning: Does not remove the action itself! It is advisable to unbind 'Use default action' key to prevent unwanted interactions. @@ -711,6 +715,7 @@ Oculta el icono que se muestra automáticamente cuando algo se sitúa enfrente del cursor. Requiere reinicio del juego.\nAdvertencia: No elimina la propia acción! Es recomendable desactivar la tecla "Usar acción por defecto" para prevenir interacciones no deseadas. Blendet das Symbol aus, das automatisch angezeigt wird, wenn sich etwas vor dem Cursor befindet. Erfordert einen Neustart des Spiels.\nWarnung: Die Aktion selbst wird nicht entfernt! Es empfiehlt sich, die Belegung der Taste 'Standardaktion verwenden' aufzuheben, um unerwünschte Interaktionen zu verhindern. Cache l'icône qui s'affiche automatiquement lorsque quelque chose est devant le curseur. Nécessite un redémarrage du jeu.\nAvertissement : l'action n'est pas supprimée ! Il est recommandé d'annuler l'affectation du bouton 'Utiliser l'action par défaut' afin d'éviter des interactions indésirables. + Nasconde l'icona mostrata in automatico quando qualcosa è davanti al cursore. La modifica richiede un riavvio del gioco.\nAttenzione: Non rimuovere l'azione stessa! È consigliato rimuovere solo il tasto dall'assegnazione 'Usa Azione Standard' per impedire interazioni non volute. diff --git a/addons/vector/XEH_postInit.sqf b/addons/vector/XEH_postInit.sqf index 12f643ece3..fb76dc5136 100644 --- a/addons/vector/XEH_postInit.sqf +++ b/addons/vector/XEH_postInit.sqf @@ -13,4 +13,4 @@ GVAR(useFeet) = false; GVAR(modeReticle) = 0; GVAR(illuminate) = false; -#include "initKeybinds.sqf" +#include "initKeybinds.inc.sqf" diff --git a/addons/vector/functions/fnc_onKeyDown.sqf b/addons/vector/functions/fnc_onKeyDown.sqf index 24a22a5782..082f22e483 100644 --- a/addons/vector/functions/fnc_onKeyDown.sqf +++ b/addons/vector/functions/fnc_onKeyDown.sqf @@ -38,7 +38,7 @@ private _fnc_setPFH = { }; GVAR(currentMode) = _this; - GVAR(holdKeyHandler) = [FUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; + GVAR(holdKeyHandler) = [LINKFUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; }; switch (_this select 0) do { diff --git a/addons/vector/functions/fnc_onKeyHold.sqf b/addons/vector/functions/fnc_onKeyHold.sqf index 60a38ba96d..f19039851b 100644 --- a/addons/vector/functions/fnc_onKeyHold.sqf +++ b/addons/vector/functions/fnc_onKeyHold.sqf @@ -16,7 +16,7 @@ * Public: No */ -if (!((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"])) exitWith { +if !((currentWeapon ACE_player) isKindOf ["ACE_Vector", configFile >> "CfgWeapons"]) exitWith { [_this select 1] call CBA_fnc_removePerFrameHandler; GVAR(currentMode) = ""; diff --git a/addons/vector/functions/fnc_onKeyUp.sqf b/addons/vector/functions/fnc_onKeyUp.sqf index 11310eb5cf..b660331e65 100644 --- a/addons/vector/functions/fnc_onKeyUp.sqf +++ b/addons/vector/functions/fnc_onKeyUp.sqf @@ -22,7 +22,7 @@ private _fnc_setPFH = { }; GVAR(currentMode) = _this;// - GVAR(holdKeyHandler) = [FUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; + GVAR(holdKeyHandler) = [LINKFUNC(onKeyHold), 0, _this] call CBA_fnc_addPerFrameHandler; }; switch (_this select 0) do { diff --git a/addons/vector/initKeybinds.sqf b/addons/vector/initKeybinds.inc.sqf similarity index 100% rename from addons/vector/initKeybinds.sqf rename to addons/vector/initKeybinds.inc.sqf diff --git a/addons/vector/stringtable.xml b/addons/vector/stringtable.xml index a3451971e7..c28e7078bf 100644 --- a/addons/vector/stringtable.xml +++ b/addons/vector/stringtable.xml @@ -46,7 +46,7 @@ Távolságmérő Medidor de Distância Дальномер - 測距機器 + 測距儀 거리측정기 测距仪 測距儀 diff --git a/addons/vehicle_damage/XEH_PREP.hpp b/addons/vehicle_damage/XEH_PREP.hpp index 524fe6ea9d..a7eb519881 100644 --- a/addons/vehicle_damage/XEH_PREP.hpp +++ b/addons/vehicle_damage/XEH_PREP.hpp @@ -11,3 +11,4 @@ PREP(knockOut); PREP(addDamage); PREP(handleDamageEjectIfDestroyed); PREP(blowOffTurret); +PREP(medicalDamage); diff --git a/addons/vehicle_damage/XEH_postInit.sqf b/addons/vehicle_damage/XEH_postInit.sqf index ce563302e3..9784d335ed 100644 --- a/addons/vehicle_damage/XEH_postInit.sqf +++ b/addons/vehicle_damage/XEH_postInit.sqf @@ -3,12 +3,14 @@ ["ace_settingsInitialized", { TRACE_1("settings init",GVAR(enabled)); if (GVAR(enabled)) then { + [QGVAR(medicalDamage), LINKFUNC(medicalDamage)] call CBA_fnc_addEventHandler; + [QGVAR(bailOut), { params ["_center", "_crewman", "_vehicle"]; TRACE_3("bailOut",_center,_crewman,_vehicle); if (isPlayer _crewman) exitWith {}; - if (!alive _crewman || { !( [_crewman] call EFUNC(common,isAwake))} ) exitWith {}; + if (!alive _crewman || {!([_crewman] call EFUNC(common,isAwake))}) exitWith {}; unassignVehicle _crewman; _crewman leaveVehicle _vehicle; @@ -29,26 +31,14 @@ ["Car", "init", LINKFUNC(addEventHandler), true, [], true] call CBA_fnc_addClassEventHandler; }; - // blow off turret effect - /* - Disabled temporarily due to issues with being able to repair tanks after death. Needs work - */ - /*["Tank", "killed", { - if (random 1 < 0.15) then { + // Blow off turret effect + // TODO: Add blowing-off-turret effect to vehicles that cook-off but aren't destroyed (no catastrophic explosion) + // The problem is that vehicles are repairable if they haven't been destroyed. So if the turret is gone and vehicle is repaired, how do we handle that? + ["Tank", "Killed", { + if (_this select 3 && random 1 < 0.15) then { (_this select 0) call FUNC(blowOffTurret); }; - }, true, [], true] call CBA_fnc_addClassEventHandler;*/ - - // event to add a turret to a curator if the vehicle already belonged to that curator - if (isServer) then { - [QGVAR(addTurretToEditable), { - params ["_vehicle", "_turret"]; - - { - _x addCuratorEditableObjects [[_turret], false]; - } forEach (objectCurators _vehicle); - }] call CBA_fnc_addEventHandler; - }; + }, true, [], true] call CBA_fnc_addClassEventHandler; }; // init eject from destroyed vehicle diff --git a/addons/vehicle_damage/XEH_preInit.sqf b/addons/vehicle_damage/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/vehicle_damage/XEH_preInit.sqf +++ b/addons/vehicle_damage/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/vehicle_damage/functions/fnc_abandon.sqf b/addons/vehicle_damage/functions/fnc_abandon.sqf index 6a9d4eeb29..83b06a80df 100644 --- a/addons/vehicle_damage/functions/fnc_abandon.sqf +++ b/addons/vehicle_damage/functions/fnc_abandon.sqf @@ -18,6 +18,8 @@ params ["_vehicle"]; TRACE_2("abandon",_vehicle,(crew _vehicle) select {alive _x}); +if (_vehicle getVariable [QGVAR(allowCrewInImmobile), false]) exitWith {}; // check for API + [{ params ["_vehicle"]; _vehicle allowCrewInImmobile false; diff --git a/addons/vehicle_damage/functions/fnc_addDamage.sqf b/addons/vehicle_damage/functions/fnc_addDamage.sqf index 75d72da340..35475bd36c 100644 --- a/addons/vehicle_damage/functions/fnc_addDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_addDamage.sqf @@ -37,6 +37,6 @@ if (_hitIndex >= 0) then { _vehicle setHitPointDamage [_hitPoint, _damage, true]; }; -if (_hitPoint isEqualTo "hitengine" && { _damage > 0.9 }) then { - _vehicle call EFUNC(cookoff,engineFire); +if (_hitPoint == "hitengine" && {_damage > 0.9}) then { + [QEGVAR(cookoff,engineFireServer), _vehicle] call CBA_fnc_serverEvent; }; diff --git a/addons/vehicle_damage/functions/fnc_addEventHandler.sqf b/addons/vehicle_damage/functions/fnc_addEventHandler.sqf index ffd64cc77f..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 { @@ -103,7 +103,7 @@ if (isNil "_eh") then { // Maybe its overridden somewhere else, but this makes sure it is the last one [{ params ["_vehicle"]; - TRACE_1("EH not added yet - added eh now", _vehicle); + TRACE_1("EH not added yet - added eh now",_vehicle); private _hd = _vehicle addEventHandler ["HandleDamage", { _this call FUNC(handleDamage) }]; _vehicle setVariable [QGVAR(handleDamage), _hd]; }, [_vehicle]] call CBA_fnc_execNextFrame; diff --git a/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf b/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf index a036f0045b..818fe6f6ef 100644 --- a/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf +++ b/addons/vehicle_damage/functions/fnc_blowOffTurret.sqf @@ -4,7 +4,7 @@ * Blow off turret effect. * * Arguments: - * 0: Vehicle + * 0: Vehicle * * Return Value: * None @@ -15,13 +15,12 @@ * Public: No */ -// delayed so the object is spawned after the model changes to a wreck -// the sudden change in the model would cause nearby physx objects to get stuck +// Delayed so the object is spawned after the model changes to a wreck +// The sudden change in the model would cause nearby PhysX objects to get stuck [{ params ["_vehicle"]; - private _config = _vehicle call CBA_fnc_getObjectConfig; - getArray (_config >> QGVAR(turret)) params [["_model", "", [""]], ["_offset", [0,0,0], [[]], 3]]; + (getArray (configOf _vehicle >> QGVAR(turret))) params [["_model", "", [""]], ["_offset", [0, 0, 0], [[]], 3]]; if (_model isEqualTo "") exitWith {}; @@ -31,6 +30,8 @@ _turret setVectorUp [random 1, random 1, 1]; _turret setVelocity [random 7, random 7, 8 + random 5]; - // add turret to all curators that already own the wreck - [QGVAR(addTurretToEditable), [_vehicle, _turret]] call CBA_fnc_serverEvent; + // Add turret to all curators that already own the wreck + if (["ace_zeus"] call EFUNC(common,isModLoaded)) then { + [QEGVAR(zeus,addObjects), [[_turret], objectCurators _vehicle]] call CBA_fnc_serverEvent; + }; }, _this, 1] call CBA_fnc_waitAndExecute; 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_detonate.sqf b/addons/vehicle_damage/functions/fnc_detonate.sqf index 67d64da442..7f0dce28c9 100644 --- a/addons/vehicle_damage/functions/fnc_detonate.sqf +++ b/addons/vehicle_damage/functions/fnc_detonate.sqf @@ -6,7 +6,6 @@ * Arguments: * 0: The vehicle * 1: Person who caused detonation (default: objNull) - * 2: An array of vehicle ammo in vehicle (default: []) * * Return Value: * None @@ -17,19 +16,12 @@ * Public: No */ -params ["_vehicle", ["_injurer", objNull], ["_vehicleAmmo", []]]; +params ["_vehicle", ["_injurer", objNull]]; -if (_vehicleAmmo isEqualTo []) then { - _vehicleAmmo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); -}; - -([_vehicle] + _vehicleAmmo) call EFUNC(cookoff,detonateAmmunition); - -if ((_vehicleAmmo select 1) > 0) then { +if (((_vehicle call EFUNC(cookoff,getVehicleAmmo)) select 1) > 0) then { { - // random amount of injuries - for "_i" from 0 to random 5 do { - [_x, random 1 , selectRandom ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"], selectRandom ["bullet", "shell", "explosive"], _injurer] call EFUNC(medical,addDamageToUnit); - }; - } forEach crew _vehicle; + [QGVAR(medicalDamage), [_x, _injurer, _injurer], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); }; + +[QEGVAR(cookoff,detonateAmmunitionServer), [_vehicle, false, _injurer, _injurer]] call CBA_fnc_serverEvent; diff --git a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf index a6e7335542..3e7b83ebb6 100644 --- a/addons/vehicle_damage/functions/fnc_handleCookoff.sqf +++ b/addons/vehicle_damage/functions/fnc_handleCookoff.sqf @@ -23,9 +23,12 @@ params ["_vehicle", "_chanceOfFire", "_intensity", ["_injurer", objNull], ["_hitPart", ""], ["_canRing", false], ["_canJet", true]]; -private _alreadyCookingOff = _vehicle getVariable [QGVAR(cookingOff), false]; +// Ignore if the vehicle is already cooking off +if (_vehicle getVariable [QEGVAR(cookoff,isCookingOff), false]) exitWith {true}; -if (!_alreadyCookingOff && { _chanceOfFire >= random 1 }) exitWith { +_chanceOfFire = _chanceOfFire * EGVAR(cookoff,probabilityCoef); + +if (_chanceOfFire >= random 1) exitWith { private _configOf = configOf _vehicle; private _fireDetonateChance = [_configOf >> QGVAR(detonationDuringFireProb), "number", 0] call CBA_fnc_getConfigEntry; if (_canRing) then { @@ -40,32 +43,17 @@ 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"]; }; - // sending nil for _maxIntensity (9th param) to use default value in ace_cookoff_fnc_cookOff - [QEGVAR(cookOff,cookOff), [_vehicle, _intensity, _injurer, _delayWithSmoke, _fireDetonateChance, _detonateAfterCookoff, _source, _canRing, nil, _canJet]] call CBA_fnc_localEvent; - _vehicle setVariable [QGVAR(cookingOff), true]; + [QEGVAR(cookOff,cookOffServer), [_vehicle, _intensity, _injurer, _injurer, _delayWithSmoke, _fireDetonateChance, _detonateAfterCookoff, _source, _canRing, _canJet]] call CBA_fnc_serverEvent; LOG_4("Cooking-off [%1] with a chance-of-fire [%2] - Delayed Smoke | Detonate after cookoff [%3 | %4]",_vehicle,_chanceOfFire,_delayWithSmoke,_detonateAfterCookoff); [_vehicle] spawn FUNC(abandon); LOG_1("[%1] is on fire is bailing",_vehicle); - // cant setVehicleAmmo 0 here because it removes FFV unit's ammo - if (GVAR(removeAmmoDuringCookoff)) then { - private _ammo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); - _ammo params ["_magazines"]; - TRACE_1("removing magazines",_magazines); - { - _x params ["_magazine"]; - _vehicle removeMagazines _magazine; - } forEach _magazines; - }; true }; -// Avoid RPT spam -if (_alreadyCookingOff) exitWith { true }; - LOG_2("[%1] No Cook-off - Chance of fire [%2]",_vehicle,_chanceOfFire); false diff --git a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf index 9556cea424..8f317323fa 100644 --- a/addons/vehicle_damage/functions/fnc_handleDetonation.sqf +++ b/addons/vehicle_damage/functions/fnc_handleDetonation.sqf @@ -21,18 +21,17 @@ */ params ["_vehicle", "_chanceOfDetonate", "_vehicleAmmo", "_explosiveAmmoCount", "_nonExplosiveAmmoCount", ["_injurer", objNull]]; -private _alreadyDetonating = _vehicle getVariable [QGVAR(detonating), false]; + private _isKnockedOut = _explosiveAmmoCount > 0; -if (!_alreadyDetonating && { _chanceOfDetonate >= random 1 }) exitWith { +// Ignore if the vehicle is already detonating ammo +if (_vehicle getVariable [QEGVAR(cookoff,isAmmoDetonating), false]) exitWith {_isKnockedOut}; + +if (_chanceOfDetonate >= random 1) exitWith { [_vehicle, _injurer, _vehicleAmmo] call FUNC(detonate); LOG_2("Detonating [%1] with a chance-to-detonate [%2]",_vehicle,_chanceOfDetonate); - _vehicle setVariable [QGVAR(detonating), true]; _isKnockedOut }; -// Avoid RPT spam -if (_alreadyDetonating) exitWith { _isKnockedOut }; - LOG_2("[%1] No Detonation - Chance of detonation [%2]",_vehicle,_chanceOfDetonate); false diff --git a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf index 01f098efb0..02033b83be 100644 --- a/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf +++ b/addons/vehicle_damage/functions/fnc_handleVehicleDamage.sqf @@ -28,13 +28,13 @@ TRACE_6("handleVehicleDamage",_vehicle,_hitPoint,_hitIndex,_injurer,_oldDamage,_ if !(alive _vehicle) exitWith { private _eventHandler = _vehicle getVariable[QGVAR(handleDamage), nil]; if !(isNil "_eventHandler") then { - _vehicle removeEventHandler ["handleDamage", _eventHandler]; + _vehicle removeEventHandler ["HandleDamage", _eventHandler]; }; LOG_1("Vehicle [%1] no longer alive",_vehicle); true }; -_hitPoint = toLower _hitPoint; +_hitPoint = toLowerANSI _hitPoint; private _hitpointHash = _vehicle getVariable [QGVAR(hitpointHash), []]; private _type = if (_hitpointHash isEqualTo []) then { "exit" diff --git a/addons/vehicle_damage/functions/fnc_medicalDamage.sqf b/addons/vehicle_damage/functions/fnc_medicalDamage.sqf new file mode 100644 index 0000000000..c5234cf1c1 --- /dev/null +++ b/addons/vehicle_damage/functions/fnc_medicalDamage.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Applies medical damage to a unit. + * + * Arguments: + * 0: Target + * 1: Source + * 2: Instigator + * 3: Guarantee death? (default: false) + * + * Return Value: + * None + * + * Example: + * [cursorObject, player, player] call ace_vehicle_damage_fnc_medicalDamage; + * + * Public: No + */ + +params ["_unit", "_source", "_instigator", ["_guaranteeDeath", false]]; + +// Check if unit is invulnerable +if !(isDamageAllowed _unit && {_unit getVariable [QEGVAR(medical,allowDamage), true]}) exitWith {}; + +if (GETEGVAR(medical,enabled,false)) then { + for "_i" from 0 to floor (4 + random 3) do { + [_unit, random [0, 0.66, 1], selectRandom ["Head", "Body", "LeftArm", "RightArm", "LeftLeg", "RightLeg"], selectRandom ["bullet", "shell", "explosive"], _instigator] call EFUNC(medical,addDamageToUnit); + }; +} else { + { + _unit setHitPointDamage [_x, (_unit getHitPointDamage _x) + random [0, 0.66, 1], true, _source, _instigator]; + } forEach ["HitFace", "HitNeck", "HitHead", "HitPelvis", "HitAbdomen", "HitDiaphragm", "HitChest", "HitBody", "HitArms", "HitHands", "HitLegs"]; +}; + +// If guaranteed death is wished +if (_guaranteeDeath && {alive _unit}) then { + [_unit, QGVAR(medicalDamage), _source, _instigator] call EFUNC(common,setDead); +}; diff --git a/addons/vehicle_damage/functions/fnc_processHit.sqf b/addons/vehicle_damage/functions/fnc_processHit.sqf index 48d6ec0055..2402df7fc2 100644 --- a/addons/vehicle_damage/functions/fnc_processHit.sqf +++ b/addons/vehicle_damage/functions/fnc_processHit.sqf @@ -37,12 +37,10 @@ if (_newDamage >= 15) exitWith { TRACE_2("immediate destruction - high damage",_newDamage,_currentPartDamage); [_vehicle] call FUNC(knockOut); [_vehicle, 1] call FUNC(handleDetonation); - // kill everyone inside for very insane damage + // Kill everyone inside for very insane damage { - _x setDamage 1; - _x setVariable [QEGVAR(medical,lastDamageSource), _injurer]; - _x setVariable [QEGVAR(medical,lastInstigator), _injurer]; - } forEach crew _vehicle; + [QGVAR(medicalDamage), [_x, _injurer, _injurer, true], _x] call CBA_fnc_targetEvent; + } forEach (crew _vehicle); _vehicle setDamage 1; _return = false; _return @@ -119,12 +117,12 @@ if (_isCar) then { _ammoEffectiveness = (_ammoEffectiveness + (_ammoEffectiveness * 0.5)) min 1; }; -private _currentVehicleAmmo = [_vehicle] call EFUNC(cookoff,getVehicleAmmo); +private _currentVehicleAmmo = _vehicle call EFUNC(cookoff,getVehicleAmmo); private _chanceOfDetonation = 0; private _explosiveAmmoCount = 0; private _nonExplosiveAmmoCount = 0; -if (count (_currentVehicleAmmo select 0) isNotEqualTo 0) then { +if ((_currentVehicleAmmo select 0) isNotEqualTo []) then { private _magConfig = configFile >> "CfgMagazines"; private _ammoConfig = configFile >> "CfgAmmo"; private _countOfExplodableAmmo = 0; @@ -163,7 +161,7 @@ switch (_hitArea) do { _chanceOfFire = 0; // no cookoff for cars }; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { [_vehicle] call FUNC(knockOut); }; @@ -191,7 +189,7 @@ switch (_hitArea) do { _chanceOfFire = 0; // no cookoff for cars }; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { [_vehicle, _hitIndex, _hitpointName, 0.89 * _penChance] call FUNC(addDamage); [_vehicle] call FUNC(knockOut); }; @@ -248,7 +246,7 @@ switch (_hitArea) do { }; { - TRACE_1("doing damage to hitpoint", _x); + TRACE_1("doing damage to hitpoint",_x); [_vehicle, -1, _x, 1 * _penChance] call FUNC(addDamage); } forEach _partKill; @@ -265,12 +263,12 @@ switch (_hitArea) do { _chanceOfFire = 0; // no cookoff for cars }; - if ([_vehicle, _chanceToDetonate, _currentVehicleAmmo, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { + if ([_vehicle, _chanceToDetonate, _explosiveAmmoCount, _nonExplosiveAmmoCount, _injurer] call FUNC(handleDetonation)) exitWith { [_vehicle] call FUNC(knockOut); }; if (0.8 * _ammoEffectiveness > random 1) then { - TRACE_1("damaged turret", _ammoEffectiveness * 0.8); + TRACE_1("damaged turret",_ammoEffectiveness * 0.8); [_vehicle, _hitIndex, _hitpointName, 1 * _penChance] call FUNC(addDamage); _vehicle setVariable [QGVAR(canShoot), false]; }; diff --git a/addons/vehicle_damage/initSettings.sqf b/addons/vehicle_damage/initSettings.inc.sqf similarity index 62% rename from addons/vehicle_damage/initSettings.sqf rename to addons/vehicle_damage/initSettings.inc.sqf index ae322a6fd8..0d3f324af2 100644 --- a/addons/vehicle_damage/initSettings.sqf +++ b/addons/vehicle_damage/initSettings.inc.sqf @@ -8,16 +8,6 @@ true // Needs mission restart ] call CBA_settings_fnc_init; -[ - QGVAR(removeAmmoDuringCookoff), "CHECKBOX", - [LSTRING(removeAmmoAfterCookoff_setting_enable), LSTRING(removeAmmoAfterCookoff_setting_description)], - LSTRING(category_displayName), - true, // default value - true, // isGlobal - {[QGVAR(removeAmmoDuringCookoff), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false // Needs mission restart -] call CBA_settings_fnc_init; - [ QGVAR(enableCarDamage), "CHECKBOX", [LSTRING(carDamage_setting_enable), LSTRING(carDamage_setting_description)], diff --git a/addons/vehicle_damage/stringtable.xml b/addons/vehicle_damage/stringtable.xml index 0aa4a3bee2..4a8fdb4264 100644 --- a/addons/vehicle_damage/stringtable.xml +++ b/addons/vehicle_damage/stringtable.xml @@ -3,9 +3,10 @@ ACE Advanced Vehicle Damage - ACE 拡張車両ダメージ + ACE アドバンスドビークルダメージ ACE Dégâts de véhicule avancés ACE Erweiterter Fahrzeugsschaden + ACE Danni Veicolo Avanzati ACE Zaawansowany system uszkodzeń pojazdów ACE 高级载具损坏 ACE 고급 차량 피해 @@ -14,9 +15,10 @@ Enable/Disable advanced vehicle damage - 拡張車両ダメージの使用を設定します。 + アドバンスドビークルダメージを有効/無効にする Active les dégâts de véhicule avancés. Aktiviert/Deaktiviert den Erweiterten Fahrzeugsschaden + Abilità danni avanzati ai veicoli Włącz/Wyłącz zaawansowane uszkodzenia pojazdów 启用/禁用高级载具损坏 고급 차량 피해 활성화/비활성화 @@ -25,9 +27,10 @@ Enable/Disable advanced car damage (Experimental) - 拡張車ダメージ (試験的) + アドバンスド車ダメージを有効/無効にする (試験的) Active les dégâts avancés sur les voitures (expérimental). Aktiviert/Deaktiviert den Erweiterten Fahrzeugsschaden (Experimentell) + Abilita danni avanzati ai veicoli (sperimentale) Włącz/Wyłącz zaawansowane uszkodzenia w samochodach (eksperymentalne) 启用/禁用高级车辆损坏(实验性) 고급 차량 피해(실험용) 활성화/비활성화 @@ -35,43 +38,22 @@ Habilita/Deshabilita el daño avanzado de coche (Experimental) - Enable/Disable advanced Car Damage - 拡張車ダメージの使用を設定します。 + Enable/Disable advanced car damage + アドバンスド車ダメージを有効/無効にする Dégâts de voiture avancés Aktiviert/Deaktiviert erweiterten Autoschaden + Abilita danni avanzati alle macchine Włącz/Wyłącz zaawansowane uszkodzenia w samochodach 启用/禁用高级车辆损坏 고급 차량 피해 활성화/비활성화 Продвинутое повреждение машин Habilitar/Deshabilitar daño avanzado de coche (Experimental) - - Removes all vehicle ammo after cook-off - 誘爆後は車両から全ての弾薬を削除します。 - Retire toutes les munitions des véhicules après une auto-inflammation. - Entfernt die gesamte Munition nach dem Durchzünden der Munition eines Fahrzeuges. - Usuwa całą amunicję z pojazdu po samozapłonie - 殉爆后移除所有车辆弹药 - 쿡오프 현상 후 차량에서 모든 탄약을 제거합니다. - Удалять все боеприпасы из техники после их детонации - Elimina toda la munición del vehículo despues ser inducida a detonar por calor - - - Enable/Disable Ammo Removal During Cook-Off - 誘爆後の弾薬処理 - Retirer les munitions durant l'auto-inflammation - Aktiviert/Deaktiviert Entfernung der Munition beim Durchzünden - Włącz/Wyłącz usuwanie amunicji podczas samozapłonu - 启用/禁用殉爆过程中的弹药移除功能 - 쿡오프시 탄약 제거 활성화/비활성화 - Удалять боеприпасы из-за детонации - Habilita/Deshabilita ka eliminación de munición durante la detonación inducida por calor - Wreck (Turret) Épave (tourelle) Restos (torreta) - Rottami (torretta) + Rottame (Torretta) Wrak (wieżyczka) Обломки (башня) Wrack (Geschützturm) diff --git a/addons/vehiclelock/XEH_postInit.sqf b/addons/vehiclelock/XEH_postInit.sqf index 40afaf32af..d16b47aef5 100644 --- a/addons/vehiclelock/XEH_postInit.sqf +++ b/addons/vehiclelock/XEH_postInit.sqf @@ -1,14 +1,14 @@ #include "script_component.hpp" //Add Event Handlers -[QGVAR(setupCustomKey), {_this call FUNC(serverSetupCustomKeyEH)}] call CBA_fnc_addEventHandler; -[QGVAR(setVehicleLock), {_this call FUNC(setVehicleLockEH)}] call CBA_fnc_addEventHandler; +[QGVAR(setupCustomKey), LINKFUNC(serverSetupCustomKeyEH)] call CBA_fnc_addEventHandler; +[QGVAR(setVehicleLock), LINKFUNC(setVehicleLockEH)] call CBA_fnc_addEventHandler; ["CBA_settingsInitialized", { TRACE_2("SettingsInitialized eh",GVAR(LockVehicleInventory),GVAR(VehicleStartingLockState)); if (hasInterface && {GVAR(LockVehicleInventory)}) then { - ["CAManBase", "InventoryOpened", {_this call FUNC(onOpenInventory)}] call CBA_fnc_addClassEventHandler; + ["CAManBase", "InventoryOpened", LINKFUNC(onOpenInventory)] call CBA_fnc_addClassEventHandler; }; if (isServer && {GVAR(VehicleStartingLockState) != -1}) then { [{ diff --git a/addons/vehiclelock/XEH_preInit.sqf b/addons/vehiclelock/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/vehiclelock/XEH_preInit.sqf +++ b/addons/vehiclelock/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf index d730589b36..4d0f065c06 100644 --- a/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf +++ b/addons/vehiclelock/functions/fnc_addKeyForVehicle.sqf @@ -23,14 +23,18 @@ if (!params [["_unit", objNull, [objNull]], ["_veh", objNull, [objNull]], ["_use }; TRACE_3("params",_unit,_veh,_useCustom); -if (isNull _unit) exitWith {ERROR("null unit");}; -if (isNull _veh) exitWith {ERROR("null vehicle");}; +if (isNull _unit) exitWith { + ERROR("null unit"); +}; +if (isNull _veh) exitWith { + ERROR("null vehicle"); +}; if (_useCustom) then { private _previousMags = magazinesDetail _unit; _unit addMagazine ["ACE_key_customKeyMagazine", 1]; //addMagazine array has global effects private _newMags = (magazinesDetail _unit) - _previousMags; - if ((count _newMags) == 0) exitWith {ERROR("failed to add magazine (inventory full?)");}; + if (_newMags isEqualTo []) exitWith {ERROR("failed to add magazine (inventory full?)");}; private _keyMagazine = _newMags select 0; TRACE_2("setting up key on server",_veh,_keyMagazine); //Have the server run add the key to the vehicle's key array: diff --git a/addons/vehiclelock/functions/fnc_lockpick.sqf b/addons/vehiclelock/functions/fnc_lockpick.sqf index 4ef3289b45..7bb29395f0 100644 --- a/addons/vehiclelock/functions/fnc_lockpick.sqf +++ b/addons/vehiclelock/functions/fnc_lockpick.sqf @@ -33,7 +33,10 @@ if ((locked _veh) == 0) exitWith {false}; if !("ACE_key_lockpick" in (_unit call EFUNC(common,uniqueItems))) exitWith {false}; private _vehLockpickStrength = _veh getVariable[QGVAR(lockpickStrength), GVAR(DefaultLockpickStrength)]; -if (!(_vehLockpickStrength isEqualType 0)) exitWith {ERROR("ACE_vehicleLock_LockpickStrength invalid"); false}; +if !(_vehLockpickStrength isEqualType 0) exitWith { + ERROR("ACE_vehicleLock_LockpickStrength invalid"); + false +}; //-1 indicates unpickable lock if (_vehLockpickStrength < 0) exitWith {false}; @@ -45,7 +48,7 @@ private _condition = { ((_unit distance _veh) < 5) && {(speed _veh) < 0.1} }; -if (!([[_unit, _veh]] call _condition)) exitWith {false}; +if !([[_unit, _veh]] call _condition) exitWith {false}; private _returnValue = _funcType in ["canLockpick", "startLockpick", "finishLockpick"]; switch (_funcType) do { diff --git a/addons/vehiclelock/functions/fnc_moduleSync.sqf b/addons/vehiclelock/functions/fnc_moduleSync.sqf index c29c7a06d2..a269fbd6e5 100644 --- a/addons/vehiclelock/functions/fnc_moduleSync.sqf +++ b/addons/vehiclelock/functions/fnc_moduleSync.sqf @@ -22,7 +22,7 @@ if (!isServer) exitWith {}; params ["_logic", "_syncedObjects", "_activated"]; TRACE_3("params",_logic,_syncedObjects,_activated); -if !(_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; +if (!_activated) exitWith {WARNING("Vehicle Lock Sync Module - placed but not active");}; [{ params ["_syncedObjects"]; diff --git a/addons/vehiclelock/functions/fnc_onOpenInventory.sqf b/addons/vehiclelock/functions/fnc_onOpenInventory.sqf index 03562a6180..f8ccc59a0f 100644 --- a/addons/vehiclelock/functions/fnc_onOpenInventory.sqf +++ b/addons/vehiclelock/functions/fnc_onOpenInventory.sqf @@ -37,10 +37,10 @@ if (GVAR(LockVehicleInventory) && //if setting not enabled !isNull (findDisplay 602) }, { - TRACE_1("car display open: closing", _this); + TRACE_1("car display open: closing",_this); (findDisplay 602) closeDisplay 0; [{ - TRACE_1("Opening Player Inventory", _this); + TRACE_1("Opening Player Inventory",_this); ACE_player action ["Gear", objNull]; }, []] call CBA_fnc_execNextFrame; }, []] call CBA_fnc_waitUntilAndExecute; diff --git a/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf b/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf index c34dbb78e2..7b99f093a7 100644 --- a/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf +++ b/addons/vehiclelock/functions/fnc_setVehicleLockEH.sqf @@ -20,5 +20,5 @@ params ["_veh", "_isLocked"]; TRACE_2("params",_veh,_isLocked); private _lockNumber = [0, 2] select _isLocked; -TRACE_2("Setting Lock State", _veh, _lockNumber); +TRACE_2("Setting Lock State",_veh,_lockNumber); _veh lock _lockNumber; diff --git a/addons/vehiclelock/initSettings.sqf b/addons/vehiclelock/initSettings.inc.sqf similarity index 91% rename from addons/vehiclelock/initSettings.sqf rename to addons/vehiclelock/initSettings.inc.sqf index 9f68c77e7c..dcb520e7e2 100644 --- a/addons/vehiclelock/initSettings.sqf +++ b/addons/vehiclelock/initSettings.inc.sqf @@ -3,8 +3,7 @@ [LSTRING(DefaultLockpickStrength_DisplayName), LSTRING(DefaultLockpickStrength_Description)], LSTRING(DisplayName), [-1,60,10,1], // [min, max, default value, trailing decimals (-1 for whole numbers only)] - true, // isGlobal - {[QGVAR(defaultLockpickStrength), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // isGlobal ] call CBA_fnc_addSetting; [ diff --git a/addons/vehiclelock/stringtable.xml b/addons/vehiclelock/stringtable.xml index 6097b9b3b9..b247967fe1 100644 --- a/addons/vehiclelock/stringtable.xml +++ b/addons/vehiclelock/stringtable.xml @@ -28,7 +28,7 @@ Открыть машину Sblocca il Veicolo Destravar veículo - 車両の鍵を開ける + 車両を解錠 차량 잠금해제 载具解锁 載具解鎖 @@ -77,9 +77,9 @@ Páčim vozidlo... Zár feltörése... Взламываем замок... - Scassino il veicolo... + Scassinando il veicolo... Usando Mixa... - 鍵をこじ開けている・・・ + 鍵をこじ開けています・・・ 문따는 중... 正在开锁... 解鎖中... @@ -126,7 +126,7 @@ Sada paklíčů, která dokáže odemknout zámky u většiny vozidel. Egy tolvajkulcs-készlet, mely a legtöbb jármű zárjait fel tudja törni. Набор отмычек, которым можно взломать почти любую машину. - Un grimardello per forzare la maggior parte dei veicoli + Un grimardello per forzare la maggior parte dei veicoli. Um set de chave mixas que pode abrir a maioria dos veículos. ピッキング ツールでは多くの車両をこじ開けられます。 거의 모든 차량을 열 수 있게 해주는 해정도구 모음입니다. @@ -144,7 +144,7 @@ Ключ для открытия большинства машин Красных. Una chiave che apre la maggior parte dei veicoli occidentali Uma chave que abre a maioria dos veículos ocidentais - このキーは多くの同盟軍車両を開けられます。 + このキーは多くのBLUFOR軍車両を開けられます。 거의 모든 청군 진영 차량을 여는 열쇠입니다. 一组解锁钥匙(可解锁大部份蓝方载具) 一組解鎖鑰匙 (可解鎖大部份藍方載具) @@ -158,7 +158,7 @@ Egy kulcs, ami a KELET egységeinek legtöbb járművét ki tudja nyitni. Klíč který by měl otevřít vetšinu Východních vozidel. Ключ для открытия большинства машин Синих. - Una chaive che apre la maggior parte dei veicoli orientali + Una chiave che apre la maggior parte dei veicoli orientali Uma chave que abre a maioria dos veículos orientais このキーは多くのOPFOR軍車両を開けられます。 거의 모든 대항군 진영 차량을 여는 열쇠입니다. @@ -174,9 +174,9 @@ Egy kulcs, ami a FÜGGETLEN egységek legtöbb járművét ki tudja nyitni. Klíč který by měl otevřít většinu Nezávislých vozidel. Ключ для открытия большинства машин Независимых. - Una chaive che apre la maggior parte dei veicoli degli indipendenti + Una chiave che apre la maggior parte dei veicoli degli indipendenti. Uma chave que abre a maioria dos veículos independentes - このキーは多くの独立軍車両を開けられます。 + このキーは多くのINDEPENDENT軍車両を開けられます。 거의 모든 무소속군 진영 차량을 여는 열쇠입니다. 一组解锁钥匙(可解锁大部份独立方载具) 一組解鎖鑰匙 (可解鎖大部份獨立方載具) @@ -190,7 +190,7 @@ Klíč který by měl otevřít většinu Civilních vozidel. Egy kulcs, ami a CIVIL járművek többségét ki tudja nyitni. Ключ для открытия большинства машин Гражданских. - Una chaive che apr ela maggior parte dei veicoli civili + Una chiave che apre la maggior parte dei veicoli civili. Uma chave que abre a maioria dos veículos civis. このキーは多くの市民車両を開けられます。 거의 모든 민간인 차량을 여는 열쇠입니다 @@ -224,7 +224,7 @@ Jármű rakodótér zárás Закрывать инвентарь транспорта Blocca Inventario Veicolo - 施錠されている車両のインベントリ + 車両インベントリをロックする 차량 소지품 잠금 上锁载具的车箱 上鎖載具的車箱 @@ -239,8 +239,8 @@ Verrouille l'inventaire des véhicules fermés à clé. Bezárja a zárt járművek rakterét is Закрывать инвентарь транспорта, если транспорт закрыт - Blocca l'inventario di un veicolo bloccato - 施錠されている車両の開けないインベントリ + Blocca l'inventario di un veicolo bloccato. + 施錠された車両のインベントリをロックします 잠긴 차량의 소지품을 뒤지지 못하게 합니다. 上锁载具的车箱,使玩家不能拿取/查看载具内的装备 上鎖載具的車箱,使玩家不能拿取/查看載具內的裝備 @@ -256,7 +256,7 @@ Jármű kezdő zár-állapot Начальное состояние замков Stato Iniziale del Blocco per Veicoli - 開始時における車両の鍵の状態 + 開始時の車両の鍵の状態 시작 시 차량 잠금 상태 载具初始上锁状态 載具初始上鎖狀態 @@ -280,6 +280,7 @@ Remove Ambiguous Lock State Eliminar estado de bloqueo ambiguo + Rimuovi stati di blocco ambigui Supprimer les états de verrouillage ambigus Устранить неоднозначные состояния замков Usuń niejednoznaczny stan blokady @@ -315,7 +316,7 @@ Zárva Закрыт Bloccato - 施錠ずみ + 施錠済 잠김 上锁 上鎖 @@ -331,7 +332,7 @@ Nyitva Открыт Sbloccato - 開錠ずみ + 解錠済 열림 解锁 解鎖 @@ -346,8 +347,8 @@ Difficulté par défaut du crochetage Alapértelmezett zártörő-erősség Сила отмычки по умолчанию - Durabilità Default del Grimaldello - ピッキング ツールの能力設定 + Durabilità Predefinita del Grimaldello + Lockpickの能力設定 기본 해정도구 설정 预设开锁能力 預設開鎖能力 @@ -363,8 +364,8 @@ Temps par défaut requis pour crocheter une serrure. Valeur par défaut : 10 secondes. Alapértelmezett idő a zárfeltöréshez (másodpercben). Alapértelmezett: 10 Время для взлома замка отмычкой (в секундах). По умолчанию: 10 - Tempo Default richiesto per forzare serrature (in secondi). Default: 10 - ピッキング ツールを使った作業時間の標準設定。(秒) 標準: 10 + Tempo Default richiesto per forzare serrature (in secondi). Predefinito: 10 + Lockpickを使った作業の所要時間の標準設定。 (秒単位) デフォルト: 10 해정을 위해 들이는 기본시간입니다(초 단위). 기본설정: 10 开锁时间(秒)。预设:10 開鎖時間(秒)。預設:10 @@ -380,7 +381,7 @@ Beállítások a zártörő erősségére és alapértelmezett zár-állapotra a járműveken. Eltávolítja az azonosíthatatlan zár-állapotokat. Настройки силы отмычек и начальное состояние замков транспорта. Устраняет неоднозначные состояния замков. Impostazioni per resistenza iniziale delle serrature e stato di blocco dei veicoli. Rimuove stati di blocco ambigui. - ピッキング ツールの能力と車両の鍵の初期状態を設定できます。あいまいな鍵の状態を削除します。 + Lockpickの能力と車両の鍵の初期状態を設定できます。あいまいな鍵の状態を削除します。 해정도구 설정과 시작시 차량의 잠금 상태 그리고 애매한 잠금 상태를 지우는 설정입니다. 设定开锁能力和初始载具上锁状态。移除不明确的锁定状态 設定開鎖能力和初始載具上鎖狀態。移除不明確的鎖定狀態 @@ -412,7 +413,7 @@ Szinkronizál a járművekkel és játékosokkal. Egyedi kulcsokat oszt ki a játékosoknak minden szinkronizált járműhöz. Csak a küldetés indításakor jelenlévő járművekhez érvényes. Синхронизируйте с транспортом и игроком. Это выдаст игроку ключи от всех синхронизированных транспортных средств. Работает только для объектов, присутствующих на старте миссии Sincronizza con veicoli e giocatori. Distribuirà chiavi ai giocatori per ogni veicolo sincronizzato. Valido solo per oggetti presenti ad inizio missione. - 車両とプレイヤへ同期します。プレイヤへ同期された車両のカスタム キーを作ります。これはミッション開始時に作成されたオブジェクトでのみ有効です。 + 車両とプレイヤーへ同期します。プレイヤーへ同期された車両のカスタム キーを作ります。これはミッション開始時に作成されたオブジェクトでのみ有効です。 차량과 플레이어에게 동기화됩니다. 동기화된 차량은 플레이어에게 열쇠를 지급합니다. 오직 미션 시작 시에 생긴 물체들만 유효합니다. 可同步在载具与玩家身上。将使被同步的玩家掌握其他被同步载具的钥匙。此模块只会在任务刚开始时触发。 可同步在載具與玩家身上。將使被同步的玩家掌握其他被同步載具的鑰匙。此模塊只會在任務剛開始時觸發 diff --git a/addons/vehicles/XEH_preInit.sqf b/addons/vehicles/XEH_preInit.sqf index 028a8aec1c..70cd66e1cc 100644 --- a/addons/vehicles/XEH_preInit.sqf +++ b/addons/vehicles/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" [ "AllVehicles", diff --git a/addons/vehicles/initSettings.sqf b/addons/vehicles/initSettings.inc.sqf similarity index 100% rename from addons/vehicles/initSettings.sqf rename to addons/vehicles/initSettings.inc.sqf diff --git a/addons/vehicles/stringtable.xml b/addons/vehicles/stringtable.xml index 0c3c5bd2f4..741901d75c 100644 --- a/addons/vehicles/stringtable.xml +++ b/addons/vehicles/stringtable.xml @@ -25,6 +25,7 @@ Tempomat włączony クルーズコントロールを有効化 开启巡航模式 + Controllo di Velocità Attivo Круиз-контроль включён Control de crucero encendido Régulateur de vitesse activé @@ -53,6 +54,7 @@ Tempomat wyłączony クルーズコントロールを無効化 关闭巡航模式 + Controllo di Velocità Non Attivo Круиз-контроль выключен Control de crucero apagado Régulateur de vitesse désactivé @@ -97,6 +99,7 @@ Tempomat クルーズコントロール 巡航模式 + Controllo di Velocità Круиз-контроль Contro de crucero Régulateur de vitesse @@ -145,7 +148,7 @@ 关闭引擎自动熄火 Désactiver l'arrêt automatique du moteur Wyłącz automatyczne wyłączanie silnika - Disattivare lo spegnimento automatico del motore + Disattiva lo spegnimento automatico del motore Otomatik motor durdurmayı devre dışı bırak 자동으로 엔진 끄기 비활성화 @@ -159,7 +162,7 @@ Zabraň automatickému vypnutí motoru při opuštění vozidla. 避免離開載具時自動熄火。 避免离开载具时自动熄火。 - Impedire lo spegnimento automatico del motore quando si esce dai veicoli. + Impedisce lo spegnimento automatico del motore quando si esce dai veicoli. Empêche l'arrêt automatique du moteur à la sortie des véhicules. Araçtan inerken motorun otomatik kapatılmasını engelleyin. Zapobiegaj automatycznemu wyłączaniu silnika podczas wychodzenia z pojazdu. @@ -185,7 +188,7 @@ Versteckt den Abspringen-Eintrag aus dem Aktionsmenü. Benötigt Neustart des Spiels. Usuwa akcję Wyskocz z menu akcji. Wymaga restartu gry. Убирает действие 'Выпрыгнуть' из меню. (Требует перезагрузки) - アクション メニューから脱出アクションを消します。ゲームの再起動が必要です。 + アクションメニューから脱出アクションを消します。ゲームの再起動が必要です。 Oculta a opção de interação para ejetar. Requer que o jogo seja reiniciado. Oculta la entrada Expulsar del menú de acciones. Requiere un reinicio del juego. 隱藏在動作選單中逃脫動作的選項。要求遊戲重新啟動。 @@ -200,6 +203,7 @@ Schrittgröße des Geschwindigkeitsbegrenzers Przeskok limitera prędkości Pas du limiteur de vitesse + Intervalli del Limitatore di Velocità 制限速度の増減量 Krokování omezovače rychlosti Шаг ограничителя скорости diff --git a/addons/viewdistance/XEH_preInit.sqf b/addons/viewdistance/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/viewdistance/XEH_preInit.sqf +++ b/addons/viewdistance/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/viewdistance/functions/fnc_changeViewDistance.sqf b/addons/viewdistance/functions/fnc_changeViewDistance.sqf index 84ba31d285..b7fb192db2 100644 --- a/addons/viewdistance/functions/fnc_changeViewDistance.sqf +++ b/addons/viewdistance/functions/fnc_changeViewDistance.sqf @@ -41,7 +41,7 @@ if (_objectViewDistanceCoeff isEqualType 0) then { } else { if (isNil QGVAR(fovBasedPFHminimalViewDistance)) then { GVAR(fovBasedPFHminimalViewDistance) = getObjectViewDistance select 0; // Minimal view distance holder and PFH isRunning variable - [FUNC(setFovBasedOvdPFH), 0, []] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(setFovBasedOvdPFH), 0, []] call CBA_fnc_addPerFrameHandler; }; }; diff --git a/addons/viewdistance/initSettings.sqf b/addons/viewdistance/initSettings.inc.sqf similarity index 100% rename from addons/viewdistance/initSettings.sqf rename to addons/viewdistance/initSettings.inc.sqf diff --git a/addons/viewdistance/stringtable.xml b/addons/viewdistance/stringtable.xml index b974c6291e..eb7ed94838 100644 --- a/addons/viewdistance/stringtable.xml +++ b/addons/viewdistance/stringtable.xml @@ -12,7 +12,7 @@ Látótáv-korlátozó Ограничитель дальности видимости Limitatore Distanza Visiva - 視界距離の制限 + 視界距離を制限 시야 제한기 视距限制器 視野距離限制器 @@ -29,7 +29,7 @@ Lehetővé teszi a játékosok által a látótávolság maximumának korlátozását. Позволяет ограничить максимальную дальность видимости, которая может быть установлена игроками. Consente di limitare la distanza visiva massima che può essere impostata dai giocatori. - プレイヤーへ最大の視界距離を制限できます。 + プレイヤーが設定できる最大視界距離を制限できます。 플레이어가 볼 수 있는 최대 시야를 제한합니다. 允许玩家最大的可视距离 允許玩家最大的可視距離 @@ -96,7 +96,7 @@ Korlátozza, mekkora látótávolságot állíthatnak be a kliensek (maximum 10000-ig) Устанавливает предел дальности, насколько клиенты могут увеличить свою дальность видимости (до 10000) Imposta il limite massimo a cui i client possono alzare la propria distanza visiva (massimo 10000) - 各クライアントが最大まで設定できる視界距離を設定します。(最大 10000) + 各クライアントが設定できる視界距離の上限 (最大 10000) 클라이언트가 최대 얼마나 멀리 볼 수 있는지 제한을 둡니다 (10000 까지 가능) 设定客户端最高可显示的视距(最高至10000) 設定客戶端最高可顯示的視野距離 (最高至10000) @@ -113,7 +113,7 @@ A kliens látótávolsága itt állítható be, és felülbírálható modulok által Предел дальности видимости клиентов устанавливается здесь и может быть переопределен модулем Limite per la distanza visiva del client impostato qui e può essere scavalcato dal modulo - クライアントへの視界距離の設定や、それをモジュールにより上書きできます + クライアントの表示距離の制限はここで設定され、モジュールによって上書きできます 클라이언트의 시야를 이 모듈로 덮어씌울 수 있습니다. 玩家的视距限制可在此设定,也可透过模块改写 玩家的視距限制可在此設定,也可透過模塊改寫 @@ -123,10 +123,12 @@ 设置为0将使用默认的视频设置 0으로 설정시 기존 비디오 설정을 사용합니다. Bei Einstellung auf 0 werden die Standard-Videoeinstellungen verwendet. + Se impostato su 0 verranno usate le impostazioni video predefinite. Ustawienie na 0, spowoduje użycie domyślnych ustawień wideo. 0に設定すると、デフォルトのビデオ設定が使用されます Значение 0 будет использовать настройки видео по умолчанию Establecer a 0 utiliza las opciones de video por defecto + La valeur 0 permet d'utiliser les paramètres vidéo par défaut Client View Distance (On Foot) @@ -190,7 +192,7 @@ Megváltoztatja a játékon belüli látótávolságot, amennyiben a játékos szárazföldi járműben van. Изменяет дальность видимости в игре, когда игрок перемещается в наземном транспорте. Cambia la distanza visiva in gioco quando il giocatore è in un veicolo terrestre. - プレイヤーが車両の時の視界距離を変更します。 + プレイヤーが車両に乗っている時の視界距離を変更します。 플레이어가 차량 내부일 경우의 시야를 바꿀 수 있습니다. 改变玩家于地面载具内时的视距 改變玩家於地面載具內時的視野距離 @@ -241,7 +243,7 @@ Dinamikus objektum-látótáv Динамич. дальность отрисовки объектов Distanza Visiva Oggetti Dinamica - 動的なオブジェクトの描画距離 + 動的なオブジェクト描画距離 동적 물체 시야 动态物体的视距 動態物件的視野距離 @@ -257,7 +259,7 @@ Beállítja az objektum-látótávot a megadott látótáv koefficienseként. Устанавливает дальность отрисовки объектов как коэффициент от общей дальности видимости. Imposta la distanza visiva degli oggetti come un coefficiente basato sulla distanza visiva oppure basato sul campo visivo. - 視野角を元にするか、視界距離によるオブジェクト描画距離を決定します。視野角を元にするオプションを有効化した場合、視野角により最低と最高値が変動します。 + オブジェクト描画距離を視界距離の係数として、または視野角に基づいて設定します。視野角を元にするオプションを有効化した場合、視野角により最低と最高値が変動します。 설정된 시야 혹은 시야각(FoV)에 계수를 적용해 물체 시야를 적용합니다. 시야각를 바탕으로 하는 옵션을 활성화할 경우 시야각에 의한 최저와 최고치가 변동됩니다. 设定物体可被观察的距离,透过视距或是视野角度来决定。 設定物件可被觀察的距離,透過視野距離或是視野角度來決定。 @@ -290,7 +292,7 @@ Minimális Очень низкая Molto Basso - 最低 + 非常に低い 매우 낮음 非常低 非常低 @@ -307,7 +309,7 @@ Alacsony Низкая Basso - + 低い 낮음 @@ -324,7 +326,7 @@ Közepes Средняя Medio - 通常 + 중간 @@ -341,7 +343,7 @@ Magas Высокая Alto - + 高い 높음 @@ -358,7 +360,7 @@ Maximális Очень высокая Molto Alto - 最高 + 非常に高い 매우 높음 非常高 非常高 @@ -440,7 +442,7 @@ Videobeállítások Видео настройки Impostazioni Video - 映像設定 + 描画設定 영상 설정 影像设定 影像設定 diff --git a/addons/viewports/XEH_preInit.sqf b/addons/viewports/XEH_preInit.sqf index a8940fc7dd..ec82c949b1 100644 --- a/addons/viewports/XEH_preInit.sqf +++ b/addons/viewports/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" #ifdef POINT_CONFIG_DEBUG call compileScript [QPATHTOF(dev\debugPoints.sqf)]; diff --git a/addons/viewports/dev/debugPoints.sqf b/addons/viewports/dev/debugPoints.sqf index 24b393d70f..53fe016b62 100644 --- a/addons/viewports/dev/debugPoints.sqf +++ b/addons/viewports/dev/debugPoints.sqf @@ -22,7 +22,7 @@ #define IDD_3DEN 313 [] spawn { - INFO_2("Pre-Init [is3den %1][3den display: %2]", is3den, !isNull findDisplay IDD_3DEN); + INFO_2("Pre-Init [is3den %1][3den display: %2]",is3den,!isNull findDisplay IDD_3DEN); if (!is3den) exitWith {}; GVAR(3denIndex) = 0; diff --git a/addons/viewports/functions/fnc_eachFrame.sqf b/addons/viewports/functions/fnc_eachFrame.sqf index 6bb452baad..21f2f09dc8 100644 --- a/addons/viewports/functions/fnc_eachFrame.sqf +++ b/addons/viewports/functions/fnc_eachFrame.sqf @@ -27,7 +27,7 @@ private _newIndex = -1; if (cba_events_control) then { if (cameraView != "INTERNAL") exitWith {}; if (isTurnedOut _player) exitWith {}; - if (!([_player, _vehicle, []] call EFUNC(common,canInteractWith))) exitWith {}; + if !([_player, _vehicle, []] call EFUNC(common,canInteractWith)) exitWith {}; BEGIN_COUNTER(newIndex); if ((_shownIndex > -1) && {currentVisionMode _player != _lastVisionMode}) then { @@ -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_getSeatInfo.sqf b/addons/viewports/functions/fnc_getSeatInfo.sqf index 86dccebdd1..01c71c3cfe 100644 --- a/addons/viewports/functions/fnc_getSeatInfo.sqf +++ b/addons/viewports/functions/fnc_getSeatInfo.sqf @@ -41,6 +41,6 @@ private _compartment = switch (_role) do { }; }; -if (!(_compartment isEqualType "")) then { _compartment = format ["Compartment%1",_compartment] }; +if !(_compartment isEqualType "") then {_compartment = format ["Compartment%1",_compartment]}; [_role, _cargoIndex, _turretPath, _compartment] 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/viewports/initSettings.sqf b/addons/viewports/initSettings.inc.sqf similarity index 100% rename from addons/viewports/initSettings.sqf rename to addons/viewports/initSettings.inc.sqf diff --git a/addons/viewports/stringtable.xml b/addons/viewports/stringtable.xml index dcef7ae4ff..be78cdc995 100644 --- a/addons/viewports/stringtable.xml +++ b/addons/viewports/stringtable.xml @@ -6,6 +6,7 @@ ビューポート 뷰포트 观察口 + Periscopi Wizjery Триплексы Periscopios @@ -15,9 +16,10 @@ Allows crew to look through periscopes Pozwala załodze patrzeć przez peryskop - 乗組員がペリスコープを通して外を見ることができます + 乗組員がペリスコープを通して外を見ることができるようにします 승무원이 잠망경을 통해 볼 수 있도록 허용합니다 允许乘员通过观察口观察 + Permetti all'equipaggio di guardare attraverso periscopi Разрешить экипажу смотреть сквозь перископ Permite a la tripulación asomarse a través de los periscopios Ermöglicht der Besatzung den Blick durch Periskope diff --git a/addons/viewrestriction/XEH_clientInit.sqf b/addons/viewrestriction/XEH_clientInit.sqf index 21455af21b..1ed4f008da 100644 --- a/addons/viewrestriction/XEH_clientInit.sqf +++ b/addons/viewrestriction/XEH_clientInit.sqf @@ -19,7 +19,7 @@ if !(hasInterface) exitWith {}; }; // Exit if third person view is not available - if (difficultyOption "thirdPersonView" == 0) exitWith { + if (difficultyOption "thirdPersonView" != 1) exitWith { WARNING("View Restriction is enabled, but 3rd person is disabled with server difficulty."); }; diff --git a/addons/viewrestriction/XEH_preInit.sqf b/addons/viewrestriction/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/viewrestriction/XEH_preInit.sqf +++ b/addons/viewrestriction/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/viewrestriction/functions/fnc_changeCamera.sqf b/addons/viewrestriction/functions/fnc_changeCamera.sqf index 6a1f7d03ff..eb6907386a 100644 --- a/addons/viewrestriction/functions/fnc_changeCamera.sqf +++ b/addons/viewrestriction/functions/fnc_changeCamera.sqf @@ -18,7 +18,7 @@ params ["_newCameraView", "_cameraOn"]; -if (! ([_newCameraView, _cameraOn] call FUNC(canChangeCamera))) exitWith {}; +if !([_newCameraView, _cameraOn] call FUNC(canChangeCamera)) exitWith {}; TRACE_1("View Restricted",XGVAR(mode)); diff --git a/addons/viewrestriction/initSettings.sqf b/addons/viewrestriction/initSettings.inc.sqf similarity index 92% rename from addons/viewrestriction/initSettings.sqf rename to addons/viewrestriction/initSettings.inc.sqf index 3ed47c10ef..80382f5b19 100644 --- a/addons/viewrestriction/initSettings.sqf +++ b/addons/viewrestriction/initSettings.inc.sqf @@ -6,7 +6,7 @@ [[0, 1, 2, 3], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson), LSTRING(Selective)], 0], true, {[QGVAR(mode), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -17,7 +17,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveFoot), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -28,7 +28,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveLand), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -39,7 +39,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveAir), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ @@ -50,7 +50,7 @@ [[0, 1, 2], [LSTRING(Disabled), LSTRING(FirstPerson), LSTRING(ThirdPerson)], 0], true, {[QGVAR(modeSelectiveSea), _this] call EFUNC(common,cbaSettings_settingChanged)}, - true + true // Needs mission restart ] call CBA_fnc_addSetting; [ diff --git a/addons/viewrestriction/stringtable.xml b/addons/viewrestriction/stringtable.xml index bd3cc65895..fee4a9bf33 100644 --- a/addons/viewrestriction/stringtable.xml +++ b/addons/viewrestriction/stringtable.xml @@ -11,7 +11,7 @@ Restriction Vue 人称限制 視野限制 - Visualizza Restrizione + Restrizione di Visuale Ограничение обзора Görüntüyü Kısıtla Reestricción de Vista @@ -25,7 +25,7 @@ La restriction de la vue limite l'usage de la vue à la 1ère/3ème personne globalement ou par type de véhicule. 人称限制可以设定在全局或是局部状况下能用的人称模式。 視野限制可以設定在全局或是局部狀況下能用的視野模式。 - Visualizza le impostazioni di restrizione per limitare l'utilizzo di prima e terza persona a livello globale o per tipologia di veicolo. + Impostazioni di restrizione visuale per limitare l'utilizzo di prima e terza persona a livello globale o per tipologia di veicolo. Настройки ограничения обзора при виде от 1-го или 3-го лица. Общие для всех, или Выборочные, в зависимости от техники. 1. veya 3. kişi görünümlerinin kullanımını genel olarak veya araç türüne göre sınırlamak için kısıtlama ayarlarını görüntüleyin. Opciones de Reestricción de Vista para limitar el uso de 1º o 3º persona globalmente o según el tipo de vehículo. @@ -50,7 +50,7 @@ Zmienia tryb globalny. (Domyślnie: Wyłączony) Globaler Modus. (Standard: Deaktiviert) Globális mód beállítása. Alapértelmeyett: Kikapcsolva - グローバル モードの設定。(標準: 無効) + グローバル モードの設定。 (デフォルト: 無効) 전체 모드를 사용합니다. 기본값: 사용 안 함 Mode global. Défaut: Désactivé 设定全局的人称模式。预设:关闭 @@ -80,7 +80,7 @@ Tryb selektywny piechoty. Domyślnie: Wyłączony (Wymagany tryb globalny: Selektywny) Selektiver Modus zu Fuß. (Standard: Deaktiviert, Benötigt Modus: Selektiv) Szelektív mód Gyalogosan. Alapértelmezett: Kikapcsolva (Mód: Szelektív szükséges) - 地上でのモードを選択します。(標準: 無効化 (要求モード: 選択性) + 地上でのモードを選択します。 (デフォルト: 無効化 (要求モード: 選択性) 보병 시점. 기본값: 사용 안 함 (모드-선택 필요) Mode sélectif hors des véhicules. Défaut: Désactivé (Nécessite Mode: Sélectif) 设定在步行的状况下能使用的人称模式。预设:关闭(需在全局设定中先选择'使用可选设定') @@ -110,7 +110,7 @@ Tryb selektywny pojazdów. Domyślnie: Wyłączony (Wymagany tryb globalny: Selektywny) Selektiver Modus in Landfahrzeugen. (Standard: Deaktiviert, Benötigt Modus: Selektiv) Szelektív mód a Szárazföldi Járművekben. Alapértelmezett: Kikapcsolva (Mód: Szelektív szükséges) - 地上車両でのモードを選択します。(標準: 無効化 (要求モード: 選択性) + 地上車両でのモードを選択します。 (デフォルト: 無効化 (要求モード: 選択性) 차량 시점. 기본값: 사용 안 함 (모드-선택 필요) Mode sélectif dans les véhicules terrestres. Défaut: Désactivé (Nécessite Mode: Sélectif) 设定在搭乘陆上载具的状况下能使用的人称模式。预设:关闭(需在全局设定中先选择'使用可选设定') @@ -140,7 +140,7 @@ Tryb selektywny lotnictwa. Domyślnie: Wyłączony (Wymagany tryb globalny: Selektywny) Selektiver Modus in Luftfahrzeugen. (Standard: Deaktiviert, Benötigt Modus: Selektiv) Szelektív mód a Légijárművekben. Alapértelmezett: Kikapcsolva (Mód: Szelektív szükséges) - 航空機でのモードを選択します。(標準: 無効化 (要求モード: 選択性) + 航空機でのモードを選択します。 (デフォルト: 無効化 (要求モード: 選択性) 항공기 시점. 기본값: 사용 안 함 (모드-선택 필요) Mode sélectif dans les véhicules aériens. Défaut: Désactivé (Nécessite Mode: Sélectif) 设定在搭乘空中载具的状况下能使用的人称模式。预设:关闭(需在全局设定中先选择'使用可选设定') @@ -170,7 +170,7 @@ Tryb selektywny jednostek pływających. Domyślnie: Wyłączony (Wymagany tryb globalny: Selektywny) Selektiver Modus zu Fuß. (Standard: Deaktiviert, Benötigt Modus: Selektiv) Szelektív mód a Vízi Járművekben. Alapértelmezett: Kikapcsolva (Mód: Szelektív szükséges) - 船舶でのモードを選択します。(標準: 無効化 (要求モード: 選択性) + 船舶でのモードを選択します。 (デフォルト: 無効化 (要求モード: 選択性) 함선 시점. 기본값: 사용 안 함 (모드-선택 필요) Mode sélectif dans les véhicules marins. Défaut: Désactivé (Nécessite Mode: Sélectif) 设定在搭乘水上载具的状况下能使用的人称模式。预设:关闭(需在全局设定中先选择'使用可选设定') @@ -200,12 +200,12 @@ Tryb selektywny UAV. Domyślnie: Wyłączony (Wymagany tryb globalny: Selektywny) Selektiver Modus in unbemannten Luftfahrzeugen. (Standard: Deaktiviert, Benötigt Modus: Selektiv Szelektív mód a Pilóta Nélküli Légijárművekben. Alapértelmezett: Kikapcsolva (Mód: Szelektív szükséges) - 無人機でのモードを選択します。(標準: 無効化 (要求モード: 選択性) + 無人機でのモードを選択します。 (デフォルト: 無効化 (要求モード: 選択性) 무인기 시점. 기본값: 사용 안 함 (모드-선택 필요) Mode sélectif dans les drones. Défaut: Désactivé (Nécessite Mode: Sélectif) 设定在搭乘无人载具的状况下能使用的人称模式。预设:关闭(需在全局设定中先选择'使用可选设定') 設定在搭乘無人載具的狀況下能使用的視野模式。預設:關閉(需在全局設定中先選擇'使用可選設定') - Modalità selettiva su UAVi. Default: Disabilitato (Necessita della Modalità: Selettiva) + Modalità selettiva su UAV. Default: Disabilitato (Necessita della Modalità: Selettiva) Выборочные установки для беспилотников. По умолчанию: Отключено (требуется режим: Выборочные) IHA araçlarında iken seçilen görüş modu. Varsayılan: Etkin Değil Modo selectivo en VANTs. Defecto: Deshabilitado (Requiere Modo: Selectivo) @@ -216,6 +216,7 @@ Deaktiviert Kikapcsolva 無効 + Disabilitata 사용 안 함 Désactivé 关闭 @@ -228,6 +229,7 @@ Forced 1st Person Wymuś 1. osobę Erzwungene Egoperspektive + Prima persona forzata 1人称視点に強制 강제 1인칭 Impose la 1ère personne @@ -241,6 +243,7 @@ Forced 3rd Person Wymuś 3. osobę Erzwungene Third-Person-Perspektive + Terza persona forzata 3人称視点に強制 강제 3인칭 Impose la 3ème personne @@ -254,6 +257,7 @@ Selective Selektywny Selektiv + Selettiva Szelektív 選択性 선택 @@ -267,8 +271,9 @@ Preserve view for vehicle types Behalte die Ansicht bei Fahrzeugtypen bei + Mantieni visuale per tipo di veicolo Запоминать вид для типов техники - 車両の種類により視点を変更 + 車両の種別により視点を変更 保留載具的視野模式 保留载具的人称模式 Zachowaj ustawienie widoku dla pojazdów @@ -280,8 +285,9 @@ Switch view on vehicle change to last used in this vehicle type (Requires Mode: Disabled) Wechsel die Ansicht bei Fahrzeugwechsel zu der zuletzt genutzen in diesen Fahrzeugtyp. (Benötigt Modus: Ausgeschaltet) + Cambia la visuale quando si cambia veicolo a quella usata la volta precedente su un veicolo dello stesso tipo (Richiede modalità: Disattivata) Переключать вид при смене техники на последний использованный в данном типе техники (требуется режим: Отключено) - 車両の種類により最後に使用した視点へ切り替え (無効モードでのみ有効) + 車両変更時の視点をその車両種別で最後に使用したものに切り替えます (要求モード: 無効) 切換到載具時自動切換到上次最後使用的視野模式(需求模式:關閉) 切换到载具时自动切换到上次最后使用的人称模式(需求模式:关闭) Zmień widok podczas zmiany pojazdu na ustawienie widoku z ostatniego używanego pojazdu tego typu (Wymaga Tryb: Wyłączony diff --git a/addons/volume/XEH_postInitClient.sqf b/addons/volume/XEH_postInitClient.sqf index 2ce8f03a10..896bb718f8 100644 --- a/addons/volume/XEH_postInitClient.sqf +++ b/addons/volume/XEH_postInitClient.sqf @@ -23,7 +23,7 @@ if (!hasInterface) exitWith {}; if (!XGVAR(lowerInVehicles)) exitWith {}; - if (vehicle _unit != _unit) then { + if (!isNull objectParent _unit) then { call FUNC(lowerVolume); } else { call FUNC(restoreVolume); diff --git a/addons/volume/XEH_preInit.sqf b/addons/volume/XEH_preInit.sqf index ae4979ef36..775f4d71d5 100644 --- a/addons/volume/XEH_preInit.sqf +++ b/addons/volume/XEH_preInit.sqf @@ -6,7 +6,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" GVAR(isLowered) = false; GVAR(initialGameVolume) = soundVolume; diff --git a/addons/volume/initSettings.sqf b/addons/volume/initSettings.inc.sqf similarity index 61% rename from addons/volume/initSettings.sqf rename to addons/volume/initSettings.inc.sqf index 8735f81527..44bb464a1e 100644 --- a/addons/volume/initSettings.sqf +++ b/addons/volume/initSettings.inc.sqf @@ -3,9 +3,6 @@ "CHECKBOX", [ELSTRING(common,Enabled), LSTRING(KeybindDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(enabled), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; @@ -14,10 +11,7 @@ "LIST", [LSTRING(Reduction), LSTRING(ReductionDescription)], format ["ACE %1", LLSTRING(Name)], - [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"], 5], - false, - {[QGVAR(reduction), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0%", "10%", "20%", "30%", "40%", "50%", "60%", "70%", "80%", "90%", "100%"], 5] ] call CBA_fnc_addSetting; [ @@ -25,10 +19,7 @@ "LIST", [LSTRING(FadeDelay), LSTRING(FadeDelayDescription)], format ["ACE %1", LLSTRING(Name)], - [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0s", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"], 1], - false, - {[QGVAR(fadeDelay), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ["0s", "1s", "2s", "3s", "4s", "5s", "6s", "7s", "8s", "9s", "10s"], 1] ] call CBA_fnc_addSetting; [ @@ -36,9 +27,6 @@ "CHECKBOX", [LSTRING(LowerInVehicles), LSTRING(LowerInVehiclesDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(lowerInVehicles), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; @@ -47,10 +35,7 @@ "CHECKBOX", [LSTRING(ShowNotification), LSTRING(ShowNotificationDescription)], format ["ACE %1", LLSTRING(Name)], - true, - false, - {[QGVAR(showNotification), _this] call EFUNC(common,cbaSettings_settingChanged)}, - false + true ] call CBA_fnc_addSetting; [ @@ -58,8 +43,5 @@ "CHECKBOX", [LSTRING(RemindIfLowered), LSTRING(RemindIfLoweredDescription)], format ["ACE %1", LLSTRING(Name)], - false, - false, - {[QGVAR(remindIfLowered), _this] call EFUNC(common,cbaSettings_settingChanged)}, false ] call CBA_fnc_addSetting; diff --git a/addons/volume/stringtable.xml b/addons/volume/stringtable.xml index a7c75769c3..feecb28b10 100644 --- a/addons/volume/stringtable.xml +++ b/addons/volume/stringtable.xml @@ -23,7 +23,7 @@ 음량 토글 切换音量 切換音量 - Attiva Volume + Cambia Volume Переключить громкость Przełącz Głosność Sesi Aç/Kapat @@ -37,7 +37,7 @@ 토글하여 음량 감소합니다. 切换降低音量。 切換降低音量。 - Attiva riduzione del volume. + Cambia Riduzione del Volume. Переключает уменьшение громкости Przełącz redukcje głosności Ses azaltmayı aç / kapat. @@ -51,7 +51,7 @@ 음량 감소됨 降低音量 降低音量 - Volume diminuito + Volume Abbassato Громкость снижена Zmniejszona głosność Azaltılmış ses @@ -65,7 +65,7 @@ 음량 복구됨 恢复音量 回復音量 - Volume ripristinato + Volume Ripristinato Громкость восстановлена Przywrócona głosność Volumen restaurado @@ -132,7 +132,7 @@ 설정 보기 显示提示 顯示提示 - Mostra notifiche + Mostra notifica Показывать уведомление Pokaż powiadomienie Bildirim Göster @@ -146,7 +146,7 @@ 음량이 감소/복구될 때 메시지를 표시합니다. 当正在降低/恢复音量时显示提示。 當正在降低/回復音量時顯示提示。 - Mostra notifiche mentre si abbassa/ripristina il volume. + Mostra notifiche quando si abbassa/ripristina il volume. Показывать уведомление при уменьшении/восстановлении громкости Pokaż powiadomienie zmniejszając/odnawiając głosność Ses azaltıldığın da bildirim göster. @@ -155,12 +155,12 @@ Fade delay Ausblendzeit - フェードへの遅延 + フェードの遅延 Retard fondu 페이드 지연 淡出/入延迟 淡出/入延遲 - Latenza della dissolvenza + Latenza del cambio volume Задержка затухания Opoznienie wyciszenia Retardo en disminución gradual @@ -168,12 +168,12 @@ Time it takes (in seconds) for the sound to fade in/out. Zeit, die es benötigt (in Sekunden), für das Geräusch, ein- bzw. auszublenden. - 音がフェードイン、アウトするまでの時間 (秒) を決定します。 + 音がフェードイン/アウトするまでの時間。 (秒単位) Temps nécessaire (en secondes) aux sons pour être réduits/rétablis. 페이드 인/아웃 되는데 걸리는 시간(초) 设定音量淡出/入时所需的秒数。 設定音量淡出/入時所需的秒數。 - Il tempo che impiega (in secondi) il suono a dissolversi entrata/uscita. + Il tempo che impiega (in secondi) il suono a cambiare volume. Время (сек.) для затухания/восстановления звука. Ilość czasu (w sekundach) ile zajmuje wyciszenie/zgłośnienie dźwięku Tiempo que tarda (en segundos) para que se active o desactive la disminuación gradual del volumen @@ -186,7 +186,7 @@ 감소 시 알림 降低音量时是否提醒 降低音量時是否提醒 - Sollecita se diminuito + Notifica se diminuito Напоминать о снижении громкости Przypomnij o zmniejszonej głosności dźwięku Eğer Düşükse Hatırlat @@ -200,7 +200,7 @@ 음량이 감소되면 매 분 마다 알려줍니다 开启后会每分钟警告一次你的音量已被降低。 開啟後會每分鐘警告一次你的音量已被降低。 - Ti notifica ogni minuto se il tuo volume è basso. + Ti notifica ogni minuto se il tuo volume è abbassato. Ежеминутное напоминание о сниженной громкости Przypomina co minuten o zmniejszonej głosności dźwięku Eğer ses düşükse her dakika hatırlatır. @@ -214,7 +214,7 @@ 음량 감소 중 降低音量中 降低音量中 - Il volume è ancora basso + Il volume è ancora abbassato Громкость все еще снижена Dźwięk jest nadal zmniejszony Ses hala düşük diff --git a/addons/weaponselect/XEH_postInit.sqf b/addons/weaponselect/XEH_postInit.sqf index 4d2c6464b2..e9f05de8bb 100644 --- a/addons/weaponselect/XEH_postInit.sqf +++ b/addons/weaponselect/XEH_postInit.sqf @@ -198,7 +198,7 @@ if (!hasInterface) exitWith {}; ["ACE3 Vehicles", QGVAR(CollisionLights), localize LSTRING(CollisionLights), { // Conditions: canInteract - if (!([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith))) exitWith {false}; + if !([ACE_player, vehicle ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; // Conditions: specific if ((ACE_player isEqualTo (vehicle ACE_player)) || {ACE_player != (driver (vehicle ACE_player))}) exitWith {false}; @@ -210,4 +210,4 @@ if (!hasInterface) exitWith {}; [0, [false, false, false]]] call CBA_fnc_addKeybind; // Register fire event handler -["ace_firedPlayer", DFUNC(throwGrenade)] call CBA_fnc_addEventHandler; +["ace_firedPlayer", LINKFUNC(throwGrenade)] call CBA_fnc_addEventHandler; diff --git a/addons/weaponselect/XEH_preInit.sqf b/addons/weaponselect/XEH_preInit.sqf index 01c9f2484f..e699f3d2f3 100644 --- a/addons/weaponselect/XEH_preInit.sqf +++ b/addons/weaponselect/XEH_preInit.sqf @@ -11,21 +11,23 @@ GVAR(GrenadesAll) = []; GVAR(GrenadesFrag) = []; GVAR(GrenadesNonFrag) = []; +private _cfgMagazines = configFile >> "CfgMagazines"; +private _cfgAmmo = configFile >> "CfgAmmo"; +private _cfgThrow = configFile >> "CfgWeapons" >> "Throw"; + { - private _magazines = getArray (configFile >> "CfgWeapons" >> "Throw" >> _x >> "magazines"); + private _magazines = getArray (_cfgThrow >> _x >> "magazines"); GVAR(GrenadesAll) append _magazines; { - private _ammo = getText (configFile >> "CfgMagazines" >> _x >> "ammo"); - private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive"); + private _ammo = getText (_cfgMagazines >> _x >> "ammo"); + private _explosive = getNumber (_cfgAmmo >> _ammo >> "explosive"); ([GVAR(GrenadesFrag), GVAR(GrenadesNonFrag)] select (_explosive == 0)) pushBack _x; - false - } count _magazines; - false -} count getArray (configFile >> "CfgWeapons" >> "Throw" >> "muzzles"); + } forEach _magazines; +} forEach getArray (_cfgThrow >> "muzzles"); -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf b/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf index 16bac855cc..8b9fcf94b7 100644 --- a/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf +++ b/addons/weaponselect/functions/fnc_fireSmokeLauncher.sqf @@ -22,7 +22,7 @@ private _weapons = _vehicle weaponsTurret _turret; if ( count _weapons > 1 - || {count _weapons > 0 && {!(_weapons select 0 in ["SmokeLauncher", "BWA3_SmokeLauncher"])}} // @todo somebody might use custom smoke launcher weapons aswell, maybe ... + || {_weapons isNotEqualTo [] && {!(_weapons select 0 in ["SmokeLauncher", "BWA3_SmokeLauncher"])}} // @todo somebody might use custom smoke launcher weapons aswell, maybe ... ) then { //This doesn't work reliably for vehilces with additional weapons for the commander. Select smoke launcher instead. diff --git a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf index 2be2d740ea..641787a394 100644 --- a/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf +++ b/addons/weaponselect/functions/fnc_playChangeFiremodeSound.sqf @@ -30,8 +30,10 @@ _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]; }; playSound3D [_filename, objNull, false, _position, _volume, _soundPitch, _distance]; + +nil // return diff --git a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf index 195bbc326b..ad17c7f18d 100644 --- a/addons/weaponselect/functions/fnc_selectNextGrenade.sqf +++ b/addons/weaponselect/functions/fnc_selectNextGrenade.sqf @@ -37,8 +37,7 @@ private _grenades = []; if (_x in _magazines) then { _grenades pushBack _x; }; - false -} count ([GVAR(GrenadesAll), GVAR(GrenadesFrag), GVAR(GrenadesNonFrag)] select _type); +} forEach ([GVAR(GrenadesAll), GVAR(GrenadesFrag), GVAR(GrenadesNonFrag)] select _type); // abort if no grenades are available if (_grenades isEqualTo []) exitWith {false}; @@ -62,14 +61,14 @@ private _vestGrenades = vestItems _unit select {_x in GVAR(GrenadesAll) private _backpackGrenades = backpackItems _unit select {_x in GVAR(GrenadesAll) && {_x != _nextGrenade}}; // remove all grenades except those we are switching to --> this breaks the selector -{_unit removeItemFromUniform _x; false} count _uniformGrenades; -{_unit removeItemFromVest _x; false} count _vestGrenades; -{_unit removeItemFromBackpack _x; false} count _backpackGrenades; +{_unit removeItemFromUniform _x} forEach _uniformGrenades; +{_unit removeItemFromVest _x} forEach _vestGrenades; +{_unit removeItemFromBackpack _x} forEach _backpackGrenades; // readd grenades -{_unit addItemToUniform _x; false} count _uniformGrenades; -{_unit addItemToVest _x; false} count _vestGrenades; -{_unit addItemToBackpack _x; false} count _backpackGrenades; +{_unit addItemToUniform _x} forEach _uniformGrenades; +{_unit addItemToVest _x} forEach _vestGrenades; +{_unit addItemToBackpack _x} forEach _backpackGrenades; [_nextGrenade, {_x == _nextGrenade} count _magazines] call FUNC(displayGrenadeTypeAndNumber); diff --git a/addons/weaponselect/functions/fnc_selectWeaponMode.sqf b/addons/weaponselect/functions/fnc_selectWeaponMode.sqf index f2810bb512..fd22bd4462 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponMode.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponMode.sqf @@ -18,35 +18,23 @@ params ["_unit", "_weapon"]; -if (_weapon == "") exitWith {}; +if (_weapon == "" || {!(_unit hasWeapon _weapon)}) exitWith {}; + +private _currentWeaponMode = (_unit weaponState _weapon) select 2; +private _muzzle = (_weapon call EFUNC(common,getWeaponMuzzles)) select 0; if (currentWeapon _unit != _weapon) exitWith { - _unit selectWeapon _weapon; + _unit selectWeapon [_weapon, _muzzle, _currentWeaponMode]; }; -// unlock safety +// Unlock safety if (_weapon in (_unit getVariable [QEGVAR(safemode,safedWeapons), []])) exitWith { [_unit, _weapon, _weapon] call EFUNC(safemode,unlockSafety); }; -private _muzzles = [_weapon] call EFUNC(common,getWeaponMuzzles); -private _modes = [_weapon] call EFUNC(common,getWeaponModes); +private _modes = _weapon call EFUNC(common,getWeaponModes); -private _index = (_modes find currentWeaponMode _unit) + 1; +_unit selectWeapon [_weapon, _muzzle, _modes select (((_modes find _currentWeaponMode) + 1) % (count _modes))]; -if (_index > count _modes - 1) then {_index = 0}; - -private _muzzle = _muzzles select 0; -private _mode = _modes select _index; - -_index = 0; - -while { - _index < 299 && {currentMuzzle _unit != _muzzle || {currentWeaponMode _unit != _mode}} -} do { - _unit action ["SwitchWeapon", _unit, _unit, _index]; - _index = _index + 1; -}; - -// play fire mode selector sound +// Play fire mode selector sound [_unit, _weapon] call FUNC(playChangeFiremodeSound); diff --git a/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf b/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf index 9a27a515ad..3882253573 100644 --- a/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf +++ b/addons/weaponselect/functions/fnc_selectWeaponMuzzle.sqf @@ -18,32 +18,22 @@ params ["_unit", "_weapon"]; -if (_weapon == "") exitWith {}; +if (_weapon == "" || {!(_unit hasWeapon _weapon)}) exitWith {}; private _muzzles = _weapon call EFUNC(common,getWeaponMuzzles); -if (currentWeapon _unit != _weapon) exitWith { - if (count _muzzles > 1) then { +if (count _muzzles <= 1) exitWith {}; - // unlock safety - /*if (_weapon in (_unit getVariable [QEGVAR(safemode,safedWeapons), []])) exitWith { - [_unit, _weapon, _muzzles select 1] call EFUNC(safemode,unlockSafety); - };*/ +private _muzzle = (_unit weaponState _weapon) select 1; - _unit selectWeapon (_muzzles select 1); - }; +private _index = if (currentWeapon _unit == _weapon) then { + (((_muzzles find currentMuzzle _unit) + 1) % (count _muzzles)) max 1 +} else { + 1 }; -private _index = (_muzzles find currentMuzzle _unit) + 1; - -if (_index > count _muzzles - 1) then {_index = 1}; - private _muzzle = _muzzles select _index; -_index = 0; -while { - _index < 299 && {currentMuzzle _unit != _muzzle} -} do { - _unit action ["SwitchWeapon", _unit, _unit, _index]; - _index = _index + 1; -}; +_unit selectWeapon [_weapon, _muzzle, ([_weapon, _muzzle] call EFUNC(common,getWeaponModes)) select 0]; + +nil // return diff --git a/addons/weaponselect/functions/fnc_throwGrenade.sqf b/addons/weaponselect/functions/fnc_throwGrenade.sqf index 4856a7b738..ffe289a589 100644 --- a/addons/weaponselect/functions/fnc_throwGrenade.sqf +++ b/addons/weaponselect/functions/fnc_throwGrenade.sqf @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); if (_weapon != "Throw") exitWith {}; diff --git a/addons/weaponselect/initSettings.sqf b/addons/weaponselect/initSettings.inc.sqf similarity index 58% rename from addons/weaponselect/initSettings.sqf rename to addons/weaponselect/initSettings.inc.sqf index 029c5201cb..f5695748b4 100644 --- a/addons/weaponselect/initSettings.sqf +++ b/addons/weaponselect/initSettings.inc.sqf @@ -2,7 +2,5 @@ QGVAR(displayText), "CHECKBOX", [LSTRING(SettingDisplayTextName), LSTRING(SettingDisplayTextDesc)], ELSTRING(common,ACEKeybindCategoryWeapons), - true, // default value - false, // isGlobal - {[QGVAR(displayText), _this] call EFUNC(common,cbaSettings_settingChanged)} + true // default value ] call CBA_fnc_addSetting; diff --git a/addons/weaponselect/stringtable.xml b/addons/weaponselect/stringtable.xml index e4814e86a2..4369c3b5f9 100644 --- a/addons/weaponselect/stringtable.xml +++ b/addons/weaponselect/stringtable.xml @@ -12,7 +12,7 @@ Szöveg mutatása gránát eldobásakor Mostra indicazioni nel lancio granate Mostrar texto ao lançar granada - 手榴弾を投げるときに通知 + 手榴弾投擲時に通知 수류탄 투척 시 화면에 문자 표시 投掷手榴弹时显示提示信息 投擲手榴彈時顯示提示訊息 @@ -178,7 +178,7 @@ Elsődleges Fegyver Kiválasztása Zvolit Hlavní Zbraň Selecionar Arma Principal - Seleziona Arma Primaria + Seleziona Cannone Primario Выбрать основное оружие 主砲を選択 주포 선택 @@ -197,7 +197,7 @@ Selecionar Metralhadora Seleziona Mitragliatrice Выбрать пулемёт - 機関砲を選択 + 機銃を選択 기관총 선택 选择机枪 選擇機槍 @@ -246,9 +246,9 @@ Gránát előkészítése Подготовить гранату Grenade prête - Granata pronta + Prepara Granata Granada pronta - 投てきよし + 手榴弾を準備 투척물 준비 准备手榴弹 準備手榴彈 @@ -299,7 +299,7 @@ Lançar Granada Selecionada Lancia la Granata Selezionata Бросить выбранную гранату - 選択された手榴弾を投げる + 選択された手榴弾を投擲 선택된 투척물 투척 投掷选择的手榴弹 投擲選擇的手榴彈 @@ -316,7 +316,7 @@ Гранат не осталось Granate esaurite Sem mais granadas - もう手榴弾は無い + 手榴弾は残っていない 투척물 없음 已无手榴弹 已無手榴彈 @@ -333,7 +333,7 @@ Não há granadas de fragmentação restantes Nessuna granata a frammentazione rimanente Осколочных гранат нет - もう破片手榴弾は無い + 破片手榴弾は残っていない 세열 수류탄 없음 已无破片手榴弹 已無破片手榴彈 @@ -349,7 +349,7 @@ Não há outras granadas restantes Nessun'altra granata rimanente. Нелетальные гранаты закончились - もうその他の手榴弾は無い + その他の手榴弾は残っていない 기타 투척물 없음 已无其他手榴弹 已無其他手榴彈 @@ -365,7 +365,7 @@ Nenhuma granada selecionada Nessuna granata selezionata Нет выбранной гранаты - 手榴弾は選択されていない + 手榴弾は未選択 선택된 수류탄 없음 未选择手榴弹 未選擇手榴彈 @@ -380,9 +380,9 @@ Wystrzel granat dymny Füstvető eltüzelése Пустить дымовую завесу - Lancia fumogeno + Lancia Cortina Fumogena Lançador de fumaça - 発煙弾発射機を発射 + 発煙弾を発射 연막발사기 박사 发射烟雾发射器 發射煙霧發射器 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/XEH_postInit.sqf b/addons/weather/XEH_postInit.sqf index 51350226e1..98909dc2d4 100644 --- a/addons/weather/XEH_postInit.sqf +++ b/addons/weather/XEH_postInit.sqf @@ -1,10 +1,12 @@ #include "script_component.hpp" GVAR(WindInfo) = false; + ["ACE3 Common", QGVAR(WindInfoKey), localize LSTRING(WindInfoKeyToggle), { // Conditions: canInteract - if !([ACE_player, ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, ACE_player, ["isNotDragging", "isNotCarrying", "isNotSitting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !(isNull objectParent ACE_player || {objectParent ACE_player isKindOf "StaticWeapon"}) exitWith {false}; // Statement [] call FUNC(displayWindInfo); @@ -15,7 +17,8 @@ GVAR(WindInfo) = false; ["ACE3 Common", QGVAR(WindInfoKey_hold), localize LSTRING(WindInfoKeyHold), { // Conditions: canInteract - if !([ACE_player, ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false}; + if !([ACE_player, ACE_player, ["isNotDragging", "isNotCarrying", "isNotSitting", "isNotInside"]] call EFUNC(common,canInteractWith)) exitWith {false}; + if !(isNull objectParent ACE_player || {objectParent ACE_player isKindOf "StaticWeapon"}) exitWith {false}; // Statement [] call FUNC(displayWindInfo); diff --git a/addons/weather/XEH_postServerInit.sqf b/addons/weather/XEH_postServerInit.sqf index da694bb5f1..2c20f672fe 100644 --- a/addons/weather/XEH_postServerInit.sqf +++ b/addons/weather/XEH_postServerInit.sqf @@ -9,8 +9,8 @@ if (GVAR(windSimulation)) then { call FUNC(initWind); - [FUNC(updateWind), 1] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(updateWind), 1] call CBA_fnc_addPerFrameHandler; }; - [FUNC(updateWeather), GVAR(updateInterval)] call CBA_fnc_addPerFrameHandler; + [LINKFUNC(updateWeather), GVAR(updateInterval)] call CBA_fnc_addPerFrameHandler; }] call CBA_fnc_addEventHandler; diff --git a/addons/weather/XEH_preInit.sqf b/addons/weather/XEH_preInit.sqf index 438c3e9962..bae7c82516 100644 --- a/addons/weather/XEH_preInit.sqf +++ b/addons/weather/XEH_preInit.sqf @@ -7,7 +7,7 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" // Make sure this data is read before client/server postInit call FUNC(getMapData); 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_calculateWindSpeed.sqf b/addons/weather/functions/fnc_calculateWindSpeed.sqf index 2ae1d94eec..d24322bef0 100644 --- a/addons/weather/functions/fnc_calculateWindSpeed.sqf +++ b/addons/weather/functions/fnc_calculateWindSpeed.sqf @@ -47,19 +47,18 @@ if (_terrainEffectEnabled) then { private _newWindSpeed = 0; { private _windSource = [100, _windDirAdjusted, _x] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; _windSource = [100, _windDirAdjusted + _x, 0] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; _windSource = [100, _windDirAdjusted - _x, 0] call _fnc_polar2vect; - if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith { + if !(terrainIntersectASL [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 9) * _windSpeed; }; - nil - } count [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; + } forEach [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; _windSpeed = _newWindSpeed; }; }; @@ -70,19 +69,18 @@ if (_obstacleEffectEnabled) then { private _newWindSpeed = 0; { private _windSource = [20, _windDirAdjusted, _x] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; _windSource = [20, _windDirAdjusted + _x, 0] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; _windSource = [20, _windDirAdjusted - _x, 0] call _fnc_polar2vect; - if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith { + if !(lineIntersects [_position, _position vectorAdd _windSource]) exitWith { _newWindSpeed = cos(_x * 2) * _windSpeed; }; - nil - } count [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]; + } forEach [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]; _windSpeed = _newWindSpeed; }; }; diff --git a/addons/weather/functions/fnc_displayAirTemp.sqf b/addons/weather/functions/fnc_displayAirTemp.sqf index 4eb5bdf3ac..08b325dcac 100644 --- a/addons/weather/functions/fnc_displayAirTemp.sqf +++ b/addons/weather/functions/fnc_displayAirTemp.sqf @@ -17,7 +17,7 @@ */ params ["_apparent_temperature", "_bias"]; -TRACE_2("displayAirTemp",_apparent_temperature, _bias); +TRACE_2("displayAirTemp",_apparent_temperature,_bias); private _temperature1 = floor(_apparent_temperature + (_bias select 0) - (random 2)); private _temperature2 = floor(_apparent_temperature + (_bias select 1) + (random 2)); diff --git a/addons/weather/functions/fnc_displayWindInfo.sqf b/addons/weather/functions/fnc_displayWindInfo.sqf index d7c45e595a..aeb7d580ae 100644 --- a/addons/weather/functions/fnc_displayWindInfo.sqf +++ b/addons/weather/functions/fnc_displayWindInfo.sqf @@ -29,14 +29,20 @@ EGVAR(advanced_ballistics,Protractor) = false; GVAR(WindInfo) = true; -TRACE_1("Starting Wind Info PFEH", GVAR(WindInfo)); +TRACE_1("Starting Wind Info PFEH",GVAR(WindInfo)); [{ disableSerialization; params ["", "_pfID"]; - if ((!GVAR(WindInfo)) || {!([ACE_player, ACE_player, []] call EFUNC(common,canInteractWith))}) exitWith { - TRACE_1("Ending Wind Info PFEH", GVAR(WindInfo)); + // Allow wind indicator inside static weapons + private _playerInStaticWeapon = objectParent ACE_Player isKindOf "StaticWeapon"; + + if ( + (!GVAR(WindInfo)) || + {!([ACE_player, ACE_player, ["notOnMap", "isNotDragging", "isNotCarrying", "isNotSitting"]] call EFUNC(common,canInteractWith)) && !(_playerInStaticWeapon)} + ) exitWith { + TRACE_1("Ending Wind Info PFEH",GVAR(WindInfo)); GVAR(WindInfo) = false; (["RscWindIntuitive"] call BIS_fnc_rscLayer) cutText ["", "PLAIN"]; [_pfID] call CBA_fnc_removePerFrameHandler; @@ -45,12 +51,18 @@ TRACE_1("Starting Wind Info PFEH", GVAR(WindInfo)); //Keeps the display open: (["RscWindIntuitive"] call BIS_fnc_rscLayer) cutRsc ["RscWindIntuitive", "PLAIN", 1, false]; + private _playerEyePos = eyePos ACE_Player; + if (_playerInStaticWeapon) then { + // Raise eyePos by 1 meter if player is in a static weapon, to prevent wind from being blocked by the open vehicle + _playerEyePos = _playerEyePos vectorAdd [0, 0, 1]; + }; + private _windSpeed = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { // With wind gradient - [eyePos ACE_player, true, true, true] call FUNC(calculateWindSpeed); + [_playerEyePos, true, true, true] call FUNC(calculateWindSpeed); } else { // Without wind gradient - [eyePos ACE_player, false, true, true] call FUNC(calculateWindSpeed); + [_playerEyePos, false, true, true] call FUNC(calculateWindSpeed); }; diff --git a/addons/weather/functions/fnc_getApproximateAirTemp.sqf b/addons/weather/functions/fnc_getApproximateAirTemp.sqf index 33227907a3..91b8af3fcc 100644 --- a/addons/weather/functions/fnc_getApproximateAirTemp.sqf +++ b/addons/weather/functions/fnc_getApproximateAirTemp.sqf @@ -18,7 +18,7 @@ params ["_unit"]; TRACE_1("params",_unit); -if (isNil (format ["%1", _unit getVariable "ACE_airTemperatureBias"])) then { +if (isNil {_unit getVariable "ACE_airTemperatureBias"}) then { _unit setVariable ["ACE_airTemperatureBias", [-(random(3) + 1), random(3) + 1]]; }; diff --git a/addons/weather/functions/fnc_getMapData.sqf b/addons/weather/functions/fnc_getMapData.sqf index d80573c286..555704fc87 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 @@ -48,34 +48,35 @@ GVAR(currentHumidity) = 0; GVAR(currentOvercast) = 0; // Get all non inherited arrays to filter maps that inherit from Stratis/Altis/Tanoa -private _nonInheritedArrays = configProperties [configFile >> "CfgWorlds" >> _worldName, "isArray _x", false]; +private _cfgPath = configFile >> "CfgWorlds" >> _worldName; +private _nonInheritedArrays = configProperties [_cfgPath, "isArray _x", false]; // And check if any custom non-inherited weather is defined through config and use that if so -if ((configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay") in _nonInheritedArrays) exitWith { - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay")) then { - GVAR(TempDay) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempDay"); +if ((_cfgPath >> "ACE_TempDay") in _nonInheritedArrays) exitWith { + if (isArray (_cfgPath >> "ACE_TempDay")) then { + GVAR(TempDay) = getArray (_cfgPath >> "ACE_TempDay"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempNight")) then { - GVAR(TempNight) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_TempNight"); + if (isArray (_cfgPath >> "ACE_TempNight")) then { + GVAR(TempNight) = getArray (_cfgPath >> "ACE_TempNight"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_Humidity")) then { - GVAR(Humidity) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_Humidity"); + if (isArray (_cfgPath >> "ACE_Humidity")) then { + GVAR(Humidity) = getArray (_cfgPath >> "ACE_Humidity"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMin")) then { - GVAR(WindSpeedMin) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMin"); + if (isArray (_cfgPath >> "ACE_WindSpeedMin")) then { + GVAR(WindSpeedMin) = getArray (_cfgPath >> "ACE_WindSpeedMin"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMean")) then { - GVAR(WindSpeedMean) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMean"); + if (isArray (_cfgPath >> "ACE_WindSpeedMean")) then { + GVAR(WindSpeedMean) = getArray (_cfgPath >> "ACE_WindSpeedMean"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMax")) then { - GVAR(WindSpeedMax) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindSpeedMax"); + if (isArray (_cfgPath >> "ACE_WindSpeedMax")) then { + GVAR(WindSpeedMax) = getArray (_cfgPath >> "ACE_WindSpeedMax"); }; - if (isArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindDirectionProbabilities")) then { - GVAR(WindDirectionProbabilities) = getArray (configFile >> "CfgWorlds" >> _worldName >> "ACE_WindDirectionProbabilities"); + if (isArray (_cfgPath >> "ACE_WindDirectionProbabilities")) then { + GVAR(WindDirectionProbabilities) = getArray (_cfgPath >> "ACE_WindDirectionProbabilities"); }; }; // Check if the map is among the most popular -if (_worldName in ["chernarus", "bootcamp_acr", "woodland_acr", "utes"]) then { +if (_worldName in ["chernarus", "bootcamp_acr", "woodland_acr", "utes"]) exitWith { // Source: http://www.iten-online.ch/klima/europa/tschechien/prag.htm GVAR(TempDay) = [1, 3, 9, 14, 19, 23, 25, 24, 21, 13, 7, 2]; GVAR(TempNight) = [-4, -3, 0, 4, 9, 12, 14, 14, 10, 6, 2, -2]; @@ -239,3 +240,17 @@ if (_worldName in ["kunduz"]) exitWith { [0.04, 0.02, 0.05, 0.14, 0.19, 0.07, 0.10, 0.07] // December ]; }; + + +// Catches any "Winter" Map that hasnt been defined otherwise - this should stay at the end of the file +// Values are not based on any RL reference since the snow terrain textures persists regardless the date +_cfgPath = _cfgPath >> "RainParticles"; +if ( + "winter" in _worldName || + {"snow" in getText (_cfgPath >> "rainDropTexture")} || + {getNumber (_cfgPath >> "snow") != 0} +) exitWith { + GVAR(TempDay) = [-10,-9,-8,-7,-6,-5,-6,-7,-8,-9,-10,-11]; + GVAR(TempNight) = [-15,-14,-13,-12,-11,-10,-9,-10,-11,-12,-13,-17]; + GVAR(Humidity) = [82, 80, 81, 82, 83, 82, 81, 82, 83, 82, 83, 82]; +}; diff --git a/addons/weather/functions/fnc_updateWeather.sqf b/addons/weather/functions/fnc_updateWeather.sqf index b5495d67c5..d7f629147d 100644 --- a/addons/weather/functions/fnc_updateWeather.sqf +++ b/addons/weather/functions/fnc_updateWeather.sqf @@ -20,8 +20,8 @@ missionNamespace setVariable [QGVAR(currentOvercast), overcast, true]; [] call FUNC(updateTemperature); [] call FUNC(updateHumidity); -// Wind simulation -if (GVAR(windSimulation) && CBA_missionTime > GVAR(next_wind_udpate)) then { +// Wind simulation, take API for temporarily disabling into account along with setting +if (GVAR(windSimulation) && {!(missionNamespace getVariable [QGVAR(disableWindSimulation), false])} && {CBA_missionTime > GVAR(next_wind_udpate)}) then { GVAR(current_wind_direction) = GVAR(next_wind_direction); GVAR(current_wind_speed) = GVAR(next_wind_speed); diff --git a/addons/weather/functions/fnc_updateWind.sqf b/addons/weather/functions/fnc_updateWind.sqf index 0a821b19c0..af3d414a18 100644 --- a/addons/weather/functions/fnc_updateWind.sqf +++ b/addons/weather/functions/fnc_updateWind.sqf @@ -15,6 +15,9 @@ * Public: No */ +// Public API to temporarily disable wind simulation +if (missionNamespace getVariable [QGVAR(disableWindSimulation), false]) exitWith {}; + private _speed = linearConversion [GVAR(last_wind_update), GVAR(next_wind_udpate), CBA_missionTime, GVAR(current_wind_speed), GVAR(next_wind_speed), true]; private _direction = linearConversion [GVAR(last_wind_update), GVAR(next_wind_udpate), CBA_missionTime, GVAR(current_wind_direction), GVAR(next_wind_direction), true]; diff --git a/addons/weather/init3DEN.sqf b/addons/weather/init3DEN.sqf index 34b7dc2d5b..74af5fbaf1 100644 --- a/addons/weather/init3DEN.sqf +++ b/addons/weather/init3DEN.sqf @@ -5,7 +5,7 @@ // cannot create checkboxes which have the default value "true" // 3den uses inverted checkboxes instead, but those only change in appearence // we have to auto set these settings manually - on mission creation -add3DENEventHandler ["onMissionNew", { +add3DENEventHandler ["OnMissionNew", { set3DENMissionAttributes [ ["Intel", "IntelWavesIsForced", true], ["Intel", "IntelWindIsForced", true] diff --git a/addons/weather/initSettings.sqf b/addons/weather/initSettings.inc.sqf similarity index 96% rename from addons/weather/initSettings.sqf rename to addons/weather/initSettings.inc.sqf index fb11e31e75..26f4442084 100644 --- a/addons/weather/initSettings.sqf +++ b/addons/weather/initSettings.inc.sqf @@ -34,6 +34,5 @@ private _category = [format ["ACE %1", LLSTRING(Module_DisplayName)]]; QGVAR(showCheckAirTemperature), "CHECKBOX", [LSTRING(showCheckAirTemperature_DisplayName), LELSTRING(common,showActionInSelfInteraction)], _category, - true, // default value - false // isGlobal + true // default value ] call CBA_fnc_addSetting; diff --git a/addons/weather/stringtable.xml b/addons/weather/stringtable.xml index 2705e75e3a..ece79abe4a 100644 --- a/addons/weather/stringtable.xml +++ b/addons/weather/stringtable.xml @@ -62,7 +62,7 @@ Module météo ACE synchronisé en multijoueur. Többjátékos szinkronizált ACE időjárás modul ACE Модуль для синхронизации погоды в мультиплеере - Modulo Sincronizzazione Meteo ACE Multiplayer + Modulo Sincronizzazione Meteo ACE Multigiocatore ACE 天候モジュールではマルチプレイで同期します。 ACE 기후 모듈과 멀티플레이가 동기화됩니다. 使用 ACE 天气模块来同步所有客户端的天气状态(多人游戏) @@ -89,7 +89,7 @@ Expands the existing weather by temperature, humidity and air pressure. Erweitert das vorhandene Wetter um Temperatur, Luftfeuchtigkeit und Luftdruck. - Espande il tempo esistente per temperatura, umidità e pressione dell'aria. + Espande il tempo esistente con temperatura, umidità e pressione dell'aria. 透過增加濕度、溫度與氣壓來增強天氣模擬的表現。 透过增加湿度、温度与气压来增强天气模拟的表现。 気温や湿度、大気圧によって既存の天候を拡張します。 @@ -112,7 +112,7 @@ Intervalle de mises à jour Frissítési intervallum Интервал обновления - Intervallo Aggiornamento + Intervallo Aggiornamenti 更新間隔 갱신 간격 更新间隔 @@ -129,8 +129,8 @@ Définit l'intervalle (en secondes) entre les mises à jour des conditions météo. Megadja az intervallumot (másodpercben) az időjárás-frissítések között Определяет интервал (в секундах) между обновлениями погоды - Definisce l'intervallo(in secondi) tra aggiornamenti del meteo - 天候を更新する間隔を定義します。(秒) + Definisce l'intervallo (in secondi) tra aggiornamenti del meteo + 天候を更新する間隔 (秒) を定義します 기후를 갱신하는 간격을 초 단위로 정합니다. 设定天气更新的时间间隔(秒) 設定天氣更新的時間間隔(秒) @@ -142,7 +142,7 @@ Simulazione del Vento (basato sulla mappa) 風力模擬(基於地圖) 风力模拟(基于地图) - 風シミュレーション (マップを基に) + 風シミュレーション (マップに基づく) 바람 시뮬레이션 (지도 기반) Symulacja Wiatru (bazowana na mapie) Симуляция ветра (на основе местности) @@ -158,7 +158,7 @@ Abilita la simulazione del vento basato sulla mappa (sovrascrive il vento vanilla) 啟用後將遵照地圖特色進行風力模擬(覆蓋掉官方原版的風力模擬) 启用后将遵照地图特色进行风力模拟(覆盖掉官方原版的风力模拟) - マップを基にした風シミュレーションを有効化 (標準の風を上書き) + マップに基づいた風シミュレーションを有効化 (ゲーム標準の風を上書き) 지도 기반의 바람 시뮬레이션을 활성화합니다. (바닐라 바람을 덮어 씀) Aktywuje symulację wiatru bazującą na mapie (nadpisuje wind z domyślnej wersji gry) Включает симуляцию ветра на основе текущей местности (переписывает ванильный ветер) @@ -173,7 +173,7 @@ Überprüfe Lufttemperatur 檢查氣溫 检查气温 - Controllare la temperatura dell'aria + Controlla temperatura dell'aria Zkontrolovat teplotu vzduchu 気温を確認 Sprawdź temperaturę powietrza @@ -189,9 +189,9 @@ Zeige "Überprüfe Lufttemperatur" im Selbstinteraktionsmenü 顯示檢查氣溫動作 显示检查气温选项 - Mostra Controlla l'azione della temperatura dell'aria + Mostra l'azione di controllo della temperatura dell'aria Ukázat akci kontroly teploty vzduchu - 気温の確認動作を表示 + 気温を確認のアクションを表示 Pokaż akcje sprawdzającą temperaturę powietrza Afficher l'interaction "Vérifier la température" Mostrar a ação "Checar a temperatura do ar" diff --git a/addons/winddeflection/XEH_postInit.sqf b/addons/winddeflection/XEH_postInit.sqf index fbdfdfc868..a414058349 100644 --- a/addons/winddeflection/XEH_postInit.sqf +++ b/addons/winddeflection/XEH_postInit.sqf @@ -9,12 +9,12 @@ GVAR(trackedBullets) = []; if (!GVAR(enabled)) exitWith {}; // Register fire event handler - ["ace_firedPlayer", DFUNC(handleFired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerNonLocal", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayer", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; if (GVAR(vehicleEnabled)) then { - ["ace_firedPlayerVehicle", DFUNC(handleFired)] call CBA_fnc_addEventHandler; - ["ace_firedPlayerVehicleNonLocal", DFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicle", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; + ["ace_firedPlayerVehicleNonLocal", LINKFUNC(handleFired)] call CBA_fnc_addEventHandler; }; [] call FUNC(updateTrajectoryPFH); diff --git a/addons/winddeflection/XEH_preInit.sqf b/addons/winddeflection/XEH_preInit.sqf index 9361d05015..894773534a 100644 --- a/addons/winddeflection/XEH_preInit.sqf +++ b/addons/winddeflection/XEH_preInit.sqf @@ -6,6 +6,6 @@ PREP_RECOMPILE_START; #include "XEH_PREP.hpp" PREP_RECOMPILE_END; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/winddeflection/functions/fnc_handleFired.sqf b/addons/winddeflection/functions/fnc_handleFired.sqf index e4b547c032..c1b93818f0 100644 --- a/addons/winddeflection/functions/fnc_handleFired.sqf +++ b/addons/winddeflection/functions/fnc_handleFired.sqf @@ -16,7 +16,7 @@ */ //IGNORE_PRIVATE_WARNING ["_unit", "_weapon", "_muzzle", "_mode", "_ammo", "_magazine", "_projectile", "_vehicle", "_gunner", "_turret"]; -TRACE_10("firedEH:",_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile, _vehicle, _gunner, _turret); +TRACE_10("firedEH:",_unit,_weapon,_muzzle,_mode,_ammo,_magazine,_projectile,_vehicle,_gunner,_turret); if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && {_projectile isKindOf "BulletBase" && {_unit isKindOf "Man"}}) exitWith {false}; diff --git a/addons/winddeflection/initSettings.sqf b/addons/winddeflection/initSettings.inc.sqf similarity index 100% rename from addons/winddeflection/initSettings.sqf rename to addons/winddeflection/initSettings.inc.sqf diff --git a/addons/winddeflection/stringtable.xml b/addons/winddeflection/stringtable.xml index 594c96e966..d0c0863a6e 100644 --- a/addons/winddeflection/stringtable.xml +++ b/addons/winddeflection/stringtable.xml @@ -61,7 +61,7 @@ Météo Wetterinformationen Időjárás-Információ - Meteo + Informazioni Meteo Informação Meteorológica 天候の情報 기상 정보 diff --git a/addons/xm157/functions/fnc_ballistics_getData.sqf b/addons/xm157/functions/fnc_ballistics_getData.sqf index 928936c51e..828db8e4ae 100644 --- a/addons/xm157/functions/fnc_ballistics_getData.sqf +++ b/addons/xm157/functions/fnc_ballistics_getData.sqf @@ -24,7 +24,6 @@ private _key = format ["weaponInfoCache-%1-%2-%3",_weaponClass,_magazineClass,_a private _weaponInfo = GVAR(data) getOrDefault [_key, []]; if ((_weaponInfo isEqualTo []) && {_magazineClass != ""}) then { TRACE_3("new weapon/mag",_weaponClass,_magazineClass,_ammoClass); - private _useABConfig = (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]); private _zeroRange = 100; private _boreHeight = [_unit, 0] call EFUNC(scopes,getBoreHeight); @@ -35,8 +34,14 @@ if ((_weaponInfo isEqualTo []) && {_magazineClass != ""}) then { _weaponConfig params ["_barrelTwist", "_twistDirection", "_barrelLength"]; private _bc = if (_ballisticCoefficients isEqualTo []) then { 0 } else { _ballisticCoefficients # 0 }; + private _useAB = ( + missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false] && + {missionNamespace getVariable [QEGVAR(advanced_ballistics,barrelLengthInfluenceEnabled), false]} && + {_bc != 0} + ); + // Get Muzzle Velocity - private _muzzleVelocity = if (_barrelLength > 0 && _useABConfig && {_bc != 0}) then { + private _muzzleVelocity = if (_barrelLength > 0 && _useAB) then { [_barrelLength, _muzzleVelocityTable, _barrelLengthTable, 0] call EFUNC(advanced_ballistics,calculateBarrelLengthVelocityShift) } else { private _initSpeed = getNumber (configFile >> "CfgMagazines" >> _magazineClass >> "initSpeed"); diff --git a/addons/xm157/functions/fnc_keyPress.sqf b/addons/xm157/functions/fnc_keyPress.sqf index b55e6988aa..3a9dd53a26 100644 --- a/addons/xm157/functions/fnc_keyPress.sqf +++ b/addons/xm157/functions/fnc_keyPress.sqf @@ -19,9 +19,10 @@ params ["_func", "_keyDown"]; if (!GVAR(shown)) exitWith { false }; // fast exit if not shown -if (!([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith))) exitWith { false }; -if (!(ACE_player call CBA_fnc_canUseWeapon)) exitWith { false }; +if !([ACE_player, objNull, ["isNotInside"]] call EFUNC(common,canInteractWith)) exitWith { false }; +if !(ACE_player call CBA_fnc_canUseWeapon) exitWith { false }; +if (currentMuzzle ACE_player != currentWeapon ACE_player) exitWith { false }; private _display = uinamespace getVariable [QGVAR(display), displayNull]; if (isNull _display) exitWith { ERROR("keyPress-no display"); false }; diff --git a/addons/xm157/functions/fnc_weaponInfo_draw.sqf b/addons/xm157/functions/fnc_weaponInfo_draw.sqf index ef9fd1d528..c03b575f4e 100644 --- a/addons/xm157/functions/fnc_weaponInfo_draw.sqf +++ b/addons/xm157/functions/fnc_weaponInfo_draw.sqf @@ -86,7 +86,7 @@ if (_retTex != ctrlText _ctrlScopeReticle) then { _ctrlScopeReticle ctrlSetText private _rangeInfo = _range call { if (_range == 0) exitWith { "" }; if (_range < 0) exitWith { // range error - blink if recent - if ((_timeSinceLastInput < 3) && {(floor (4*_timeSinceLastInput)) % 2 == 1}) then { "----" } else { "" }; + ["", "----"] select ((_timeSinceLastInput < 3) && {(floor (4*_timeSinceLastInput)) % 2 == 1}); }; format ["%1 m", _range toFixed 0] }; @@ -98,7 +98,7 @@ _ctrl ctrlSetText _rangeInfo; private _bearingInfo = call { private _bearingSetting = GVAR(data) getOrDefault ["bearing_show", 0]; if ((_bearingSetting == 2) && {_timeSinceLastInput > 2}) exitWith { "" }; - if ((_bearingSetting == 1)) exitWith { format ["%1", floor (17.777777 * _weaponDir)]; }; // (6400 Mils, not MRAD) + if ((_bearingSetting == 1)) exitWith { str floor (17.777777 * _weaponDir); }; // (6400 Mils, not MRAD) format ["%1°", floor _weaponDir]; }; private _ctrl = _display displayCtrl IDC_SCREEN_TEXT_UPPER_LEFT; diff --git a/addons/yardage450/XEH_postInit.sqf b/addons/yardage450/XEH_postInit.sqf index 2d4ef89968..1f3cb1a1cf 100644 --- a/addons/yardage450/XEH_postInit.sqf +++ b/addons/yardage450/XEH_postInit.sqf @@ -1,6 +1,8 @@ #include "script_component.hpp" -#include "initKeybinds.sqf" +if (!hasInterface) exitWith {}; + +#include "initKeybinds.inc.sqf" GVAR(active) = false; diff --git a/addons/yardage450/functions/fnc_turnOn.sqf b/addons/yardage450/functions/fnc_turnOn.sqf index e30798c523..62bb135a2c 100644 --- a/addons/yardage450/functions/fnc_turnOn.sqf +++ b/addons/yardage450/functions/fnc_turnOn.sqf @@ -15,12 +15,12 @@ * Public: No */ -#define __dsp (uiNamespace getVariable "ACE_RscYardage450") -#define __ctrlTarget (__dsp displayCtrl 720041) -#define __ctrlLaser (__dsp displayCtrl 720042) -#define __ctrlRange (__dsp displayCtrl 720043) -#define __ctrlMeters (__dsp displayCtrl 720044) -#define __ctrlYards (__dsp displayCtrl 720045) +#define DISPLAY_YARDAGE (uiNamespace getVariable "ACE_RscYardage450") +#define CTRL_TARGET (DISPLAY_YARDAGE displayCtrl 720041) +#define CTRL_LASER (DISPLAY_YARDAGE displayCtrl 720042) +#define CTRL_RANGE (DISPLAY_YARDAGE displayCtrl 720043) +#define CTRL_METERS (DISPLAY_YARDAGE displayCtrl 720044) +#define CTRL_YARDS (DISPLAY_YARDAGE displayCtrl 720045) if (currentWeapon ACE_player != "ACE_Yardage450" || cameraView != "GUNNER") exitWith {}; @@ -33,25 +33,28 @@ GVAR(active) = true; [{ if (CBA_missionTime - GVAR(powerOnTime) > 30) exitWith { GVAR(active) = false; - 74210 cutText ["", "PLAIN"]; + QUOTE(ADDON) cutText ["", "PLAIN"]; [_this select 1] call CBA_fnc_removePerFrameHandler; }; if (currentWeapon ACE_player == "ACE_Yardage450" && cameraView == "GUNNER") then { - 74210 cutRsc ["ACE_RscYardage450", "PLAIN", 1, false]; - - __ctrlLaser ctrlShow GVAR(lasing); - if (GVAR(targetAcquired)) then { - __ctrlTarget ctrlSetText "Target Acquired"; - __ctrlRange ctrlSetText GVAR(targetRangeText); - } else { - __ctrlTarget ctrlSetText ""; - __ctrlRange ctrlSetText "---"; + if (isNil {DISPLAY_YARDAGE} || {isNull DISPLAY_YARDAGE} || {ctrlIDD DISPLAY_YARDAGE != -1}) then { + TRACE_1("making display",DISPLAY_YARDAGE); + QUOTE(ADDON) cutRsc ["ACE_RscYardage450", "PLAIN", 1, false]; }; - __ctrlMeters ctrlShow !GVAR(useYards); - __ctrlYards ctrlShow GVAR(useYards); + + CTRL_LASER ctrlShow GVAR(lasing); + if (GVAR(targetAcquired)) then { + CTRL_TARGET ctrlSetText "Target Acquired"; + CTRL_RANGE ctrlSetText GVAR(targetRangeText); + } else { + CTRL_TARGET ctrlSetText ""; + CTRL_RANGE ctrlSetText "---"; + }; + CTRL_METERS ctrlShow !GVAR(useYards); + CTRL_YARDS ctrlShow GVAR(useYards); } else { - 74210 cutText ["", "PLAIN"]; + QUOTE(ADDON) cutText ["", "PLAIN"]; }; }, 0, []] call CBA_fnc_addPerFrameHandler; diff --git a/addons/yardage450/initKeybinds.sqf b/addons/yardage450/initKeybinds.inc.sqf similarity index 100% rename from addons/yardage450/initKeybinds.sqf rename to addons/yardage450/initKeybinds.inc.sqf diff --git a/addons/yardage450/stringtable.xml b/addons/yardage450/stringtable.xml index cf955f8a74..4e94b4a5d8 100644 --- a/addons/yardage450/stringtable.xml +++ b/addons/yardage450/stringtable.xml @@ -27,7 +27,7 @@ Medidor de Distância a laser Lézeres távolságmérő Лазерный дальномер - Distanziometro Laser + Telemetro Laser Télémètre laser レーザー測距機 레이저 거리측정기 diff --git a/addons/zeus/CfgVehicles.hpp b/addons/zeus/CfgVehicles.hpp index 1dc4f083e3..5fb4a4f61a 100644 --- a/addons/zeus/CfgVehicles.hpp +++ b/addons/zeus/CfgVehicles.hpp @@ -191,6 +191,13 @@ class CfgVehicles { function = QFUNC(moduleLoadIntoCargo); icon = "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa"; }; + class GVAR(moduleUnloadFromCargo): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = CSTRING(ModuleUnloadFromCargo_DisplayName); + function = QFUNC(moduleUnloadFromCargo); + icon = "a3\ui_f\data\IGUI\Cfg\Actions\loadVehicle_ca.paa"; + }; class GVAR(moduleCargoParadrop): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(AI); @@ -249,6 +256,12 @@ class CfgVehicles { displayName = CSTRING(ModuleSimulation_DisplayName); function = QFUNC(moduleSimulation); }; + class GVAR(moduleSpectator): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Utility); + displayName = ECSTRING(spectator,Module_DisplayName); + curatorInfoType = QGVAR(RscSpectator); + }; class GVAR(moduleSuicideBomber): GVAR(moduleBase) { curatorCanAttach = 1; category = QGVAR(AI); @@ -336,6 +349,13 @@ class CfgVehicles { function = QFUNC(moduleBurn); icon = QPATHTOF(ui\Icon_Module_Zeus_Burn_ca.paa); }; + class GVAR(moduleMedicalMenu): GVAR(moduleBase) { + curatorCanAttach = 1; + category = QGVAR(Medical); + displayName = CSTRING(ModuleMedicalMenu_DisplayName); + function = QFUNC(moduleMedicalMenu); + icon = QPATHTOF(UI\Icon_Module_Zeus_Medic_ca.paa); + }; class Man; class CAManBase: Man { diff --git a/addons/zeus/XEH_PREP.hpp b/addons/zeus/XEH_PREP.hpp index 46cbbeb446..69dd7b18a6 100644 --- a/addons/zeus/XEH_PREP.hpp +++ b/addons/zeus/XEH_PREP.hpp @@ -8,11 +8,11 @@ PREP(bi_moduleRemoteControl); PREP(canCreateModule); PREP(getModuleDestination); PREP(handleZeusUnitAssigned); -PREP(moduleAddArsenal); PREP(moduleAddAceArsenal); +PREP(moduleAddArsenal); +PREP(moduleAddOrRemoveFRIES); PREP(moduleAddSpareTrack); PREP(moduleAddSpareWheel); -PREP(moduleAddOrRemoveFRIES); PREP(moduleBurn); PREP(moduleCaptive); PREP(moduleCargoParadrop); @@ -23,16 +23,18 @@ PREP(moduleGroupSide); PREP(moduleHeal); PREP(moduleLayTrench); PREP(moduleLoadIntoCargo); -PREP(moduleRemoveArsenal); +PREP(moduleMedicalMenu); PREP(moduleRemoveAceArsenal); +PREP(moduleRemoveArsenal); PREP(moduleSearchNearby); PREP(moduleSetEngineer); PREP(moduleSetMedic); -PREP(moduleSetMedicalVehicle); PREP(moduleSetMedicalFacility); +PREP(moduleSetMedicalVehicle); PREP(moduleSetRepairFacility); PREP(moduleSetRepairVehicle); PREP(moduleSimulation); +PREP(moduleSpectator); PREP(moduleSuicideBomber); PREP(moduleSuppressiveFire); PREP(moduleSuppressiveFireLocal); @@ -42,6 +44,7 @@ PREP(moduleToggleFlashlight); PREP(moduleToggleNvg); PREP(moduleUnconscious); PREP(moduleUnGarrison); +PREP(moduleUnloadFromCargo); PREP(moduleZeusSettings); PREP(showMessage); PREP(ui_attributeCargo); @@ -54,6 +57,7 @@ PREP(ui_groupSide); PREP(ui_patrolArea); PREP(ui_searchArea); PREP(ui_setEngineer); +PREP(ui_spectator); PREP(ui_suicideBomber); PREP(ui_teleportPlayers); PREP(ui_toggleFlashlight); diff --git a/addons/zeus/XEH_postInit.sqf b/addons/zeus/XEH_postInit.sqf index b4d1302ab5..15b4c15f76 100644 --- a/addons/zeus/XEH_postInit.sqf +++ b/addons/zeus/XEH_postInit.sqf @@ -11,6 +11,7 @@ QGVAR(GlobalSkillAI) addPublicVariableEventHandler FUNC(moduleGlobalSetSkill); [QGVAR(moduleSearchNearby), CBA_fnc_searchNearby] call CBA_fnc_addEventHandler; [QGVAR(moduleSearchArea), CBA_fnc_taskSearchArea] call CBA_fnc_addEventHandler; [QGVAR(suppressiveFire), LINKFUNC(moduleSuppressiveFireLocal)] call CBA_fnc_addEventHandler; +[QGVAR(moduleSpectator), LINKFUNC(moduleSpectator)] call CBA_fnc_addEventHandler; // Editable object commands must be ran on server, this events are used in the respective module if (isServer) then { diff --git a/addons/zeus/XEH_preInit.sqf b/addons/zeus/XEH_preInit.sqf index c1bea7c581..46e95431a1 100644 --- a/addons/zeus/XEH_preInit.sqf +++ b/addons/zeus/XEH_preInit.sqf @@ -7,18 +7,18 @@ PREP_RECOMPILE_START; PREP_RECOMPILE_END; if (isServer) then { - [QGVAR(zeusUnitAssigned), FUNC(handleZeusUnitAssigned)] call CBA_fnc_addEventHandler; + [QGVAR(zeusUnitAssigned), LINKFUNC(handleZeusUnitAssigned)] call CBA_fnc_addEventHandler; // Only add an InitPost EH if setting is enabled (and apply retroactively) ["CBA_settingsInitialized", { if (GVAR(autoAddObjects)) then { - ["AllVehicles", "InitPost", FUNC(addObjectToCurator), true, [], true] call CBA_fnc_addClassEventHandler; + ["AllVehicles", "InitPost", LINKFUNC(addObjectToCurator), true, [], true] call CBA_fnc_addClassEventHandler; }; }] call CBA_fnc_addEventHandler; }; GVAR(GlobalSkillAI) = [0.5,0.5,0.5,0.5,true,true]; -#include "initSettings.sqf" +#include "initSettings.inc.sqf" ADDON = true; diff --git a/addons/zeus/config.cpp b/addons/zeus/config.cpp index 8b752771b7..d90c906294 100644 --- a/addons/zeus/config.cpp +++ b/addons/zeus/config.cpp @@ -49,12 +49,14 @@ class CfgPatches { QGVAR(moduleUnconscious), QGVAR(moduleSetMedic), QGVAR(moduleSetMedicalVehicle), - QGVAR(moduleSetMedicalFacility) + QGVAR(moduleSetMedicalFacility), + QGVAR(moduleMedicalMenu) }; }; class GVAR(cargo): ADDON { units[] = { QGVAR(moduleLoadIntoCargo), + QGVAR(moduleUnloadFromCargo), QGVAR(moduleCargoParadrop) }; }; @@ -97,6 +99,11 @@ class CfgPatches { QGVAR(moduleLayTrench) }; }; + class GVAR(spectator): ADDON { + units[] = { + QGVAR(moduleSpectator) + }; + }; }; class ACE_Curator { @@ -110,6 +117,7 @@ class ACE_Curator { GVAR(arsenal) = "ace_arsenal"; GVAR(fire) = "ace_fire"; GVAR(trenches) = "ace_trenches"; + GVAR(spectator) = "ace_spectator"; }; #include "CfgFactionClasses.hpp" diff --git a/addons/zeus/functions/fnc_addObjectToCurator.sqf b/addons/zeus/functions/fnc_addObjectToCurator.sqf index 9651630ccc..4b87904d0f 100644 --- a/addons/zeus/functions/fnc_addObjectToCurator.sqf +++ b/addons/zeus/functions/fnc_addObjectToCurator.sqf @@ -17,7 +17,7 @@ params ["_object"]; -if (!(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)])) exitWith {}; +if !(_object getVariable [QGVAR(addObject), GVAR(autoAddObjects)]) exitWith {}; [{ TRACE_1("Delayed addCuratorEditableObjects",_this); diff --git a/addons/zeus/functions/fnc_bi_moduleArsenal.sqf b/addons/zeus/functions/fnc_bi_moduleArsenal.sqf index f2be4a3838..8dd5f26929 100644 --- a/addons/zeus/functions/fnc_bi_moduleArsenal.sqf +++ b/addons/zeus/functions/fnc_bi_moduleArsenal.sqf @@ -29,11 +29,11 @@ if (_activated && local _logic) then { case (isnull _unit): {_error = localize "str_a3_BIS_fnc_showCuratorFeedbackMessage_506";}; case !(alive _unit): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorDead";}; case (isnull group _unit || !(side group _unit in [east,west,resistance,civilian])): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorBrain";}; - case (vehicle _unit != _unit || effectivecommander _unit != _unit): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorVehicle";}; + case (!isNull objectParent _unit || effectivecommander _unit != _unit): {_error = localize "str_a3_BIS_fnc_moduleArsenal_errorVehicle";}; }; if (_error == "") then { - if (["ACE_Arsenal"] call EFUNC(common,isModLoaded)) then { + if (["ace_arsenal"] call EFUNC(common,isModLoaded)) then { if (!isPlayer _unit || {player == _unit}) then { [{ diff --git a/addons/zeus/functions/fnc_bi_moduleCurator.sqf b/addons/zeus/functions/fnc_bi_moduleCurator.sqf index c597955a23..cdc4d35b64 100644 --- a/addons/zeus/functions/fnc_bi_moduleCurator.sqf +++ b/addons/zeus/functions/fnc_bi_moduleCurator.sqf @@ -23,13 +23,13 @@ params ["_logic", "_units", "_activated"]; if (_activated) then { - //--- Terminate when not created on the server - if (!isserver && local _logic && isnull (getassignedcuratorunit _logic)) exitwith { + // Terminate when not created on the server + if (!isServer && local _logic && isnull (getassignedcuratorunit _logic)) exitwith { [format ["%1 is trying to create curator logic ModuleCurator_F",profilename],"bis_fnc_error",false] call bis_fnc_mp; deletevehicle _logic; }; - //--- Get curator owner + // Get curator owner _ownerVar = _logic getvariable ["owner",""]; _ownerUID = parsenumber _ownerVar; if (cheatsenabled) then { @@ -46,13 +46,13 @@ if (_activated) then { }; _isAdmin = _ownerVar == "#adminLogged" || _ownerVar == "#adminVoted"; - //--- Wipe out the variable so clients can't access it + // Wipe out the variable so clients can't access it _logic setvariable ["owner",nil]; - //--- Server + // Server if (isserver) then { - //--- Prepare admin variable + // Prepare admin variable _adminVar = ""; if (_isAdmin) then { _letters = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"]; @@ -61,12 +61,12 @@ if (_activated) then { _logic setvariable ["adminVar",_adminVar,true]; }; - //--- Get allowed addons + // Get allowed addons _addonsType = _logic getvariable ["Addons",2]; _addons = []; switch _addonsType do { - //--- All (including unofficial ones) + // All (including unofficial ones) case 3: { _cfgPatches = configfile >> "cfgpatches"; for "_i" from 0 to (count _cfgPatches - 1) do { @@ -79,10 +79,10 @@ if (_activated) then { _logic addcuratoraddons _addons; }; - //--- All active + // All active case 2: {}; - //--- All mission + // All mission case 1: { _addonsList = []; { @@ -92,13 +92,13 @@ if (_activated) then { _logic addcuratoraddons _addonsList; }; - //--- None + // None case 0: { removeallcuratoraddons _logic; }; }; - //--- Handle ownership + // Handle ownership [_logic,_ownerVar,_ownerUID,_adminVar] spawn { scriptname "BIS_fnc_moduleCurator: Owner"; @@ -110,16 +110,16 @@ if (_activated) then { _name = _logic getvariable ["name",""]; if (_name == "") then {_name = localize "STR_A3_curator";}; - //--- Wait until mission starts + // Wait until mission starts waitUntil {time > 0}; // NOTE: DO NOT CHANGE TO CBA_missionTime, IT BREAKS THE MODULE - //--- Refresh addon list, so it's broadcasted to clients + // Refresh addon list, so it's broadcasted to clients _addons = curatoraddons _logic; removeAllCuratorAddons _logic; _logic addcuratoraddons _addons; while {true} do { - //--- Wait for player to become Zeus + // Wait for player to become Zeus switch true do { case (_ownerUID > 0): { waituntil { @@ -133,7 +133,7 @@ if (_activated) then { }; if (isnull _logic) exitwith {}; - //--- Assign + // Assign _player = objnull; switch true do { case (_ownerUID > 0): { @@ -150,7 +150,7 @@ if (_activated) then { waituntil {_player assignCurator _logic; getassignedcuratorunit _logic == _player || isnull _logic}; if (isnull _logic) exitwith {}; - //--- Add radio channels + // Add radio channels { _x radiochanneladd [_player]; } foreach (_logic getvariable ["channels",[]]); @@ -159,7 +159,7 @@ if (_activated) then { private _msgCode = { params ["_logic","_player"]; - //--- Sent notification to all assigned players + // Sent notification to all assigned players if ((_logic getVariable ["showNotification",true]) && GVAR(zeusAscension)) then { { if (isplayer _x) then { @@ -181,7 +181,7 @@ if (_activated) then { // Added by ace_zeus [QGVAR(zeusUnitAssigned), [_logic,_player]] call CBA_fnc_globalEvent; - //--- Wait for player to stop being Zeus + // Wait for player to stop being Zeus switch true do { case (_ownerUID > 0): { waituntil { @@ -195,12 +195,12 @@ if (_activated) then { }; if (isnull _logic) exitwith {}; - //--- Add radio channels + // Add radio channels { _x radiochannelremove [_player]; } foreach (_logic getvariable ["channels",[]]); - //--- Unassign + // Unassign waituntil {unassigncurator _logic; isnull (getassignedcuratorunit _logic) || isnull _logic}; if (isnull _logic) exitwith {}; }; @@ -211,14 +211,14 @@ if (_activated) then { params ["_logic"]; if (GVAR(zeusBird)) then { - //--- Create bird + // Create bird _birdType = _logic getVariable ["birdType","eagle_f"]; if (_birdType != "") then { _bird = createvehicle [_birdType,[100,100,100],[],0,"none"]; _logic setVariable ["bird",_bird,true]; }; - //--- Locality changed + // Locality changed _logic addeventhandler [ "local", { @@ -237,7 +237,7 @@ if (_activated) then { [_logic] call _birdCode; }; - //--- Activated all future addons + // Activated all future addons _addons = []; { if (typeof _x == "ModuleCuratorAddAddons_F") then { @@ -254,12 +254,12 @@ if (_activated) then { if (time <= 0) then { _addons call bis_fnc_activateaddons; }; }; - //--- Player + // Player if (hasinterface) then { waituntil {local player}; - _serverCommand = if (_ownerVar == "#adminLogged") then {"#shutdown"} else {"#kick"}; + _serverCommand = ["#kick", "#shutdown"] select (_ownerVar == "#adminLogged"); - //--- Black effect until the interface is open + // Black effect until the interface is open _forced = _logic getvariable ["forced",0] > 0; if (_forced) then { _isCurator = switch true do { @@ -279,15 +279,15 @@ if (_activated) then { }; }; - //--- Check if player is server admin + // Check if player is server admin if (_isAdmin) then { _adminVar = _logic getvariable ["adminVar",""]; _logic setvariable ["adminVar",nil]; if (isserver) then { - //--- Host + // Host missionnamespace setvariable [_adminVar,player]; } else { - //--- Client + // Client [_logic,_adminVar,_serverCommand] spawn { scriptname "BIS_fnc_moduleCurator: Admin check"; @@ -314,7 +314,7 @@ if (_activated) then { sleep 1; waituntil {alive player}; - //--- Show warning when Zeus key is not assigned + // Show warning when Zeus key is not assigned if (count (actionkeys "curatorInterface") == 0) then { [ format [ @@ -324,7 +324,7 @@ if (_activated) then { ] call bis_fnc_guiMessage; }; - //--- Show hint about pinging for players + // Show hint about pinging for players if ( isnil {profilenamespace getvariable "bis_fnc_curatorPinged_done"} && @@ -339,7 +339,7 @@ if (_activated) then { }; }; - //--- Add local event handlers + // Add local event handlers _logic addeventhandler ["curatorFeedbackMessage",{_this call bis_fnc_showCuratorFeedbackMessage;}]; _logic addeventhandler ["curatorPinged",{_this call bis_fnc_curatorPinged;}]; _logic addeventhandler ["curatorObjectPlaced",{_this call bis_fnc_curatorObjectPlaced;}]; 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/functions/fnc_bi_moduleRemoteControl.sqf b/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf index b2288be91c..2aa438be53 100644 --- a/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf +++ b/addons/zeus/functions/fnc_bi_moduleRemoteControl.sqf @@ -30,7 +30,7 @@ if (_activated && local _logic && !isnull curatorcamera) then { //--- Get unit under cursor _unit = objnull; _mouseOver = missionnamespace getvariable ["bis_fnc_curatorObjectPlaced_mouseOver",[""]]; - if ((_mouseOver select 0) == typename objnull) then {_unit = _mouseOver select 1;}; + if ((_mouseOver select 0) == "OBJECT") then {_unit = _mouseOver select 1;}; _unit = effectivecommander _unit; //--- Temp owner diff --git a/addons/zeus/functions/fnc_getModuleDestination.sqf b/addons/zeus/functions/fnc_getModuleDestination.sqf index b328201d6c..10d7acae9e 100644 --- a/addons/zeus/functions/fnc_getModuleDestination.sqf +++ b/addons/zeus/functions/fnc_getModuleDestination.sqf @@ -113,9 +113,9 @@ GVAR(moduleDestination_mapDrawEH) = [((findDisplay 312) displayCtrl 50), "draw", } else { TRACE_4("cleaning up",_this select 1,GVAR(moduleDestination_displayEHMouse),GVAR(moduleDestination_displayEHKeyboard),GVAR(moduleDestination_mapDrawEH)); (_this select 1) call CBA_fnc_removePerFrameHandler; - (findDisplay 312) displayRemoveEventHandler ["mouseButtonDown", GVAR(moduleDestination_displayEHMouse)]; + (findDisplay 312) displayRemoveEventHandler ["MouseButtonDown", GVAR(moduleDestination_displayEHMouse)]; (findDisplay 312) displayRemoveEventHandler ["KeyDown", GVAR(moduleDestination_displayEHKeyboard)]; - ((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["draw", GVAR(moduleDestination_mapDrawEH)]; + ((findDisplay 312) displayCtrl 50) ctrlRemoveEventHandler ["Draw", GVAR(moduleDestination_mapDrawEH)]; GVAR(moduleDestination_displayEHMouse) = nil; GVAR(moduleDestination_displayEHKeyboard) = nil; GVAR(moduleDestination_mapDrawEH) = nil; diff --git a/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf b/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf index 208e781319..2e4efca6e0 100644 --- a/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf +++ b/addons/zeus/functions/fnc_moduleAddSpareTrack.sqf @@ -32,10 +32,10 @@ if !(["ace_cargo"] call EFUNC(common,isModLoaded) && ["ace_repair"] call EFUNC(c if !(alive _mouseOverUnit) then { [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { - if (getNumber (configFile >> "CfgVehicles" >> "ACE_Track" >> QEGVAR(cargo,size)) > [_mouseOverUnit] call EFUNC(cargo,getCargoSpaceLeft)) then { + if ("ACE_Track" call EFUNC(cargo,getSizeItem) > _mouseOverUnit call EFUNC(cargo,getCargoSpaceLeft)) then { [LSTRING(OnlyEnoughCargoSpace)] call FUNC(showMessage); } else { - ["ace_addCargo", ["ACE_Track", _mouseOverUnit, 1, true]] call CBA_fnc_localEvent; + ["ace_addCargo", ["ACE_Track", _mouseOverUnit, 1]] call CBA_fnc_localEvent; }; }; }; diff --git a/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf b/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf index 1746b1045a..d913300709 100644 --- a/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf +++ b/addons/zeus/functions/fnc_moduleAddSpareWheel.sqf @@ -32,10 +32,10 @@ if !(["ace_cargo"] call EFUNC(common,isModLoaded) && ["ace_repair"] call EFUNC(c if !(alive _mouseOverUnit) then { [LSTRING(OnlyAlive)] call FUNC(showMessage); } else { - if (getNumber (configFile >> "CfgVehicles" >> "ACE_Wheel" >> QEGVAR(cargo,size)) > [_mouseOverUnit] call EFUNC(cargo,getCargoSpaceLeft)) then { + if ("ACE_Wheel" call EFUNC(cargo,getSizeItem) > _mouseOverUnit call EFUNC(cargo,getCargoSpaceLeft)) then { [LSTRING(OnlyEnoughCargoSpace)] call FUNC(showMessage); } else { - ["ace_addCargo", ["ACE_Wheel", _mouseOverUnit, 1, true]] call CBA_fnc_localEvent; + ["ace_addCargo", ["ACE_Wheel", _mouseOverUnit, 1]] call CBA_fnc_localEvent; }; }; }; diff --git a/addons/zeus/functions/fnc_moduleBurn.sqf b/addons/zeus/functions/fnc_moduleBurn.sqf index 4cf2017b67..9fb3b085af 100644 --- a/addons/zeus/functions/fnc_moduleBurn.sqf +++ b/addons/zeus/functions/fnc_moduleBurn.sqf @@ -17,26 +17,22 @@ params ["_logic"]; -if !(local _logic) exitWith {}; +if (!local _logic) exitWith {}; private _unit = attachedTo _logic; deleteVehicle _logic; switch (false) do { - case !(isNull _unit): { + case (!isNull _unit): { [LSTRING(NothingSelected)] call FUNC(showMessage); }; - case (_unit isKindOf "CAManBase"): { + case (_unit isKindOf "CAManBase" && {getNumber (configOf _unit >> "isPlayableLogic") == 0}): { [LSTRING(OnlyInfantry)] call FUNC(showMessage); }; - case (alive _unit): { - [LSTRING(OnlyAlive)] call FUNC(showMessage); - }; case (["ace_fire"] call EFUNC(common,isModLoaded)): { [LSTRING(RequiresAddon)] call FUNC(showMessage); }; default { - [QEGVAR(fire,burn), [_unit, 5]] call CBA_fnc_globalEvent; + [QEGVAR(fire,burn), [_unit, 5], _unit] call CBA_fnc_targetEvent; }; }; - diff --git a/addons/zeus/functions/fnc_moduleCargoParadrop.sqf b/addons/zeus/functions/fnc_moduleCargoParadrop.sqf index 69d90d310d..2aaffb3796 100644 --- a/addons/zeus/functions/fnc_moduleCargoParadrop.sqf +++ b/addons/zeus/functions/fnc_moduleCargoParadrop.sqf @@ -30,13 +30,13 @@ TRACE_4("moduleCargoParadrop placed",_logic,typeOf _vehicle,_pilot,typeOf _pilot deleteVehicle _logic; // cleanup logic now, we just needed it to get the attached vehicle -if (!(missionNamespace getVariable [QEGVAR(cargo,enable), false])) exitWith { +if !(missionNamespace getVariable [QEGVAR(cargo,enable), false]) exitWith { [LSTRING(RequiresAddon)] call FUNC(showMessage); }; if (isNull _vehicle) exitWith { [LSTRING(NothingSelected)] call FUNC(showMessage); }; -if (!(_vehicle isKindOf "Air")) exitWith { +if !(_vehicle isKindOf "Air") exitWith { [format ["%1 %2", localize "str_dn_aircraft", localize "str_msg_no_veh_select"]] call FUNC(showMessage); }; if ((!alive _vehicle) || {!alive _pilot}) exitWith { diff --git a/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf b/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf index 615a11d271..6570648499 100644 --- a/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf +++ b/addons/zeus/functions/fnc_moduleCargoParadropWaypoint.sqf @@ -22,7 +22,7 @@ TRACE_2("moduleCargoParadropWaypoint",_vehicleGroup,_wpPos); private _vehicle = vehicle leader _vehicleGroup; private _commander = driver _vehicle; private _cargo = _vehicle getVariable [QEGVAR(cargo,loaded), []]; -if (!(_vehicle isKindOf "Air")) exitWith {WARNING_1("not in a air vehicle",typeOf _vehicle); true}; +if !(_vehicle isKindOf "Air") exitWith {WARNING_1("not in a air vehicle",typeOf _vehicle); true}; if (_cargo isEqualTo []) exitWith {WARNING_1("no cargo",_cargo); true}; private _previousSpeedMode = speedMode _vehicleGroup; @@ -48,7 +48,7 @@ waitUntil { }; TRACE_2("Finished primary movement",_vehicle distance2D _wpPos,_closeEnoughTicks); -if ((!alive _vehicle) || {!alive _commander}) exitWith {TRACE_2("died",alive _vehicle, alive _commander); true}; +if ((!alive _vehicle) || {!alive _commander}) exitWith {TRACE_2("died",alive _vehicle,alive _commander); true}; if (((getPos _vehicle) select 2) < 25) exitWith {TRACE_1("too low",getPos _vehicle); true}; // Fly level and straight diff --git a/addons/zeus/functions/fnc_moduleHeal.sqf b/addons/zeus/functions/fnc_moduleHeal.sqf index 9a49375003..4bf0525ea7 100644 --- a/addons/zeus/functions/fnc_moduleHeal.sqf +++ b/addons/zeus/functions/fnc_moduleHeal.sqf @@ -43,7 +43,7 @@ switch (false) do { }; // Heal validated target -if (["ace_medical"] call EFUNC(common,isModLoaded)) then { +if (GETEGVAR(medical,enabled,false)) then { TRACE_1("healing with ace_medical",_unit); [QEGVAR(medical_treatment,fullHealLocal), [_unit], _unit] call CBA_fnc_targetEvent; } else { diff --git a/addons/zeus/functions/fnc_moduleMedicalMenu.sqf b/addons/zeus/functions/fnc_moduleMedicalMenu.sqf new file mode 100644 index 0000000000..a69a65fb74 --- /dev/null +++ b/addons/zeus/functions/fnc_moduleMedicalMenu.sqf @@ -0,0 +1,41 @@ +#include "..\script_component.hpp" +/* + * Author: Brett Mayson + * Opens the medical menu for the unit + * + * Arguments: + * 0: The module logic + * + * Return Value: + * None + * + * Example: + * [LOGIC] call ace_zeus_fnc_moduleMedicalMenu + * + * Public: No + */ + +params ["_logic"]; + +if !(local _logic) exitWith {}; + +private _unit = attachedTo _logic; +deleteVehicle _logic; + +switch (false) do { + case !(isNull _unit): { + [LSTRING(NothingSelected)] call FUNC(showMessage); + }; + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call FUNC(showMessage); + }; + case (["ace_medical_gui"] call EFUNC(common,isModLoaded)): { + [LSTRING(RequiresAddon)] call FUNC(showMessage); + }; + case ([objNull, _unit] call EFUNC(medical_gui,canOpenMenu)): { + [LSTRING(MedicalMenuDisabled)] call FUNC(showMessage); + }; + default { + [_unit] call EFUNC(medical_gui,openMenu); + }; +}; diff --git a/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf b/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf index 6c511bae07..6d2a94139b 100644 --- a/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf +++ b/addons/zeus/functions/fnc_moduleRemoveArsenal.sqf @@ -30,7 +30,7 @@ switch (true) do { }; default { - TRACE_1("Calling removeVirtualXXXCargo functions", _object); + TRACE_1("Calling removeVirtualXXXCargo functions",_object); [_object, (_object call BIS_fnc_getVirtualItemCargo), true] call BIS_fnc_removeVirtualItemCargo; [_object, (_object call BIS_fnc_getVirtualWeaponCargo), true] call BIS_fnc_removeVirtualWeaponCargo; [_object, (_object call BIS_fnc_getVirtualMagazineCargo), true] call BIS_fnc_removeVirtualMagazineCargo; diff --git a/addons/zeus/functions/fnc_moduleSetMedic.sqf b/addons/zeus/functions/fnc_moduleSetMedic.sqf index a05dc65d50..d44dd56e59 100644 --- a/addons/zeus/functions/fnc_moduleSetMedic.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedic.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); diff --git a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf index 8ff9b4a731..b6742a25a4 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalFacility.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); @@ -40,7 +40,7 @@ if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { if (GETVAR(_unit,EGVAR(captives,isHandcuffed),false)) then { [LSTRING(OnlyNonCaptive)] call FUNC(showMessage); } else { - if (!(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false))) then { + if !(GETVAR(_unit,EGVAR(medical,isMedicalFacility),false)) then { _unit setVariable [QEGVAR(medical,isMedicalFacility), true, true]; }; }; diff --git a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf index e3051f9824..26bb3fcfe9 100644 --- a/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf +++ b/addons/zeus/functions/fnc_moduleSetMedicalVehicle.sqf @@ -21,7 +21,7 @@ params ["_logic"]; if !(local _logic) exitWith {}; -if !(["ACE_Medical"] call EFUNC(common,isModLoaded)) then { +if !(GETEGVAR(medical,enabled,false)) then { [LSTRING(RequiresAddon)] call FUNC(showMessage); } else { private _mouseOver = GETMVAR(bis_fnc_curatorObjectPlaced_mouseOver,[""]); diff --git a/addons/zeus/functions/fnc_moduleSpectator.sqf b/addons/zeus/functions/fnc_moduleSpectator.sqf new file mode 100644 index 0000000000..fb9ca2a63b --- /dev/null +++ b/addons/zeus/functions/fnc_moduleSpectator.sqf @@ -0,0 +1,39 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Zeus module function to make the local player an ACE Spectator. + * + * Arguments: + * 0: Force interface + * 1: Hide player + * 2: Sides available to spectate + * 3: Camera modes available + * 4: Vision modes available + * + * Return Value: + * None + * + * Example: + * [true, true, [west], [0, 1, 2], [-2, -1, 0, 1]] call ace_zeus_fnc_moduleSpectator + * + * Public: No + */ + +params ["_force", "_hide", "_sides", "_modes", "_visions"]; +TRACE_1("params",_this); + +// Update sides available to spectate +[_sides, [west, east, independent, civilian] - _sides] call EFUNC(spectator,updateSides); + +// Update available camera modes +[_modes, [0, 1, 2] - _modes] call EFUNC(spectator,updateCameraModes); + +// Update available vision modes +[_visions, [-2, -1, 0, 1, 2, 3, 4, 5, 6, 7] - _visions] call EFUNC(spectator,updateVisionModes); + +// Make unit spectator (close Zeus camera if open) +if (!isNull curatorCamera) then { + (findDisplay 312) closeDisplay 2; +}; + +[true, _force, _hide] call EFUNC(spectator,setSpectator); diff --git a/addons/zeus/functions/fnc_moduleSuicideBomber.sqf b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf index 8346eb4266..8425ff1548 100644 --- a/addons/zeus/functions/fnc_moduleSuicideBomber.sqf +++ b/addons/zeus/functions/fnc_moduleSuicideBomber.sqf @@ -57,7 +57,7 @@ if (_autoSeek) then { LOG("Unit deleted or killed, PFH removed"); }; - if (!([_unit] call EFUNC(common,isAwake))) exitWith {}; + if !([_unit] call EFUNC(common,isAwake)) exitWith {}; // Detonation private _nearObjects = (_unit nearObjects _activationRadius) select {side _x == _activationSide && {_x != _unit} && {alive _x}}; diff --git a/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf b/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf index 2a013fa4c2..a624b7dded 100644 --- a/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf +++ b/addons/zeus/functions/fnc_moduleSuppressiveFire.sqf @@ -69,7 +69,7 @@ if ([_unit] call EFUNC(common,isPlayer)) exitWith { } else { // Direct fire - Get a target position that will work private _lis = lineIntersectsSurfaces [eyePos _unit, _targetASL, _unit, _vehicle]; - if ((count _lis) > 0) then { // If point is hidden, unit won't fire, do a ray cast to find where they should shoot at + if (_lis isNotEqualTo []) then { // If point is hidden, unit won't fire, do a ray cast to find where they should shoot at _targetASL = ((_lis select 0) select 0); TRACE_1("using ray cast pos",_mousePosASL distance _targetASL); }; diff --git a/addons/zeus/functions/fnc_moduleUnloadFromCargo.sqf b/addons/zeus/functions/fnc_moduleUnloadFromCargo.sqf new file mode 100644 index 0000000000..dc4b1dea9a --- /dev/null +++ b/addons/zeus/functions/fnc_moduleUnloadFromCargo.sqf @@ -0,0 +1,47 @@ +#include "..\script_component.hpp" +/* + * Author: johnb43 + * Loads the object module is placed on into selected vehicle. + * + * Arguments: + * 0: Module logic + * 1: Synchronized units + * 2: Activated + * + * Return Value: + * None + * + * Example: + * [LOGIC, [bob, kevin], true] call ace_zeus_fnc_moduleUnloadFromCargo + * + * Public: No + */ + +if (canSuspend) exitWith { + [FUNC(moduleUnloadFromCargo), _this] call CBA_fnc_directCall; +}; + +params ["_logic"]; + +if !(local _logic) exitWith {}; + +private _vehicle = attachedTo _logic; + +deleteVehicle _logic; + +if !(missionNamespace getVariable [QEGVAR(cargo,enable), false]) exitWith { + [LSTRING(RequiresAddon)] call FUNC(showMessage); +}; +if (isNull _vehicle) exitWith { + [LSTRING(NothingSelected)] call FUNC(showMessage); +}; +if (!alive _vehicle) exitWith { + [LSTRING(OnlyAlive)] call FUNC(showMessage); +}; +if ((_vehicle getVariable [QEGVAR(cargo,loaded), []]) isEqualTo []) exitWith { + [LSTRING(paradrop_noCargoLoaded)] call FUNC(showMessage); +}; + +EGVAR(cargo,interactionVehicle) = _vehicle; +EGVAR(cargo,interactionParadrop) = false; +createDialog QEGVAR(cargo,menu); diff --git a/addons/zeus/functions/fnc_showMessage.sqf b/addons/zeus/functions/fnc_showMessage.sqf index 8bbd7d510d..53094dbfb3 100644 --- a/addons/zeus/functions/fnc_showMessage.sqf +++ b/addons/zeus/functions/fnc_showMessage.sqf @@ -18,7 +18,7 @@ * Public: Yes */ -if (!(_this isEqualTypeParams [""])) exitWith {ERROR_1("First arg must be string [%1]",_this);}; +if !(_this isEqualTypeParams [""]) exitWith {ERROR_1("First arg must be string [%1]",_this);}; private _message = _this apply {if ((_x isEqualType "") && {isLocalized _x}) then {localize _x} else {_x}}; [objNull, format _message] call BIS_fnc_showCuratorFeedbackMessage; diff --git a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf index 31f41d76c6..5a7c5fc5e0 100644 --- a/addons/zeus/functions/fnc_ui_globalSetSkill.sqf +++ b/addons/zeus/functions/fnc_ui_globalSetSkill.sqf @@ -24,7 +24,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Specific on-load stuff: private _fnc_sliderMove = { @@ -74,5 +74,5 @@ private _fnc_onConfirm = { [QGVAR(GlobalSkillAI),GVAR(GlobalSkillAI)] call FUNC(moduleGlobalSetSkill); }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_groupSide.sqf b/addons/zeus/functions/fnc_ui_groupSide.sqf index 4dff592f62..110e2e302d 100644 --- a/addons/zeus/functions/fnc_ui_groupSide.sqf +++ b/addons/zeus/functions/fnc_ui_groupSide.sqf @@ -24,7 +24,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Validate the module target: private _unit = effectiveCommander (attachedTo _logic); @@ -101,7 +101,7 @@ private _fnc_onSelection = { _ctrl ctrlSetTextColor _color; - _ctrl ctrlAddEventHandler ["buttonclick", _fnc_onSelection]; + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onSelection]; } forEach IDCs; private _fnc_onUnload = { @@ -129,5 +129,5 @@ private _fnc_onConfirm = { deleteVehicle _logic; }; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonClick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_setEngineer.sqf b/addons/zeus/functions/fnc_ui_setEngineer.sqf index b2515c311d..3f008403cc 100644 --- a/addons/zeus/functions/fnc_ui_setEngineer.sqf +++ b/addons/zeus/functions/fnc_ui_setEngineer.sqf @@ -23,7 +23,7 @@ private _ctrlButtonOK = _display displayCtrl 1; // IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; // Validate module target private _unit = attachedTo _logic; diff --git a/addons/zeus/functions/fnc_ui_spectator.sqf b/addons/zeus/functions/fnc_ui_spectator.sqf new file mode 100644 index 0000000000..fe9b4a3668 --- /dev/null +++ b/addons/zeus/functions/fnc_ui_spectator.sqf @@ -0,0 +1,265 @@ +#include "..\script_component.hpp" +/* + * Author: mharis001 + * Initializes the "Spectator" Zeus module display. + * + * Arguments: + * 0: spectator controls group + * + * Return Value: + * None + * + * Example: + * [CONTROL] call ace_zeus_fnc_ui_spectator + * + * Public: No + */ + +#define SIDE_IDCs [92540, 92541, 92542, 92543] +#define CAMERA_IDCs [92550, 92551, 92552] +#define VISION_IDCs [92558, 92559, 92560, 92561] + +params ["_control"]; + +private _display = ctrlParent _control; +private _ctrlButtonOK = _display displayCtrl 1; // IDC_OK +private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; +TRACE_1("Logic Object",_logic); + +_control ctrlRemoveAllEventHandlers "SetFocus"; + +// Validate module target +private _unit = attachedTo _logic; +TRACE_1("Unit",_unit); + +scopeName "Main"; +private _fnc_errorAndClose = { + params ["_msg"]; + _display closeDisplay 0; + deleteVehicle _logic; + [_msg] call FUNC(showMessage); + breakOut "Main"; +}; + +switch (false) do { + case (["ace_spectator"] call EFUNC(common,isModLoaded)): { + [LSTRING(RequiresAddon)] call _fnc_errorAndClose; + }; + case (!isNull _unit): { + [LSTRING(NothingSelected)] call _fnc_errorAndClose; + }; + case (_unit isKindOf "CAManBase"): { + [LSTRING(OnlyInfantry)] call _fnc_errorAndClose; + }; + case (alive _unit): { + [LSTRING(OnlyAlive)] call _fnc_errorAndClose; + }; + case ([_unit, true] call EFUNC(common,isPlayer)): { + [LSTRING(OnlyPlayers)] call _fnc_errorAndClose; + }; +}; + +// Specific onLoad stuff +private _side = side _unit; + +// Spectate sides +private _fnc_onSideSelection = { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + private _color = _ctrl getVariable "color"; + private _scale = 1; + + private _sides = _display getVariable [QGVAR(spectateSides), []]; + private _selectedSide = (ctrlIDC _ctrl) - 92540; + + // Add or remove from spectatable sides and update color and scale + if (_selectedSide in _sides) then { + _display setVariable [QGVAR(spectateSides), _sides - [_selectedSide]]; + _color set [3, 0.5]; + } else { + _display setVariable [QGVAR(spectateSides), _sides + [_selectedSide]]; + _color set [3, 1]; + _scale = 1.2; + }; + + _ctrl ctrlSetTextColor _color; + [_ctrl, _scale, 0.1] call BIS_fnc_ctrlSetScale; +}; + +// Use the unit's side as default +private _activeSide = [east, west, independent, civilian] find _side; + +// Handle sides other than default four (sideEnemy) +if (_activeSide != -1) then { + _display setVariable [QGVAR(spectateSides), [_activeSide]]; +}; + +{ + private _ctrl = _display displayCtrl _x; + private _side = _x - 92540; + private _color = [_side] call BIS_fnc_sideColor; + _ctrl setVariable ["color", _color]; + _ctrl ctrlSetActiveColor _color; + _color set [3, 0.5]; + + if (_side == _activeSide) then { + [_ctrl, 1.2, 0] call BIS_fnc_ctrlSetScale; + _color set [3, 1]; + }; + + _ctrl ctrlSetTextColor _color; + + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onSideSelection]; +} forEach SIDE_IDCs; + +// Camera modes +private _fnc_onModesSelection = { + params ["_ctrl"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + private _color = [1, 1, 1, 0.5]; + private _scale = 1; + + private _modes = _display getVariable [QGVAR(cameraModes), []]; + private _selectedMode = (ctrlIDC _ctrl) - 92550; + + // Add or remove from camera modes and update color and scale + if (_selectedMode in _modes) then { + _display setVariable [QGVAR(cameraModes), _modes - [_selectedMode]]; + } else { + _display setVariable [QGVAR(cameraModes), _modes + [_selectedMode]]; + _color set [3, 1]; + _scale = 1.2; + }; + + _ctrl ctrlSetTextColor _color; + [_ctrl, _scale, 0.1] call BIS_fnc_ctrlSetScale; +}; + +// Use setting as default since global variable will change +private _availableModes = [[0, 1, 2], [1, 2], [0], [1], [2]] select EGVAR(spectator,restrictModes); +_display setVariable [QGVAR(cameraModes), _availableModes]; + +{ + private _ctrl = _display displayCtrl _x; + private _color = [1, 1, 1, 0.5]; + + if ((_x - 92550) in _availableModes) then { + [_ctrl, 1.2, 0] call BIS_fnc_ctrlSetScale; + _color set [3, 1]; + }; + + _ctrl ctrlSetTextColor _color; + + _ctrl ctrlAddEventHandler ["ButtonClick", _fnc_onModesSelection]; +} forEach CAMERA_IDCs; + +// Vision Modes +private _fnc_onVisionSelection = { + params ["_ctrl", "_state"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitwith {}; + + // Convert to boolean since EH returns state as 0 or 1 + private _state = [false, true] select _state; + + private _visions = _display getVariable [QGVAR(visionModes), []]; + private _selectedVision = (ctrlIDC _ctrl) - 92560; + + // Add or remove from vision modes + if (_state) then { + _display setVariable [QGVAR(visionModes), _visions + [_selectedVision]]; + } else { + _display setVariable [QGVAR(visionModes), _visions - [_selectedVision]]; + }; + + // Handle all checked/unchecked + private _allCheckboxes = VISION_IDCs apply {cbChecked (_display displayCtrl _x)}; + + if (_allCheckboxes isEqualTo [_state, _state, _state, _state]) then { + (_display displayCtrl 92557) cbSetChecked _state; + }; +}; + +// Use setting as default since global variable will change +private _availableVisions = [[-2,-1,0,1], [-2,-1], [-2,0,1], [-2]] select EGVAR(spectator,restrictVisions); +_display setVariable [QGVAR(visionModes), _availableVisions]; + +{ + private _ctrl = _display displayCtrl _x; + + if ((_x - 92560) in _availableVisions) then { + _ctrl cbSetChecked true; + }; + + _ctrl ctrlAddEventHandler ["CheckedChanged", _fnc_onVisionSelection]; +} forEach VISION_IDCs; + +// Init all visions checkbox +private _fnc_onVisionsAll = { + params ["_ctrl", "_state"]; + + private _display = ctrlParent _ctrl; + if (isNull _display) exitWith {}; + + // Convert to boolean since EH returns state as 0 or 1 + _state = _state == 1; + + // Set state of all checkboxes + { + (_display displayCtrl _x) cbSetChecked _state; + } forEach VISION_IDCs; + + // Store new visions mode setting + private _setting = [[], [-2, -1, 0, 1]] select _state; + _display setVariable [QGVAR(visionModes), _setting]; +}; + +private _allCheckbox = _display displayCtrl 92557; + +// Set to checked by default if setting is all vision modes +if (_availableVisions isEqualTo [-2, -1, 0, 1]) then { + _allCheckbox cbSetChecked true; +}; + +_allCheckbox ctrlAddEventHandler ["CheckedChanged", _fnc_onVisionsAll]; + +// Confirm and Cancel +private _fnc_onUnload = { + private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; + if (isNull _logic) exitWith {}; + + deleteVehicle _logic; +}; + +private _fnc_onConfirm = { + params [["_ctrlButtonOK", controlNull, [controlNull]]]; + + private _display = ctrlParent _ctrlButtonOK; + if (isNull _display) exitWith {}; + + private _logic = missionNamespace getVariable ["BIS_fnc_initCuratorAttributes_target", objNull]; + if (isNull _logic) exitWith {}; + + private _unit = attachedTo _logic; + if (isNull _unit) exitWith {}; + + private _force = lbCurSel (_display displayCtrl 92531) > 0; + private _hide = lbCurSel (_display displayCtrl 92532) > 0; + private _sides = (_display getVariable [QGVAR(spectateSides), []]) apply {_x call BIS_fnc_sideType}; + private _modes = _display getVariable [QGVAR(cameraModes), []]; + private _visions = _display getVariable [QGVAR(visionModes), []]; + + [QGVAR(moduleSpectator), [_force, _hide, _sides, _modes, _visions], _unit] call CBA_fnc_targetEvent; + + deleteVehicle _logic; +}; + +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf index 1becc04004..b7aab41126 100644 --- a/addons/zeus/functions/fnc_ui_teleportPlayers.sqf +++ b/addons/zeus/functions/fnc_ui_teleportPlayers.sqf @@ -23,7 +23,7 @@ private _ctrlButtonOK = _display displayCtrl 1; //IDC_OK private _logic = GETMVAR(BIS_fnc_initCuratorAttributes_target,objNull); TRACE_1("logicObject",_logic); -_control ctrlRemoveAllEventHandlers "setFocus"; +_control ctrlRemoveAllEventHandlers "SetFocus"; //Specific on-load stuff: private _listbox = _display displayCtrl 16189; @@ -91,5 +91,5 @@ private _fnc_onConfirm = { }; _display displayAddEventHandler ["KeyUp", _fnc_onKeyUp]; -_display displayAddEventHandler ["unload", _fnc_onUnload]; -_ctrlButtonOK ctrlAddEventHandler ["buttonclick", _fnc_onConfirm]; +_display displayAddEventHandler ["Unload", _fnc_onUnload]; +_ctrlButtonOK ctrlAddEventHandler ["ButtonClick", _fnc_onConfirm]; diff --git a/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf b/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf index 9c34bc8f65..5c9a220615 100644 --- a/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf +++ b/addons/zeus/functions/fnc_ui_toggleFlashlight.sqf @@ -53,7 +53,7 @@ if !(isNull _unit) then { if (isNull _unit) then { (_display displayCtrl 56220) lbDelete 0; } else { - (_display displayCtrl 56218) lbSetCurSel ([0, 1] select (_unit isFlashlightOn currentWeapon _unit)); + (_display displayCtrl 56218) lbSetCurSel (parseNumber (_unit isFlashlightOn currentWeapon _unit)); }; private _fnc_onUnload = { diff --git a/addons/zeus/functions/fnc_ui_toggleNvg.sqf b/addons/zeus/functions/fnc_ui_toggleNvg.sqf index 1e60a777ea..5d5747c7ca 100644 --- a/addons/zeus/functions/fnc_ui_toggleNvg.sqf +++ b/addons/zeus/functions/fnc_ui_toggleNvg.sqf @@ -53,7 +53,7 @@ if !(isNull _unit) then { if (isNull _unit) then { (_display displayCtrl 92856) lbDelete 0; } else { - (_display displayCtrl 92855) lbSetCurSel ([0, 1] select (hmd _unit isNotEqualTo "")); + (_display displayCtrl 92855) lbSetCurSel (parseNumber (hmd _unit isNotEqualTo "")); }; private _fnc_onUnload = { diff --git a/addons/zeus/initSettings.sqf b/addons/zeus/initSettings.inc.sqf similarity index 100% rename from addons/zeus/initSettings.sqf rename to addons/zeus/initSettings.inc.sqf diff --git a/addons/zeus/stringtable.xml b/addons/zeus/stringtable.xml index 983ae43bc3..a6eaaac158 100644 --- a/addons/zeus/stringtable.xml +++ b/addons/zeus/stringtable.xml @@ -45,7 +45,7 @@ Különböző beállítási lehetőségeket biztosít a Zeus részeihez. Позволяет контролировать различные аспекты Зевса. Fornisce controllo su vari aspetti di Zeus. - Zeus の操作性を様々な側面から強化します。 + Zeusの操作性を様々な側面から強化します。 제우스에게 다양한 방면의 조작을 제공해줍니다 提供宙斯各个方面的控制权 提供宙斯各個方面的控制權 @@ -61,7 +61,7 @@ Felemelkedési üzenetek Сообщения о вознесении Messaggi di Ascesa - 転生表示 + Zeus転生通知 재림 메세지 宙斯上任信息 宙斯上任訊息 @@ -77,7 +77,7 @@ Globális üzeneteket jelez ki, ha egy játékos Zeus-nak lesz beosztva. Отображает глобальное всплывающее сообщение, когда один из игроков становится Зевсом. Mostra messaggi popup globali quando un giocatore viene assegnato come Zeus. - プレイヤーが Zeus になる際、全体へポップアップ表示を行います。 + プレイヤーがZeusになる際、全体へポップアップ表示を行います。 플레이어가 제우스가 되면 서버에 알림 팝업이 등장합니다. 当一位玩家被指定为宙斯时显示全局信息 當一位玩家被指定為宙斯時顯示全域訊息 @@ -109,8 +109,8 @@ Crée un aigle qui suit la caméra Zeus. Lerak egy sast, ami követi a Zeus kamerát. Спавнит орла, который следует за камерой Зевса. - Crea un'aquila che segue la camera Zeus. - Zeus カメラを追うイーグルを出現します。 + Crea un'aquila che segue la videocamera Zeus. + Zeusカメラを追いかける鷲を出現させます。 제우스의 카메라를 따라다니는 독수리를 생성합니다. 生成一个老鹰跟着宙斯的摄影机 生成一個老鷹跟著宙斯的攝影機 @@ -142,8 +142,8 @@ Joue des bruits de vent lorsque Zeus contrôle une unité distante. Szélhangokat játszik le, ha a Zeus távvezérel egy egységet. Проигрывает звук ветра каждый раз, когда Зевс вселяется в юнита. - Esegui rumori di vento quando Zeus controlla un'unità in remoto. - ユニットが Zeus 遠隔操作になった際、風の音がします。 + Riproduci rumori di vento quando Zeus controlla un'unità in remoto. + Zeusがユニットを遠隔操作した際、風の音を再生します。 제우스가 유닛을 조작할 때 바람소리가 납니다. 当宙斯开始控制单位时利用风的声音提示 當宙斯開始控制單位時利用風的聲音提示 @@ -158,8 +158,8 @@ Alerte d'artillerie Tüzérségi figyelmeztetés Предупреждение об арте - Allarme Esplosivi - 砲撃警告 + Allerta Artiglieria + 砲撃の警告 폭격 경고 武装警告 武裝警告 @@ -174,8 +174,8 @@ Diffuse un avertissement radio lorsque Zeus utilise de l'artillerie. Rádiós figyelmeztetés kiadása, ha a Zeus tüzérséget használ. Проигрывает звук радио каждый раз, когда Зевс использует артиллерию. - Riproduci un messaggio radio quando Zeus usa esplosivi. - Zeus が砲撃を使う際に、無線で警告を流します。 + Riproduci un messaggio radio quando Zeus usa artiglieria. + Zeusが砲撃を使う際に、無線で警告を流します。 제우스가 폭격 시 경고 무전을 재생합니다. 当宙斯开始攻击时使用无线电警告 當宙斯開始攻擊時使用無線電警告 @@ -207,7 +207,7 @@ Feltárja az aknákat a szövetségeseknek, és jelölőket helyez el a térképen. Показывает мины союзникам и отмечает их маркерами на карте. Rivela mine ad alleati e piazza marcatori in mappa. - 友軍に地雷と地図へ設置マーカーを表示します。 + 地雷の位置を味方に公開し、マップマーカーを配置します。 아군에게 지도 상의 모든 지뢰를 표시합니다. 地图将标记队友放置的地雷 地圖將標記隊友放置的地雷 @@ -254,8 +254,8 @@ Commuter captivité Elfogott állapot váltása Пленный (вкл./выкл.) - Attivatore Prigioniero - 捕虜に切り替え + Imposta Prigioniero + 捕虜状態を切り替え 포로 토글 切换俘虏 切換俘虜 @@ -266,7 +266,7 @@ Défendre la zone Защитить зону Bránit oblast - 防衛範囲 + エリアの防衛 Broń obszaru Verteidige Gebiet 지역 방어 @@ -313,7 +313,7 @@ 添加或删除宙斯的可编辑物体 Aktiviere oder deaktiviere zu bearbeitende Objekte von Zeus Agguingi o rimuovi oggetti che Zeus può modificare - Zeus から編集可能オブジェクトの追加と削除をする + Zeusから編集可能オブジェクトの追加と削除をする Dodaj lub usuń edytowalne obiekty z Zeus'a Добавить или удалить редактируемые объекты от Зевса Adiciona ou remove objetos editáveis do Zeus @@ -361,7 +361,7 @@ 모든 큐레이터 Wszyscy kuratorzy Tous les curateurs - Tutti i Moderatori + Tutti gli Zeus 所有宙斯 所有編輯者 Все кураторы @@ -372,11 +372,11 @@ Apply changes to all curators Änderungen bei allen Kuratoren aktualisieren - 全キュレーターへ変更を適用します。 + 全キュレーターへ変更を適用します 모든 큐레이터에 변화를 적용합니다 Zatwierdź zmiany dla wszystkich kuratorów Applique les changements à tous les curateurs. - Applica i cambiamenti a tutti i moderatori + Applica i cambiamenti a tutti gli Zeus 确认变更给所有宙斯 確認變更給所有編輯者 Применить изменения ко всем кураторам @@ -388,7 +388,7 @@ Additional Objects Zusätzliche Objekte Oggetti aggiuntivi - オブジェクト増加 + 追加のオブジェクト Dodatkowe obiekty Доп. объекты Objetos adicionais @@ -402,8 +402,8 @@ Additional objects to include in the action regardless of Task Radius Zusätzliche Objekte unabhängig vom Aufgabenradius einbeziehen - Oggetti aggiuntivi da includere nell'azione indipendentemente dal Raggio di Attività - タスク範囲に関係無くオブジェクトを更に増加させます + Oggetti aggiuntivi da includere nell'azione indipendentemente dal Raggio dell'Incarico + タスク半径に関係なく次のオブジェクトを編集可能に追加します Dodatkowe obiekty do uwzględnienia w akcji niezależnie od zasięgu zadania Дополнительные объекты для включения в действие, независимо от радиуса выполнения задачи Objetos adicionais para incluir na ação, ignorando a distância da tarefa @@ -419,11 +419,11 @@ Compétence globale de l'IA Мастерство ботов Globální zkušenosti AI - 総合的AIスキル + 全体のAIスキル Globalne umiejętności AI Globale KI-Fähigkeit 서버 인공지능 실력 - Abilità AI Globale + Abilità IA Globale AI 技巧设定 AI技巧設定 Habilidade Global da IA @@ -530,7 +530,7 @@ Rozpoznanie Aufklärung 탐지 - Ricognizione + Individuazione 索敌能力 索敵能力 Detecção @@ -575,7 +575,7 @@ Czy AI powinno szukać osłon Soll KI nach Deckung suchen 인공지능이 엄폐물을 찾아갑니다 - Le AI dovrebbero cercare una copertura + Le IA dovrebbero cercare coperture 决定 AI 是否会寻找掩护 決定AI是否會尋找掩護 A IA dever buscar cobertura @@ -605,7 +605,7 @@ Czy AI powinno automatycznie przechodzić w tryb walki Soll KI automatisch in Kampfmodus umschalten 인공지능이 자동적으로 교전 상태에 돌입합니다 - Le AI dovrebbero passare in modalità di combattimento automaticamente + Le IA dovrebbero passare in modalità di combattimento automaticamente 决定 AI 是否会自动与敌人交战 決定AI是否會自動與敵人交戰 A IA deveria automaticamente mudar para modo de combate @@ -616,7 +616,7 @@ Camp du groupe Сторона группы Strana skupiny - グループ側 + グループの陣営 Strona grupy Gruppenseite 진영 측 @@ -632,7 +632,7 @@ Zone de patrouille Патрулировать зону Oblast hlídkování - 哨戒範囲 + エリアの哨戒 Patrol obszaru Patrouillengebiet 정찰 구역 @@ -653,8 +653,8 @@ Commuter capitulation Kapituláló állapot váltása Сдавшийся (вкл./выкл.) - Attivatore Resa - 投降として切り替え + Imposta Resa + 投降状態を切り替え 항복 토글 切换投降 切換投降 @@ -711,7 +711,7 @@ Téléporter joueurs Телепортиваровать игроков Teleportovat hráče - プレイヤーを移動 + プレイヤーのテレポート Teleportuj graczy Spieler teleportieren 플레이어 순간이동 @@ -747,7 +747,7 @@ Teleportuje wybranego gracza na pozycję modułu Teleportiert ausgewählten Spieler zur Position des Moduls 모듈의 위치로 플레이어 순간이동 - Teletrasporta il giocatore selezionato nella posizione del modulo + Teletrasporta il giocatore selezionato sulla posizione del modulo 传送选定的玩家至模块位置 傳送選定的玩家至模塊位置 Teleporta o jogador selecionado para a posição do módulo @@ -758,7 +758,7 @@ Téléporter le groupe Телепортировать Группу Teleportovat skupinu - グループを移動 + グループで移動 Teleport grupy Gruppe teleportieren 그룹 순간이동 @@ -794,8 +794,8 @@ Commuter état de conscience Eszméletlen állapot váltása Без сознания (вкл./выкл.) - Attivatore Incoscienza - 気絶を切り替え + Imposta Incoscienza + 無意識状態を切り替え 기절 토글 切换昏迷 切換昏迷 @@ -806,7 +806,7 @@ Zone de recherche Обыскать зону Prohledat oblast - 捜索範囲 + エリアの捜索 Przeszukaj teren Durchsuche Gebiet 지역 수색 @@ -822,11 +822,11 @@ Chercher un bâtiment proche Обыскать ближайшие здания Prohledat nejbližší budovu - 近くの建物を捜索します + 至近の建物を捜索 Przeszukaj najbliższy budynek Durchsuche nahegelegenes Gebäude 근처 건물 수색 - Cerca Edifici nelle Vicinanze + Bonifica Edifici Vicini 搜索附近的建筑物 搜索附近的建築物 Procurar construções próximas @@ -857,7 +857,7 @@ Asignar vehículo médico Assegna Veicolo Medico Affecter véhicule sanitaire - 医療車両として割り当て + 医療車両に割り当て 의무 차량 임명 指定医疗载具 指定醫療載具 @@ -872,7 +872,7 @@ Asignar instalación médica Assegna Struttura Medica Affecter installation sanitaire - 医療施設として割り当て + 医療施設に割り当て 의무 시설 임명 指定医疗设施 指定醫療設施 @@ -884,7 +884,7 @@ シミュレーションを切り替え 재현 토글 Commuter Simulation - Attivatore Simulazione + Imposta Simulazione 切换模拟 切換模擬 Переключить симуляцию @@ -919,7 +919,7 @@ Ersatzkette hinzufügen Agregar oruga de repuesto Ajouter une chenille de rechange - 車両へ予備タイヤを追加 + 予備履帯を追加 예비 궤도 추가 增加备用履带 增加備用履帶 @@ -934,9 +934,9 @@ Używaj tylko na żywych jednostkach Применимо только к живым юнитам Csak élő egységeken használni - Si può fare solo su persone vive + Si può fare solo su unità vive Unidade deve estar viva - ユニットを生存させます + ユニットは生きている必要があります 대상이 반드시 살아 있어야 합니다 单位必须是活的 單位必須是活著 @@ -953,7 +953,7 @@ Csak járműben kívül lévő egységeken használni Si può usare solo su fanteria a piedi Unidade deve ser uma infantaria desmontada - ユニットを歩兵にさせます + ユニットは歩兵である必要があります 대상이 반드시 보병이어야 합니다 单位必须是步兵 單位必須是步兵 @@ -968,7 +968,7 @@ Jednotka musí být budova Si può usare solo su strutture L'unité doit être une structure. - ユニットを構造物とします + ユニットは構造物である必要があります 대상이 반드시 건축물이어야 합니다 单位必须是建筑 單位必須是建築 @@ -983,7 +983,7 @@ Jednotka musí být vozidlo Si può usare solo su veicoli L'unité doit être un véhicule. - ユニットを車両とします + ユニットは車両である必要があります 대상이 반드시 차량이어야 합니다 单位必须是载具 單位必須是載具 @@ -998,7 +998,7 @@ Einheit muss ein Fahrzeug mit Ladekapazität sein La unidad debe ser un vehículo con espacio de carga L'unité doit être un véhicule muni d'un espace de stockage. - ユニットをカーゴ スペースがある車両にします + ユニットは貨物室のある車両である必要があります 대상이 반드시 화물을 실을 수 있는 차량이어야 합니다 单位必须是载具且有载货空间 單位必須是載具且有載貨空間 @@ -1013,7 +1013,7 @@ Einheit muss freie Ladekapazität haben La unidad debe tener espacio de carga disponible L'unité doit avoir de l'espace de chargement disponible. - ユニットへカーゴ スペースを与えます + ユニットの貨物室に空きが必要です 대상의 화물공간이 남아 있어야 합니다 单位必须有剩余的载货空间 單位必須有剩餘的載貨空間 @@ -1029,7 +1029,7 @@ Csak elfogatlan egységeken használni Юнит не должен быть пленным L'unità non dev'essere un prigioniero - ユニットを捕虜にさせません + ユニットは捕虜ではない必要があります 대상이 포로면 안됩니다 单位不能被俘虏 單位不能被俘虜 @@ -1039,7 +1039,7 @@ L'unité doit appartenir à un camp approprié. Юнит должен принадлежать соответствующей стороне Jednotka musí patřit k příslušné straně - ユニットを適切な陣営にします + ユニットは適切な陣営である必要があります Jednostka musi należeć do odpowiedniej strony Einheit muss einer passenden Seite angehören 대상이 적절한 진영에 속해야 합니다 @@ -1054,7 +1054,7 @@ Le bâtiment le plus proche est trop éloigné. Ближайшие здания слишком далеко Nejbližší budova je příliš daleko - 近くに建物がありません。 + 一番近い建物まで遠すぎます Najbliższy budynek jest zbyt daleko Nächstgelegenes Gebäude ist zu weit entfernt 가장 가까운 건물이 너무 멉니다 @@ -1075,7 +1075,7 @@ Ничего не выделено Semmi sincs az egér alatt Piazza su una unità - ユニットの上に設置 + ユニットの上に配置する必要があります 대상에 배치하기 放置在一个单位上 放置在一個單位上 @@ -1092,15 +1092,31 @@ Egy jelenleg hiányzó bővítményt igényel Требуется аддон, который отсутствует Richiede un addon che non è presente - 要求されたアドオンは存在していません + 要求されたアドオンがありません 需要一个不存在的插件 需要一個不存在的插件 현재 없는 애드온을 필요로 합니다 + + Only Players + プレイヤーのみ + Nur Spieler + 오직 플레이어만 + Tylko gracze + Joueurs seulement + Solo Giocatori + 仅玩家 + 只有玩家 + Только игроки + Apenas Jogadores + Pouze hráči + Solo jugadores + Sadece Oyuncular + None Keiner - Niente + Nessuno Żadne なし Нет @@ -1132,7 +1148,7 @@ Players and AI Spieler und KI's - Giocati e AI + Giocatori e IA Gracze i SI プレイヤーとAI Игроки и ИИ @@ -1180,7 +1196,7 @@ Cargaison : Груз: Náklad: - カーゴ: + 貨物: Ładunek: Ladung: 화물: @@ -1197,7 +1213,7 @@ 選擇要卸載的貨物 选择要卸载的货物 Scegli il carico da scaricare - 選択したカーゴを降ろす + 積み荷を選択すると降ろせます Wybierz ładunek do wyładowania Выберите груз для выгрузки Selecione objeto para descarregar @@ -1211,7 +1227,7 @@ Task Radius Rayon de la tâche Радиус задания - タスク範囲 + タスク半径 Obszar zadania Radius der Aufgabe 작업 반경 @@ -1226,7 +1242,7 @@ Radius to perform the task within Rayon dans lequel effectuer la tâche. Радиус выполнения задания - 次の範囲をタスクとして実行 + タスクを実行される半径 Obszar na którym zadanie powinno zostać wykonane Radius, in dem die Aufgabe ausgeführt werden soll 다음 반경 내에서 작업 @@ -1246,7 +1262,7 @@ Wpisano nieprawidłowy promień Ungültiger Radius eingegeben 알 수 없는 반경 입력됨 - Raggio Invalido Inserito + Inserito Raggio Invalido 错误的半径值 錯誤的半徑值 Raio inválido inserido @@ -1268,11 +1284,11 @@ Krycí palba - Add Full Arsenal + Add Full BI Arsenal Füge ganzes Arsenal hinzu Ajouter un arsenal complet - Aggiungi Arsenale Completo - オブジェクトに完全なアーセナルを追加 + Aggiungi Arsenale BI Completo + BI 武器庫を追加 增加完整的虚拟军火库到物体上 增加完整的虛擬軍火庫到物件上 Dodaj Wirtualny Arsenał @@ -1284,11 +1300,11 @@ Añadir Arsenal completo - Remove Arsenal + Remove BI Arsenal Entferne Arsenal Retirer un arsenal - Rimuovi Arsenale - オブジェクトからアーセナルを削除 + Rimuovi Arsenale BI + BI 武器庫を削除 移除物体上的虚拟军火库 移除物件上的虛擬軍火庫 Usuń Wirtualny Arsenał @@ -1302,8 +1318,8 @@ Load into Cargo In Frachtraum laden - Carica nel Cargo - カーゴに積み込み + Carica nel carico + 貨物室へ積載 裝載到貨物中 装载到货物中 화물 싣기 @@ -1314,11 +1330,21 @@ Charger dans le véhicule Cargar en la carga + + Unload from cargo + Aus Frachtraum ausladen + Scarica dal carico + 貨物室から降ろす + 화물 내리기 + Выгрузить из отсека + Décharger de la cargaison + Descargar de la carga + Toggle NVGs Nachtsichtgeräte Hinzufügen/Entfernen Commuter JVN - Attiva NVGs + Attiva NVG 暗視装置の切り替え 切換夜視鏡 切换夜视仪 @@ -1349,8 +1375,8 @@ Add or remove NVGs from units Nachtsichtgeräte Hinzufügen/Entfernen Ajoute ou retire l'équipement de vision nocturne aux unités. - Aggiunge o rimuove NVGs alle unità - ユニットから暗視装置の追加と削除 + Aggiunge o rimuove NVG alle unità + ユニットの暗視装置を追加または削除します 增加或移除單位的夜視鏡 增加或移除单位的夜视仪 야시경 추가/제거 @@ -1364,10 +1390,10 @@ Toggle Target Ziel umschalten - 目標を切り替え + 切り替えの対象 切换目标 切換目標 - Scambia obiettivo + Imposta Bersaglio Przełącz cel Кому переключить Alternar alvo @@ -1379,10 +1405,10 @@ Units affected by the toggle Betroffene Spieler beim umschalten - ユニットは切り替えに影響を受けます + 切り替えの影響を受ける対象 被菜单位受切换影响 受切換所影響的單位 - Unità influenzate dallo scambio + Unità influenzate dall'impostazione Jednostki pod wpływem przełączenia Юниты, к которым применяется переключение Unidades afetadas pela alteração @@ -1411,7 +1437,7 @@ Toggle Flashlights Ändere Taschenlampen Commuter lampes torches - Attiva torce + Attiva Torce フラッシュライトの切り替え 切換手電筒 切换手电筒 @@ -1427,7 +1453,7 @@ Flashlights Taschenlampe Lampes torches - Torcia + Torce フラッシュライト 手電筒 手电筒 @@ -1443,8 +1469,8 @@ Add Gear Ausrüstung hinzufügen Ajouter du matériel - Aggiungi equipaggiamento - 装備を追加 + Aggiungi Equipaggiamento + 装備の追加 增加裝備 增加装备 장비 추가 @@ -1459,8 +1485,8 @@ Garrison Group Gebäude besetzen Garnir zone - 歩哨グループ - Proteggi gruppo + グループの駐屯 + Barrica Gruppo 佈置駐軍 布置驻军 그룹 주둔 @@ -1474,7 +1500,7 @@ Fill from top to bottom Von oben nach unten befüllen Remplir de haut en bas - 上から下まで占拠 + 上から下へと占拠 Riempi dall'alto al basso 由上而下進行填滿 由上而下进行填满 @@ -1490,7 +1516,7 @@ Gebäude von der höchsten Position zuerst befüllen Les bâtiments se remplissent en commençant par le haut. 建物を最も高い位置から占拠していきます - Riempi gli edifici dalla posizione più alta prima + Riempi gli edifici prima dalla posizione più alta 從建築物的最高點開始布置衛哨 从建筑物的最高点开始布置卫哨 건물의 높은 위치부터 먼저 채움 @@ -1520,7 +1546,7 @@ Gleichmäßig befüllen Remplissage homogène 均一に占拠 - Riempimento uguale + Riempimento omogeno 平均分配 平均分配 평균 채우기 @@ -1534,7 +1560,7 @@ Building by building Gebäude nach Gebäude Bâtiment par bâtiment - 建物から建物へ + 建物ごとに Edificio per edificio 一棟填滿後再換下一棟 一栋填满后再换下一栋 @@ -1565,7 +1591,7 @@ Teleportieren Téléporter テレポート - Teletrasporto + Teletrasporta 傳送 传送 순간이동 @@ -1580,8 +1606,8 @@ Un-garrison Group Garnisionsgruppe auflösen Dégarnir zone - 非歩哨グループ - Non proteggere gruppo + グループの駐屯解除 + Sbarrica Gruppo 解除駐軍駐守狀態 解除驻军驻守状态 주둔해제 @@ -1600,7 +1626,7 @@ Keine Spieler gefunden Nincsenek játékosok Nessun giocatore trovato - プレーヤーが見つかりません + プレーヤーが見つかりませんでした 플레이어가 없습니다. Nie znaleziono graczy Nenhum jogador encontrado @@ -1617,7 +1643,7 @@ Fahrzeug reparieren zuweisen Hozzárendelés javítóműhöz Assegna veicolo di riparazione - 修理車両を割り当てる + 修理車両に割り当て 수리 차량 지정 Przydziel pojazd do naprawy Definir como veículo de reparo @@ -1634,7 +1660,7 @@ Zuweisen von Reparatureinrichtung Hozzárendelés javításhoz Assegna struttura di riparazione - 修理施設を割り当てる + 修理施設に割り当て 수리 시설 지정 Przydziel naprawę Definir como oficina de reparo @@ -1650,8 +1676,8 @@ Assigner ingénieur Engineer zuweisen Engedélyezze a mérnököt - Assign Engineer - 担当エンジニア + Assegna Geniere + 工兵に割り当て 엔지니어 지정 Przydziel inżyniera Definir como engenheiro @@ -1667,8 +1693,8 @@ Qualification technique Ingenieur Fähigkeit Mérnöki készség - Abilità ingegnere - エンジニアのスキル + Abilità Geniere + 工兵のスキル 기술자의 기술 Umiejętność inżyniera Habilidade do engenheiro @@ -1685,7 +1711,7 @@ Vollständige Heilung Teljes gyógyítás Guarigione completa - 完全に回復 + 完全回復 완전 치유 Pełne uleczenie Cura completa @@ -1702,7 +1728,7 @@ Selbstmordattentäter Öngyilkos merénylő Kamikaze - 自爆テロ犯 + 自爆兵化 자살 폭탄 Samobójca Bombardeiro suicida @@ -1718,7 +1744,7 @@ Camp cible Aktivierungsseite Aktiválási oldal - Lato di attivazione + Fazione Bersaglio 対象陣営 활성화 진영 Strona aktywacji @@ -1735,7 +1761,7 @@ Rayon de déclenchement Aktivierungsradius Aktiválási sugár - Raggio di attivazione + Raggio di Attivazione 活性化半径 활성화 반경 Promień aktywacji @@ -1752,7 +1778,7 @@ Taille de l'explosion Explosionsgröße Robbanásméret - Dimensione di esplosione + Dimensione dell'Esplosione 爆発サイズ 폭발 크기 Rozmiar wybuchu @@ -1769,7 +1795,7 @@ Recherche automatique Automatische Suche Automatikus keresés - Ricerca automatica + Ricerca Automatica 自動誘導 자동 탐색 Auto Seek @@ -1786,8 +1812,8 @@ L'unité essaiera de trouver activement des unités proches appartenant à au camp cible, puis elle se déplacera dans leur direction.\nLa portée de la recherche automatique est basée sur l'aptitude en repérage de l'unité, avec une distance minimale de 100 mètres. Die Einheit versucht aktiv, in der Nähe befindliche Einheiten der Aktivierungsseite zu finden und sich dorthin zu bewegen. Der Bereich der automatischen Suche basiert auf der Fähigkeit der Zielentfernung der Einheit mit einer Mindestentfernung von 100 Metern. Az egység aktívan megpróbálja megtalálni és elmozdulni az aktivációs oldal közeli egységei felé.Az automatikus keresési tartomány az egység helyszíni szakértelmén alapul, legalább 100 méterrel. - L'unità cercherà attivamente di trovare e spostarsi verso le unità vicine del lato di attivazione. La gamma di Auto Seek si basa sull'abilità a distanza spot dell'unità con un minimo di 100 metri. - 対象陣営ユニットを見つけて移動しようと積極的に試みます。自動誘導の範囲は、ユニットの索敵能力に基づいており、最低100メートルです。 + L'unità cercherà attivamente di trovare e spostarsi verso unità vicine della fazione bersaglio. La distanza di Ricerca Automatica si basa sull'abilità di identificazione dell'unità, con un minimo di 100 metri. + 対象陣営ユニットを見つけて移動しようと積極的に試みます。自動誘導の半径は、ユニットの索敵能力に基づいており、最低100メートルです。 유닛은 활성화 측의 근접 유닛을 향해 적극적으로 찾아서 이동하려고 시도합니다. 자동 탐색의 범위는 유닛의 색적 거리 스킬을 기준으로 최소 100미터입니다. Jednostka będzie aktywnie próbowała znaleźć i ruszyć w kierunku pobliskich jednostek strony aktywacji. Zasięg Auto Seek opiera się na umiejętności punktowej odległości jednostki z minimum 100 metrów. A unidade tentará ativamente encontrar e se mover para as unidades próximas do lado da ativação. O alcance da Auto Seek é baseado na habilidade de distância do ponto da unidade com um mínimo de 100 metros. @@ -1803,7 +1829,7 @@ Die Einheit ist bereits ein Selbstmordattentäter Az egység már öngyilkos bombázó L'unità è già un kamikaze - 既に自爆ユニットです + ユニットは既に自爆兵です 유닛은 이미 자살 폭탄 테러범입니다. Jednostka jest już zamachowcem-samobójcą A unidade já é um suicida @@ -1817,7 +1843,7 @@ ACE 武器庫を追加 添加 ACE 军火库 增加完整的ACE軍火庫 - Aggiungi l'arsenale ACE completo + Aggiungi Arsenale ACE Completo Dodaj pełny arsenał ACE Добавить полный ACE Арсенал Adicionar Arsenal ACE Completo @@ -1833,7 +1859,7 @@ ACE 武器庫を削除 删除 ACE 军火库 移除ACE軍火庫 - Rimuovi l'arsenale ACE + Rimuovi Arsenale ACE Usuń arsenał ACE Убрать ACE Арсенал Remover Arsenal ACE @@ -1847,7 +1873,7 @@ Create Zeus Zeus erstellen Создать Зевса - Zeus を作る + Zeus を作成 Stwórz Zeus'a Crea Zeus Criar Zeus @@ -1863,7 +1889,7 @@ Delete Zeus Zeus löschen Удалить Зевса - Zeus を消す + Zeus を削除 Usuń Zeus'a Cancella Zeus Apagar Zeus @@ -1894,13 +1920,13 @@ Paradrop Cargo Ladung abwerfen (Fallschirm) - カーゴを空中投下 + 貨物を空中投下 Zrzut ładunku (cargo) Десантировать груз Soltar carga de paraquedas 空投貨物 空投货物 - Paradrop Cargo + Paracaduta Carico Výsadek nákladu Paralargage de cargaison Paraşüt Kargosu @@ -1910,7 +1936,7 @@ No cargo loaded Keine Ladung geladen - カーゴは未積載 + 貨物は積載されていません Niczego nie załadowano do cargo Грузовой отсек пуст Nenhuma carga carregada @@ -1927,6 +1953,7 @@ Burn Unit Einheit anzünden 焚烧单位 + Incendia Unità 유닛 불로 태우기 Podpal Jednostkę ユニットを燃やす @@ -1934,12 +1961,42 @@ Quemar a unidad Brûler l'unité + + Medical Menu + Sanitätsmenü + Menu medyczne + Menu Médico + Медицинское меню + Menú médico + Zdravotnická nabídka + Menù Medico + Menu médical + 医療メニュー + 의료 메뉴 + 医疗菜单 + 醫療選單 + Medikal Menü + + + The medical menu is disabled + Das Sanitätsmenü ist deaktiviert + Il Menù Medico è disabilitato + 医療メニューは無効になっています + 의료 메뉴가 비활성화되었습니다 + Медицинское меню отключено + Le Menu médical est désactivé + El menú médico está deshabilitado + Lay Trenchline Wykop Okop 참호라인 깔기 Poser une tranchée Grabenlinie legen + Piazza Trincea + 塹壕溝線を敷設 + Проложить траншею + Poner una Trinchera +SHIFT to force (Can only lay N/S or E/W) @@ -1947,6 +2004,66 @@ + Shift 키로 강제하기 (동서남북 방향으로만 깔 수 있음) +MAJ pour forcer (Disponible uniquement sur les alignements N/S ou E/O) +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 на принудительное (может укладываться только на Север/Юг или Восток/Запад) + +SHIFT para forzar (Puede solo colocar en N/S or E/O) + + + Forces the spectator interface preventing the player from closing it with the Escape key + 観戦インターフェイスを強制し、ユーザがEscキーでも閉じられないようにします。 + Активирует интерфейс spectator, не позволяя игроку закрыть его с помощью клавиши Escape. + 플레이어가 Esc 키로 관전자 인터페이스를 닫지 못하도록 강제로 관전자 인터페이스를 설정합니다. + Erzwingt die Zuschauer-Ansicht und verhindert dass der Spieler sie mit der Esc-Taste schließen kann + Forza l'interfaccia di spettatore, impedendo al giocatore di chiuderla con il tasto Esc + + + Hide player + プレイヤーを隠す + Скрыть игрока + 플레이어 숨기기 + Spieler ausblenden + Nascondi giocatore + + + Hides the player by making them invisible, invulnerable, muted, and removing them from their group + 透明化、無敵化、ミュート、グループからの除外を行いプレーヤーを隠します + Скрывает игрока, делая его невидимым, неуязвимым, отключая звук и удаляя из группы. + 플레이어를 투명, 무적, 음소거화하고 그룹에서 제거하여 숨깁니다. + Blendet den Spieler aus, macht ihn unsichtbar, unverwundbar, stumm und entfernt ihn von seiner Gruppe + Nasconde il giocatore, rendendolo invisibile, invulnerabile, muto e lo rimuove dal proprio gruppo + + + Sets the sides that are available to spectate + 指定の陣営を観戦可能に設定します + Устанавливает стороны, доступные для режима spectator + 관전 가능한 진영을 설정합니다. + Bestimmt die Seiten denen man zuschauen kann + Imposta le fazioni che lo spettatore può osservare + + + White Hot + 白=熱源 + Белый + 백색 열원 + Weiß-Schwarz + Bianco-caldo + + + Black Hot + 黒=熱源 + Чёрный + 흑색 열원 + Schwarz-Weiß + Nero-caldo + + + Toggle All + 全てを切り替え + Выключить все + 전부 토글 + Alle wechseln + Cambia tutti diff --git a/addons/zeus/ui/RscAttributes.hpp b/addons/zeus/ui/RscAttributes.hpp index 0ff21b145f..da3f53364f 100644 --- a/addons/zeus/ui/RscAttributes.hpp +++ b/addons/zeus/ui/RscAttributes.hpp @@ -915,3 +915,231 @@ class GVAR(RscSuicideBomber): RscDisplayAttributes { class ButtonCancel: ButtonCancel {}; }; }; + +class GVAR(RscSpectator): RscDisplayAttributes { + onLoad = QUOTE([ARR_3('onLoad',_this,QQGVAR(RscSpectator))] call FUNC(zeusAttributes)); + onUnload = QUOTE([ARR_3('onUnload',_this,QQGVAR(RscSpectator))] call FUNC(zeusAttributes)); + class Controls: Controls { + class Background: Background {}; + class Title: Title {}; + class Content: Content { + class Controls { + class spectator: RscControlsGroupNoScrollbars { + onSetFocus = QUOTE(_this call FUNC(ui_spectator)); + idc = 92530; + x = 0; + y = 0; + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(10.7)); + class controls { + class ForceInterfaceLabel: RscText { + idc = -1; + text = "$STR_a3_cfgvehicles_modulecurator_f_arguments_forced"; + tooltip = CSTRING(ModuleSpectator_ForceInterface_Tooltip); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class ForceInterface: ctrlToolbox { + idc = 92531; + x = QUOTE(W_PART(10.1)); + y = 0; + w = QUOTE(W_PART(15.9)); + h = QUOTE(H_PART(1)); + rows = 1; + columns = 2; + strings[] = {ECSTRING(common,No), ECSTRING(common,Yes)}; + }; + class HidePlayerLabel: ForceInterfaceLabel { + text = CSTRING(ModuleSpectator_HidePlayer); + tooltip = CSTRING(ModuleSpectator_HidePlayer_Tooltip); + y = QUOTE(H_PART(1.1)); + }; + class HidePlayer: ForceInterface { + idc = 92532; + y = QUOTE(H_PART(1.1)); + }; + class SpectateSides: RscControlsGroupNoScrollbars { + idc = 92533; + x = 0; + y = QUOTE(H_PART(2.2)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); + class controls { + class Label: RscText { + idc = -1; + text = "$STR_A3_Spectator_Eden_WhitelistedSides_Name"; + tooltip = CSTRING(ModuleSpectator_SpectableSides_Tooltip); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = QUOTE(W_PART(10)); + y = 0; + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class BLUFOR: RscActivePicture { + idc = 92541; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_west_ca.paa"; + x = QUOTE(W_PART(12.5)); + y = QUOTE(H_PART(0.25)); + w = QUOTE(W_PART(2)); + h = QUOTE(H_PART(2)); + tooltip = "$STR_WEST"; + }; + class OPFOR: BLUFOR { + idc = 92540; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_east_ca.paa"; + x = QUOTE(W_PART(15.5)); + tooltip = "$STR_EAST"; + }; + class Independent: BLUFOR { + idc = 92542; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_guer_ca.paa"; + x = QUOTE(W_PART(18.5)); + tooltip = "$STR_guerrila"; + }; + class Civilian: BLUFOR { + idc = 92543; + text = "\a3\Ui_F_Curator\Data\Displays\RscDisplayCurator\side_civ_ca.paa"; + x = QUOTE(W_PART(21.5)); + tooltip = "$STR_Civilian"; + }; + }; + }; + class CameraModes: RscControlsGroupNoScrollbars { + idc = 92534; + x = 0; + y = QUOTE(H_PART(4.8)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.5)); + class controls { + class Label: RscText { + idc = -1; + text = ECSTRING(spectator,modes_DisplayName); + tooltip = ECSTRING(spectator,modes_Description); + x = 0; + y = 0; + w = QUOTE(W_PART(10)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x =QUOTE(W_PART(10)); + y = 0; + w = QUOTE(W_PART(16)); + h = QUOTE(H_PART(2.5)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class Free: RscActivePicture { + idc = 92550; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Free.paa"; + x = QUOTE(W_PART(13.375)); + y = QUOTE(H_PART(0.375)); + w = QUOTE(W_PART(1.75)); + h = QUOTE(H_PART(1.75)); + tooltip = "$STR_A3_Spectator_free_camera_tooltip"; + }; + class Follow: Free { + idc = 92552; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Follow.paa"; + x = QUOTE(W_PART(17.125)); + tooltip = "$STR_A3_Spectator_3pp_camera_tooltip"; + }; + class FirstPerson: Free { + idc = 92551; + text = "a3\Ui_f\data\GUI\Rsc\RscDisplayEGSpectator\Fps.paa"; + x = QUOTE(W_PART(20.875)); + tooltip = "$STR_A3_Spectator_1pp_camera_tooltip"; + }; + }; + }; + class VisionModes: RscControlsGroupNoScrollbars { + idc = 92535; + x = 0; + y = QUOTE(H_PART(7.4)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(3.3)); + class controls { + class Label: RscText { + idc = -1; + text = ECSTRING(spectator,visions_DisplayName); + tooltip = ECSTRING(spectator,visions_Description); + x = 0; + y = 0; + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(1)); + colorBackground[] = {0, 0, 0, 0.5}; + }; + class Background: RscText { + idc = -1; + x = 0; + y = QUOTE(H_PART(1)); + w = QUOTE(W_PART(26)); + h = QUOTE(H_PART(2.3)); + colorBackground[] = {1, 1, 1, 0.1}; + }; + class AllCheckBox: RscCheckBox { + idc = 92557; + tooltip = CSTRING(ToggleAll); + x = QUOTE(W_PART(25)); + y = 0; + w = QUOTE(W_PART(1)); + h = QUOTE(H_PART(1)); + }; + class NormalLabel: Label { + text = "$STR_speed_normal"; + tooltip = ""; + x = QUOTE(W_PART(1)); + y = QUOTE(H_PART(1.1)); + w = QUOTE(W_PART(10.8)); + colorBackground[] = {0, 0, 0, 0.6}; + }; + class Normal: AllCheckBox { + idc = 92558; + x = QUOTE(W_PART(11.9)); + y = QUOTE(H_PART(1.1)); + }; + class NightVisionLabel: NormalLabel { + text = "$STR_usract_night_vision"; + y = QUOTE(H_PART(2.2)); + }; + class NightVision: Normal { + idc = 92559; + y = QUOTE(H_PART(2.2)); + }; + class WhiteHotLabel: NormalLabel { + text = CSTRING(ModuleSpectator_WhiteHot); + x = QUOTE(W_PART(13.1)); + }; + class WhiteHot: Normal { + idc = 92560; + x = QUOTE(W_PART(24)); + }; + class BlackHotLabel: WhiteHotLabel { + text = CSTRING(ModuleSpectator_BlackHot); + y = QUOTE(Y_PART(2.2)); + }; + class BlackHot: WhiteHot { + idc = 92561; + y = QUOTE(H_PART(2.2)); + }; + }; + }; + }; + }; + }; + }; + class ButtonOK: ButtonOK {}; + class ButtonCancel: ButtonCancel {}; + }; +}; diff --git a/docs/_config.yml b/docs/_config.yml index 52ba8da828..ee7822969d 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -8,9 +8,9 @@ ace: githubUrl: https://github.com/acemod/ACE3 version: major: 3 - minor: 16 + minor: 17 patch: 1 - build: 74 + build: 86 markdown: kramdown diff --git a/docs/_config_dev.yml b/docs/_config_dev.yml index 67de48f2f6..348e1aee44 100644 --- a/docs/_config_dev.yml +++ b/docs/_config_dev.yml @@ -8,9 +8,9 @@ ace: githubUrl: https://github.com/acemod/ACE3 version: major: 3 - minor: 16 + minor: 17 patch: 1 - build: 74 + build: 86 markdown: kramdown diff --git a/docs/_includes/_footer.html b/docs/_includes/_footer.html index ec55355d99..b13d9d47b5 100644 --- a/docs/_includes/_footer.html +++ b/docs/_includes/_footer.html @@ -36,6 +36,12 @@ +
+

+ ACE3 is free and open-source software. +
+ acemod +

diff --git a/docs/_includes/_header.html b/docs/_includes/_header.html index 7123c5968a..8c6cd8c39e 100644 --- a/docs/_includes/_header.html +++ b/docs/_includes/_header.html @@ -27,6 +27,7 @@ + diff --git a/docs/_posts/2024-04-01-ace3-version3170.md b/docs/_posts/2024-04-01-ace3-version3170.md new file mode 100644 index 0000000000..fddc71642a --- /dev/null +++ b/docs/_posts/2024-04-01-ace3-version3170.md @@ -0,0 +1,48 @@ +--- +title: ACEREP #00012 +description: Status report on ACE3 version 3.17.0 +parent: posts +image: +author: Jonpas +layout: post +--- + +This post accompanies the release of ACE3 v3.17.0, a smaller but not any less significant release. We will also take a peek at at our new experimental project. + + + +### Release Cadence + +With improved tooling such as [HEMTT](https://github.com/BrettMayson/HEMTT) simplifying our release processes, we have been aiming aiming to do releases more often than in the past. This is one of the first bigger releases following the set cadence. + +While releases are expected to be smaller as less time passes between them resulting in fewer changes, the new cadence should effectively contribute to higher quality and stability of ACE3 overall. + +We are maintaining our philosophy of "no schedule, no ETAs" and simply release when the team is able to and opts to do so. Work done on the project should not affect this and we aim to release more often even if there are only little or insignificant changes. + +### Integrated CUP Compatibility + +[Community Upgrade Project](https://www.cup-arma3.org/) has always provided compatibility and support for ACE3. Originally it has been hosted and maintained by the CUP Team. With the availability of automatically loading a compatibility patch if the given mod is loaded, we have worked together with the CUP Team to bring ACE3 Compatibility for CUP directly into the ACE3 mod. + +**This means you should remove any compatibility patches provided by CUP** and instead simply use ACE3 together with CUP. In addition to integrated compatibility, some additional improvements were also made. + +### ACE Anvil + +
+
+ ACE Anvil Logo +
+
+ +[ACE Anvil](https://github.com/acemod/ACE-Anvil) is an **experimental** realism mod for Arma Reforger, the first Arma game running on the Enfusion engine. + +Anvil is not expected to reach feature parity with ACE3. It is heavily experimental and we invite you to contribute to it. As Arma Reforger is a test platform, go wild, we are happy to add any realism or quality of life features, even some that might not be strictly within ACE's usual scope. + +Learn more about ACE Anvil at the [Anvil Documentation](https://anvil.acemod.org/)! + +### The End Things + +The change log for ACE3 v3.17.0 can be found [here](https://github.com/acemod/ACE3/releases/v3.17.0){:target="_blank"}. + +We are still in need for translations for some languages within the ACE3 project. Please have a look at [this GitHub issue to track the progress and what languages lack translations](https://github.com/acemod/ACE3/issues/367){:target="_blank"}. Any and all help with this is very appreciated. + +Make sure to [follow us on Twitter](https://twitter.com/intent/follow?screen_name=ace3mod&tw_p=followbutton){:target="_blank"} and to [like our Facebook page](https://www.facebook.com/ACE3Mod/){:target="_blank"}. diff --git a/docs/docker-compose.yml b/docs/docker-compose.yml index ca25a38c0a..5645a80000 100644 --- a/docs/docker-compose.yml +++ b/docs/docker-compose.yml @@ -1,5 +1,3 @@ -version: "3.2" - services: docs: container_name: ace3mod_jekyll diff --git a/docs/img/news/240401_ace_anvil_logo.webp b/docs/img/news/240401_ace_anvil_logo.webp new file mode 100644 index 0000000000..8a679e7a59 Binary files /dev/null and b/docs/img/news/240401_ace_anvil_logo.webp differ 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/index.html b/docs/index.html index 1b830ece20..c15d788798 100644 --- a/docs/index.html +++ b/docs/index.html @@ -8,7 +8,7 @@ sitemap: exclude: "yes" --- -Fork me on GitHub +Fork me on GitHub
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/tools/document_functions.py b/docs/tools/document_functions.py index c3286cf6ef..dab567d208 100644 --- a/docs/tools/document_functions.py +++ b/docs/tools/document_functions.py @@ -192,6 +192,9 @@ class FunctionFile: if arg_default is None: arg_default = "" + if ("SCALAR" in arg_types or "NUMVER" in arg_types): + self.feedback("Bad Arg Type \"{}\"".format(arg_types), 1) + arguments.append([arg_index, arg_name, arg_types, arg_default, arg_notes]) else: # Notes about the above argument won't start with an index diff --git a/docs/wiki/class-names.md b/docs/wiki/class-names.md index d8537f0645..4a4f9b032f 100644 --- a/docs/wiki/class-names.md +++ b/docs/wiki/class-names.md @@ -240,6 +240,7 @@ ACE_plasmaIV_250 | Plasma IV (250ml) | ACE_ItemCore | ACE_salineIV | Saline IV (1000ml) | ACE_ItemCore | ACE_salineIV_500 | Saline IV (500ml) | ACE_ItemCore | ACE_salineIV_250 | Saline IV (250ml) | ACE_ItemCore | +ACE_suture | Suture | ACE_ItemCore | ACE_surgicalKit | Surgical Kit | ACE_ItemCore | ACE_tourniquet | Tourniquet (CAT) | ACE_ItemCore | ACE_medicalSupplyCrate | Simple ACE Medical Supply Crate | ammo box | diff --git a/docs/wiki/development/arma-3-scheduler-and-our-practices.md b/docs/wiki/development/arma-3-scheduler-and-our-practices.md index 440f0f9557..d2ffda2a07 100644 --- a/docs/wiki/development/arma-3-scheduler-and-our-practices.md +++ b/docs/wiki/development/arma-3-scheduler-and-our-practices.md @@ -36,7 +36,7 @@ Code running in the unscheduled environment uses linear execution, that means it ## 2. What is the scheduler and why do I care? -The Arma 3 script scheduler basically gives a fair-share execution to all running scripts, FSMs, and SQS files running on any given client or server at any given time. See the [Biki article](https://community.bistudio.com/wiki/Biki2.0:Performance_Considerations){:target="_blank"} for a in-depth explanation of this. What this basically means though, is that all scripts get a fair share; this also means scheduled execution is drastically affected by other mods that use scheduled execution. For example, if 2 different spawn's are running in a tight loop of `while {true} do {...};`, they will both get exactly 50% of the scheduling time. +The Arma 3 script scheduler basically gives a fair-share execution to all running scripts, FSMs, and SQS files running on any given client or server at any given time. See the [Biki article](https://community.bistudio.com/wiki/Biki2.0:Performance_Considerations){:target="_blank"} for an in-depth explanation of this. What this basically means though, is that all scripts get a fair share; this also means scheduled execution is drastically affected by other mods that use scheduled execution. For example, if 2 different spawn's are running in a tight loop of `while {true} do {...};`, they will both get exactly 50% of the scheduling time. With the way mission makers and mod makers generally use `spawn`/`execVM`, this means you're actually getting drastically less execution time in the scheduled environment than you might think. This leads to visible delay issues all the way up to massive delay on execution. You can easily test and prove this by looping spawns and watching the execution times extend. diff --git a/docs/wiki/development/coding-guidelines.md b/docs/wiki/development/coding-guidelines.md index 786a5d74e8..fe9f0bfdf0 100644 --- a/docs/wiki/development/coding-guidelines.md +++ b/docs/wiki/development/coding-guidelines.md @@ -381,11 +381,19 @@ However the following is allowed: _value = (_array select 0) select 1; ``` -Any conditions in statements shall always be wrapped around brackets. +Any conditions in statements shall always be wrapped around brackets. Both uses of the `!` operator below are allowed. ```sqf -if (!_value) then {}; if (_value) then {}; +if (!_value) then {}; +if !(_value) then {}; +``` + +Use of the `!` operator on the lefthand-side of brackets can be more readable, particularly for more complex conditions or macros: + +```sqf +if !(_value && _otherValue && {_thirdValue call _something}) then {}; +if !(GETEGVAR(addon,globalVariableName,defaultValue)) then {}; ``` ### 5.6 Magic Numbers @@ -632,81 +640,6 @@ player addEventHandler ["Fired", FUNC(handleFired)]; // bad player addEventHandler ["Fired", {call FUNC(handleFired)}]; // good ``` -### 7.4 Hashes - -When a key value pair is required, make use of the hash implementation from ACE3. - -Hashes are a variable type that store key value pairs. They are not implemented natively in SQF, so there are a number of macros and functions for their usage in ACE3. If you are unfamiliar with the idea, they are similar in function to `setVariable`/`getVariable` but do not require an object to use. - -The following example is a simple usage using our macros which will be explained further below. - -```sqf -_hash = HASHCREATE; -HASH_SET(_hash,"key","value"); -if (HASH_HASKEY(_hash,"key")) then { - player sideChat format ["val: %1", HASH_GET(_hash,"key"); // will print out "val: value" -}; -HASH_REM(_hash,"key"); -if (HASH_HASKEY(_hash,"key")) then { - // this will never execute because we removed the hash key/val pair "key" -}; -``` - -A description of the above macros is below. - -| Macro | Use | -| ------|-------| -|`HASHCREATE` | Used to create an empty hash. | -|`HASH_SET(hash,key,val)` | Will set the hash key to that value, a key can be anything, even objects. | -|`HASH_GET(hash,key)` | Will return the value of that key (or nil if it doesn't exist). | -|`HASH_HASKEY(hash,key)` | Will return true/false if that key exists in the hash. | -|`HASH_REM(hash,key)` | Will remove that hash key. | - -#### 7.4.1 Hashlists - -A hashlist is an extension of a hash. It is a list of hashes! The reason for having this special type of storage container rather than using a normal array is that an array of normal hashes that are similar will duplicate a large amount of data in their storage of keys. A hashlist on the other hand uses a common list of keys and an array of unique value containers. The following will demonstrate its usage. - -```sqf -_defaultKeys = ["key1", "key2", "key3"]; -// create a new hashlist using the above keys as default -_hashList = HASHLIST_CREATELIST(_defaultKeys); - -//lets get a blank hash template out of this hashlist -_hash = HASHLIST_CREATEHASH(_hashList); - -//_hash is now a standard hash... -HASH_SET(_hash,"key1","1"); - -//to store it to the list we need to push it to the list -HASHLIST_PUSH(_hashList, _hash); - -//now lets get it out and store it in something else for fun -//it was pushed to an empty list, so it's index is 0 -_anotherHash = HASHLIST_SELECT(_hashList,0); - -// this should print "val: 1" -player sideChat format["val: %1", HASH_GET(_anotherHash,"key1")]; - -//Say we need to add a new key to the hashlist -//that we didn't initialize it with? We can simply -//set a new key using the standard HASH_SET macro -HASH_SET(_anotherHash,"anotherKey","another value"); -``` - -As you can see above working with hashlists are fairly simple, a more in depth explanation of the macros is below. - -| Macro | Use | -| -------|---------| -|`HASHLIST_CREATELIST(keys)` | Creates a new hashlist with the default keys, pass [] for no default keys. | -|`HASHLIST_CREATEHASH(hashlist)` | Returns a blank hash template from a hashlist. | -|`HASHLIST_PUSH(hashList, hash)` | Pushes a new hash onto the end of the list. | -|`HASHLIST_SELECT(hashlist, index)` | Returns the hash at that index in the list. | -|`HASHLIST_SET(hashlist, index, hash)` | Sets a specific index to that hash. | - -##### 7.4.1.1 A note on pass by reference and hashes - -Hashes and hashlists are implemented with SQF arrays, and as such they are passed by reference to other functions. Remember to make copies (using the `+` operator) if you intend for the hash or hashlist to be modified with out the need for changing the original value. - ## 8. Performance Considerations ### 8.1 Adding Elements to Arrays diff --git a/docs/wiki/development/modularity-and-pbo-structure.md b/docs/wiki/development/modularity-and-pbo-structure.md index 6f8ab50ef4..c0632036c1 100644 --- a/docs/wiki/development/modularity-and-pbo-structure.md +++ b/docs/wiki/development/modularity-and-pbo-structure.md @@ -23,7 +23,7 @@ Main principles: - Anything that is 100% config should require Common and not Interaction. ``` -Main -> Common -> OptionsMenu -> Interaction -> Most things +Main -> Common -> Interaction -> Most things Main -> Common -> Config things 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/feature/grenades.md b/docs/wiki/feature/grenades.md index 679b309b1e..2b60c08d4e 100644 --- a/docs/wiki/feature/grenades.md +++ b/docs/wiki/feature/grenades.md @@ -23,6 +23,8 @@ version: ### 1.1 Throw modes Provides different modes for throwing grenades (high throw, precision throw and drop mode). +A grenade is only rollable if the fuse time (`explosionTime`) is >= 1 second and the player isn't in a vehicle. + ### 1.2 Hand flares Adds throwable hand flares in the colors white, red, green and yellow. Additionally buffs existing flares by making them brighter and last longer. diff --git a/docs/wiki/feature/hitreactions.md b/docs/wiki/feature/hitreactions.md index 7d12c1cb12..a84d1c0b78 100644 --- a/docs/wiki/feature/hitreactions.md +++ b/docs/wiki/feature/hitreactions.md @@ -18,3 +18,6 @@ version: ### 1.1 Falling under fire If a unit is shot while running it falls to the ground in a prone position, the area where the shot lands does not matters. Note that the shot needs to inflict a certain amount of damage to make the unit fall, a small cut won't make the unit stumble. + +### 1.2 Weapon dropping +If a unit's arm is shot it will cause the gun to be dropped based on the chance set. The default is 0. diff --git a/docs/wiki/feature/maptools.md b/docs/wiki/feature/maptools.md index c6f4903780..f8ce7e5416 100644 --- a/docs/wiki/feature/maptools.md +++ b/docs/wiki/feature/maptools.md @@ -21,8 +21,11 @@ This adds the possibility to draw accurate lines on the map screen. ### 1.2 Map tools This adds map tools that can be used to measure distances between two points or bearings on the map. -### 1.3 GPS on map -If you are equipped with a vanilla GPS it will be shown on the map. (You don't need the `Map Tools` item in your inventory for this.) +### 1.3 Plotting Board +This adds a plotting board that can be used to aid in the rapid usage and adjustment of short-ranged indirect fires, as well as quick measurements of directions and distances between points, and general land-navigation. + +### 1.4 GPS on map +If you have GPS capability, a GPS display will be shown on the map, indicating current grid position. (You don't need the `Map Tools` item in your inventory for this.) ## 2. Usage @@ -39,3 +42,16 @@ If you are equipped with a vanilla GPS it will be shown on the map. (You don't n - Press ALT + LMB to start the line, left click again to end it. - To delete a line press Del around the center of the line. - Note that you can change the color of the lines by clicking on one of the coloured column on top of the screen (While the map is opened). + +### 2.3 Using the plotting board +- To use map tools the `Plotting Board` item is required. +- Open the map M (Arma 3 default key bind `Map`). +- Press the self interaction key Ctrl + ⊞ Win (ACE3 default key bind `Self Interaction Key`). +- Select `Show Plotting Board`. +- Note that you can drag the Plotting Board around with LMB and rotate the different parts of the Plotting Board, each independently from each other, with Ctrl + LMB. +- When a new marker (Local or Group Channel) is created on the inner circle of the Plotting board, the marker will move accordingly when the Plotting Board gets moved or rotated. + +### 2.4 Drawing lines +- You can draw lines on the plotting board. +- These lines are removed from the map once the plotting board is hidden, but they restored when the plotting board is shown again. +- These lines are moved along with the plotting board when the plotting board is dragged. diff --git a/docs/wiki/framework/advanced-fatigue-framework.md b/docs/wiki/framework/advanced-fatigue-framework.md index 93c9aa9b77..9afd9891d7 100644 --- a/docs/wiki/framework/advanced-fatigue-framework.md +++ b/docs/wiki/framework/advanced-fatigue-framework.md @@ -13,16 +13,18 @@ version: ## 1. Global Settings -ACE provides four settings to tweak Advanced Fatigue. Adjust these factors depending on how hard you want your experience to be. +ACE provides multiple settings to tweak Advanced Fatigue. Adjust these settings depending on how hard you want your experience to be. +- **Enabled:** This allow you to toggle Advanced Fatigue on or off. Mission needs to be restarted if this setting is changed. +- **Show stamina bar:** Shows/hides the stamina bar. +- **Fade Stamina bar automatically:** Adjusts transparency of the bar based on stamina status. - **Performance factor:** This influences the overall performance of players, malnourished or super soldiers, everything is possible. - **Recovery factor:** Do you like looking at the landscape or think breaks are boring? Whatever the case, this influences the length of your stamina breaks. - **Load factor:** If you believe a Javelin is the perfect companion for your .50 BMG sniper rifle you probably should tweak this setting. -- **Terrain factor**: Not everyone is used to mountainous terrain. Tweak this until you feel more at home. -- **Sway factor**: Influences the amount of weapon sway. Higher means more sway. - -Note that while there currently is no restriction on the value of these settings, it's generally recommended to keep them between 0 and 2. - +- **Terrain factor:** Not everyone is used to mountainous terrain. Tweak this until you feel more at home. +- **Sway factor:** Influences the amount of weapon sway. Higher means more sway. +- **Rested sway factor:** Influences the amount of weapon sway while rested is deployed. Higher means more sway. +- **Deployed sway factor:** Influences the amount of weapon sway while weapon is deployed. Higher means more sway. ## 2. Unit Specific Settings diff --git a/docs/wiki/framework/arsenal-framework.md b/docs/wiki/framework/arsenal-framework.md index 95c7e82211..954bbc0a7e 100644 --- a/docs/wiki/framework/arsenal-framework.md +++ b/docs/wiki/framework/arsenal-framework.md @@ -31,11 +31,11 @@ To quickly add a full ACE Arsenal to a box for all clients use the following cod `ace_arsenal_fnc_initBox` -| | Argument | Type | Optional (default value) ----| -------- | ---- | ------------------------ -0 | Box | Object | Required -1 | Items | Array of strings or boolean | Required -2 | Initialize globally | Boolean | Optional (default: `false`) +| | Argument | Type | Optional (default value) | +|----| -------- | ---- | ------------------------ | +| 0 | Box | Object | Required | +| 1 | Items | Array of strings or boolean | Required | +| 2 | Initialize globally | Boolean | Optional (default: `false`) | This will add the virtual items passed as arguments and add an ACE interaction to open ACE Arsenal. @@ -51,11 +51,11 @@ Please note that at least one virtual item needs to be added otherwise ACE Arsen `ace_arsenal_fnc_openBox` -| | Argument | Type | Optional (default value) ----| -------- | ---- | ------------------------ -0 | Box | Object | Required -1 | Unit to open ACE Arsenal on | Object | Required -2 | Ignore virtual items and fill ACE Arsenal | Boolean | Optional (default: `false`) +| | Argument | Type | Optional (default value) | +|----| -------- | ---- | ------------------------ | +| 0 | Box | Object | Required | +| 1 | Unit to open ACE Arsenal on | Object | Required | +| 2 | Ignore virtual items and fill ACE Arsenal | Boolean | Optional (default: `false`) | Examples: - `[_box, player] call ace_arsenal_fnc_openBox` @@ -67,10 +67,10 @@ In the second example a full ACE Arsenal will be opened on the player. `ace_arsenal_fnc_removeBox` -| | Argument | Type | Optional (default value) ----| -------- | ---- | ------------------------ -0 | Box | Object | Required -2 | Remove globally | Boolean | Optional (default: `false`) +| | Argument | Type | Optional (default value) | +|----| -------- | ---- | ------------------------ | +| 0 | Box | Object | Required | +| 2 | Remove globally | Boolean | Optional (default: `false`) | Example: `[_box, true] call ace_arsenal_fnc_removeBox` @@ -81,11 +81,11 @@ Example: `ace_arsenal_fnc_addVirtualItems` -| | Argument | Type | Optional (default value) ----| -------- | ---- | ------------------------ -0 | Box | Object | Required -1 | Items | Array of strings or boolean | Required -2 | Add globally | Boolean | Optional (default: `false`) +| | Argument | Type | Optional (default value) | +|----| -------- | ---- | ------------------------ | +| 0 | Box | Object | Required | +| 1 | Items | Array of strings or boolean | Required | +| 2 | Add globally | Boolean | Optional (default: `false`) | Passing an array of strings (class names) will add each one of those items to the specified box, passing true will add ALL items that are compatible with ACE Arsenal (the sorting is done on game startup). Faces, voices and insignia can't be added via this function. @@ -97,11 +97,11 @@ Examples: `ace_arsenal_fnc_removeVirtualItems` -| | Argument | Type | Optional (default value) ----| -------- | ---- | ------------------------ -0 | Box | Object | Required -1 | Items | Array of strings or boolean | Required -2 | Remove globally | Boolean | Optional (default: `false`) +| | Argument | Type | Optional (default value) | +|----| -------- | ---- | ------------------------ | +| 0 | Box | Object | Required | +| 1 | Items | Array of strings or boolean | Required | +| 2 | Remove globally | Boolean | Optional (default: `false`) | Like adding virtual items, passing an array of string (class names) will remove each ones of those items, however passing true will remove all virtual items and also remove the interaction to access ACE Arsenal. Faces, voices and insignia can't be removed via this function. @@ -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 @@ -184,11 +185,11 @@ Players with Zeus access can save default loadouts ingame, doing so will make th `ace_arsenal_fnc_addDefaultLoadout` -| | Argument | Type | Optional (default value) ----| -------- | ---- | ------------------------ -0 | Name of loadout | String | Required -1 | getUnitLoadout array or CBA extended loadout array | Array | Required -2 | Add loadout globally | Boolean | Optional (default: `false`) +| | Argument | Type | Optional (default value) | +|----| -------- | ---- | ------------------------ | +| 0 | Name of loadout | String | Required | +| 1 | getUnitLoadout array or CBA extended loadout array | Array | Required | +| 2 | Add loadout globally | Boolean | Optional (default: `false`) | Example: `["Squad Leader", getUnitLoadout sql1, true] call ace_arsenal_fnc_addDefaultLoadout` @@ -228,22 +229,22 @@ The arguments passed to the bar, text and condition statements are: `ace_arsenal_fnc_addStat` -| | Argument | Type | Optional (default value) ---- | -------- | ---- | ------------------------ -0 | Tabs to add the stat to | Array of arrays | Required -0.1 | Left tab indexes | Array of numbers | Required -0.2 | Right tab indexes | Array of numbers | Required -1 | Stat class ID | String | Required -2 | Config entries to pass | Array of strings | Required -3 | Title | String | Required -4 | Show bar / show text bools | Array of booleans | Required -4.1 | Show bar | Boolean | Required -4.2 | Show text | Boolean | Required -5 | Array of statements | Array of code | Required -5.1 | Bar code | Code | Required -5.2 | Text code | Code | Required -5.3 | Condition | Code | Required -6 | Priority | Number | Optional (default: `0`) +| | Argument | Type | Optional (default value) | +| --- | -------- | ---- | ------------------------ | +| 0 | Tabs to add the stat to | Array of arrays | Required | +| 0.1 | Left tab indexes | Array of numbers | Required | +| 0.2 | Right tab indexes | Array of numbers | Required | +| 1 | Stat class ID | String | Required | +| 2 | Config entries to pass | Array of strings | Required | +| 3 | Title | String | Required | +| 4 | Show bar / show text bools | Array of booleans | Required | +| 4.1 | Show bar | Boolean | Required | +| 4.2 | Show text | Boolean | Required | +| 5 | Array of statements | Array of code | Required | +| 5.1 | Bar code | Code | Required | +| 5.2 | Text code | Code | Required | +| 5.3 | Condition | Code | Required | +| 6 | Priority | Number | Optional (default: `0`) | Return Value: - Array of stat IDs @@ -262,9 +263,9 @@ If a stat already exists (so same class ID and tab), it will ignore the new addi `ace_arsenal_fnc_removeStat` -| | Argument | Type | Optional (default value) ----| -------- | ---- | ------------------------ -0 | Array of IDs | Array | Required +| | Argument | Type | Optional (default value) | +|----| -------- | ---- | ------------------------ | +| 0 | Array of IDs | Array | Required | Stats IDs are unique, IDs are generated as follows: @@ -344,15 +345,15 @@ The argument passed to the condition is: `ace_arsenal_fnc_addSort` -| | Argument | Type | Optional (default value) ---- | -------- | ---- | ------------------------ -0 | Tabs to add the sort to | Array of arrays | Required -0.1 | Left tab indexes | Array of numbers | Required -0.2 | Right tab indexes | Array of numbers | Required -1 | Stat class ID | String | Required -2 | Title | String | Required -3 | Algorithm | Code | Required -4 | Condition | Code | Optional (default: `{true}`) +| | Argument | Type | Optional (default value) | +| --- | -------- | ---- | ------------------------ | +| 0 | Tabs to add the sort to | Array of arrays | Required | +| 0.1 | Left tab indexes | Array of numbers | Required | +| 0.2 | Right tab indexes | Array of numbers | Required | +| 1 | Stat class ID | String | Required | +| 2 | Title | String | Required | +| 3 | Algorithm | Code | Required | +| 4 | Condition | Code | Optional (default: `{true}`) | Return Value: - Array of sort IDs @@ -381,9 +382,9 @@ If a sorting method already exists (so same class ID and tab), it will ignore th `ace_arsenal_fnc_removeSort` -| | Argument | Type | Optional (default value) ----| -------- | ---- | ------------------------ -0 | Array of IDs | Array | Required +| | Argument | Type | Optional (default value) | +|----| -------- | ---- | ------------------------ | +| 0 | Array of IDs | Array | Required | Sorting method IDs are unique and are generated in the same fashion as the stat IDs (see `5.3 Removing stats via a function`). @@ -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 { @@ -433,14 +438,15 @@ The focused unit object is passed to the condition and statement functions. `ace_arsenal_fnc_addAction` -| | Argument | Type | Optional (default value) ---- | -------- | ---- | ------------------------ -0 | Tabs to add the sort to | Array of numbers | Required -1 | Action class ID | String | Required -2 | Title | String | Required -3 | Actions | Array of arrays | Required -4 | Condition | Code | Optional (default: `{true}`) -5 | Scope editor | Number | Optional (default: `2`) +| | Argument | Type | Optional (default value) | +| --- | -------- | ---- | ------------------------ | +| 0 | Tabs to add the sort to | Array of numbers | Required | +| 1 | Action class ID | String | Required | +| 2 | Title | String | Required | +| 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 @@ -468,9 +474,9 @@ If an action already exists (so same class ID and tab within an action), it will `ace_arsenal_fnc_removeAction` -| | Argument | Type | Optional (default value) ----| -------- | ---- | ------------------------ -0 | Array of IDs | Array | Required +| | Argument | Type | Optional (default value) | +|----| -------- | ---- | ------------------------ | +| 0 | Array of IDs | Array | Required | Action IDs are unique and their generation is explained in `7.2 Adding sorting methods via a function`. @@ -486,27 +492,28 @@ All are local. | Name | Arguments | Added in | | ------------- | ------------- | ------------- | -| ace_arsenal_boxInitialized | Arsenal box (OBJECT), items (BOOL or ARRAY) | -| ace_arsenal_boxRemoved | Arsenal box (OBJECT) | -| ace_arsenal_displayOpened | Arsenal display (DISPLAY) | -| ace_arsenal_displayClosed | None | -| ace_arsenal_leftPanelFilled | Arsenal display (DISPLAY), current left panel IDC (SCALAR), current right panel IDC (SCALAR) | -| ace_arsenal_rightPanelFilled | Arsenal display (DISPLAY), current left panel IDC (SCALAR), current right panel IDC (SCALAR) | -| ace_arsenal_onLoadoutSave | Loadout index (SCALAR), [loadout name (STRING), loadout data (ARRAY)] | -| ace_arsenal_onLoadoutSaveExtended | Loadout index (SCALAR), [loadout name (STRING), CBA extended loadout data (ARRAY)] | 3.15.1 -| ace_arsenal_onLoadoutLoad | loadout data (ARRAY), loadout name (STRING) | -| ace_arsenal_onLoadoutLoadExtended | CBA extended loadout data (ARRAY), loadout name (STRING) | 3.15.1 -| ace_arsenal_onLoadoutDelete | loadout name (STRING) | -| ace_arsenal_loadoutShared | Loadouts list listnBox control (CONTROL), loadout author (STRING), loadout name (STRING), loadout data (ARRAY) | -| ace_arsenal_loadoutUnshared | Loadouts list listnBox control (CONTROL), loadout author (STRING), loadout name (STRING) | -| ace_arsenal_cargoChanged | Arsenal display (DISPLAY), item (STRING), add or remove (NUMBER), shiftState (BOOL) | -| ace_arsenal_loadoutImported | Arsenal display (DISPLAY), import list (BOOL) | -| ace_arsenal_loadoutExported | Arsenal display (DISPLAY), export list (BOOL) | -| ace_arsenal_loadoutsDisplayOpened | loadouts screen display (DISPLAY) | 3.12.3 | -| 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_weaponItemChanged | weapon classname (STRING), item classname (STRING), item index (NUMBER, 0-5: muzzle, side, optic, bipod, magazine, underbarrel) | 3.16.0 | +| `ace_arsenal_boxInitialized` | Arsenal box (OBJECT), items (BOOL or ARRAY) | +| `ace_arsenal_boxRemoved` | Arsenal box (OBJECT) | +| `ace_arsenal_displayOpened` | Arsenal display (DISPLAY) | +| `ace_arsenal_displayClosed` | None | +| `ace_arsenal_leftPanelFilled` | Arsenal display (DISPLAY), current left panel IDC (SCALAR), current right panel IDC (SCALAR) | +| `ace_arsenal_rightPanelFilled` | Arsenal display (DISPLAY), current left panel IDC (SCALAR), current right panel IDC (SCALAR) | +| `ace_arsenal_onLoadoutSave` | Loadout index (SCALAR), [loadout name (STRING), loadout data (ARRAY)] | +| `ace_arsenal_onLoadoutSaveExtended` | Loadout index (SCALAR), [loadout name (STRING), CBA extended loadout data (ARRAY)] | 3.15.1 +| `ace_arsenal_onLoadoutLoad` | loadout data (ARRAY), loadout name (STRING) | +| `ace_arsenal_onLoadoutLoadExtended` | CBA extended loadout data (ARRAY), loadout name (STRING) | 3.15.1 +| `ace_arsenal_onLoadoutDelete` | loadout name (STRING) | +| `ace_arsenal_loadoutShared` | Loadouts list listnBox control (CONTROL), loadout author (STRING), loadout name (STRING), loadout data (ARRAY) | +| `ace_arsenal_loadoutUnshared` | Loadouts list listnBox control (CONTROL), loadout author (STRING), loadout name (STRING) | +| `ace_arsenal_cargoChanged` | Arsenal display (DISPLAY), item (STRING), add or remove (NUMBER), shiftState (BOOL) | +| `ace_arsenal_loadoutImported` | Arsenal display (DISPLAY), import list (BOOL) | +| `ace_arsenal_loadoutExported` | Arsenal display (DISPLAY), export list (BOOL) | +| `ace_arsenal_loadoutsDisplayOpened` | loadouts screen display (DISPLAY) | 3.12.3 | +| `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 @@ -514,13 +521,13 @@ All are local. `ace_arsenal_fnc_addRightPanelButton` -| | Argument | Type | Optional (default value) ----| -------- | ---- | ------------------------ -0 | Misc. items | Array of strings | Required -1 | Tooltip | String | Optional (default: `""`) -2 | Picture path | String | Optional (default: `"\z\ace\addons\arsenal\data\iconCustom.paa"`) -3 | Override a specific button | Number | Optional (default: `-1`) -4 | Move button on overwrite | Bool | Optional (default: `false`) +| | Argument | Type | Optional (default value) | +|----| -------- | ---- | ------------------------ | +| 0 | Misc. items | Array of strings | Required | +| 1 | Tooltip | String | Optional (default: `""`) | +| 2 | Picture path | String | Optional (default: `"\z\ace\addons\arsenal\data\iconCustom.paa"`) | +| 3 | Override a specific button | Number | Optional (default: `-1`) | +| 4 | Move button on overwrite | Bool | Optional (default: `false`) | Return Value: - Successful: Number of the slot (0-9) diff --git a/docs/wiki/framework/artillery-tables-framework.md b/docs/wiki/framework/artillery-tables-framework.md new file mode 100644 index 0000000000..be2adb3331 --- /dev/null +++ b/docs/wiki/framework/artillery-tables-framework.md @@ -0,0 +1,38 @@ +--- +layout: wiki +title: Artillery Tables +description: Explains the configs for artillery tables. +group: framework +parent: wiki +mod: ace +version: + major: 3 + minor: 13 + patch: 0 +--- + +## 1. Magazine Configs + +```cpp +class CfgMagazines { + class yourMag { + ace_artillerytables_airFriction = -0.00006; // default value + // drag coefficent (when Air Resistance setting is enabled) + // can set to 0 to disable all muzzle effects and airFriction + // can set to +1 to use the ammo's native airFriction (not common, as most artillery ammo will have none) +``` + +## 2. Vehicle Configs + +```cpp +class CfgVehicles { + class yourVic { + ace_artillerytables_showRangetable = 1; // [0 disabled, 1 enabled] falls back to artilleryScanner + // Show rangetable for this vehicle + + ace_artillerytables_showGunLaying = 1; // [0 disabled, 1 enabled, 2 enabled w/ alt elevationMode] falls back to artilleryScanner + // Shows gun laying info (elev/azimuth) + + ace_artillerytables_applyCorrections = 1; // [0 disabled, 1 enabled] falls back to artilleryScanner + // Apply advanced corrections (when setting enabled) +``` diff --git a/docs/wiki/framework/attach-framework.md b/docs/wiki/framework/attach-framework.md index 2ed5f74561..f118b3b934 100644 --- a/docs/wiki/framework/attach-framework.md +++ b/docs/wiki/framework/attach-framework.md @@ -15,7 +15,7 @@ version: ## 1. Config Values ### 1.1 Make item attachable -An item can be added to the ACE Attach framework by adding the ``ACE_attachable`` property to a class in ``CfgWeapons`` or ``CfgMagazines``. The value must be the classname of a valid class in ``CfgVehicles``: +An item can be added to the ACE Attach framework by adding the `ACE_attachable` property to a class in `CfgWeapons` or `CfgMagazines`. The value must be the classname of a valid class in `CfgVehicles`: ```cpp class CfgWeapons { class attach_item: CBA_MiscItem { @@ -29,16 +29,16 @@ class CfgVehicles { scope = 1; // Should be 1 (private) or 2 (public), scope 0 will cause errors on object creation displayName = "New ACE attachable item"; model = "\path\to\my\model.p3d"; - vehicleClass = ""; + vehicleClass = ""; }; }; ``` ### 1.2 Define attach orientation for non-symmetric items -In the case the item needs to have a particular orientation when attached, add the config value: ``ace_attach_orientation`` which is an array describing the ``roll`` and ``yaw`` orientation of the object. -The default value is: ``[0,0]``. +In the case the item needs to have a particular orientation when attached, add the config value: `ace_attach_orientation` which is an array describing the `roll` and `yaw` orientation of the object. +The default value is: `[0,0]`. -Example: +Example: ```cpp class CfgWeapons { class attach_item: CBA_MiscItem { @@ -49,11 +49,11 @@ class CfgWeapons { ``` ## 2. Event Handlers -### 2.1 Listenable Events +### 2.1 Listenable Events | Event Key | Parameters | Locality | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_attach_attached` | [_attachedObject, _itemClassname, _temporary] | Local | Called after an item is attached to an object. `_temporary` flag means the item is being re-attached (after a unit is exiting a vehicle, for example) -|`ace_attach_detaching` | [_attachedObject, _itemClassname, _temporary] | Local | Called just before an item is detached/removed from an object. `_temporary` flag means the item will be reattached later, see above. +|----------|---------|---------|---------| +|`ace_attach_attached` | [_attachedObject, _itemClassname, _temporary] | Local | Called after an item is attached to an object. `_temporary` flag means the item is being re-attached (after a unit is exiting a vehicle, for example) | +|`ace_attach_detaching` | [_attachedObject, _itemClassname, _temporary] | Local | Called just before an item is detached/removed from an object. `_temporary` flag means the item will be reattached later, see above. | ### 2.2 Other events for attached objects Use [CBA Extended Event Handlers](https://github.com/CBATeam/CBA_A3/wiki/Extended-Event-Handlers-(new)). Note that objects attached to units will be deleted/created upon entering/exiting vehicles and should be handled accordingly. diff --git a/docs/wiki/framework/cargo-framework.md b/docs/wiki/framework/cargo-framework.md index 5f8a5e8c8c..a1d810ce9c 100644 --- a/docs/wiki/framework/cargo-framework.md +++ b/docs/wiki/framework/cargo-framework.md @@ -16,14 +16,18 @@ version: ### 1.1 Preparing a vehicle for ACE3 cargo +{% raw %} ```cpp class CfgVehicles { class yourVehicleBaseClass { ace_cargo_space = 4; // Cargo space your vehicle has ace_cargo_hasCargo = 1; // Enables cargo to be loaded inside the vehicle (1-yes, 0-no) + ace_cargo_loadmasterTurrets[] = {{1}}; // If vehicle inherits from "Air", you can set this attribute. + // When sitting in the turret paths you define here, you can paradrop cargo items. By default, pilots and co-pilots can paradrop cargo items. }; }; ``` +{% endraw %} ### 1.2 Making an object loadable @@ -43,6 +47,24 @@ class CfgVehicles {

ace_cargo_hasCargo and ace_cargo_canLoad are only needed if you aren't inheriting from any of BI base classes or if you are trying to disable loading for a specific vehicle / object.

+### 1.3 Adding predefined cargo via config + +```cpp +class CfgVehicles { + class yourVehicleClass { + ace_cargo_space = 4; // Add if necessary + ace_cargo_hasCargo = 1; // Add if necessary + class ace_cargo { + class cargo { + class ACE_medicalSupplyCrate { // Doesn't have to have the same name as the item you're adding + type = "ACE_medicalSupplyCrate"; + amount = 1; + }; + }; + }; + }; +}; +``` ## 2. Events @@ -50,8 +72,9 @@ class CfgVehicles { Event Name | Passed Parameter(s) | Locality | Description ---------- | ----------- | ------------------- | -------- -`ace_cargoLoaded` | [_item, _vehicle] | Global | Cargo has been Loaded into vehicle -`ace_cargoUnloaded` | [_item, _vehicle, _unloadType] | Global | Cargo has been Unloaded from vehicle +`ace_cargoAdded` | [_itemClass, _vehicle, _amount] | Global | Cargo has been added to vehicle +`ace_cargoLoaded` | [_item, _vehicle] | Global | Cargo has been loaded into vehicle +`ace_cargoUnloaded` | [_item, _vehicle, _unloadType] | Global | Cargo has been unloaded from vehicle `ace_cargoRemoved` | [_itemClass, _vehicle, _amountRequested, _amountRemoved] | Global | Cargo has been removed (deleted) from vehicle ## 3. Editor Attributes @@ -73,12 +96,12 @@ To disable cargo for a mission object use: ### 4.2 Adjusting cargo size of an object `ace_cargo_fnc_setSize` -Note that this function can be used to make objects loadable/unloadable (set to `-1` for unloadable). +Note that this function can be used to make objects loadable/unloadable (set to `-1` to disable cargo interactions). ```sqf - * Set the cargo size of any object. Has global effect. + * Sets the cargo size of any object. Has global effect. * Adds the load action menu if necessary. - * Negative size makes unloadable. + * A negative size disables the object's cargo interactions. * * Arguments: * 0: Object @@ -97,7 +120,7 @@ Note that this function can be used to make objects loadable/unloadable (set to Note that this function can be used to enable/disable a vehicle's cargo space (set to `0` to disable). ```sqf - * Set the cargo space of any object. Has global effect. + * Sets the cargo space of any object. Has global effect. * Adds the cargo action menu if necessary. * * Arguments: @@ -113,14 +136,17 @@ Note that this function can be used to enable/disable a vehicle's cargo space (s ### 4.4 Load cargo into vehicle -`ace_cargo_fnc_loadItem` (Also callable from cba event `ace_loadCargo`) -Note first arg can be a in-game object or a classname of an object type. +`ace_cargo_fnc_loadItem` (Also callable from CBA event `ace_loadCargo`) +Note first argument can be a in-game object or a classname of an object type. ```sqf + * Load an object into a vehicle. + * Objects loaded via classname remain virtual until unloaded. + * * Arguments: - * 0: Item - * 1: Vehicle - * 2: Ignore interaction distance and stability checks + * 0: Item to be loaded or + * 1: Holder object (vehicle) + * 2: Ignore interaction distance and stability checks (default: false) * * Return Value: * Object loaded @@ -131,16 +157,16 @@ Note first arg can be a in-game object or a classname of an object type. ### 4.5 Unload cargo from vehicle -`ace_cargo_fnc_unloadItem` (Also callable from cba event `ace_unloadCargo`) +`ace_cargo_fnc_unloadItem` (Also callable from CBA event `ace_unloadCargo`) ```sqf * Arguments: - * 0: Item - * 1: Vehicle + * 0: Item to be unloaded or + * 1: Holder object (vehicle) * 2: Unloader (default: objNull) * * Return Value: - * Object was unloaded + * Object unloaded * * Example: * [object, vehicle] call ace_cargo_fnc_unloadItem @@ -152,8 +178,8 @@ Note first arg can be a in-game object or a classname of an object type. ```sqf * Arguments: - * 0: Item or - * 1: Vehicle + * 0: Item to be removed or + * 1: Holder object (vehicle) * 2: Amount (default: 1) * * Return Value: @@ -167,5 +193,5 @@ Note first arg can be a in-game object or a classname of an object type. ### 4.7 Disable cargo renaming via script ```sqf -cargoBox setVariable ["ace_cargo_noRename", true] +cargoBox setVariable ["ace_cargo_noRename", true, _disableGlobally] ``` diff --git a/docs/wiki/framework/cookoff-framework.md b/docs/wiki/framework/cookoff-framework.md index b53fea2049..8129699154 100644 --- a/docs/wiki/framework/cookoff-framework.md +++ b/docs/wiki/framework/cookoff-framework.md @@ -12,43 +12,22 @@ version: patch: 0 --- -## 1. Disabling / Enabling Cook off for individual vehicles +## 1. Disabling cook-off fire for individual vehicles -You can dynamically enable and/or disable vehicle cook off for individual vehicles by using `setVariable`: +Cook-off fire can be disabled for a specific vehicle (does not affect ammo cook-off): ``` -VEHICLE setVariable ["ace_cookoff_enable", true, true]; +_vehicle setVariable ["ace_cookoff_enable", false, true]; ``` -The above will enable cook off for that specific vehicle, no matter the mission settings. +Mission settings will always apply however, so you can't enable cook-off on a vehicle if the mission settings have cook-off for vehicles disabled. -Likewise, cook off can also be disabled for a specific vehicle: +## 2. Disabling ammunition cook-off for individual vehicles and boxes + +Ammunition cook-off can be disabled for a specific vehicle or box (does not affect cook-off fire): ``` -VEHICLE setVariable ["ace_cookoff_enable", false, true]; +_vehicleOrBox setVariable ["ace_cookoff_enableAmmoCookoff", false, true]; ``` -## 2. Cook off probability - -You can set the probability of cook off for individual vehicle types by changing the `ace_cookoff_probability` value in the vehicle's config: - -``` -class MyVehicle { - ace_cookoff_probability = 0.6; -}; -``` - -Global cook off probability can also be adjusted with the `ace_cookoff_probabilityCoef` mission setting. - -Higher values will make cook-off more probable, whilst lower values will make cook-off less probable. - -## 3. Ignore damage to turret - -For use on vehicles when damage to the main turret would not cause a vehicle cookoff. -e.g. RCWS turrets - -``` -class MyVehicle { - ace_vehicle_damage_turretFireProb = 0; -}; -``` +Mission settings will always apply however, so you can't enable ammunition cook-off on a vehicle or box if the mission settings have ammunition cook-off disabled. diff --git a/docs/wiki/framework/dragging-framework.md b/docs/wiki/framework/dragging-framework.md index f4400aed44..43a7c98ba4 100644 --- a/docs/wiki/framework/dragging-framework.md +++ b/docs/wiki/framework/dragging-framework.md @@ -46,58 +46,58 @@ You will **not** be able to carry / drag objects that are too heavy, the mass is `ace_dragging_fnc_setDraggable` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Any object | Object | Required -1 | Enable dragging, true to enable, false to disable | Boolean | Required -2 | Position to offset the object from player | Array | Optional (default: `[0, 1.5, 0]`) -3 | Direction in degree to rotate the object | Number | Optional (default: `0`) -4 | Ignore weight limitation for dragging | Boolean | Optional (default: `false`) -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Any object | Object | Required | +| 1 | Enable dragging, true to enable, false to disable | Boolean | Required | +| 2 | Position to offset the object from player | Array | Optional (default: `[0, 1.5, 0]`) | +| 3 | Direction in degree to rotate the object | Number | Optional (default: `0`) | +| 4 | Ignore weight limitation for dragging | Boolean | Optional (default: `false`) | +| **R** | None | None | Return value | #### 2.1.1 Example 1 `[foo, true, [0, 2, 0], 45] call ace_dragging_fnc_setDraggable;` - | Arguments | Explanation ----| --------- | ----------- -0 | `foo` | My object -1 | `true` | Dragging is enabled -2 | `[0,2,0]` | 0 meters sideways, 2 meters forward, 0 meters upwards -3 | `45` | Rotated by 45° +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `foo` | My object | +| 1 | `true` | Dragging is enabled | +| 2 | `[0,2,0]` | 0 meters sideways, 2 meters forward, 0 |meters upwards +| 3 | `45` | Rotated by 45° | #### 2.1.2 Example 2 `[bar, false, [3, -2, 2], 20] call ace_dragging_fnc_setDraggable;` - | Arguments | Explanation ----| --------- | ----------- -0 | `bar` | My object -1 | `false` | Dragging is disabled -2 | `[3, -2, 2]` | 3 meters sideways, 2 meters backwards, 2 meters upwards -3 | `20` | Rotated by 20° +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `bar` | My object | +| 1 | `false` | Dragging is disabled | +| 2 | `[3, -2, 2]` | 3 meters sideways, 2 meters backwards, 2 meters upwards | +| 3 | `20` | Rotated by 20° | ### 2.2 Enabling / disabling carrying `ace_dragging_fnc_setCarryable` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Any object | Object | Required -1 | Enable carrying, true to enable, false to disable | Boolean | Required -2 | Position to offset the object from player | Array | Optional (default: `[0, 1, 1]`) -3 | Direction in degree to rotate the object | Number | Optional (default: `0`) -4 | Ignore weight limitation for carrying | Boolean | Optional (default: `false`) -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Any object | Object | Required | +| 1 | Enable carrying, true to enable, false to disable | Boolean | Required | +| 2 | Position to offset the object from player | Array | Optional (default: `[0, 1, 1]`) | +| 3 | Direction in degree to rotate the object | Number | Optional (default: `0`) | +| 4 | Ignore weight limitation for carrying | Boolean | Optional (default: `false`) | +| **R** | None | None | Return value | #### 2.2.1 Example `[foo, true, [0, 3, 1], 10] call ace_dragging_fnc_setCarryable;` - | Arguments | Explanation ----| --------- | ----------- -0 | `foo` | My object -1 | `true`| Carrying is enabled -2 | `[0,2,0]` | 0 meters sideways, 3 meters forward, 1 meter upwards -3 | `10` | Rotated by 10° +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `foo` | My object | +| 1 | `true`| Carrying is enabled | +| 2 | `[0,2,0]` | 0 meters sideways, 3 meters forward, 1 meter upwards | +| 3 | `10` | Rotated by 10° | diff --git a/docs/wiki/framework/events-framework.md b/docs/wiki/framework/events-framework.md index 7244271520..5155cf7593 100644 --- a/docs/wiki/framework/events-framework.md +++ b/docs/wiki/framework/events-framework.md @@ -23,31 +23,34 @@ E.G.: If you only need to do action when player's weapon fires, this will be fas The vehicle events will also have the following local variables available `_gunner (OBJECT), _turret (ARRAY)`. | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_firedPlayer` | [_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | ACE_player fires -|`ace_firedPlayerNonLocal` | [_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | Any other player fires -|`ace_firedNonPlayer` | [_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | AI fires -|`ace_firedPlayerVehicle` | [_vehicle, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | ACE_player turret fires -|`ace_firedPlayerVehicleNonLocal` | [_vehicle, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | Any other player turret fires -|`ace_firedNonPlayerVehicle` | [_vehicle, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | AI turret fires +|----------|---------|---------|---------|---------| +|`ace_firedPlayer` | [_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | ACE_player fires | +|`ace_firedPlayerNonLocal` | [_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | Any other player fires | +|`ace_firedNonPlayer` | [_unit, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | AI fires | +|`ace_firedPlayerVehicle` | [_vehicle, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | ACE_player turret fires | +|`ace_firedPlayerVehicleNonLocal` | [_vehicle, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | Any other player turret fires | +|`ace_firedNonPlayerVehicle` | [_vehicle, _weapon, _muzzle, _mode, _ammo, _magazine, _projectile] | Local | Listen | AI turret fires | +|`ace_versioning_clientCheckDone` | [[_missingAddonsClient, _additionalAddonsClient, _olderVersionsClient, _newerVersionsClient]] | Local | Listen | When PBO checking has finished on a client | +|`ace_versioning_serverCheckDone` | [[_serverFiles, _serverVersions]] | Local | Listen | When PBO checking has finished on the server | ### 2.2 Medical (`ace_medical`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_unconscious` | [_unit, _state(BOOL)] | Global | Listen | Unit's unconscious state changed -|`ace_placedInBodyBag` | [_target, _bodyBag, _isGrave] | Global | Listen | Target placed into a bodybag Note: (Target will soon be deleted, target could be a bodybag) -|`ace_placedInGrave` | [_target, _grave] | Global | Listen | Target placed into a grave, _grave will be objNull if `Create Grave Markers` is disabled Note: (Target will soon be deleted) -|`ace_treatmentStarted` | [_caller, _target, _selectionName, _className, _itemUser, _usedItem] | Local | Listen | Treatment action has started (local on the _caller) -|`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_unconscious` | [_unit, _state(BOOL)] | Global | Listen | Unit's unconscious state changed | +|`ace_placedInBodyBag` | [_target, _bodyBag, _isGrave] | Global | Listen | Target placed into a bodybag Note: (Target will soon be deleted, target could be a bodybag) | +|`ace_placedInGrave` | [_target, _grave] | Global | Listen | Target placed into a grave, _grave will be objNull if `Create Grave Markers` is disabled Note: (Target will soon be deleted) | +|`ace_treatmentStarted` | [_caller, _target, _selectionName, _className, _itemUser, _usedItem, _createLitter] | Local | Listen | Treatment action has started (local on the _caller) | +|`ace_treatmentSucceded` | [_caller, _target, _selectionName, _className, _itemUser, _usedItem, _createLitter] | Local | Listen | Treatment action is completed (local on the _caller) | +|`ace_treatmentFailed` | [_caller, _target, _selectionName, _className, _itemUser, _usedItem, _createLitter] | 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, _itemUser, _usedItem, _createLitter, _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 | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| +|----------|---------|---------|---------|---------| |`ace_interactMenuOpened` | [_menuType] | Local | Listen | Interaction Menu Opened |`ace_interactMenuClosed` | [_menuType] | Local | Listen | Interaction Menu Closed |`ace_interact_menu_newControllableObject` | [_typeOf] | Local | Listen | New controlable object, only fires once per type (add self interactions) @@ -55,78 +58,114 @@ MenuType: 0 = Interaction, 1 = Self Interaction ### 2.4 Cargo (`ace_cargo`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_addCargo` | [_item (CLASSNAME or OBJECT), _vehicle, _cargoCount] | Target | Callable | Scripted way to add cargo to vehicle -|`ace_cargoLoaded` | [_item, _vehicle] | Global | Listen | Cargo has been Loaded into vehicle -|`ace_cargoUnloaded` | [_item, _vehicle, _unloadType] | Global | Listen | Cargo has been Unloaded from vehicle +|----------|---------|---------|---------|---------| +|`ace_addCargo` | [_item (CLASSNAME or OBJECT), _vehicle, _cargoCount] | Target | Callable | Scripted way to add cargo to vehicle | +|`ace_cargoLoaded` | [_item, _vehicle] | Global | Listen | Cargo has been Loaded into vehicle | +|`ace_cargoUnloaded` | [_item, _vehicle, _unloadType] | Global | Listen | Cargo has been Unloaded from vehicle | ### 2.5 Captives (`ace_captives`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_captiveStatusChanged` | [_unit, _state(BOOL), _reason ("SetHandcuffed" or "SetSurrendered"), _caller] | Global | Listen | Unit's captivity state changed -|`ace_captives_setSurrendered` | [_unit, _state(BOOL)] | Target | Callable | Sets a unit to either start or stop surrendering -|`ace_captives_setHandcuffed` | [_unit, _state(BOOL)] | Target | Callable | Sets a unit to either start or stop being handcuffed +|----------|---------|---------|---------|---------| +|`ace_captiveStatusChanged` | [_unit, _state(BOOL), _reason ("SetHandcuffed" or "SetSurrendered"), _caller] | Global | Listen | Unit's captivity state changed | +|`ace_captives_setSurrendered` | [_unit, _state(BOOL)] | Target | Callable | Sets a unit to either start or stop surrendering | +|`ace_captives_setHandcuffed` | [_unit, _state(BOOL)] | Target | Callable | Sets a unit to either start or stop being handcuffed | +|`ace_captives_escortingCaptive` | [_unit, _state(BOOL), _caller] | Local | Listen | Caller starting or stopping escort of unit | ### 2.6 Settings (`ace_common`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_settingsInitialized` | [] | Local | Listen | All modules are read and settings are ready -|`ace_settingChanged` | [_name,_value] | Local | Listen | A setting has been changed +|----------|---------|---------|---------|---------| +|`ace_settingsInitialized` | [] | Local | Listen | All modules are read and settings are ready | +|`ace_settingChanged` | [_name,_value] | Local | Listen | A setting has been changed | ### 2.7 Tagging (`ace_tagging`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_tagCreated` | [_tagObject, _texture, _tagAttachedTo (can be null), _unitThatCreated] | Global | Listen | Tag is created +|----------|---------|---------|---------|---------| +|`ace_tagCreated` | [_tagObject, _texture, _tagAttachedTo (can be null), _unitThatCreated] | Global | Listen | Tag is created | ### 2.8 Explosives (`ace_explosives`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_allowDefuse` | [_mine, _allow] | Global or Target | Callable | Set allowance of the dynamic defusal action on a mine -|`ace_tripflareTriggered` | [_flareObject, [_posX, _posY, _posZ]] | Global | Listen | Tripflare triggered -|`ace_explosives_clackerAdded` | [_unit, _explosive, _id] | Local | Listen | Clacker added to explosive -|`ace_explosives_place` | [_explosive, _dir, _pitch, _unit] | Global | Listen | Explosive is armed -|`ace_explosives_setup` | [_explosiveVehicle, _magClassname, _unit] | Global | Listen | Explosive is placed in the world +|----------|---------|---------|---------|---------| +|`ace_allowDefuse` | [_mine, _allow] | Global or Target | Callable | Set allowance of the dynamic defusal action on a mine | +|`ace_tripflareTriggered` | [_flareObject, [_posX, _posY, _posZ]] | Global | Listen | Tripflare triggered | +|`ace_explosives_clackerAdded` | [_unit, _explosive, _id] | Local | Listen | Clacker added to explosive | +|`ace_explosives_place` | [_explosive, _dir, _pitch, _unit] | Global | Listen | Explosive is armed | +|`ace_explosives_setup` | [_explosiveVehicle, _magClassname, _unit] | Global | Listen | Explosive is placed in the world | ### 2.9 Logistics Wirecutter (`ace_logistics`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_wireCuttingStarted` | [_unit, _fence] | Global | Listen | Fence cutting started +|----------|---------|---------|---------|---------| +|`ace_wireCuttingStarted` | [_unit, _fence] | Global | Listen | Fence cutting started | ### 2.9 Refuel (`ace_refuel`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_refuel_started` | [_source, _target] | Local | Listen | Refueling has started -|`ace_refuel_tick` | [_source, _target, _amount] | Local | Listen | Amount of fuel transferred in a tick -|`ace_refuel_stopped` | [_source, _target] | Local | Listen | Refueling has stopped +|----------|---------|---------|---------|---------| +|`ace_refuel_started` | [_source, _target] | Local | Listen | Refuelling has started | +|`ace_refuel_tick` | [_source, _target, _amount] | Local | Listen | Amount of fuel transferred in a tick | +|`ace_refuel_stopped` | [_source, _target] | Local | Listen | Refuelling has stopped | ### 2.10 Cook Off (`ace_cookoff`) | Event Key | Parameters | Locality | Type | Description | |----------|---------|---------|---------|---------|---------| -|`ace_cookoff_cookOff` | _vehicle | Global | Listen | Vehicle cook off has started -|`ace_cookoff_cookOffBox` | _box | Global | Listen | Ammo box cook off has started -|`ace_cookoff_engineFire` | _vehicle | Global | Listen | Engine fire has started - +|`ace_cookoff_cookOff` | [_vehicle, _intensity, _instigator, _smokeDelayEnabled, _ammoDetonationChance, _detonateAfterCookoff, _fireSource, _canRing, _maxIntensity, _canJet] | Global | Listen | Vehicle cook-off has started | +|`ace_cookoff_cookOffBox` | [_box, _source, _instigator, _delay] | Global | Listen | Ammo box cook-off has started | +|`ace_cookoff_engineFire` | [_vehicle] | Global | Listen | Engine fire has started | ### 2.11 Attach (`ace_attach`) | Event Key | Parameters | Locality | Type | Description | -|----------|---------|---------|---------|---------|---------| -|`ace_attach_attached` | [_attachedObject, _itemClassname, _temporary] | Local | Listen | After an item was attached to a unit/vehicle. _temporary flag means a item is being re-attached after the player exits a vehicle -|`ace_attach_detaching` | [_attachedObject, _itemName, _temporary] | Local | Listen | Just before an item gets detached/removed from a unit/vehicle. _temporary flag means its detached because the player unit entered a vehicle. +|----------|---------|---------|---------|---------| +|`ace_attach_attached` | [_attachedObject, _itemClassname, _temporary] | Local | Listen | After an item was attached to a unit/vehicle. _temporary flag means a item is being re-attached after the player exits a vehicle | +|`ace_attach_detaching` | [_attachedObject, _itemName, _temporary] | Local | Listen | Just before an item gets detached/removed from a unit/vehicle. _temporary flag means its detached because the player unit entered a vehicle. | ### 2.12 Trenches (`ace_trenches`) | Event Key | Parameters | Locality | Type | Description | |---------- |------------|----------|------|-------------| -| `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). +| `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 + +### 2.15 Medical Status (`ace_medical_status`) + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_medical_status_getBloodLoss` | [_unit, _bloodLoss] | Local | Listen | Called when blood loss is calculated for a unit, mods can listen and modify the blood loss value by modifying the array + +### 2.16 Interaction (`ace_interaction`) + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_interaction_doorOpeningStarted` | [_house, _door, _animations] | Local | Listen | Called when local unit starts interacting with doors +| `ace_interaction_doorOpeningStopped` | [_house, _door, _animations] | Local | Listen | Called when local unit stops interacting with doors + +### 2.17 Headless (`ace_headless`) + +| Event Key | Parameters | Locality | Type | Description | +|---------- |------------|----------|------|-------------| +| `ace_headless_groupTransferPre` | [_group, _HC (OBJECT), _previousOwner, _idHC] | Target | Listen | Called just before a group is transferred from any machine to a HC. Called where group currently is local and on the HC, where group is going to be local. +| `ace_headless_groupTransferPost` | [_group, _HC (OBJECT), _previousOwner, _idHC, _transferredSuccessfully] | Target | Listen | Called just after a group is transferred from a machine to a HC. Called where group was local and on the HC, where group is now local. `_transferredSuccessfully` is passed so mods can actually check if the locality was properly transferred, as ownership transfer is not guaranteed. ## 3. Usage Also Reference [CBA Events System](https://github.com/CBATeam/CBA_A3/wiki/Custom-Events-System){:target="_blank"} documentation. @@ -137,21 +176,21 @@ Also Reference [CBA Events System](https://github.com/CBATeam/CBA_A3/wiki/Custom `CBA_fnc_addEventHandler` - Adds an event handler with the event name and returns the event handler ID. - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Event name | String | Required -1 | Code block | Code | Required -**R** | Event ID | Number | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Event name | String | Required | +| 1 | Code block | Code | Required | +| **R** | Event ID | Number | Return value | #### 3.1.2 Remove Event `CBA_fnc_removeEventHandler` - Removes a specific event handler of the given event name, using the ID returned from `CBA_fnc_addEventHandler`. - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Event name | String | Required -1 | Event ID | Number | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Event name | String | Required | +| 1 | Event ID | Number | Required | +| **R** | None | None | Return value | ### 3.2 Calling Events @@ -159,42 +198,42 @@ Also Reference [CBA Events System](https://github.com/CBATeam/CBA_A3/wiki/Custom `CBA_fnc_localEvent` - Calls an event only on the local machine, useful for inter-module events. - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Event name | String | Required -1 | Arguments | Any | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Event name | String | Required | +| 1 | Arguments | Any | Required | +| **R** | None | None | Return value | #### 3.2.2 Target Event `CBA_fnc_targetEvent` - Calls an event only on the target machine or list of target machines. - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Event name | String | Required -1 | Arguments | Any | Required -2 | Target(s) | Object OR Number OR Array | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Event name | String | Required | +| 1 | Arguments | Any | Required | +| 2 | Target(s) | Object OR Number OR Array | Required | +| **R** | None | None | Return value | #### 3.2.3 Server Event `CBA_fnc_serverEvent` - Calls an event only on the server machine (dedicated or self-hosted). - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Event name | String | Required -1 | Arguments | Any | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Event name | String | Required | +| 1 | Arguments | Any | Required | +| **R** | None | None | Return value | #### 3.2.4 Global Event `CBA_fnc_globalEvent` - Calls an event on all machines - the local machine, and the server machine. - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Event name | String | Required -1 | Arguments | Any | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Event name | String | Required | +| 1 | Arguments | Any | Required | +| **R** | None | None | Return value | ### 3.3 Synchronized Events @@ -205,12 +244,12 @@ Adds a globally synchronized event handler which will expire events after the pr `ace_common_fnc_addSyncedEventHandler` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Event name | String | Required -1 | Code block | Code | Required -2 | Time to live | Number OR Code | Optional (default: `0`) -**R** | Event ID | Number | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Event name | String | Required | +| 1 | Code block | Code | Required | +| 2 | Time to live | Number OR Code | Optional (default: `0`) | +| **R** | Event ID | Number | Return value | #### 3.3.2 Remove Synchronized Event @@ -218,10 +257,10 @@ Removes a specific event handler of the given event name, using the ID returned `ace_common_fnc_removeSyncedEventHandler` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Event name | String | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Event name | String | Required | +| **R** | None | None | Return value | #### 3.3.3 Call Synchronized Event @@ -229,12 +268,12 @@ Calls a globally synchronized event, which will also be run on JIP players unles `ace_common_fnc_syncedEvent` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Event name | String | Required -1 | Arguments | Any | Required -2 | Time to live for this call | Number OR Code | Optional (default: `0`) -**R** | Event ID | Number | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Event name | String | Required | +| 1 | Arguments | Any | Required | +| 2 | Time to live for this call | Number OR Code | Optional (default: `0`) | +| **R** | Event ID | Number | Return value | ### 3.4 Example diff --git a/docs/wiki/framework/explosives-framework.md b/docs/wiki/framework/explosives-framework.md index 9d943e3eee..8abffa9448 100644 --- a/docs/wiki/framework/explosives-framework.md +++ b/docs/wiki/framework/explosives-framework.md @@ -120,16 +120,16 @@ class CfgWeapons { ## 4. Trigger list -Name | Use ----- | ----- -`Command` | Explode when activated via clacker. -`MK16_Transmitter` | Explode when activated via M26 clacker. -`DeadManSwitch` | Explode after activated via the switch or the person dies. -`Cellphone` | Explode when the number is called. -`PressurePlate` | Explode upon being stepped upon. -`IRSensor` | Explode after movement is detected in front of the mine. -`Timer` | Explode after timer drop to 0. -`Tripwire` | Explode when something touch the tripwire. +| Name | Use | +| ---- | ----- | +| `Command` | Explode when activated via clacker. | +| `MK16_Transmitter` | Explode when activated via M26 clacker. | +| `DeadManSwitch` | Explode after activated via the switch or the person dies. | +| `Cellphone` | Explode when the number is called. | +| `PressurePlate` | Explode upon being stepped upon. | +| `IRSensor` | Explode after movement is detected in front of the mine. | +| `Timer` | Explode after timer drop to 0. | +| `Tripwire` | Explode when something touch the tripwire. | ## 5. Scripting @@ -138,41 +138,41 @@ Name | Use `ace_explosives_fnc_scriptedExplosive` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Explosive objects | Array | Required -1 | Delay before detonation | Number | Optional (default: `0`, randomized up to given number if negative) -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Explosive objects | Array | Required | +| 1 | Delay before detonation | Number | Optional (default: `0`, randomized up to given number if negative) | +| **R** | None | None | Return value | #### 5.1.1 Example `[[charge1, charge2], -3] call ace_explosives_fnc_scriptedExplosive;` - | Arguments | Explanation ----| --------- | ----------- -0 | `[charge1, charge2]` | Explosive objects to detonate -1 | `-3` | Randomized delay, up to 3 seconds +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `[charge1, charge2]` | Explosive objects to detonate | +| 1 | `-3` | Randomized delay, up to 3 seconds | ### 5.2 Connect Explosive `ace_explosives_fnc_connectExplosive` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Unit to connect to | Object | Required -1 | Explosive object to connect to | Object | Required -2 | Detonator type class name (must be present on unit) | String | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Unit to connect to | Object | Required | +| 1 | Explosive object to connect to | Object | Required | +| 2 | Detonator type class name (must be present on unit) | String | Required | +| **R** | None | None | Return value | #### 5.2.1 Example `[player, claymore1, "ACE_Clacker"] call ace_explosives_fnc_connectExplosive;` - | Arguments | Explanation ----| --------- | ----------- -0 | `player` | Unit explosive will connect to -1 | `claymore1` | Explosive object that will be connected -2 | `"ACE_Clacker"` | Detonator type class name +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `player` | Unit explosive will connect to | +| 1 | `claymore1` | Explosive object that will be connected | +| 2 | `"ACE_Clacker"` | Detonator type class name | #### 5.3 Detonation Handler. @@ -207,7 +207,7 @@ Jammer that blocks RF triggers: #### 5.4 Disabling `setShotParents`. -ACE will set the owner/instigator of the explosive to the unit placeing/detonating it. +ACE will set the owner/instigator of the explosive to the unit placing/detonating it. This can be disabled by executing ```sqf diff --git a/docs/wiki/framework/fastroping-framework.md b/docs/wiki/framework/fastroping-framework.md index fad016a8bf..57c6b9055d 100644 --- a/docs/wiki/framework/fastroping-framework.md +++ b/docs/wiki/framework/fastroping-framework.md @@ -18,7 +18,7 @@ If you want to prepare a helicopter from your addon for fastroping, there's a fe By using simple rope origin points you will only need two config entries: -``` +```cpp ace_fastroping_enabled = 1; ace_fastroping_ropeOrigins[] = { {x, y, z}, @@ -28,7 +28,7 @@ ace_fastroping_ropeOrigins[] = { This will create the ropes at the two given points. If you have defined memory points for the rope origins, you can use them too: -``` +```cpp ace_fastroping_enabled = 1; ace_fastroping_ropeOrigins[] = {"ropeOriginLeft", "ropeOriginRight"}; ``` @@ -41,7 +41,7 @@ If your helicopter is not fastroping capable by default, you can make it take a To make your helicopter FRIES capable, you need to add the following config entries: -``` +```cpp ace_fastroping_enabled = 2; ace_fastroping_friesType = "yourFRIESType"; ace_fastroping_friesAttachmentPoint[] = {x, y, z}; @@ -87,16 +87,16 @@ ACE3 provides two functions that are compatible with most helicopters and all AC `ace_fastroping_fnc_equipFRIES` -| | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Helicopter | Object | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Helicopter | Object | Required | +| **R** | None | None | Return value | ### 4.2. Remove FRIES from helicopter `ace_fastroping_fnc_unequipFRIES` -| | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Helicopter | Object | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Helicopter | Object | Required | +| **R** | None | None | Return value | diff --git a/docs/wiki/framework/field-rations-framework.md b/docs/wiki/framework/field-rations-framework.md index bc433e7d52..34b8b8fbcd 100644 --- a/docs/wiki/framework/field-rations-framework.md +++ b/docs/wiki/framework/field-rations-framework.md @@ -16,19 +16,19 @@ redirect_from: "/wiki/frameworkx/field-rations-framework.html" ### 1.1 Consumable Items -Config Name | Type | Description ------------ | ---- | ----------- -`acex_field_rations_thirstQuenched` | Number | Amount of thirst quenched when item is consumed* -`acex_field_rations_hungerSatiated` | Number | Amount of hunger satiated when item is consumed* -`acex_field_rations_consumeTime` | Number | Time required to consume the item (in seconds) -`acex_field_rations_consumeText` | String | Progress bar text (OPTIONAL) -`acex_field_rations_consumeAnims` | Array | Animations to play when consuming item** (OPTIONAL) -`acex_field_rations_consumeSounds` | Array | Sounds to play when consuming item** (OPTIONAL) -`acex_field_rations_replacementItem` | String | Class name of replacement item to add on consumption (OPTIONAL) -`acex_field_rations_refillItem` | String | Makes an item refillable, class name of item added when refilled (OPTIONAL) -`acex_field_rations_refillAmount` | Number | Amount of water required to refill item (OPTIONAL) -`acex_field_rations_refillTime` | Number | Time required to refill item (in seconds) (OPTIONAL) -`ACE_isFieldRationItem` | Number | Force adds the item to the ACE Field Rations category in ACE Arsenal (OPTIONAL) +| Config Name | Type | Description | +| ----------- | ---- | ----------- | +| `acex_field_rations_thirstQuenched` | Number | Amount of thirst quenched when item is consumed* | +| `acex_field_rations_hungerSatiated` | Number | Amount of hunger satiated when item is consumed* | +| `acex_field_rations_consumeTime` | Number | Time required to consume the item (in seconds) | +| `acex_field_rations_consumeText` | String | Progress bar text (OPTIONAL) | +| `acex_field_rations_consumeAnims` | Array | Animations to play when consuming item** (OPTIONAL) | +| `acex_field_rations_consumeSounds` | Array | Sounds to play when consuming item** (OPTIONAL) | +| `acex_field_rations_replacementItem` | String | Class name of replacement item to add on consumption (OPTIONAL) | +| `acex_field_rations_refillItem` | String | Makes an item refillable, class name of item added when refilled (OPTIONAL) | +| `acex_field_rations_refillAmount` | Number | Amount of water required to refill item (OPTIONAL) | +| `acex_field_rations_refillTime` | Number | Time required to refill item (in seconds) (OPTIONAL) | +| `ACE_isFieldRationItem` | Number | Force adds the item to the ACE Field Rations category in ACE Arsenal (OPTIONAL) | _* Value range is 0 to 100 and can be modified by the corresponding coefficient setting._ @@ -37,17 +37,17 @@ _** Array is in format: STAND, CROUCH, PRONE. If player is in vehicle, the first ### 1.2 Water Sources -Config Name | Type | Description ------------ | ---- | ----------- -`acex_field_rations_waterSupply` | Number | Amount of water inside the object (-1 - disabled, -10 - infinite) (OPTIONAL) -`acex_field_rations_offset` | Array | Refill action offset relative to model (OPTIONAL) +| Config Name | Type | Description | +| ----------- | ---- | ----------- | +| `acex_field_rations_waterSupply` | Number | Amount of water inside the object (-1 - disabled, -10 - infinite) (OPTIONAL) | +| `acex_field_rations_offset` | Array | Refill action offset relative to model (OPTIONAL) | ## 2. Events -Event Name | Passed Parameter(s) | Locality | Description ----------- | ------------------- | -------- | ----------- -`acex_rationConsumed` | [_player, _consumeItem, _replacementItem, _thirstQuenched, _hungerSatiated, _isMagazine] | Local | Item consumed -`acex_rationRefilled` | [_source, _player, _item, _refillItem, _refillAmount, _isMagazine] | Local | Item refilled +| Event Name | Passed Parameter(s) | Locality | Description | +| ---------- | ------------------- | -------- | ----------- | +| `acex_rationConsumed` | [_player, _consumeItem, _replacementItem, _thirstQuenched, _hungerSatiated, _isMagazine] | Local | Item consumed | +| `acex_rationRefilled` | [_source, _player, _item, _refillItem, _refillAmount, _isMagazine] | Local | Item refilled | ## 3. Scripting diff --git a/docs/wiki/framework/fire-framework.md b/docs/wiki/framework/fire-framework.md index 2236c5a1c8..147710384c 100644 --- a/docs/wiki/framework/fire-framework.md +++ b/docs/wiki/framework/fire-framework.md @@ -21,19 +21,27 @@ Use `CBA_fnc_serverEvent` to use the following features. Events are defined only `ace_fire_addFireSource` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Source of flame | Object/Position ASL | Required -1 | Radius of fire | Number | Required -2 | Intensity of fire (1, 10] | Number | Required -3 | Fire source ID | Any | Required -4 | Condition to stop fire | Code | Optional (default: `{ true }`) -5 | Arguments to pass to condition | Any | Optional (default: `[]`) +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Source of flame | Object/Position ASL | Required | +| 1 | Radius of fire | Number | Required | +| 2 | Intensity of fire (1, 10] | Number | Required | +| 3 | Fire source ID | Array/Boolean/Code/Config/Group/Namespace/NaN/Number/Object/Side/String | Required | +| 4 | Condition to stop fire | Code | Optional (default: `{true}`) | +| 5 | Arguments to pass to condition | Any | Optional (default: `[]`) | ### 1.2 Removing fire source `ace_fire_removeFireSource` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Fire source ID | Any | Required +| | 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..9de0fab35b 100644 --- a/docs/wiki/framework/fortify-framework.md +++ b/docs/wiki/framework/fortify-framework.md @@ -114,10 +114,11 @@ The Fortify budget can be updated for any side using the function. ### 2.1 Listenable -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_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 +| Event Name | Passed Parameter(s) | Locality | Description | +| ---------- | ----------- | ------------------- | -------- | +| `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_onDeployStop` | [player, object, cost] | Local | Player stops placing object. Raised only if stopped before trying to place (= before progress bar appears). If it's during progress bar, only `ace_fortify_deployCanceled` is raised. | +| `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/frag-framework.md b/docs/wiki/framework/frag-framework.md index 07c59764f5..d05f5068f6 100644 --- a/docs/wiki/framework/frag-framework.md +++ b/docs/wiki/framework/frag-framework.md @@ -60,22 +60,22 @@ Dimensionless value, as long as same unit as `ace_frag_metal` (for example `kg/k Gurney constant for explosive force. You can find a list of common explosive types below. If you can not find it here, or want more accurate numbers, just google the type of explosive and Gurney constant and you can find substantial information. This is **not** the detonation velocity of the explosive, do not confuse them! -Type | Speed ---------------- | -------- -Composition B | 2700 m/s -Composition C-3 | 2680 m/s -Cyclotol 75/25 | 2790 m/s -HMX | 2800 m/s -LX-14 | 2970 m/s -Octol 75/25 | 2800 m/s -PBX 9404 | 2900 m/s -PBX 9502 | 2377 m/s -Pentolite | 2750 m/s -PETN | 2930 m/s -RDX | 2830 m/s -Tetryl | 2500 m/s -TNT | 2440 m/s -Tritonal | 2320 m/s +| Type | Speed | +| --------------- | -------- | +| Composition B | 2700 m/s | +| Composition C-3 | 2680 m/s | +| Cyclotol 75/25 | 2790 m/s | +| HMX | 2800 m/s | +| LX-14 | 2970 m/s | +| Octol 75/25 | 2800 m/s | +| PBX 9404 | 2900 m/s | +| PBX 9502 | 2377 m/s | +| Pentolite | 2750 m/s | +| PETN | 2930 m/s | +| RDX | 2830 m/s | +| Tetryl | 2500 m/s | +| TNT | 2440 m/s | +| Tritonal | 2320 m/s | ### 1.4 Gurney shape factor @@ -83,11 +83,11 @@ Tritonal | 2320 m/s Shape factor for the explosive configuration. You should choose it based on the general configuration of explosives/metal in the warhead. Most grenades for example are a sphere. Artillery and aircraft bombs are a cylinder. Mines generally a flat plate. Below is a list of the three common shapes and their factors. -Shape | Factor --------- | ------ -Sphere | 3/5 -Cylinder | 1/2 -Plate | 3/5 +| Shape | Factor | +| -------- | ------ | +| Sphere | 3/5 | +| Cylinder | 1/2 | +| Plate | 3/5 | There are other configurations but these are the most common. If you are interested in others check out the wikipedia link given above. Most of these will not correctly function in ACE3 though due to additional variables for the equation. @@ -97,18 +97,18 @@ There are other configurations but these are the most common. If you are interes There are different types of fragmentation fragments to choose from, and they can be defined in this config value. -| Type -| ---- -| ACE_frag_tiny -| ACE_frag_tiny_HD -| ACE_frag_small -| ACE_frag_small_HD -| ACE_frag_medium -| ACE_frag_medium_HD -| ACE_frag_large -| ACE_frag_large_HD -| ACE_frag_huge -| ACE_frag_huge_HD +| Type | +| ------------------ | +| ACE_frag_tiny | +| ACE_frag_tiny_HD | +| ACE_frag_small | +| ACE_frag_small_HD | +| ACE_frag_medium | +| ACE_frag_medium_HD | +| ACE_frag_large | +| ACE_frag_large_HD | +| ACE_frag_huge | +| ACE_frag_huge_HD | The tinier the piece of fragmentation the shorter the distance of travel. The `_HD` variants are all even higher drag versions. Grenades generally should use the `_HD` variants. Experimentation here is important. diff --git a/docs/wiki/framework/goggles-framework.md b/docs/wiki/framework/goggles-framework.md index 1b9b27588b..07840ebf95 100644 --- a/docs/wiki/framework/goggles-framework.md +++ b/docs/wiki/framework/goggles-framework.md @@ -34,7 +34,7 @@ class CfgGlasses { ### 2.1 Listenable -Event Name | Description | Passed Parameter(s) | Locality ----------- | ----------- | ------------------- | -------- -`ace_glassesChanged` | Glasses Changed | `[_unit, _glassesClass]` | Local -`ace_glassesCracked` | Glasses Cracked | `[_unit]` | Local +| Event Name | Description | Passed Parameter(s) | Locality | +| ---------- | ----------- | ------------------- | -------- | +| `ace_glassesChanged` | Glasses Changed | `[_unit, _glassesClass]` | Local | +| `ace_glassesCracked` | Glasses Cracked | `[_unit]` | Local | diff --git a/docs/wiki/framework/grenades-framework.md b/docs/wiki/framework/grenades-framework.md index a0b0ceeea7..755773c171 100644 --- a/docs/wiki/framework/grenades-framework.md +++ b/docs/wiki/framework/grenades-framework.md @@ -1,7 +1,7 @@ --- layout: wiki title: Grenades Framework -description: Explains how to set-up flashbangs, particularly multi-bangs. +description: Explains how to set-up incendiary, flares and flashbangs, particularly multi-bangs. group: framework parent: wiki order: 7 @@ -14,11 +14,12 @@ version: ## 1. Overview -ACE provides a simple interface for creating flashbang grenades and specifying their properties. It is important that one sets `timeToLive` to be greater than the total possible time until the last explosion, i.e, `ace_grenades_flashbangBangs * ace_grenades_flashbangInterval + ace_grenades_flashbangIntervalMaxDeviation`. Any explosions that occur after the `timeToLive` has expired will occur at `(0,0)`. +ACE provides a simple interface for creating incendiary, flare and flashbang grenades, as well as specifying their properties. For flashbangs, it is important that one sets `timeToLive` to be greater than the total possible time until the last explosion, i.e, `ace_grenades_flashbangBangs * ace_grenades_flashbangInterval + ace_grenades_flashbangIntervalMaxDeviation`. Any explosions that occur after the `timeToLive` has expired will occur at `(0,0)`. ## 2. Config Values +### 2.1 Flashbang Config Values There are several config entries specific to ACE flashbangs. All successive values can be left undefined and they will be given the defaults shown in the first example below, with the exception of `ace_grenades_flashbang`, which is equal to `0` if left undefined. ```cpp @@ -49,22 +50,80 @@ class CfgAmmo { ace_grenades_flashbangBangs = 6; // 6 bangs ace_grenades_flashbangInterval = 0.25; // 0.25 seconds between each subsequent bang ace_grenades_flashbangIntervalMaxDeviation = 0.05; // Deviation of up to ± 0.05 seconds on each fuse + ace_grenades_flashbangExplodeSound[] = { // Sound that is played upon detonation + {"A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_01.wss", 5, 1.2, 400}, // file path, volume, pitch, max distance + {"A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_02.wss", 5, 1.2, 400} + }; }; }; ``` -### 2.1 ace_grenades_flashbang +#### 2.1.1 ace_grenades_flashbang If set to zero or left undefined, the grenade is not treated as a flashbang. If it is set to 1, the grenade will be treated as a flashbang with the associated effects. -### 2.2 ace_grenades_flashbangBangs +#### 2.1.2 ace_grenades_flashbangBangs The flashbang will explode as many times as is specified. The default is 1. -### 2.3 ace_grenades_flashbangInterval +#### 2.1.3 ace_grenades_flashbangInterval The average amount of time in seconds, after `explosionTime` has passed, between each subsequent bang. -### 2.4 ace_grenades_flashbangIntervalMaxDeviation +#### 2.1.4 ace_grenades_flashbangIntervalMaxDeviation The amount of randomness in the fuse time. + +### 2.1.5 ace_grenades_flashbangExplodeSound + +The sounds that can be used when the flashbang detonates. It randomly selects an entry from this array (equal chances, there are no weights involved). +If not defined, `[format ["A3\Sounds_F\arsenal\explosives\grenades\Explosion_HE_grenade_0%1.wss", floor (random 4) + 1], 5, 1.2, 400]` is used as a default instead (4 sounds total). + +### 2.2 Incendiary Config Values + +```cpp +class CfgAmmo { + class ACE_G_M14 { + ace_grenades_incendiary = 1; + }; +}; +``` + +#### 2.2.1 ace_grenades_incendiary + +If set to zero or left undefined, the grenade is not treated as an incendiary. If it is set to 1, the grenade will be treated as an incendiary with the associated effects. + +### 2.3 Flare Config Values + +```cpp +class CfgAmmo { + class ACE_G_Handflare_White { + ace_grenades_flare = 1; + ace_grenades_color[] = {0.5,0.5,0.5,0.5}; // R, G, B, light intensity + }; +}; +``` + +#### 2.3.1 ace_grenades_flare + +If set to zero or left undefined, the grenade is not treated as a flare. If it is set to 1, the grenade will be treated as a flare with the associated effects. + +#### 2.3.1 ace_grenades_color + +Sets the color of the emitted light. The first 3 values of the array of the color, the last is the light intensity. + +### 2.4 Grenade Rolling + +#### 2.4.1 ace_grenades_rollVectorDirAndUp + +Sets the `setVectorDirAndUp` of the grenade when the grenade is rolled. + +## 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/headless-framework.md b/docs/wiki/framework/headless-framework.md index 6dbc83c512..7a2a5a0822 100644 --- a/docs/wiki/framework/headless-framework.md +++ b/docs/wiki/framework/headless-framework.md @@ -30,14 +30,29 @@ As of ACEX v3.2.0 _(before merge into ACE3)_ this feature can also be enabled wi ## 2. Scripting -### 2.1 Disable Transferring for a Group +### 2.1 Manipulating HC Transfers of Groups via function -To prevent a group from transferring to a Headless Client use the following line on a group leader (or every unit in a group in case group leader may not spawn): +`ace_headless_fnc_blacklist` + + | Arguments | Type | Optional (default value) +---| --------- | ---- | ------------------------ +0 | Units | Object, Group or Array of both | Required +1 | Add (true) or remove (false) from blacklist | Bool | Optional (default: `true`) +2 | Owner to transfer units to | Number | Optional (default: `-1`) +3 | Rebalance (0 = no rebalance, 1 = rebalance, 2 = force rebalance) | Number | (default: `0`) +**R** | None | None | Return value + +`Force rebalance` means that all units, including the ones that are on the HCs, are rebalanced amongst the HCs, whereas `rebalance` means that newly spawned units are going to be evenly distributed amongst HCs. Therefore, `rebalance` does not guarantee that the HCs will have an equal amount of groups, whereas `force rebalance` does. + +### 2.2 Disable Transferring for a Group via variable + +To prevent a group from transferring to a Headless Client use the following line on a unit within a group: ```sqf this setVariable ["acex_headless_blacklist", true]; ``` +This variable can also be set on vehicles, disabling transferal of any groups having units in said vehicles. ## 3. Limitations @@ -48,3 +63,7 @@ Some Arma 3 features are incompatible, this is up to BI to add support. Disable Additionally, groups will not be transferred due to lack of support if they: - Have waypoints with synchronized triggers (waypoint would not change status based on trigger condition) (added in ACEX v3.2.0 - _before merge into ACE3_) + +Groups will not be transferred to avoid issues: +- If a player is within the group. +- If they contain UAVs. diff --git a/docs/wiki/framework/hitreactions-framework.md b/docs/wiki/framework/hitreactions-framework.md new file mode 100644 index 0000000000..ca3ff93f5b --- /dev/null +++ b/docs/wiki/framework/hitreactions-framework.md @@ -0,0 +1,32 @@ +--- +layout: wiki +title: Hit Reactions Framework +description: Explains how to set-up weapons with ACE3 hit reactions system. +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 18 + patch: 0 +--- + +## 1. Config Values + +```cpp +class CfgWeapons { + class MyWeapon { + ace_hitreactions_undroppable = 1; // Prevents weapon from being dropped + }; +}; +``` + +## 2. Mission Variables + +### 2.1 Safe pickup distance for AI + +Allows 3rd party mods to set the distance between AI and the nearest hostile that is considered safe to go pickup a dropped weapon. +```sqf +ace_hitreactions_safePickupDistance = 10; // default is 8 +``` diff --git a/docs/wiki/framework/interactionMenu-framework.md b/docs/wiki/framework/interactionMenu-framework.md index 68e49414e2..fb66fb3918 100644 --- a/docs/wiki/framework/interactionMenu-framework.md +++ b/docs/wiki/framework/interactionMenu-framework.md @@ -40,21 +40,25 @@ class CfgVehicles { exceptions[] = {}; statement = "_player switchMove 'TestDance'"; icon = "\z\dance.paa"; + }; + }; + }; +}; ``` -Config Name | Type | Description ----------- | ----------- | ------------------- -`displayName` | String | Text shown to user -`condition` | String (of code) | Condition to show the action -`statement` | String (of code) | Statement run when selected -`icon` | String (file path) | Icon shown (OPTIONAL) -`exceptions` | Array (of strings) | Exceptions to `canInteractWith` conditions (e.g. `"notOnMap"`) (OPTIONAL) -`insertChildren` | String (of code) | Code to return sub actions (OPTIONAL) -`modifierFunction` | String (of code) | Code to modify this action (OPTIONAL) -`runOnHover` | Number or String | (1=true) OR Condition code - Will run the statement on hover (OPTIONAL) -`distance` | Number | External Base Actions Only, Max distance player can be from action point -`position` | String (of code) | External Base Actions Only, Code to return a position in model cords (priority over `selection`) -`selection` | String | External Base Actions Only, A memory point for `selectionPosition` +| Config Name | Type | Description | +| ---------- | ----------- | ------------------- | +| `displayName` | String | Text shown to user | +| `condition` | String (of code) | Condition to show the action | +| `statement` | String (of code) | Statement run when selected | +| `icon` | String (file path) | Icon shown (OPTIONAL) | +| `exceptions` | Array (of strings) | Exceptions to `canInteractWith` conditions (e.g. `"notOnMap"`) (OPTIONAL) | +| `insertChildren` | String (of code) | Code to return sub actions (OPTIONAL) | +| `modifierFunction` | String (of code) | Code to modify this action (OPTIONAL) | +| `runOnHover` | Number or String | (1=true) OR Condition code - Will run the statement on hover (OPTIONAL) | +| `distance` | Number | External Base Actions Only, Max distance player can be from action point | +| `position` | String (of code) | External Base Actions Only, Code to return a position in model cords (priority over `selection`) | +| `selection` | String | External Base Actions Only, A memory point for `selectionPosition` | Actions can be inserted anywhere on the config tree, e.g. hearing's earplugs is a sub action of `ACE_Equipment`: @@ -62,7 +66,10 @@ Actions can be inserted anywhere on the config tree, e.g. hearing's earplugs is class CAManBase: Man { class ACE_SelfActions { class ACE_Equipment { - class ACE_PutInEarplugs { + class ACE_PutInEarplugs {}; + }; + }; +}; ``` ## 3. Adding actions via scripts @@ -233,7 +240,7 @@ This is the ideal way to add self interaction actions, as adding them via `addAc params ["_type"]; // string of the object's classname if (!(_type isKindOf "Car")) exitWith {}; if ((getNumber (configFile >> "CfgVehicles" >> _type >> "side")) != 3) exitWith {}; - + private _action = ["playRadio","Play Radio","",{playMusic "NeverGonnaGiveYouUp"},{true}] call ace_interact_menu_fnc_createAction; [_type, 1, ["ACE_SelfActions"], _action, true] call ace_interact_menu_fnc_addActionToClass; }] call CBA_fnc_addEventHandler; diff --git a/docs/wiki/framework/laser-framework.md b/docs/wiki/framework/laser-framework.md new file mode 100644 index 0000000000..fef12a4760 --- /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/docs/wiki/framework/medical-framework.md b/docs/wiki/framework/medical-framework.md index 834eeced80..c0e94b5f9e 100644 --- a/docs/wiki/framework/medical-framework.md +++ b/docs/wiki/framework/medical-framework.md @@ -219,25 +219,32 @@ Custom wound handlers should follow the same spec as the built-in handler: `ace_medical_damage_fnc_woundsHandlerBase` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Unit that was hit | Object | Required -1 | Array of damage dealt to each body part | Array | Required -2 | Type of damage | String | Required -**R** | Parameters to be passed to the next handler in the list, e.g. `_this` or a modified copy of it. Return `[]` to prevent further handling. | Array | Required +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Unit that was hit | Object | Required | +| 1 | Array of damage dealt to each body part | Array | Required | +| 2 | Type of damage | String | Required | +| **R** | Parameters to be passed to the next handler in the list, e.g. `_this` or a modified copy of it. Return `[]` to prevent further handling. | Array | Required | The damage elements are sorted in descending order according to how much damage was dealt to each body part _before armor was taken into account_, but the actual damage values are _after armor_. ### Example `[player, [[0.5, "Body", 1], [0.3, "Head", 0.6]], "grenade"] ace_medical_damage_fnc_woundsHandlerBase` - | Arguments | Explanation ----| --------- | ----------- -0 | `player` | Unit that was hit -1 | `[[0.5, "Body", 1], [0.3, "Head", 0.6]]` | 0.5 damage to body (was 1 before armor), 0.3 damage to head (was 0.6 before armor) -2 | `"grenade"` | type grenade (non-selection-specific) +| | Arguments | Explanation | +| ---| --------- | ----------- | +| 0 | `player` | Unit that was hit | +| 1 | `[[0.5, "Body", 1], [0.3, "Head", 0.6]]` | 0.5 damage to body (was 1 before armor), 0.3 damage to head (was 0.6 before armor) | +| 2 | `"grenade"` | type grenade (non-selection-specific) | ## 5. Tweaking internal variables Some of ACE Medical's underlying behavior, primarily related to damage handling and the vitals loop, can be fine-tuned by editing `ace_medical_const_` variables, found in [script_macros_medical.hpp](https://github.com/acemod/ACE3/blob/master/addons/medical_engine/script_macros_medical.hpp). Modification of those values should be done by advanced users only. Values and variable names are subject to change without prior warning. Modifying values mid-mission may lead to undefined behavior. Expect minimal support. + +### 5.1 Disable seat locking for unconscious +ACE will lock the seat of an unconscious or dead unit to prevent automatic unloading. This can be disabled by setting: +```sqf +ace_medical_engine_disableSeatLocking = true; // disable on everything +ace_medical_engine_disableSeatLocking = ["ship"]; // disable just on boats +``` diff --git a/docs/wiki/framework/medical-treatment-framework.md b/docs/wiki/framework/medical-treatment-framework.md index ca10a9878a..52e661a516 100644 --- a/docs/wiki/framework/medical-treatment-framework.md +++ b/docs/wiki/framework/medical-treatment-framework.md @@ -57,9 +57,60 @@ class ACE_Medical_Treatment_Actions { }; ``` -## 2. Mission Variables +## 2. Medical Vehicles and Facilities -### 2.1 Grave Digging Object Configuration +### 2.1 Medical Vehicles + +To configure a vehicle as a Medical Vehicle by default, set the `attendant` property in the vehicle's config to `1`. +```cpp +class CfgVehicles { + class MyAmbulance { + attendant = 1; + }; +}; +``` +To set a vehicle as a Medical Vehicle mid-mission, set the `ace_medical_isMedicalVehicle` variable globally. +```sqf +// Sets the object behind your cursor to be a medical vehicle +cursorObject setVariable ["ace_medical_isMedicalVehicle", true, true]; + +// Create an interaction to turn a vehicle into a medical vehicle +private _statement = {_target setVariable ["ace_medical_isMedicalVehicle", true, true]}; +private _action = ["TAG_makeMedicalVehicle", "Set as Medical Vehicle", _statement, {!([_target] call ace_medical_treatment_fnc_isMedicalVehicle)}] call ace_interact_menu_fnc_createAction; +[cursorObject, 0, ["ACE_MainActions"], _action] call ace_interact_menu_fnc_createAction; + +// Set all vehicles of type "B_Truck_01_transport_F" as medical vehicles +private _classname = "B_Truck_01_transport_F"; +private _affectChildClasses = false; // Affect variants of this vehicle +["B_Truck_01_transport_F", "InitPost", { + params ["_vehicle"]; + if (!local _vehicle) exitWith {}; + _vehicle setVariable ["ace_medical_isMedicalVehicle", true, true]; +}, _affectChildClasses, [], true] call CBA_fnc_addClassEventHandler; +``` + +### 2.2 Medical Facilities + +To configure an object as a Medical Facility by default, add a new array containing its classname to the `ace_medical_facilities` class in config root. +```cpp +class CfgVehicles { + class ThingX; + class MyMedicalFacility: ThingX {}; + class MyMedicalFacility2_ElectricBoogaloo: MyMedicalFacility {}; +}; + +class ace_medical_facilities { + TAG_allOfMyFacilities[] = {"MyMedicalFacility", "MyMedicalFacility2_ElectricBoogaloo"}; +}; +``` +To set an object as a Medical Facility mid-mission, set the `ace_medical_isMedicalFacility` variable globally. See above. + + +Both Medical Facilities and Medical Vehicles can also be created via the Eden Editor's attributes menu. + +## 3. Mission Variables + +### 3.1 Grave Digging Object Configuration The object created when digging a grave can be modified by setting the `ace_medical_treatment_graveClassname` variable. ```sqf @@ -70,3 +121,17 @@ The object's rotation can also be modified, if necessary. ```sqf ace_medical_treatment_graveRotation = 0; // rotation angle (will depend on model classname) ``` + +### 3.2 Zeus Medical Menu Module + +If a mission maker wishes to disable Zeus access to the medical menu, they can set the variable below: +```sqf +ace_medical_gui_enableZeusModule = false; // default is true +``` + +### 3.3 SpO2 Configuration + +If 3rd party mods want to disable SpO2 being set to a minimum upon successful CPR, they can set the variable below: +```sqf +ace_medical_treatment_setSpO2UponCPRSuccess = false; // default is true +``` diff --git a/docs/wiki/framework/missile-guidance-framework.md b/docs/wiki/framework/missile-guidance-framework.md index 3b31975da3..ff6859d735 100644 --- a/docs/wiki/framework/missile-guidance-framework.md +++ b/docs/wiki/framework/missile-guidance-framework.md @@ -117,6 +117,6 @@ class ace_missileguidance_attackProfiles { ### 5.1 Listenable -Event Name | Description | Passed Parameter(s) | Locality ----------- | ----------- | ------------------- | -------- -`ace_missileguidance_handoff` | Missile handed off | `[_target, _args]` | Global +| Event Name | Description | Passed Parameter(s) | Locality | +| ---------- | ----------- | ------------------- | -------- | +| `ace_missileguidance_handoff` | Missile handed off | `[_target, _args]` | Global | diff --git a/docs/wiki/framework/nametags-framework.md b/docs/wiki/framework/nametags-framework.md new file mode 100644 index 0000000000..d27a358b17 --- /dev/null +++ b/docs/wiki/framework/nametags-framework.md @@ -0,0 +1,45 @@ +--- +layout: wiki +title: Nametags Framework +description: Explains how to implement rank icons for factions. +group: framework +order: 5 +parent: wiki +mod: ace +version: + major: 3 + minor: 13 + patch: 0 +--- + +## 1. Config Values + +### 1.1 Faction rank icons + +Defines the rank icons used by a faction. + +```cpp +class CfgFactionClasses { + class MyFaction { + ace_nametags_rankIcons[] = { + "\z\ace\addons\nametags\UI\icons_germany\private_gs.paa", // path to private rank icon + "\z\ace\addons\nametags\UI\icons_germany\corporal_gs.paa", // path to corporal rank icon + "\z\ace\addons\nametags\UI\icons_germany\sergeant_gs.paa", // path to sergeant rank icon + "\z\ace\addons\nametags\UI\icons_germany\lieutenant_gs.paa", // path to lieutenant rank icon + "\z\ace\addons\nametags\UI\icons_germany\captain_gs.paa", // path to captain rank icon + "\z\ace\addons\nametags\UI\icons_germany\major_gs.paa", // path to major rank icon + "\z\ace\addons\nametags\UI\icons_germany\colonel_gs.paa" // path to colonel rank icon + }; + }; +}; +``` + +## 2. Mission Variables + +### 2.1 Faction rank icon usage + +If disabled, it won't use the faction icons defined via the config entry listed above. +Needs to be set before postInit. +```sqf +ace_nametags_useFactionIcons = false; // by default true +``` diff --git a/docs/wiki/framework/overpressure-framework.md b/docs/wiki/framework/overpressure-framework.md index 7e7969f62a..243157c186 100644 --- a/docs/wiki/framework/overpressure-framework.md +++ b/docs/wiki/framework/overpressure-framework.md @@ -46,6 +46,6 @@ class CfgWeapons { ### 2.1 Listenable -Event Name | Description | Passed Parameter(s) | Locality ----------- | ----------- | ------------------- | -------- -`ace_overpressure` | Overpressure damage inflicted | `[_firer, _posASL, _direction, _weapon, _magazine, _ammo]` | Target +| Event Name | Description | Passed Parameter(s) | Locality | +| ---------- | ----------- | ------------------- | -------- | +| `ace_overpressure` | Overpressure damage inflicted | `[_firer, _posASL, _direction, _weapon, _magazine, _ammo]` | Target | diff --git a/docs/wiki/framework/rearm-framework.md b/docs/wiki/framework/rearm-framework.md index 7f899f54c9..a4061cb2bc 100644 --- a/docs/wiki/framework/rearm-framework.md +++ b/docs/wiki/framework/rearm-framework.md @@ -71,31 +71,31 @@ Meant to run on server only. `ace_rearm_fnc_makeSource` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Ammo Truck | Object | Required -1 | Supply Count | Number | Optional (default: `0`) -1 | Add (`true`) or set (`false`) supply | Bool | Optional (default: `false`) -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Ammo Truck | Object | Required | +| 1 | Supply Count | Number | Optional (default: `0`) | +| 1 | Add (`true`) or set (`false`) supply | Bool | Optional (default: `false`) | +| **R** | None | None | Return value | #### 3.1.1 Example `[cursorObject, 1200] call ace_rearm_fnc_makeSource` - | Arguments | Explanation ----| --------- | ----------- -0 | `cursorObject` | Rearm source object -1 | `1200` | Ammo supply +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `cursorObject` | Rearm source object | +| 1 | `1200` | Ammo supply | ### 3.2 Enabling / disabling rearming `ace_rearm_fnc_disable` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Ammo Truck | Object | Required -1 | Disable rearming, true to disable, false to enable | Boolean | Optional (default: `true`) -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Ammo Truck | Object | Required | +| 1 | Disable rearming, true to disable, false to enable | Boolean | Optional (default: `true`) | +| **R** | None | None | Return value | This function disables rearming for all supported turrets of a vehicle. @@ -103,9 +103,9 @@ This function disables rearming for all supported turrets of a vehicle. `[tank] call ace_rearm_fnc_disable;` - | Arguments | Explanation ----| --------- | ----------- -0 | `tank` | My object +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `tank` | My object | Disables rearming on the object `tank`. @@ -113,10 +113,10 @@ Disables rearming on the object `tank`. `[tank, false] call ace_rearm_fnc_disable;` - | Arguments | Explanation ----| --------- | ----------- -0 | `tank` | My object -1 | `false`| Rearming is enabled +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `tank` | My object | +| 1 | `false` | Rearming is enabled | Enables rearming on the object `tank`. @@ -124,10 +124,10 @@ Enables rearming on the object `tank`. `ace_rearm_fnc_getSupplyCount` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Ammo Truck | Object | Required -**R** | Supply count | Number | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Ammo Truck | Object | Required | +| **R** | Supply count | Number | Return value | This function returns the current supply count of the ammo truck. @@ -135,9 +135,9 @@ This function returns the current supply count of the ammo truck. `[ammo_truck] call ace_rearm_fnc_getSupplyCount;` - | Arguments | Explanation ----| --------- | ----------- -0 | `ammo_truck` | My object +| | Arguments | Explanation | +| ---| ------------- | ----------- | +| 0 | `ammo_truck` | My object | The remaining supply count of `ammo_truck` will be returned. @@ -145,11 +145,11 @@ The remaining supply count of `ammo_truck` will be returned. `ace_rearm_fnc_setSupplyCount` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Ammo Truck | Object | Required -1 | Supply Count | Boolean | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Ammo Truck | Object | Required | +| 1 | Supply Count | Boolean | Required | +| **R** | None | None | Return value | This function sets the current supply count of the ammo truck. It can be used to replenish the ammo truck on `Limited ammo supply based on caliber` setting. @@ -157,21 +157,21 @@ This function sets the current supply count of the ammo truck. It can be used to `[ammo_truck, 1000] call ace_rearm_fnc_setSupplyCount;` - | Arguments | Explanation ----| --------- | ----------- -0 | `ammo_truck` | My ammo truck object -1 | `1000`| Supply Count +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `ammo_truck` | My ammo truck object | +| 1 | `1000`| Supply Count | ### 3.5 Adding specific magazines `ace_rearm_fnc_addMagazineToSupply` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Ammo Truck | Object | Required -1 | Magazine Classname | String | Required -2 | Only add content of one ammo box | Boolean | Optional (default: `false`) -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Ammo Truck | Object | Required | +| 1 | Magazine Classname | String | Required | +| 2 | Only add content of one ammo box | Boolean | Optional (default: `false`) | +| **R** | None | None | Return value | This function is most useful with the module setting `Only specific Magazines`. Note that this function only adds one magazine of a specific class. Other magazines of the same size are not available on this module setting. It has to be used to replenish the ammo truck on `Only specific Magazines` setting. @@ -181,10 +181,10 @@ This function can also be used to increase the supply count on setting `Limited `[ammo_truck, "32Rnd_155mm_Mo_shells"] call ace_rearm_fnc_addMagazineToSupply;` - | Arguments | Explanation ----| --------- | ----------- -0 | `ammo_truck` | My ammo truck object -1 | `"32Rnd_155mm_Mo_shells"` | Some magazine class +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `ammo_truck` | My ammo truck object | +| 1 | `"32Rnd_155mm_Mo_shells"` | Some magazine class | The 32 artillery shells are added to the supply count or the magazine storage of the specified ammo truck. @@ -192,11 +192,11 @@ The 32 artillery shells are added to the supply count or the magazine storage of `ace_rearm_fnc_addVehicleMagazinesToSupply` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Ammo Truck | Object | Required -1 | Any vehicle object or class name | Object or String | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Ammo Truck | Object | Required | +| 1 | Any vehicle object or class name | Object or String | Required | +| **R** | None | None | Return value | This function wraps `ace_rearm_fnc_addMagazineToSupply` and uses it to add all default magazines of all supported turrets of the vehicle to the ammo truck. @@ -204,10 +204,10 @@ This function wraps `ace_rearm_fnc_addMagazineToSupply` and uses it to add all d `[ammo_truck, tank] call ace_rearm_fnc_addVehicleMagazinesToSupply;` - | Arguments | Explanation ----| --------- | ----------- -0 | `ammo_truck` | My ammo truck object -1 | `tank`| A vehicle object +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `ammo_truck` | My ammo truck object | +| 1 | `tank`| A vehicle object | All magazines found in the class config of the object `tank` are made available. @@ -215,10 +215,10 @@ All magazines found in the class config of the object `tank` are made available. `[ammo_truck, "B_MBT_01_arty_F"] call ace_rearm_fnc_addVehicleMagazinesToSupply;` - | Arguments | Explanation ----| --------- | ----------- -0 | `ammo_truck` | My ammo truck object -1 | `"B_MBT_01_arty_F"`| Vehicle class name +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `ammo_truck` | My ammo truck object | +| 1 | `"B_MBT_01_arty_F"`| Vehicle class name | All magazines found in the config of the vehicle class `B_MBT_01_arty_F` are made available. @@ -227,21 +227,21 @@ All magazines found in the config of the vehicle class `B_MBT_01_arty_F` are mad `ace_rearm_fnc_removeMagazineFromSupply` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Ammo Truck | Object | Required -1 | Magazine Classname | String | Required -2 | Number of Rounds to withdraw | Number | Optional (default: `-1`) -**R** | Magazine could be removed successfully | Boolean | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Ammo Truck | Object | Required | +| 1 | Magazine Classname | String | Required | +| 2 | Number of Rounds to withdraw | Number | Optional (default: `-1`) | +| **R** | Magazine could be removed successfully | Boolean | Return value | #### 3.7.1 Example 1 `[ammo_truck, "500Rnd_127x99_mag_Tracer_Red"] call ace_rearm_fnc_removeMagazineFromSupply;` - | Arguments | Explanation ----| --------- | ----------- -0 | `ammo_truck` | My ammo truck object -1 | `"500Rnd_127x99_mag_Tracer_Red"`| Carrying is enabled +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `ammo_truck` | My ammo truck object | +| 1 | `"500Rnd_127x99_mag_Tracer_Red"`| Carrying is enabled | Removes one ammo box worth of "500Rnd_127x99_mag_Tracer_Red" from the supply. Depending on the module setting the ammo box does hold an entire magazine or only the caliber based amount of rounds. @@ -249,16 +249,16 @@ Removes one ammo box worth of "500Rnd_127x99_mag_Tracer_Red" from the supply. De `[ammo_truck, "500Rnd_127x99_mag_Tracer_Red", 50] call ace_rearm_fnc_removeMagazineFromSupply;` - | Arguments | Explanation ----| --------- | ----------- -0 | `ammo_truck` | My ammo truck object -1 | `"500Rnd_127x99_mag_Tracer_Red"`| Carrying is enabled -2 | `50` | Number of rounds +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `ammo_truck` | My ammo truck object | +| 1 | `"500Rnd_127x99_mag_Tracer_Red"`| Carrying is enabled | +| 2 | `50` | Number of rounds | Removes one ammo box with 50 rounds of 500Rnd_127x99_mag_Tracer_Red from the supply. This is 10% of the supply of an entire magazine. ## 4. Events -| Name | Arguments | Global? | Added in | -| ------------- | ------------- | ------------- | -| ace_rearm_sourceInitalized | Yes | Ammo truck (OBJECT) | 3.16.0 | +| Name | Arguments | Global? | Added in | +| ------------- | --------- | ------- | -------- | +| `ace_rearm_sourceInitalized` | Ammo truck (OBJECT) | Yes | 3.16.0 | diff --git a/docs/wiki/framework/refuel-framework.md b/docs/wiki/framework/refuel-framework.md index c91c8cb6e3..3cf10d7205 100644 --- a/docs/wiki/framework/refuel-framework.md +++ b/docs/wiki/framework/refuel-framework.md @@ -45,57 +45,57 @@ Meant to be called on server only. `ace_refuel_fnc_makeSource` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Fuel Source | Object | Required -1 | Amount (in liters) | Number | Optional (default: `0`) -2 | Hooks positions | Array | Optional (default: `[[0,0,0]]`) -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Fuel Source | Object | Required | +| 1 | Amount (in liters) | Number | Optional (default: `0`) | +| 2 | Hooks positions | Array | Optional (default: `[[0,0,0]]`) | +| **R** | None | None | Return value | #### 2.1.1 Example `[cursorObject, 100] call ace_refuel_fnc_makeSource` - | Arguments | Explanation ----| --------- | ----------- -0 | `cursorObject` | Fuel source object -1 | `100` | Fuel amount (in liters) +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `cursorObject` | Fuel source object | +| 1 | `100` | Fuel amount (in liters) | ### 2.2 Getting the fuel supply `ace_refuel_fnc_getFuel` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Fuel Truck | Object | Required -**R** | Fuel amount left (in liters) | Number | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Fuel Truck | Object | Required | +| **R** | Fuel amount left (in liters) | Number | Return value | #### 2.2.1 Example `[fuelTruck] call ace_refuel_fnc_getFuel;` - | Arguments | Explanation ----| --------- | ----------- -0 | `fuelTruck` | My fuel truck object +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `fuelTruck` | My fuel truck object | ### 2.3 Setting the fuel supply `ace_refuel_fnc_setFuel` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Fuel Truck | Object | Required -1 | Amount (in liters) | Number | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +| ---| --------- | ---- | ------------------------ | +| 0 | Fuel Truck | Object | Required | +| 1 | Amount (in liters) | Number | Required | +| **R** | None | None | Return value | #### 2.3.1 Example `[fuelTruck, 428] call ace_refuel_fnc_setFuel;` - | Arguments | Explanation ----| --------- | ----------- -0 | `fuelTruck` | Fuel truck object -1 | `428` | New fuel amount (in liters) +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `fuelTruck` | Fuel truck object | +| 1 | `428` | New fuel amount (in liters) | ### 2.4 Make a jerry can @@ -103,19 +103,19 @@ Meant to be run on all clients and server. `ace_refuel_fnc_makeJerryCan` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Jerry Can | Object | Required -1 | Amount (in liters) | Number | Optional (default: `20`) -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Jerry Can | Object | Required | +| 1 | Amount (in liters) | Number | Optional (default: `20`) | +| **R** | None | None | Return value | #### 2.4.1 Example 1 `[can] call ace_refuel_fnc_makeJerryCan;` - | Arguments | Explanation ----| --------- | ----------- -0 | `can` | Jerry can object +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `can` | Jerry can object | The jerry can will have the default 20 liters volume. @@ -123,16 +123,16 @@ The jerry can will have the default 20 liters volume. `[can, 200] call ace_refuel_fnc_makeJerryCan;` - | Arguments | Explanation ----| --------- | ----------- -0 | `can` | Jerry can object -1 | `200` | Amount (in liters) +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `can` | Jerry can object | +| 1 | `200` | Amount (in liters) | The jerry can will now have a volume of 200 liters. ## 3. Events | Name | Arguments | Global? | Added in | -| ------------- | ------------- | ------------- | -| ace_refuel_sourceInitialized | Fuel source (OBJECT), items (BOOL or ARRAY) | Yes | 3.16.0 | +| ------------- | ------------- | ----- | ------------- | +| ace_refuel_sourceInitialized | Fuel source (OBJECT) | Yes | 3.16.0 | | ace_refuel_jerryCanInitalized | Jerry can (OBJECT) | Yes | 3.16.0 | diff --git a/docs/wiki/framework/reloadlaunchers-framework.md b/docs/wiki/framework/reloadlaunchers-framework.md index d055cc533c..074dc09ff0 100644 --- a/docs/wiki/framework/reloadlaunchers-framework.md +++ b/docs/wiki/framework/reloadlaunchers-framework.md @@ -26,6 +26,6 @@ class CfgWeapons { ### 2.1 Listenable -Event Name | Description | Passed Parameter(s) | Locality ----------- | ----------- | ------------------- | -------- -`ace_reloadlaunchers_reloadLauncher` | Launcher reloaded | `[_unit, _target, _weapon, _magazine]` | Target +| Event Name | Description | Passed Parameter(s) | Locality | +| ---------- | ----------- | ------------------- | -------- | +| `ace_reloadlaunchers_reloadLauncher` | Launcher reloaded | `[_unit, _target, _weapon, _magazine]` | Target | diff --git a/docs/wiki/framework/sitting-framework.md b/docs/wiki/framework/sitting-framework.md index 09f59a9df4..b8f8ff37b0 100644 --- a/docs/wiki/framework/sitting-framework.md +++ b/docs/wiki/framework/sitting-framework.md @@ -29,6 +29,7 @@ class CfgVehicles { acex_sitting_sitDirection = 180; // Direction relative to object acex_sitting_sitPosition[] = {0, -0.1, -0.45}; // Position relative to object (may behave weird with certain objects) acex_sitting_interactPosition[] = {0, -0.1, -0.45}; + ace_sitting_animations[] = {"ace_sitting_HubSittingChairA_idle1"}; // Overwrite random animation pool XEH_ENABLED; // Enable XEH (only necessary if XEH is not yet enabled for this class or the one this inherits from) }; }; diff --git a/docs/wiki/framework/slideshow-framework.md b/docs/wiki/framework/slideshow-framework.md index 0697116039..575a81420c 100644 --- a/docs/wiki/framework/slideshow-framework.md +++ b/docs/wiki/framework/slideshow-framework.md @@ -32,16 +32,16 @@ Important notes: `ace_slideshow_fnc_createSlideshow` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Screen Objects | Array | Required -1 | Controller Objects | Array | Required (screen objects are used if empty `[]`, none are available with automatic transitions) -2 | Image Paths | Array | Required (paths must use backslash `\`) -3 | Action Names | Array | Required -4 | Slide Duration | Number | Optional (default: `0`, `0` disables automatic transitions) -5 | Set Name | String | Optional (default: localized `"Slides"`) -6 | Texture Selection | Number | Optional (default: `0`) -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Screen Objects | Array | Required | +| 1 | Controller Objects | Array | Required (screen objects are used if empty `[]`, none are available with automatic transitions) | +| 2 | Image Paths | Array | Required (paths must use backslash `\`) | +| 3 | Action Names | Array | Required | +| 4 | Slide Duration | Number | Optional (default: `0`, `0` disables automatic transitions) | +| 5 | Set Name | String | Optional (default: localized `"Slides"`) | +| 6 | Texture Selection | Number | Optional (default: `0`) | +| **R** | None | None | Return value | _Note: Set Name argument added in 3.9.1._ @@ -49,15 +49,15 @@ _Note: Set Name argument added in 3.9.1._ `[[object1, object2], [controller1], ["images\image1.paa", "images\image2.paa"], ["Action1", "Action2"], 5, "My Slides", 1] call ace_slideshow_fnc_createSlideshow;` - | Arguments | Explanation ----| --------- | ----------- -0 | `[object1, object2]` | Objects on which images will be projected on -1 | `[controller1]` | Objects with which slideshow can be controlled -2 | `["images\image1.paa", "images\image2.paa"]` | Paths to images projected on screen objects -3 | `["Action1", "Action2"]` | Action names for interaction menu if automatic transitions are not enabled -4 | `5` | 5s slide duration before change to next image -5 | `"My Slides"` | Main interaction point name, for easier distinguishing of multiple slideshow sets -6 | `1` | Uses texture selection 1 for objects with multiple options +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `[object1, object2]` | Objects on which images will be projected on | +| 1 | `[controller1]` | Objects with which slideshow can be controlled | +| 2 | `["images\image1.paa", "images\image2.paa"]` | Paths to images projected on screen objects | +| 3 | `["Action1", "Action2"]` | Action names for interaction menu if automatic transitions are not enabled | +| 4 | `5` | 5s slide duration before change to next image | +| 5 | `"My Slides"` | Main interaction point name, for easier distinguishing of multiple slideshow sets | +| 6 | `1` | Uses texture selection 1 for objects with multiple options | ### 2.2 Create Map Images @@ -86,7 +86,7 @@ _Note: Set Name argument added in 3.9.1._ tex1 = [] call ace_slideshow_fnc_mapImage; tex2 = [(getPos aWhiteboard), 0.5, [[getpos aWhiteboard, "you", "mil_start"]], 0] call ace_slideshow_fnc_mapImage; tex3 = [[4000, 4000], 0.5, [[[5000, 5000], "target", "mil_objective"]], 2] call ace_slideshow_fnc_mapImage; -[[aWhiteboard], [], [tex1, tex2, tex3], ["Full", "Sat Start", "Sat Objective"]] call ace_slideshow_fnc_createSlideshow; +[[aWhiteboard], [], [tex1, tex2, tex3], ["Full", "Sat Start", "Sat Objective"]] call ace_slideshow_fnc_createSlideshow; ``` ### 2.2.2 Map Slideshow Advanced Example @@ -105,12 +105,12 @@ private _initCode = { [{ params ["_displayID","_idPFH"]; private _display = findDisplay _displayID; - if (isNull _display) exitWith { + if (isNull _display) exitWith { systemChat format ["%1 - removing pfeh", _this]; [_idPFH] call CBA_fnc_removePerFrameHandler; }; displayUpdate _display; - + private _map = _display displayCtrl 1; _map ctrlMapAnimAdd [0, 0.3, getpos theUAV]; ctrlMapAnimCommit _map; diff --git a/docs/wiki/framework/spectator-framework.md b/docs/wiki/framework/spectator-framework.md index 22bc0c0021..c78285b98b 100644 --- a/docs/wiki/framework/spectator-framework.md +++ b/docs/wiki/framework/spectator-framework.md @@ -48,11 +48,11 @@ Note that these settings govern the default spectator behaviour. Through the use ### 3.1 Listenable -Event Name | Passed Parameter(s) | Locality | Description ----------- | ----------- | ------------------- | -------- -`ace_spectatorSet` | [_isSpectator, _player] | Global | Player's spectator status was changed -`ace_spectator_displayLoaded` | _display | Local | Spectator display was loaded -`ace_spectator_displayUnloaded` | _display | Local | Spectator display was unloaded +| Event Name | Passed Parameter(s) | Locality | Description | +| ---------- | ----------- | ------------------- | -------- | +| `ace_spectatorSet` | [_isSpectator, _player] | Global | Player's spectator status was changed | +| `ace_spectator_displayLoaded` | _display | Local | Spectator display was loaded | +| `ace_spectator_displayUnloaded` | _display | Local | Spectator display was unloaded | ## 4. Scripting diff --git a/docs/wiki/framework/tagging-framework.md b/docs/wiki/framework/tagging-framework.md index e263a2afaa..126971abf5 100644 --- a/docs/wiki/framework/tagging-framework.md +++ b/docs/wiki/framework/tagging-framework.md @@ -41,28 +41,28 @@ class ACE_Tags { `ace_tagging_fnc_addCustomTag` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Unique Identifier | String | Required -1 | Display Name | String | Required -2 | Required Item | String | Required -3 | Textures | Array | Required -4 | Icon | String | Optional (default: `""` - Default white point) -5 | Material Paths | Array | Optional (default: `[]] - No custom material) -6 | Tag Model | String | Optional (default: `"UserTexture1m_F"` - 1x1m texture surface) -**R** | Successfully Added Tag | Boolean | Return value +| | Arguments | Type | Optional (default value) | +| ---| --------- | ---- | ------------------------ | +| 0 | Unique Identifier | String | Required | +| 1 | Display Name | String | Required | +| 2 | Required Item | String | Required | +| 3 | Textures | Array | Required | +| 4 | Icon | String | Optional (default: `""` - Default white point) | +| 5 | Material Paths | Array | Optional (default: `[]` - No custom material) | +| 6 | Tag Model | String | Optional (default: `"UserTexture1m_F"` - 1x1m texture surface) | +| **R** | Successfully Added Tag | Boolean | Return value | #### 2.1.1 Example `["ace_victoryRed", "Victory Red", "ACE_SpraypaintRed", ["tagTexture1.paa", "tagTexture2.paa"], "icon.paa"] call ace_tagging_fnc_addCustomTag;` - | Arguments | Explanation ----| --------- | ----------- -0 | `"ace_victoryRed"` | Unique identifier (similar to class name) -1 | `"Victory Red"` | Name of your tag being displayed in the interaction menu -2 | `"ACE_SpraypaintRed"` | Required item to have in the inventory to be able to spray your tag -3 | `["tagTexture1.paa", "tagTexture2.paa"]` | List of texture variants (one is randomly selected when tagging) -4 | `"icon.paa"` | Icon being displayed in the interaction menu +| | Arguments | Explanation | +| ---| --------- | ----------- | +| 0 | `"ace_victoryRed"` | Unique identifier (similar to class name) | +| 1 | `"Victory Red"` | Name of your tag being displayed in the interaction menu | +| 2 | `"ACE_SpraypaintRed"` | Required item to have in the inventory to be able to spray your tag | +| 3 | `["tagTexture1.paa", "tagTexture2.paa"]` | List of texture variants (one is randomly selected when tagging) | +| 4 | `"icon.paa"` | Icon being displayed in the interaction menu | ### 2.2 Tags in description.ext diff --git a/docs/wiki/framework/trenches-framework.md b/docs/wiki/framework/trenches-framework.md index 5fc2dc636e..40e83689ba 100644 --- a/docs/wiki/framework/trenches-framework.md +++ b/docs/wiki/framework/trenches-framework.md @@ -30,7 +30,7 @@ class CfgSurfaces { ```cpp class CfgWeapons { // same config also works on backpacks (CfgVehicles) class yourBaseClass; - class yourEntrenchingToolClass: yourBaseClass + class yourEntrenchingToolClass: yourBaseClass { ace_trenches_entrenchingTool = 1; }; }; diff --git a/docs/wiki/framework/ui-framework.md b/docs/wiki/framework/ui-framework.md index af391f36d5..3b6ec08951 100644 --- a/docs/wiki/framework/ui-framework.md +++ b/docs/wiki/framework/ui-framework.md @@ -53,21 +53,21 @@ Adding new elements through scripting is currently not possible. `ace_ui_fnc_setElementVisibility` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Source | String | Required -1 | Set/Unset | Boolean | Required -2 | Element Name | String | Required -3 | Show/Hide | Boolean | Optional (default: `false`) -**R** | Successfully Modified | Boolean | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Source | String | Required | +| 1 | Set/Unset | Boolean | Required | +| 2 | Element Name | String | Required | +| 3 | Show/Hide | Boolean | Optional (default: `false`) | +| **R** | Successfully Modified | Boolean | Return value | #### 2.1.1 Example `["ace_reload", true, "ammoCount", false] call ace_ui_fnc_setElementVisibility;` - | Arguments | Explanation ----| --------- | ----------- -0 | `"ace_reload"` | Source displayed in hint when trying to edit this element from in-game settings or in RPT when some other source tries to edit it -1 | `true` | Set element, preventing others to change it (except config, which always has priority) -2 | `"ammoCount"` | Element name to modify -3 | `false` | Hide the element +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `"ace_reload"` | Source displayed in hint when trying to edit this element from in-game settings or in RPT when some other source tries to edit it | +| 1 | `true` | Set element, preventing others to change it (except config, which always has priority) | +| 2 | `"ammoCount"` | Element name to modify | +| 3 | `false` | Hide the element | diff --git a/docs/wiki/framework/vehicledamage-framework.md b/docs/wiki/framework/vehicledamage-framework.md index 7e22bccf5d..04137e9c73 100644 --- a/docs/wiki/framework/vehicledamage-framework.md +++ b/docs/wiki/framework/vehicledamage-framework.md @@ -47,7 +47,7 @@ Default: 0.5 #### 1.1.5 `ace_vehicle_damage_turretFireProb` -The probabilitiy for the vehicle to catch on fire upon its turret being penetrated +The probability for the vehicle to catch on fire upon its turret being penetrated Default: 0.2 @@ -65,23 +65,29 @@ Default: 0.2 #### 1.1.8 `ace_vehicle_damage_canHaveFireRing` -Whether or not this vehicle can spawn `ring-of-fire` effect (Boolean value: 0 or 1) +Whether or not this vehicle can spawn a `ring-of-fire` effect (Boolean value: 0 or 1) Default: 0 -#### 1.1.9 `ace_vehicle_damage_slatHitpoints` +#### 1.1.9 `ace_cookoff_canHaveFireJet` + +Whether or not this vehicle can spawn a `jet` effect (Boolean value: 0 or 1) + +Default: 0 + +#### 1.1.10 `ace_vehicle_damage_slatHitpoints` An array of all hitpoints that are defined to be SLAT. String array Default: {} -#### 1.1.10 `ace_vehicle_damage_eraHitpoints` +#### 1.1.11 `ace_vehicle_damage_eraHitpoints` An array of all hitpoints that are defined to be ERA. String array Default: {} -#### 1.1.11 `ace_vehicle_damage_turret` +#### 1.1.12 `ace_vehicle_damage_turret` String for turret classname to spawn when catastrophically destroyed. Turret will pop-off and this is the class spawned @@ -126,3 +132,11 @@ Default ARMA config value. We assume that the warheads are vanilla strings, so o - `TandemHEAT` If no `ace_vehicle_damage_incendiary` defined, this value will be used to assume a default based on above table of common values (excluding `Incendiary Bullet` which is 0). + +## 3. Disabling crew bailing for individual vehicles + +Crew bailing when their vehicle is disabled (immobile or can't shoot) can be disabled for a specific vehicle: + +``` +_vehicle setVariable ["ace_vehicle_damage_allowCrewInImmobile", true, true]; +``` diff --git a/docs/wiki/framework/vehiclelock-framework.md b/docs/wiki/framework/vehiclelock-framework.md index 751e1ba65d..d882cab971 100644 --- a/docs/wiki/framework/vehiclelock-framework.md +++ b/docs/wiki/framework/vehiclelock-framework.md @@ -27,26 +27,26 @@ Sync the module with vehicles and players. Custom keys will be handed to players ## 3. Scripting -### 3.1 Assing Vehicle Key +### 3.1 Adding Vehicle Key `ace_vehiclelock_fnc_addKeyForVehicle` - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Unit | Object | Required -1 | Vehicle | Object | Required -2 | Use Custom Key | Boolean | Optional (default: `false`, `false` for side key, `true` for custom key) -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Unit | Object | Required | +| 1 | Vehicle | Object | Required | +| 2 | Use Custom Key | Boolean | Optional (default: `false`, `false` for side key, `true` for custom key) | +| **R** | None | None | Return value | #### 3.1.1 Example `[bob, car1, true] call ace_vehiclelock_fnc_addKeyForVehicle;` - | Arguments | Explanation ----| --------- | ----------- -0 | `bob` | Unit the key will be added to -1 | `car1` | Vehicle the key will work on -2 | `true` | Set custom key +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `bob` | Unit the key will be added to | +| 1 | `car1` | Vehicle the key will work on | +| 2 | `true` | Set custom key | ### 3.2 Override Side diff --git a/docs/wiki/framework/vehicles-framework.md b/docs/wiki/framework/vehicles-framework.md index a1f66e807a..dac52d0cfa 100644 --- a/docs/wiki/framework/vehicles-framework.md +++ b/docs/wiki/framework/vehicles-framework.md @@ -38,18 +38,18 @@ class CfgVehicles { `ace_vehicles_fnc_setVehicleStartDelay` Has global effects. - | Arguments | Type | Optional (default value) ----| --------- | ---- | ------------------------ -0 | Vehicle | Object | Required -1 | Delay (in seconds) | Number | Required -**R** | None | None | Return value +| | Arguments | Type | Optional (default value) | +|----| --------- | ---- | ------------------------ | +| 0 | Vehicle | Object | Required | +| 1 | Delay (in seconds) | Number | Required | +| **R** | None | None | Return value | #### 1.2.1 Example `[myCar, 2.2] call ace_vehicles_fnc_setVehicleStartDelay;` - | Arguments | Explanation ----| --------- | ----------- -0 | `myCar` | My car object -1 | `2.2` | New startup delay +| | Arguments | Explanation | +|----| --------- | ----------- | +| 0 | `myCar` | My car object | +| 1 | `2.2` | New startup delay | diff --git a/docs/wiki/framework/weather-framework.md b/docs/wiki/framework/weather-framework.md index 4c42ef6ab2..3abdc9d247 100644 --- a/docs/wiki/framework/weather-framework.md +++ b/docs/wiki/framework/weather-framework.md @@ -19,3 +19,10 @@ ACE3 Weather extends the existing weather by temperature, humidity and air press The additional wind simulation, which is also influenced by the season and the geographical location, can be deactivated if necessary. Cloud cover, rain and fog can still be set via the mission settings. + + +## 2. Wind Simulation + +## 2.1 Temporarily Pause Wind Simulation + +When Wind Simulation is enabled at mission start, it can be temporarily disabled by setting `ace_weather_disableWindSimulation = true`. To reenable wind simulation, the variable must either be set to `false` or `nil`. \ No newline at end of file diff --git a/docs/wiki/framework/wirecutter-framework.md b/docs/wiki/framework/wirecutter-framework.md index 3f2a97c0b1..65a4ed1f98 100644 --- a/docs/wiki/framework/wirecutter-framework.md +++ b/docs/wiki/framework/wirecutter-framework.md @@ -36,6 +36,6 @@ class CfgVehicles { ### 2.1 Listenable -Event Name | Description | Passed Parameter(s) | Locality ----------- | ----------- | ------------------- | -------- -`ace_wireCuttingStarted` | Wire cutting started | `[_unit, _fence]` | Global +| Event Name | Description | Passed Parameter(s) | Locality | +| ---------- | ----------- | ------------------- | -------- | +| `ace_wireCuttingStarted` | Wire cutting started | `[_unit, _fence]` | Global | diff --git a/docs/wiki/framework/xm157-framework.md b/docs/wiki/framework/xm157-framework.md index 45a2a19c21..d92d4b37e9 100644 --- a/docs/wiki/framework/xm157-framework.md +++ b/docs/wiki/framework/xm157-framework.md @@ -52,5 +52,4 @@ class CfgWeapons { }; }; }; - ``` diff --git a/extras/assets/CookoffSounds/ConvertWAVtoWSS.bat b/extras/assets/CookoffSounds/ConvertWAVtoWSS.bat new file mode 100644 index 0000000000..2db7169f14 --- /dev/null +++ b/extras/assets/CookoffSounds/ConvertWAVtoWSS.bat @@ -0,0 +1 @@ +forfiles /s /m *.wav /c "DeWSSDos -wss/0 -P -V -Y @path @FNAME.wss" diff --git a/extras/assets/CookoffSounds/shotbullet/close_1.wav b/extras/assets/CookoffSounds/shotbullet/close_1.wav new file mode 100644 index 0000000000..27e0c44dd3 Binary files /dev/null and b/extras/assets/CookoffSounds/shotbullet/close_1.wav differ diff --git a/extras/assets/CookoffSounds/shotbullet/close_2.wav b/extras/assets/CookoffSounds/shotbullet/close_2.wav new file mode 100644 index 0000000000..c51039cb73 Binary files /dev/null and b/extras/assets/CookoffSounds/shotbullet/close_2.wav differ diff --git a/extras/assets/CookoffSounds/shotbullet/close_3.wav b/extras/assets/CookoffSounds/shotbullet/close_3.wav new file mode 100644 index 0000000000..46955fa696 Binary files /dev/null and b/extras/assets/CookoffSounds/shotbullet/close_3.wav differ diff --git a/extras/assets/CookoffSounds/shotbullet/far_1.wav b/extras/assets/CookoffSounds/shotbullet/far_1.wav new file mode 100644 index 0000000000..bfccf1461b Binary files /dev/null and b/extras/assets/CookoffSounds/shotbullet/far_1.wav differ diff --git a/extras/assets/CookoffSounds/shotbullet/far_2.wav b/extras/assets/CookoffSounds/shotbullet/far_2.wav new file mode 100644 index 0000000000..39b3e09dee Binary files /dev/null and b/extras/assets/CookoffSounds/shotbullet/far_2.wav differ diff --git a/extras/assets/CookoffSounds/shotbullet/far_3.wav b/extras/assets/CookoffSounds/shotbullet/far_3.wav new file mode 100644 index 0000000000..5714da8440 Binary files /dev/null and b/extras/assets/CookoffSounds/shotbullet/far_3.wav differ diff --git a/extras/assets/CookoffSounds/shotbullet/mid_1.wav b/extras/assets/CookoffSounds/shotbullet/mid_1.wav new file mode 100644 index 0000000000..f757ca68f7 Binary files /dev/null and b/extras/assets/CookoffSounds/shotbullet/mid_1.wav differ diff --git a/extras/assets/CookoffSounds/shotbullet/mid_2.wav b/extras/assets/CookoffSounds/shotbullet/mid_2.wav new file mode 100644 index 0000000000..419e62e847 Binary files /dev/null and b/extras/assets/CookoffSounds/shotbullet/mid_2.wav differ diff --git a/extras/assets/CookoffSounds/shotbullet/mid_3.wav b/extras/assets/CookoffSounds/shotbullet/mid_3.wav new file mode 100644 index 0000000000..c2366ceb17 Binary files /dev/null and b/extras/assets/CookoffSounds/shotbullet/mid_3.wav differ diff --git a/extras/assets/CookoffSounds/shotrocket/close_1.wav b/extras/assets/CookoffSounds/shotrocket/close_1.wav new file mode 100644 index 0000000000..e76da3c464 Binary files /dev/null and b/extras/assets/CookoffSounds/shotrocket/close_1.wav differ diff --git a/extras/assets/CookoffSounds/shotrocket/close_2.wav b/extras/assets/CookoffSounds/shotrocket/close_2.wav new file mode 100644 index 0000000000..82f5c2c657 Binary files /dev/null and b/extras/assets/CookoffSounds/shotrocket/close_2.wav differ diff --git a/extras/assets/CookoffSounds/shotrocket/close_3.wav b/extras/assets/CookoffSounds/shotrocket/close_3.wav new file mode 100644 index 0000000000..29b447e502 Binary files /dev/null and b/extras/assets/CookoffSounds/shotrocket/close_3.wav differ diff --git a/extras/assets/CookoffSounds/shotrocket/far_1.wav b/extras/assets/CookoffSounds/shotrocket/far_1.wav new file mode 100644 index 0000000000..ec019a7d5e Binary files /dev/null and b/extras/assets/CookoffSounds/shotrocket/far_1.wav differ diff --git a/extras/assets/CookoffSounds/shotrocket/far_2.wav b/extras/assets/CookoffSounds/shotrocket/far_2.wav new file mode 100644 index 0000000000..640860b81f Binary files /dev/null and b/extras/assets/CookoffSounds/shotrocket/far_2.wav differ diff --git a/extras/assets/CookoffSounds/shotrocket/far_3.wav b/extras/assets/CookoffSounds/shotrocket/far_3.wav new file mode 100644 index 0000000000..7481f3dfe9 Binary files /dev/null and b/extras/assets/CookoffSounds/shotrocket/far_3.wav differ diff --git a/extras/assets/CookoffSounds/shotrocket/mid_1.wav b/extras/assets/CookoffSounds/shotrocket/mid_1.wav new file mode 100644 index 0000000000..b4e2c75259 Binary files /dev/null and b/extras/assets/CookoffSounds/shotrocket/mid_1.wav differ diff --git a/extras/assets/CookoffSounds/shotrocket/mid_2.wav b/extras/assets/CookoffSounds/shotrocket/mid_2.wav new file mode 100644 index 0000000000..a21b529f07 Binary files /dev/null and b/extras/assets/CookoffSounds/shotrocket/mid_2.wav differ diff --git a/extras/assets/CookoffSounds/shotrocket/mid_3.wav b/extras/assets/CookoffSounds/shotrocket/mid_3.wav new file mode 100644 index 0000000000..3fdffdbe0f Binary files /dev/null and b/extras/assets/CookoffSounds/shotrocket/mid_3.wav differ diff --git a/extras/assets/CookoffSounds/shotshell/close_1.wav b/extras/assets/CookoffSounds/shotshell/close_1.wav new file mode 100644 index 0000000000..105d092a91 Binary files /dev/null and b/extras/assets/CookoffSounds/shotshell/close_1.wav differ diff --git a/extras/assets/CookoffSounds/shotshell/close_2.wav b/extras/assets/CookoffSounds/shotshell/close_2.wav new file mode 100644 index 0000000000..899cde6505 Binary files /dev/null and b/extras/assets/CookoffSounds/shotshell/close_2.wav differ diff --git a/extras/assets/CookoffSounds/shotshell/close_3.wav b/extras/assets/CookoffSounds/shotshell/close_3.wav new file mode 100644 index 0000000000..dbfeb32694 Binary files /dev/null and b/extras/assets/CookoffSounds/shotshell/close_3.wav differ diff --git a/extras/assets/CookoffSounds/shotshell/far_1.wav b/extras/assets/CookoffSounds/shotshell/far_1.wav new file mode 100644 index 0000000000..5490655406 Binary files /dev/null and b/extras/assets/CookoffSounds/shotshell/far_1.wav differ diff --git a/extras/assets/CookoffSounds/shotshell/far_2.wav b/extras/assets/CookoffSounds/shotshell/far_2.wav new file mode 100644 index 0000000000..f5cd390b60 Binary files /dev/null and b/extras/assets/CookoffSounds/shotshell/far_2.wav differ diff --git a/extras/assets/CookoffSounds/shotshell/far_3.wav b/extras/assets/CookoffSounds/shotshell/far_3.wav new file mode 100644 index 0000000000..99fc796e7d Binary files /dev/null and b/extras/assets/CookoffSounds/shotshell/far_3.wav differ diff --git a/extras/assets/CookoffSounds/shotshell/mid_1.wav b/extras/assets/CookoffSounds/shotshell/mid_1.wav new file mode 100644 index 0000000000..a911545a7f Binary files /dev/null and b/extras/assets/CookoffSounds/shotshell/mid_1.wav differ diff --git a/extras/assets/CookoffSounds/shotshell/mid_2.wav b/extras/assets/CookoffSounds/shotshell/mid_2.wav new file mode 100644 index 0000000000..e8dc3e06de Binary files /dev/null and b/extras/assets/CookoffSounds/shotshell/mid_2.wav differ diff --git a/extras/assets/CookoffSounds/shotshell/mid_3.wav b/extras/assets/CookoffSounds/shotshell/mid_3.wav new file mode 100644 index 0000000000..ea6ddd94e6 Binary files /dev/null and b/extras/assets/CookoffSounds/shotshell/mid_3.wav differ 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/include/a3/data_f/penetration/hard_ground.rvmat b/include/a3/data_f/penetration/hard_ground.rvmat new file mode 100644 index 0000000000..1c4d7f82b0 --- /dev/null +++ b/include/a3/data_f/penetration/hard_ground.rvmat @@ -0,0 +1,9 @@ +surfaceInfo="A3\data_f\Penetration\hard_ground.bisurf"; +ambient[]={0.48699999,0.32800001,0.249,1}; +diffuse[]={0.48699999,0.32800001,0.249,1}; +forcedDiffuse[]={0,0,0,0}; +emmisive[]={0,0,0,1}; +specular[]={0,0,0,1}; +specularPower=1; +PixelShaderID="Normal"; +VertexShaderID="Basic"; diff --git a/include/a3/ui_f/hpp/defineResincl.inc b/include/a3/ui_f/hpp/defineResincl.inc index 2f513642bc..df589bde2d 100644 --- a/include/a3/ui_f/hpp/defineResincl.inc +++ b/include/a3/ui_f/hpp/defineResincl.inc @@ -1380,6 +1380,7 @@ enum #define IDC_OPTIONS_PP_DOF_SLIDER 1317 #define IDC_OPTIONS_PP_DOF_VALUE 1318 #define IDC_OPTIONS_PP_CAUSTICS 1319 +#define IDC_OPTIONS_PP_HAZE 1329 #define IDC_OPTIONS_PP_SHARPEN_SLIDER 1320 #define IDC_OPTIONS_PP_SHARPEN_VALUE 1321 #define IDC_OPTIONS_PP_COLOR_CORRECTIONS 1322 diff --git a/include/a3/ui_f_curator/ui/displays/RscDisplayAttributes.sqf b/include/a3/ui_f_curator/ui/displays/RscDisplayAttributes.sqf index be5a9adb3e..09aba83b06 100644 --- a/include/a3/ui_f_curator/ui/displays/RscDisplayAttributes.sqf +++ b/include/a3/ui_f_curator/ui/displays/RscDisplayAttributes.sqf @@ -54,7 +54,7 @@ switch _mode do { _control = _display displayctrl _idc; //--- Admin specific attribute - _show = if (getnumber (_cfgControl >> "adminOnly") > 0) then {_enableAdmin} else {true}; + _show = [true, _enableAdmin] select (getnumber (_cfgControl >> "adminOnly") > 0); if ((_allAttributes || {_x == configname _cfgControl} count _attributes > 0) && _show) then { _controlPos = ctrlposition _control; @@ -75,10 +75,10 @@ switch _mode do { _target = missionnamespace getvariable ["BIS_fnc_initCuratorAttributes_target",objnull]; _name = switch (typename _target) do { - case (typename objnull): {gettext (configfile >> "cfgvehicles" >> typeof _target >> "displayname")}; - case (typename grpnull): {groupid _target}; - case (typename []): {format ["%1: %3 #%2",groupid (_target select 0),_target select 1,localize "str_a3_cfgmarkers_waypoint_0"]}; - case (typename ""): {markertext _target}; + case ("OBJECT"): {gettext (configfile >> "cfgvehicles" >> typeof _target >> "displayname")}; + case ("GROUP"): {groupid _target}; + case ("ARRAY"): {format ["%1: %3 #%2",groupid (_target select 0),_target select 1,localize "str_a3_cfgmarkers_waypoint_0"]}; + case ("STRING"): {markertext _target}; }; _ctrlTitle ctrlsettext format [ctrltext _ctrlTitle,toupper _name]; @@ -115,19 +115,19 @@ switch _mode do { _display = _this select 0; _target = missionnamespace getvariable ["BIS_fnc_initCuratorAttributes_target",objnull]; switch (typename _target) do { - case (typename objnull): { + case ("OBJECT"): { _isAlive = alive _target; waituntil {isnull _display || (_isAlive && !alive _target)}; }; - case (typename grpnull): { + case ("GROUP"): { waituntil {isnull _display || isnull _target}; }; - case (typename []): { + case ("ARRAY"): { _grp = _target select 0; _wpCount = count waypoints _grp; waituntil {isnull _display || (count waypoints _grp != _wpCount)}; }; - case (typename ""): { + case ("STRING"): { waituntil {isnull _display || markertype _target == ""}; }; }; diff --git a/include/a3/weapons_f/acc/data/optics.rvmat b/include/a3/weapons_f/acc/data/optics.rvmat new file mode 100644 index 0000000000..1183f3e16d --- /dev/null +++ b/include/a3/weapons_f/acc/data/optics.rvmat @@ -0,0 +1,82 @@ +class StageTI +{ + texture="a3\data_f\default_ti_ca.paa"; +}; +ambient[]={0,0,0,1}; +diffuse[]={0,0,0,1}; +forcedDiffuse[]={0,0,0,1}; +emmisive[]={0,0,0,1}; +specular[]={1,1,1,1}; +specularPower=500; +PixelShaderID="Super"; +VertexShaderID="Super"; +class Stage1 +{ + texture="a3\weapons_f\acc\data\optics_nohq.paa"; + uvSource="tex1"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage2 +{ + texture="#(argb,8,8,3)color(0.5,0.5,0.5,0.5,DT)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage3 +{ + texture="#(argb,8,8,3)color(0,0,0,0.0,MC)"; + uvSource="tex"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage4 +{ + texture="a3\weapons_f\acc\data\optics_as.paa"; + uvSource="tex1"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage5 +{ + texture="#(argb,8,8,3)color(1,1,1,0.0,SMDI)"; + uvSource="tex1"; + class uvTransform + { + aside[]={1,0,0}; + up[]={0,1,0}; + dir[]={0,0,0}; + pos[]={0,0,0}; + }; +}; +class Stage6 +{ + texture="#(ai,64,64,1)fresnel(0.915,0.38)"; + uvSource="none"; +}; +class Stage7 +{ + texture="a3\data_f\env_land_optic_co.paa"; + uvSource="none"; +}; diff --git a/include/a3/weapons_f/acc/data/scope_view3_ca.paa b/include/a3/weapons_f/acc/data/scope_view3_ca.paa new file mode 100644 index 0000000000..d7ef93da49 Binary files /dev/null and b/include/a3/weapons_f/acc/data/scope_view3_ca.paa differ diff --git a/include/a3/weapons_f/acc/data/scope_view_ca.paa b/include/a3/weapons_f/acc/data/scope_view_ca.paa new file mode 100644 index 0000000000..a8dc6b370a Binary files /dev/null and b/include/a3/weapons_f/acc/data/scope_view_ca.paa differ diff --git a/include/a3/weapons_f/data/nightvisiontl.paa b/include/a3/weapons_f/data/nightvisiontl.paa new file mode 100644 index 0000000000..04bddf8795 Binary files /dev/null and b/include/a3/weapons_f/data/nightvisiontl.paa differ diff --git a/include/a3/weapons_f/reticle/data/optics_bg_dirt_ca.paa b/include/a3/weapons_f/reticle/data/optics_bg_dirt_ca.paa new file mode 100644 index 0000000000..d08da9e16d Binary files /dev/null and b/include/a3/weapons_f/reticle/data/optics_bg_dirt_ca.paa differ diff --git a/include/vn/weapons_f_vietnam/mines/m14/vn_mine_m14_mag.p3d b/include/vn/weapons_f_vietnam/mines/m14/vn_mine_m14_mag.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/m15/vn_mine_m15_mag.p3d b/include/vn/weapons_f_vietnam/mines/m15/vn_mine_m15_mag.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/m16/vn_mine_m16_mag.p3d b/include/vn/weapons_f_vietnam/mines/m16/vn_mine_m16_mag.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/m16/vn_mine_tripwire_m16_02.p3d b/include/vn/weapons_f_vietnam/mines/m16/vn_mine_tripwire_m16_02.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/m16/vn_mine_tripwire_m16_04.p3d b/include/vn/weapons_f_vietnam/mines/m16/vn_mine_tripwire_m16_04.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/m18/vn_mine_m18.p3d b/include/vn/weapons_f_vietnam/mines/m18/vn_mine_m18.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/m18/vn_mine_m18_x3.p3d b/include/vn/weapons_f_vietnam/mines/m18/vn_mine_m18_x3.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/punji/vn_mine_punji_01_mag.p3d b/include/vn/weapons_f_vietnam/mines/punji/vn_mine_punji_01_mag.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/punji/vn_mine_punji_02_mag.p3d b/include/vn/weapons_f_vietnam/mines/punji/vn_mine_punji_02_mag.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/punji/vn_mine_punji_03_mag.p3d b/include/vn/weapons_f_vietnam/mines/punji/vn_mine_punji_03_mag.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/tm57/vn_mine_tm57_mag.p3d b/include/vn/weapons_f_vietnam/mines/tm57/vn_mine_tm57_mag.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/tripwire_arty/vn_mine_tripwire_arty.p3d b/include/vn/weapons_f_vietnam/mines/tripwire_arty/vn_mine_tripwire_arty.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/tripwire_f1/vn_mine_tripwire_f1_02.p3d b/include/vn/weapons_f_vietnam/mines/tripwire_f1/vn_mine_tripwire_f1_02.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/include/vn/weapons_f_vietnam/mines/tripwire_f1/vn_mine_tripwire_f1_04.p3d b/include/vn/weapons_f_vietnam/mines/tripwire_f1/vn_mine_tripwire_f1_04.p3d deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/optionals/tracers/stringtable.xml b/optionals/tracers/stringtable.xml index 30b6b04d88..f4b1d5a750 100644 --- a/optionals/tracers/stringtable.xml +++ b/optionals/tracers/stringtable.xml @@ -8,7 +8,7 @@ Магазин 150 патр. 5.56 мм с послед. трас. (зелёные) 5.56 mm 150 colpi ricarica traccianti (verdi) caricatore 5.56 mm 150 ranný zásobník, stopovka pro přebití (Zelená) - Recarregar magazine de 150 balas tracejantes (verde) + Recarregar magazine de 150 balas tracejantes (Verde) 5.56 mm 150発入り 残通知 曳光弾 (緑) マガジン Cargador de 150 Cartuchos 5.56 mm Trazadora de recarga (Verde) 5.56mm 150발들이 재장전 알림 예광탄 (초록) 탄창 @@ -32,7 +32,7 @@ Магазин 150 патр. 5.56 мм трассирующих (зелёные) 5.56 mm 150 colpi traccianti (verdi) caricatore 5.56 mm 150 ranný zásobník, stopovka (Zelená) - Magazine 5.56mm Tracejante (verde) + Magazine 5.56mm Tracejante (Verde) 5.56 mm 150発入り 曳光弾 (緑) マガジン Cargador de 150 Cartuchos 5.56 mm Trazadora (Verde) 5.56mm 150발들이 예광탄 (초록) 탄창 @@ -80,7 +80,7 @@ Короб 200 патр. 5.56 мм с послед. трас. (зелёные) 5.56 mm 200colpi Ricarica traccianti (verdi) scatola 5.56 mm 200 ranný box, stopovka pro přebití (Zelená) - Recarregar Caixa 5.56mm 200 Balas tracejantes (verdes) + Recarregar Caixa 5.56mm 200 Balas tracejantes (Verdes) 5.56 mm 200発入り 残通知 曳光弾 (緑) ボックス Caja de 200 Cartuchos 5.56 mm Trazadora de recarga (Verde) 5.56mm 150발들이 예광탄 (노랑) 탄창 @@ -92,7 +92,7 @@ Короб 200 патр. 5.56 мм трассирующих (зелёные) 5.56 mm 200colpi Traccianti (verdi) Scatola 5.56 mm 200 ranný box, stopovka (Zelená) - Caixa 5.56mm 200 balas tracejantes (verdes) + Caixa 5.56mm 200 balas tracejantes (Verdes) 5.56 mm 200発入り 曳光弾 (緑) ボックス Caja de 200 Cartuchos 5.56 mm Trazadora (Verde) 5.56mm 200발들이 예광탄 (초록) 탄상자 @@ -260,7 +260,7 @@ Магазин 30 патр. 6.5 мм с послед. трас. (зелёные) 6.5mm 30Colpi Ricarica Traccianti(verdi) Caricatore 6.5 mm 30 ranný zásobník, stopovka pro přebití (Zelená) - Recarregar magazine 6.5mm 30 balas tracejantes (verde) + Recarregar magazine 6.5mm 30 balas tracejantes (Verde) 6.5 mm 30発入り 残通知 曳光弾 (緑) マガジン Cargador de 30 Cartuchos 6.5 mm Trazadora de recarga (Verde) 6.5mm 30발들이 재장전 알림 예광탄 (초록) 탄창 @@ -308,7 +308,7 @@ Магазин 30 патр. 6.5 мм трассирующих (зелёные) 6.5mm 30Colpi Traccianti (Verdi) Caricatore 6.5 mm 30 ranný zásobník, stopovka (Zelená) - Magazine 6.5mm 30 balas tracejantes (verde) + Magazine 6.5mm 30 balas tracejantes (Verde) 6.5 mm 30発入り 曳光弾 (緑) マガジン Cargador de 30 Cartuchos 6.5 mm Trazadora (Verde) 6.5mm 30발들이 예광탄 (초록) 탄창 @@ -352,11 +352,11 @@ 6.5mm 100Rnd Mixed Mag (Green) - 100 Schuss 6.5mm Magazin gemischt (grün) + 100 Schuss 6.5mm Magazin gemischt (Grün) Магазин 100 патр. 6.5 мм TE4 (зелёные) 6.5mm 100Colpi Misti Caricatore (verdi) 6.5 mm 100 ranný zásobník, částečná stopovka (Zelená) - Magazine 6.5mm 100 balas misturadas (verde) + Magazine 6.5mm 100 balas misturadas (Verde) 6.5 mm 100発入り 混合 (緑) マガジン Cargador de 100 cartuchos 6.5 mm Mezcla (Verde) 6.5mm 100발들이 혼합탄 (초록) 탄창 @@ -378,7 +378,7 @@ 6.5mm 100Rnd Mag Tracer (Green) 100 Schuss 6.5mm Magazin Leuchtspur (Grün) Магазин 100 патр. 6.5 мм трассирующих (зелёные) - 6.5mm 100Colpi Caricatore Tracciante (verde) + 6.5mm 100Colpi Caricatore Tracciante (Verde) 6.5 mm 100 ranný zásobník, stopovka (Zelená) Magazine 6.5mm 100 balas tracejantes 6.5 mm 100発入り (緑) マガジン @@ -496,7 +496,7 @@ 6.5 mm 200Rnd Belt Case Mixed (Green) - 6,5 mm 200-Schuss-Gurtkiste Gemischt (grün) + 6,5 mm 200-Schuss-Gurtkiste Gemischt (Grün) Короб 200 патр. 6.5 мм TE4 (зелёные) 6.5mm 200Colpi Caricatore esteso Misti (Verdi) 6.5 mm 200 ranný pás, částečná stopovka (Zelená) @@ -520,7 +520,7 @@ 6.5 mm 200Rnd Belt Case Mixed (Red) - 6,5 mm 200-Schuss-Gurtkiste Gemischt (grün) + 6,5 mm 200-Schuss-Gurtkiste Gemischt (Grün) Короб 200 патр. 6.5 мм TE4 (красные) 6.5 mm 200Colpi Caritore maggiorato Misti (rossi) 6.5 mm 200 ranný pás, částečná stopovka (Červená) @@ -544,7 +544,7 @@ 6.5 mm 200Rnd Belt Case Tracer (Green) - 6,5 mm 200-Schuss-Gurtkiste Leuchtspur (grün) + 6,5 mm 200-Schuss-Gurtkiste Leuchtspur (Grün) Короб 200 патр. 6.5 мм трассирующих (зелёные) 6.5 mm 200Colpi Caricatore maggiorato Traccianti (verdi) 6.5 mm 200 ranný pás, částečná stopovka (Zelená) @@ -600,7 +600,7 @@ 7.62 mm 20Colpi Traccianti (verdi) Caricatore 7.62 mm 20 ranný zásobník, stopovka (Zelená) 7.62 mm Magazynek 20szt. Smugowa (Zielona) - Magazine 7.62 mm 20 Balas Tracejantes (verdes) + Magazine 7.62 mm 20 Balas Tracejantes (Verdes) 7.62 mm 20発入り 曳光弾 (緑) マガジン Cargador de 20 cartuchos 7.62 mm Trazadora (Verde) 7.62mm 20발들이 예광탄 (초록) 탄창 @@ -764,7 +764,7 @@ .338 NM 130Rnd Belt Mixed (Green) - .338 NM 130 Schuss Gurt gemischt (grün) + .338 NM 130 Schuss Gurt gemischt (Grün) Лента 130 патр. .338 NM TE4 (зелёные) .338 NM 130Colpi Caricatore a nastro Misto (Verde) .338 NM 130 ranný pás, částečná stopovka (Zelená) diff --git a/sqfc.json b/sqfc.json index 53209261b8..948f7ed1d5 100644 --- a/sqfc.json +++ b/sqfc.json @@ -6,11 +6,8 @@ "P:/" ], "excludeList": [ - "initsettings.sqf", - "initkeybinds.sqf", - "xeh_prep.sqf", + ".inc.sqf", "\\dev\\", - "medical_ai\\statemachine.sqf", "common\\functions\\fnc_dummy.sqf", "zeus\\functions\\fnc_zeusAttributes.sqf" ], diff --git a/tools/.vscode/settings.json b/tools/.vscode/settings.json index 57fcac4d62..490d2309b7 100644 --- a/tools/.vscode/settings.json +++ b/tools/.vscode/settings.json @@ -1,6 +1,7 @@ { "files.exclude": { "**/.hemttout": true, - "**/include": true + "**/include": true, + "**/extras": true } } \ No newline at end of file diff --git a/tools/.vscode/tasks.json b/tools/.vscode/tasks.json index 233c20e78c..eb919f5309 100644 --- a/tools/.vscode/tasks.json +++ b/tools/.vscode/tasks.json @@ -63,6 +63,16 @@ "--debug" ] }, + { + "label": "HEMTT check", + "command": "hemtt.exe", + "options": { + "cwd": "${workspaceFolder}" + }, + "args": [ + "check" + ], + }, { "label": "Test All", "dependsOn": [ @@ -71,7 +81,8 @@ "Validate Stringtables", "Validate headers", "Check Strings", - "SQFVM Checker" + "SQFVM Checker", + "HEMTT check" ], "group": { "kind": "test", @@ -89,8 +100,7 @@ "ci" ], "group": { - "kind": "build", - "isDefault": true + "kind": "build" } }, { @@ -103,7 +113,10 @@ "build", "-v" ], - "group": "build" + "group": { + "kind": "build", + "isDefault": true + } } ] } \ No newline at end of file diff --git a/include/vn/characters_f_vietnam/OPFOR/vests/items/vn_mine_satchel_02.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_AT15.p3d similarity index 100% rename from include/vn/characters_f_vietnam/OPFOR/vests/items/vn_mine_satchel_02.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_AT15.p3d diff --git a/include/vn/objects_f_vietnam/supply/a2_ammo/macv/vn_us_30cal.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V1.p3d similarity index 100% rename from include/vn/objects_f_vietnam/supply/a2_ammo/macv/vn_us_30cal.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V1.p3d diff --git a/include/vn/objects_f_vietnam/supply/a2_ammo/macv/vn_us_can_30.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V2.p3d similarity index 100% rename from include/vn/objects_f_vietnam/supply/a2_ammo/macv/vn_us_can_30.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V2.p3d diff --git a/include/vn/objects_f_vietnam/supply/a2_ammo/pavn/vn_pavn_50_can.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V3.p3d similarity index 100% rename from include/vn/objects_f_vietnam/supply/a2_ammo/pavn/vn_pavn_50_can.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V3.p3d diff --git a/include/vn/objects_f_vietnam/usarmy/furniture/vn_us_fort_common_crate_01.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V4.p3d similarity index 100% rename from include/vn/objects_f_vietnam/usarmy/furniture/vn_us_fort_common_crate_01.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_IED_V4.p3d diff --git a/include/vn/objects_f_vietnam/usarmy/supply/mortar_m2/vn_prop_60mm_crate_01.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_Satchel.p3d similarity index 100% rename from include/vn/objects_f_vietnam/usarmy/supply/mortar_m2/vn_prop_60mm_crate_01.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_Satchel.p3d diff --git a/include/vn/objects_f_vietnam/usarmy/supply/mortar_m29/vn_prop_81mm_crate_02.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_TM46.p3d similarity index 100% rename from include/vn/objects_f_vietnam/usarmy/supply/mortar_m29/vn_prop_81mm_crate_02.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_Put/CUP_TM46.p3d diff --git a/include/vn/static_f_vietnam/mortar_m2/vn_shell_60mm_m302_wp_ammo.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/AGS/data/ui/ags_static_ca.paa similarity index 100% rename from include/vn/static_f_vietnam/mortar_m2/vn_shell_60mm_m302_wp_ammo.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/AGS/data/ui/ags_static_ca.paa diff --git a/include/vn/static_f_vietnam/mortar_m2/vn_shell_60mm_m49a2_he_ammo.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/DShKM/data/ui/icomap_DShKM_ca.paa similarity index 100% rename from include/vn/static_f_vietnam/mortar_m2/vn_shell_60mm_m49a2_he_ammo.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/DShKM/data/ui/icomap_DShKM_ca.paa diff --git a/include/vn/static_f_vietnam/mortar_m2/vn_shell_60mm_m83_lume_ammo.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/KORD/data/ui/icomap_kord_ca.paa similarity index 100% rename from include/vn/static_f_vietnam/mortar_m2/vn_shell_60mm_m83_lume_ammo.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/KORD/data/ui/icomap_kord_ca.paa diff --git a/include/vn/static_f_vietnam/mortar_m29/vn_shell_81mm_m374_he_ammo.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/M2/data/ui/icomap_M2_ca.paa similarity index 100% rename from include/vn/static_f_vietnam/mortar_m29/vn_shell_81mm_m374_he_ammo.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/M2/data/ui/icomap_M2_ca.paa diff --git a/include/vn/static_f_vietnam/mortar_type53/vn_shell_82mm_d832_wp_ammo.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/M252/data/ui/icomap_mortar_m251_ca.paa similarity index 100% rename from include/vn/static_f_vietnam/mortar_type53/vn_shell_82mm_d832_wp_ammo.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/M252/data/ui/icomap_mortar_m251_ca.paa diff --git a/include/vn/static_f_vietnam/mortar_type53/vn_shell_82mm_o832d_he_ammo.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/Mk19/data/ui/icomap_mk19_stat_ca.paa similarity index 100% rename from include/vn/static_f_vietnam/mortar_type53/vn_shell_82mm_o832d_he_ammo.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/Mk19/data/ui/icomap_mk19_stat_ca.paa diff --git a/include/vn/static_f_vietnam/mortar_type53/vn_shell_82mm_s832s_lume_ammo.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/Podnos/data/ui/podnos_2b14_ca.paa similarity index 100% rename from include/vn/static_f_vietnam/mortar_type53/vn_shell_82mm_s832s_lume_ammo.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/Podnos/data/ui/podnos_2b14_ca.paa diff --git a/include/vn/static_f_vietnam/tow/vn_static_tow_mag.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/SPG9/data/ui/icon_spg9_ca.paa similarity index 100% rename from include/vn/static_f_vietnam/tow/vn_static_tow_mag.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/SPG9/data/ui/icon_spg9_ca.paa diff --git a/include/vn/weapons_f_vietnam/mines/m112/vn_mine_m112_mag.p3d b/tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/TOW/data/ui/icomap_tow_static_ca.paa similarity index 100% rename from include/vn/weapons_f_vietnam/mines/m112/vn_mine_m112_mag.p3d rename to tools/pDummies/CUP/Weapons/CUP_Weapons_StaticWeapons/TOW/data/ui/icomap_tow_static_ca.paa diff --git a/tools/sqf_linter.py b/tools/sqf_linter.py index 58a1491a99..c71c72094e 100644 --- a/tools/sqf_linter.py +++ b/tools/sqf_linter.py @@ -11,17 +11,13 @@ from sqf.exceptions import SQFParserError addon_base_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -files_to_ignore_lower = [ - x.lower() for x in ["initSettings.sqf", "initKeybinds.sqf", "XEH_PREP.sqf"] -] - def get_files_to_process(basePath): arma_files = [] for (root, _dirs, files) in os.walk(basePath): for file in files: if file.endswith(".sqf"): - if file.lower() in files_to_ignore_lower: + if file.endswith(".inc.sqf"): continue filePath = os.path.join(root, file) arma_files.append(filePath) diff --git a/tools/sqfvmChecker.py b/tools/sqfvmChecker.py index 021bc98daa..69d7566100 100644 --- a/tools/sqfvmChecker.py +++ b/tools/sqfvmChecker.py @@ -6,9 +6,6 @@ import tomllib addon_base_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) -files_to_ignore_lower = [ - x.lower() for x in ["initSettings.sqf", "initKeybinds.sqf", "XEH_PREP.sqf"] -] sqfvm_exe = os.path.join(addon_base_path, "sqfvm.exe") virtual_paths = [ # would need to add more even more to /include to use it @@ -24,7 +21,7 @@ def get_files_to_process(basePath): for root, _dirs, files in os.walk(os.path.join(addon_base_path, "addons")): for file in files: if file.endswith(".sqf") or file == "config.cpp": - if file.lower() in files_to_ignore_lower: + if file.endswith(".inc.sqf"): continue skipPreprocessing = False for addonTomlPath in [os.path.join(root, "addon.toml"), os.path.join(os.path.dirname(root), "addon.toml")]: